fix(SW-1446): make clear history action work, reduces complexity and improves separation of concerns
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { cx } from "class-variance-authority"
|
import { cx } from "class-variance-authority"
|
||||||
import { useRouter } from "next/navigation"
|
import { memo, useTransition } from "react"
|
||||||
import { memo, useMemo, useTransition } from "react"
|
|
||||||
import {
|
import {
|
||||||
Autocomplete,
|
Autocomplete,
|
||||||
Button as ButtonRAC,
|
Button as ButtonRAC,
|
||||||
@@ -17,24 +16,20 @@ import { Button } from "@scandic-hotels/design-system/Button"
|
|||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import { ResultHistory } from "../Results/ResultHistory"
|
import { Results } from "../Results"
|
||||||
import { ResultMatches } from "../Results/ResultMatches"
|
|
||||||
|
|
||||||
import styles from "./clientInline.module.css"
|
import styles from "./clientInline.module.css"
|
||||||
|
|
||||||
import type { ClientProps } from "@/types/components/destinationOverviewPage/jumpTo/client"
|
import type { ClientProps } from "@/types/components/destinationOverviewPage/jumpTo/client"
|
||||||
|
|
||||||
const ResultMatchesMemo = memo(ResultMatches)
|
const ResultsMemo = memo(Results)
|
||||||
const ResultHistoryMemo = memo(ResultHistory)
|
|
||||||
|
|
||||||
export function ClientInline({
|
export function ClientInline({
|
||||||
results,
|
results,
|
||||||
latest,
|
latest,
|
||||||
setFilterString,
|
setFilterString,
|
||||||
onAction,
|
onAction,
|
||||||
onClearHistory,
|
|
||||||
}: ClientProps) {
|
}: ClientProps) {
|
||||||
const router = useRouter()
|
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const [isPending, startTransition] = useTransition()
|
const [isPending, startTransition] = useTransition()
|
||||||
const isMounted = useIsMounted()
|
const isMounted = useIsMounted()
|
||||||
@@ -42,20 +37,6 @@ export function ClientInline({
|
|||||||
const showResults = !!results
|
const showResults = !!results
|
||||||
const showHistory = isMounted() && (!results || results.length === 0)
|
const showHistory = isMounted() && (!results || results.length === 0)
|
||||||
|
|
||||||
const latestResults = useMemo(() => {
|
|
||||||
return latest.concat({
|
|
||||||
id: "actions", // The string "Actions" converts into a divider below
|
|
||||||
name: "Actions",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: "clearHistory",
|
|
||||||
type: "clearHistory",
|
|
||||||
displayName: intl.formatMessage({ id: "Clear searches" }),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
}, [intl, latest])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Autocomplete>
|
<Autocomplete>
|
||||||
<div className={styles.autocomplete}>
|
<div className={styles.autocomplete}>
|
||||||
@@ -73,22 +54,6 @@ export function ClientInline({
|
|||||||
onSubmit={(evt) => {
|
onSubmit={(evt) => {
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
evt.stopPropagation()
|
evt.stopPropagation()
|
||||||
|
|
||||||
startTransition(() => {
|
|
||||||
if (results) {
|
|
||||||
const firstItem = results[0].children[0]
|
|
||||||
onAction(firstItem.id)
|
|
||||||
if (firstItem.url) {
|
|
||||||
router.push(firstItem.url)
|
|
||||||
}
|
|
||||||
} else if (latest) {
|
|
||||||
const firstItem = latest[0].children[0]
|
|
||||||
onAction(firstItem.id)
|
|
||||||
if (firstItem.url) {
|
|
||||||
router.push(firstItem.url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={styles.fields}>
|
<div className={styles.fields}>
|
||||||
@@ -145,12 +110,19 @@ export function ClientInline({
|
|||||||
aria-live="polite"
|
aria-live="polite"
|
||||||
>
|
>
|
||||||
{showResults ? (
|
{showResults ? (
|
||||||
<ResultMatchesMemo results={results} onAction={onAction} />
|
<ResultsMemo
|
||||||
|
aria-label={intl.formatMessage({ id: "Results" })}
|
||||||
|
results={results}
|
||||||
|
onAction={onAction}
|
||||||
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
{showHistory ? (
|
{showHistory ? (
|
||||||
<ResultHistoryMemo
|
<ResultsMemo
|
||||||
results={latestResults}
|
aria-label={intl.formatMessage({
|
||||||
onClearHistory={onClearHistory}
|
id: "Latest searches",
|
||||||
|
})}
|
||||||
|
results={latest}
|
||||||
|
onAction={onAction}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { cx } from "class-variance-authority"
|
import { cx } from "class-variance-authority"
|
||||||
import { useRouter } from "next/navigation"
|
import { memo, useTransition } from "react"
|
||||||
import { memo, useMemo, useTransition } from "react"
|
|
||||||
import {
|
import {
|
||||||
Autocomplete,
|
Autocomplete,
|
||||||
Button as ButtonRAC,
|
Button as ButtonRAC,
|
||||||
@@ -20,44 +19,26 @@ import { useIntl } from "react-intl"
|
|||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import { ResultHistory } from "../Results/ResultHistory"
|
import { Results } from "../Results"
|
||||||
import { ResultMatches } from "../Results/ResultMatches"
|
|
||||||
|
|
||||||
import styles from "./clientModal.module.css"
|
import styles from "./clientModal.module.css"
|
||||||
|
|
||||||
import type { ClientProps } from "@/types/components/destinationOverviewPage/jumpTo/client"
|
import type { ClientProps } from "@/types/components/destinationOverviewPage/jumpTo/client"
|
||||||
|
|
||||||
const ResultMatchesMemo = memo(ResultMatches)
|
const ResultsMemo = memo(Results)
|
||||||
const ResultHistoryMemo = memo(ResultHistory)
|
|
||||||
|
|
||||||
export function ClientModal({
|
export function ClientModal({
|
||||||
results,
|
results,
|
||||||
latest,
|
latest,
|
||||||
setFilterString,
|
setFilterString,
|
||||||
onAction,
|
onAction,
|
||||||
onClearHistory,
|
|
||||||
}: ClientProps) {
|
}: ClientProps) {
|
||||||
const router = useRouter()
|
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const [isPending, startTransition] = useTransition()
|
const [isPending, startTransition] = useTransition()
|
||||||
|
|
||||||
const showResults = !!results
|
const showResults = !!results
|
||||||
const showHistory = !results || results.length === 0
|
const showHistory = !results || results.length === 0
|
||||||
|
|
||||||
const latestResults = useMemo(() => {
|
|
||||||
return latest.concat({
|
|
||||||
id: "actions", // The string "Actions" converts into a divider below
|
|
||||||
name: "Actions",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: "clearHistory",
|
|
||||||
type: "clearHistory",
|
|
||||||
displayName: intl.formatMessage({ id: "Clear searches" }),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
}, [intl, latest])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogTrigger>
|
<DialogTrigger>
|
||||||
<ButtonRAC className={styles.trigger}>
|
<ButtonRAC className={styles.trigger}>
|
||||||
@@ -106,22 +87,6 @@ export function ClientModal({
|
|||||||
onSubmit={(evt) => {
|
onSubmit={(evt) => {
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
evt.stopPropagation()
|
evt.stopPropagation()
|
||||||
|
|
||||||
startTransition(() => {
|
|
||||||
if (results) {
|
|
||||||
const firstItem = results[0].children[0]
|
|
||||||
onAction(firstItem.id)
|
|
||||||
if (firstItem.url) {
|
|
||||||
router.push(firstItem.url)
|
|
||||||
}
|
|
||||||
} else if (latest) {
|
|
||||||
const firstItem = latest[0].children[0]
|
|
||||||
onAction(firstItem.id)
|
|
||||||
if (firstItem.url) {
|
|
||||||
router.push(firstItem.url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="Body/Supporting text (caption)/smBold">
|
<Typography variant="Body/Supporting text (caption)/smBold">
|
||||||
@@ -166,15 +131,19 @@ export function ClientModal({
|
|||||||
aria-live="polite"
|
aria-live="polite"
|
||||||
>
|
>
|
||||||
{showResults ? (
|
{showResults ? (
|
||||||
<ResultMatchesMemo
|
<ResultsMemo
|
||||||
|
aria-label={intl.formatMessage({ id: "Results" })}
|
||||||
results={results}
|
results={results}
|
||||||
onAction={onAction}
|
onAction={onAction}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
{showHistory ? (
|
{showHistory ? (
|
||||||
<ResultHistoryMemo
|
<ResultsMemo
|
||||||
results={latestResults}
|
aria-label={intl.formatMessage({
|
||||||
onClearHistory={onClearHistory}
|
id: "Latest searches",
|
||||||
|
})}
|
||||||
|
results={latest}
|
||||||
|
onAction={onAction}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import {
|
|
||||||
Collection,
|
|
||||||
Header,
|
|
||||||
Menu,
|
|
||||||
MenuItem,
|
|
||||||
MenuSection,
|
|
||||||
Text,
|
|
||||||
} from "react-aria-components"
|
|
||||||
import { useIntl } from "react-intl"
|
|
||||||
|
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
|
||||||
|
|
||||||
import styles from "./results.module.css"
|
|
||||||
|
|
||||||
import type { ResultMatchesProps } from "@/types/components/destinationOverviewPage/jumpTo/results"
|
|
||||||
|
|
||||||
export function ResultMatches({ results, onAction }: ResultMatchesProps) {
|
|
||||||
const intl = useIntl()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Menu
|
|
||||||
aria-label={intl.formatMessage({ id: "Results" })}
|
|
||||||
className={styles.menu}
|
|
||||||
items={results}
|
|
||||||
onAction={(key) => onAction(key.toString())}
|
|
||||||
renderEmptyState={() => {
|
|
||||||
return (
|
|
||||||
<div className={styles.noResults}>
|
|
||||||
<Typography variant="Body/Paragraph/mdBold">
|
|
||||||
<Header className={styles.noResultsLabel}>
|
|
||||||
{intl.formatMessage({ id: "No results" })}
|
|
||||||
</Header>
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="Body/Paragraph/mdRegular">
|
|
||||||
<span className={styles.noResultsDescription}>
|
|
||||||
{intl.formatMessage({
|
|
||||||
id: "We couldn't find a matching location for your search.",
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{(section) => (
|
|
||||||
<MenuSection key={section.id}>
|
|
||||||
<Typography variant="Title/Overline/sm">
|
|
||||||
<Header className={styles.sectionHeader}>{section.name}</Header>
|
|
||||||
</Typography>
|
|
||||||
<Collection items={section.children}>
|
|
||||||
{(item) => (
|
|
||||||
<MenuItem
|
|
||||||
className={styles.item}
|
|
||||||
href={item.url}
|
|
||||||
key={item.id}
|
|
||||||
textValue={item.displayName}
|
|
||||||
>
|
|
||||||
<Typography variant="Body/Paragraph/mdBold">
|
|
||||||
<Text slot="label" className={styles.itemLabel}>
|
|
||||||
{item.displayName}
|
|
||||||
</Text>
|
|
||||||
</Typography>
|
|
||||||
{item.description ? (
|
|
||||||
<Typography variant="Body/Paragraph/mdRegular">
|
|
||||||
<Text slot="description" className={styles.itemDescription}>
|
|
||||||
{item.description}
|
|
||||||
</Text>
|
|
||||||
</Typography>
|
|
||||||
) : null}
|
|
||||||
</MenuItem>
|
|
||||||
)}
|
|
||||||
</Collection>
|
|
||||||
</MenuSection>
|
|
||||||
)}
|
|
||||||
</Menu>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ import SkeletonShimmer from "@/components/SkeletonShimmer"
|
|||||||
|
|
||||||
import styles from "./results.module.css"
|
import styles from "./results.module.css"
|
||||||
|
|
||||||
export function ResultSkeleton() {
|
export function ResultsSkeleton() {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -10,22 +10,24 @@ import {
|
|||||||
} from "react-aria-components"
|
} from "react-aria-components"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { Button } from "@scandic-hotels/design-system/Button"
|
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import styles from "./results.module.css"
|
import styles from "./results.module.css"
|
||||||
|
|
||||||
import type { ResultHistoryProps } from "@/types/components/destinationOverviewPage/jumpTo/results"
|
import type { ResultsProps } from "@/types/components/destinationOverviewPage/jumpTo/results"
|
||||||
|
|
||||||
export function ResultHistory({ results, onClearHistory }: ResultHistoryProps) {
|
export function Results({
|
||||||
|
"aria-label": ariaLabel,
|
||||||
|
results,
|
||||||
|
onAction,
|
||||||
|
}: ResultsProps) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<Menu
|
||||||
aria-label={intl.formatMessage({
|
aria-label={ariaLabel}
|
||||||
id: "Latest searches",
|
onAction={onAction}
|
||||||
})}
|
|
||||||
className={styles.menu}
|
className={styles.menu}
|
||||||
items={results}
|
items={results}
|
||||||
renderEmptyState={() => {
|
renderEmptyState={() => {
|
||||||
@@ -45,19 +47,18 @@ export function ResultHistory({ results, onClearHistory }: ResultHistoryProps) {
|
|||||||
className={styles.item}
|
className={styles.item}
|
||||||
textValue={item.displayName}
|
textValue={item.displayName}
|
||||||
>
|
>
|
||||||
<Button
|
{item.id === "clearHistory" ? (
|
||||||
typography="Body/Supporting text (caption)/smBold"
|
<>
|
||||||
variant="Text"
|
<MaterialIcon icon="delete" color="CurrentColor" />
|
||||||
onPress={onClearHistory}
|
<Typography variant="Body/Supporting text (caption)/smBold">
|
||||||
className={styles.clearHistoryButton}
|
<Text slot="label">
|
||||||
>
|
{intl.formatMessage({
|
||||||
<MaterialIcon icon="delete" color="CurrentColor" />
|
id: "Clear searches",
|
||||||
<Text slot="label">
|
})}
|
||||||
{intl.formatMessage({
|
</Text>
|
||||||
id: "Clear searches",
|
</Typography>
|
||||||
})}
|
</>
|
||||||
</Text>
|
) : null}
|
||||||
</Button>
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
</Collection>
|
</Collection>
|
||||||
@@ -51,11 +51,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.actionsSection .item {
|
.actionsSection .item {
|
||||||
padding-top: 0;
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clearHistoryButton {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: var(--Space-x05);
|
gap: var(--Space-x05);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useCallback, useMemo, useState } from "react"
|
import { useCallback, useMemo, useState } from "react"
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
import { useIsMounted, useMediaQuery } from "usehooks-ts"
|
import { useIsMounted, useMediaQuery } from "usehooks-ts"
|
||||||
|
|
||||||
import { isDefined } from "@/server/utils"
|
import { isDefined } from "@/server/utils"
|
||||||
@@ -24,6 +25,7 @@ export function JumpToClient<T extends JumpToData>({
|
|||||||
onAction,
|
onAction,
|
||||||
onClearHistory,
|
onClearHistory,
|
||||||
}: JumpToProps<T>) {
|
}: JumpToProps<T>) {
|
||||||
|
const intl = useIntl()
|
||||||
const isMounted = useIsMounted()
|
const isMounted = useIsMounted()
|
||||||
const displayInModal = useMediaQuery("(max-width: 767px)")
|
const displayInModal = useMediaQuery("(max-width: 767px)")
|
||||||
|
|
||||||
@@ -143,12 +145,23 @@ export function JumpToClient<T extends JumpToData>({
|
|||||||
{
|
{
|
||||||
id: "latestSearches",
|
id: "latestSearches",
|
||||||
name: "Latest searches",
|
name: "Latest searches",
|
||||||
children,
|
children: children,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "actions", // The string "Actions" converts into a divider
|
||||||
|
name: "Actions",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: "clearHistory",
|
||||||
|
type: "clearHistory",
|
||||||
|
displayName: intl.formatMessage({ id: "Clear searches" }),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}, [data, history])
|
}, [data, history, intl])
|
||||||
|
|
||||||
const results = useMemo(() => {
|
const results = useMemo(() => {
|
||||||
if (filterString) {
|
if (filterString) {
|
||||||
@@ -163,8 +176,15 @@ export function JumpToClient<T extends JumpToData>({
|
|||||||
results,
|
results,
|
||||||
latest,
|
latest,
|
||||||
setFilterString,
|
setFilterString,
|
||||||
onAction,
|
onAction: (key) => {
|
||||||
onClearHistory,
|
switch (key) {
|
||||||
|
case "clearHistory":
|
||||||
|
onClearHistory()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
onAction(key)
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}, [results, latest, setFilterString, onAction, onClearHistory])
|
}, [results, latest, setFilterString, onAction, onClearHistory])
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ export function JumpToResolver({ dataPromise }: JumpToResolverProps) {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onClearHistory={() => {
|
onClearHistory={() => {
|
||||||
debugger
|
|
||||||
clearHistory()
|
clearHistory()
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -5,5 +5,4 @@ export type ClientProps = {
|
|||||||
latest: NonNullable<LocationMatchResultsState>
|
latest: NonNullable<LocationMatchResultsState>
|
||||||
setFilterString: (filter: string | null) => void
|
setFilterString: (filter: string | null) => void
|
||||||
onAction: JumpToProps<JumpToData>["onAction"]
|
onAction: JumpToProps<JumpToData>["onAction"]
|
||||||
onClearHistory: () => void
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import type { Key } from "react-aria-components"
|
||||||
|
|
||||||
export type JumpToDataItem = {
|
export type JumpToDataItem = {
|
||||||
id: string
|
id: Key
|
||||||
displayName: string
|
displayName: string
|
||||||
type: "hotels" | "cities"
|
type: "hotels" | "cities"
|
||||||
description: string
|
description: string
|
||||||
@@ -15,7 +17,7 @@ export type JumpToHistory = {
|
|||||||
type: JumpToDataItem["type"]
|
type: JumpToDataItem["type"]
|
||||||
}[]
|
}[]
|
||||||
|
|
||||||
export type JumpToProps<T extends { id: string }[]> = {
|
export type JumpToProps<T extends { id: Key }[]> = {
|
||||||
data: T
|
data: T
|
||||||
history: JumpToHistory
|
history: JumpToHistory
|
||||||
onAction: (id: T[number]["id"]) => void
|
onAction: (id: T[number]["id"]) => void
|
||||||
@@ -23,7 +25,7 @@ export type JumpToProps<T extends { id: string }[]> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type LocationMatch = {
|
export type LocationMatch = {
|
||||||
id: string
|
id: Key
|
||||||
displayName: string
|
displayName: string
|
||||||
type: string
|
type: string
|
||||||
description?: string
|
description?: string
|
||||||
@@ -35,7 +37,7 @@ export type ScoringMatch = LocationMatch & {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type LocationMatchResult = {
|
export type LocationMatchResult = {
|
||||||
id: string
|
id: Key
|
||||||
name: string
|
name: string
|
||||||
children: LocationMatch[]
|
children: LocationMatch[]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
import type { ClientProps } from "./client"
|
import type { ClientProps } from "./client"
|
||||||
|
|
||||||
export type ResultHistoryProps = Pick<ClientProps, "onClearHistory"> & {
|
export type ResultsProps = Pick<ClientProps, "onAction"> & {
|
||||||
results: ClientProps["latest"]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ResultMatchesProps = Pick<ClientProps, "onAction"> & {
|
|
||||||
results: NonNullable<ClientProps["results"]>
|
results: NonNullable<ClientProps["results"]>
|
||||||
|
"aria-label": string
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user