filters
Filters with prefetched async options
Filters with prefetched async options
Загрузка превью…
src/filters/c-filters-11.vue
<!--
ПОРТ c-filters-11 ("Filters with prefetched async options").
Апстрим прогоняет `loadOptions` через реальный `setTimeout` (600ms) на
первом вызове, чтобы симулировать сетевую задержку prefetch-а. Попапы
значений не раскрываются на статичном скриншоте (см. docs/PORTING.md,
раздел про `filters`), поэтому `loadOptions` физически не вызывается при
монтировании — сам факт задержки не мог бы повлиять на диф. Тем не менее
правило (никакого таймера, влияющего на первый рендер / детерминированный
источник данных) соблюдено дословно: `setTimeout` заменён на
`Promise.resolve()` (сохраняет асинхронность вызова — как и апстримный
`loadOptions`, возвращающий `Promise`), а кеширование через closure-ref
перенесено как есть.
-->
<script setup lang="ts">
import { h, ref } from "vue"
import {
Filters,
type Filter,
type FilterFieldConfig,
type FilterOption,
} from "@/components/reui/filters"
function UsersIcon() {
return h(
"svg",
{
xmlns: "http://www.w3.org/2000/svg",
width: "24",
height: "24",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
"stroke-width": "2",
"stroke-linecap": "round",
"stroke-linejoin": "round",
class: "size-3.5",
},
[
h("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }),
h("path", { d: "M16 3.128a4 4 0 0 1 0 7.744" }),
h("path", { d: "M22 21v-2a4 4 0 0 0-3-3.87" }),
h("circle", { cx: "9", cy: "7", r: "4" }),
]
)
}
// Prefetch source: the whole remote list, cached in a closure ref once
// `loadOptions` resolves for the first time (same shape as the React `useRef`
// cache in the upstream pattern).
const TEAMS: FilterOption<string>[] = [
{ value: "eng", label: "Engineering" },
{ value: "design", label: "Design" },
{ value: "product", label: "Product" },
{ value: "marketing", label: "Marketing" },
{ value: "sales", label: "Sales" },
{ value: "support", label: "Customer Support" },
{ value: "finance", label: "Finance" },
{ value: "people", label: "People Ops" },
{ value: "legal", label: "Legal" },
{ value: "it", label: "IT" },
{ value: "data", label: "Data & Analytics" },
{ value: "security", label: "Security" },
]
let cache: FilterOption<string>[] | null = null
const demoFields: FilterFieldConfig<string>[] = [
{
key: "team",
label: "Team",
icon: UsersIcon,
type: "multiselect",
// Prefetch the whole list once, then filter the cached copy by the
// query so the search box still works without more requests. Real
// network delay replaced by a plain microtask (ponytail: no fake timer
// may gate the first render; the async shape of `loadOptions` itself is
// preserved verbatim).
loadOptions: async (query: string) => {
if (!cache) {
await Promise.resolve()
cache = TEAMS
}
const q = query.trim().toLowerCase()
return q ? cache.filter((team) => team.label.toLowerCase().includes(q)) : cache
},
},
]
const filters = ref<Filter<string>[]>([])
function handleFiltersChange(next: Filter<string>[]) {
filters.value = next
}
</script>
<template>
<div class="flex grow content-start items-start self-start">
<Filters :filters="filters" :fields="demoFields" @change="handleFiltersChange" />
</div>
</template>
Установка
npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-filters-11.jsonЗависимости реестра
Источник: порт из ReUI (Keenthemes, MIT)