@krak-stack/registry 0.1.5 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/components/ui/data-table.js +78 -28
- package/dist/components/ui/editing-locale-switcher.js +8 -0
- package/dist/components/ui/effect-form.js +71 -21
- package/dist/components/ui/file-picker.js +8 -0
- package/dist/components/ui/form.js +71 -21
- package/dist/components/ui/google-map.js +8 -0
- package/dist/components/ui/icon-input.js +71 -21
- package/dist/components/ui/loading.js +8 -0
- package/dist/components/ui/locale-switcher.js +8 -0
- package/dist/components/ui/pagination.js +8 -0
- package/dist/components/ui/search-menu.js +8 -0
- package/dist/components/ui/theme-switcher.js +8 -0
- package/dist/components/ui/virtualized-combobox.d.ts +3 -0
- package/dist/components/ui/virtualized-combobox.js +71 -21
- package/dist/lib/docs-ai.d.ts +3 -3
- package/dist/lib/docs-ai.js +2 -1
- package/dist/lib/docs-core.d.ts +32 -27
- package/dist/lib/docs-core.js +134 -35
- package/dist/lib/seo.d.ts +88 -0
- package/dist/lib/seo.js +104 -0
- package/dist/services/agent/client/index.js +22 -15
- package/dist/services/agent/client/widget.d.ts +0 -1
- package/dist/services/agent/index.d.ts +2 -2
- package/dist/services/agent/index.js +0 -9
- package/dist/services/agent/schema.d.ts +3 -3
- package/dist/services/agent/schema.js +1 -6
- package/package.json +5 -13
- package/dist/services/embedding.d.ts +0 -2
- package/dist/services/embedding.js +0 -23
- package/dist/services/opentelemetry.d.ts +0 -8
- package/dist/services/opentelemetry.js +0 -23
package/README.md
CHANGED
|
@@ -20,9 +20,33 @@ import { HttpApiSpec } from "@krak-stack/registry/httpapi/helpers";
|
|
|
20
20
|
import { createMdxDocsSource, makeDocs } from "@krak-stack/registry/docs";
|
|
21
21
|
import { makeChatDocumentation } from "@krak-stack/registry/docs-ai";
|
|
22
22
|
import { Query } from "@krak-stack/registry/query";
|
|
23
|
+
import { createSeo } from "@krak-stack/registry/seo";
|
|
23
24
|
import { NotificationService } from "@krak-stack/registry/service-notification";
|
|
24
25
|
```
|
|
25
26
|
|
|
27
|
+
Create a configured SEO helper once with site-wide defaults, then use it for each page:
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
const siteSeo = createSeo({
|
|
31
|
+
origin: "https://krakstack.net",
|
|
32
|
+
locales: ["en", "fr"],
|
|
33
|
+
siteName: "KrakStack",
|
|
34
|
+
sameAs: ["https://github.com/krakcons/krakstack"],
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
<Route
|
|
38
|
+
head={() =>
|
|
39
|
+
siteSeo({
|
|
40
|
+
title: "KrakStack",
|
|
41
|
+
description: "Production-ready building blocks for TanStack apps.",
|
|
42
|
+
locale: "en",
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
/>;
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The returned object contains `meta`, `links`, and derived JSON-LD `scripts`. Website pages receive `WebSite` and `Organization` data; documentation pages can pass `type: "article"` for `Article` data. Use the lower-level `seo` function directly when a configured factory is not useful.
|
|
49
|
+
|
|
26
50
|
HTTP API client, schema, AI tool, CLI, and MCP utilities are available under
|
|
27
51
|
the `@krak-stack/registry/httpapi/*` subpaths. Keep application-specific API
|
|
28
52
|
layers, handlers, authentication, and client bindings in the application.
|
|
@@ -53,9 +53,10 @@ function Button({
|
|
|
53
53
|
// ../../src/components/ui/virtualized-combobox.tsx
|
|
54
54
|
import { Combobox as ComboboxPrimitive } from "@base-ui/react";
|
|
55
55
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
56
|
-
import { Check, ChevronsUpDown } from "lucide-react";
|
|
56
|
+
import { Check, ChevronsUpDown, X } from "lucide-react";
|
|
57
57
|
import {
|
|
58
58
|
useCallback,
|
|
59
|
+
useEffect,
|
|
59
60
|
useImperativeHandle,
|
|
60
61
|
useRef
|
|
61
62
|
} from "react";
|
|
@@ -139,6 +140,14 @@ var routeStrategies = [
|
|
|
139
140
|
{
|
|
140
141
|
match: "/api/:path(.*)?",
|
|
141
142
|
exclude: true
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
match: "/sitemap.xml",
|
|
146
|
+
exclude: true
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
match: "/llms.txt",
|
|
150
|
+
exclude: true
|
|
142
151
|
}
|
|
143
152
|
];
|
|
144
153
|
var urlPatterns = [
|
|
@@ -554,11 +563,13 @@ import { jsx as jsx5, jsxs } from "react/jsx-runtime";
|
|
|
554
563
|
"use client";
|
|
555
564
|
var messages = {
|
|
556
565
|
en: {
|
|
566
|
+
clear: "Clear selection",
|
|
557
567
|
search: "Search...",
|
|
558
568
|
selected: (count) => `${count} selected`,
|
|
559
569
|
selectMore: "Select more"
|
|
560
570
|
},
|
|
561
571
|
fr: {
|
|
572
|
+
clear: "Effacer la sélection",
|
|
562
573
|
search: "Rechercher...",
|
|
563
574
|
selected: (count) => `${count} sélectionnés`,
|
|
564
575
|
selectMore: "Sélectionner davantage"
|
|
@@ -572,6 +583,7 @@ var optionEquals = (item, selected) => item.value === selected.value;
|
|
|
572
583
|
var VirtualizedComboboxList = ({
|
|
573
584
|
emptyLabel,
|
|
574
585
|
groupSelections,
|
|
586
|
+
itemIndexRef,
|
|
575
587
|
messages: messageOverrides,
|
|
576
588
|
renderItem,
|
|
577
589
|
selectedValues,
|
|
@@ -579,22 +591,29 @@ var VirtualizedComboboxList = ({
|
|
|
579
591
|
}) => {
|
|
580
592
|
const filteredItems = ComboboxPrimitive.useFilteredItems();
|
|
581
593
|
const labels = virtualizedComboboxMessages(messageOverrides);
|
|
582
|
-
const
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
594
|
+
const itemEntries = filteredItems.map((item, index) => ({
|
|
595
|
+
kind: "item",
|
|
596
|
+
item,
|
|
597
|
+
index
|
|
598
|
+
}));
|
|
599
|
+
const selectedEntries = itemEntries.filter(({ item }) => selectedValues.has(item.value));
|
|
600
|
+
const availableEntries = itemEntries.filter(({ item }) => !selectedValues.has(item.value));
|
|
601
|
+
const entries = groupSelections ? [
|
|
602
|
+
...selectedEntries.length > 0 ? [
|
|
590
603
|
{
|
|
591
604
|
kind: "group",
|
|
592
|
-
key:
|
|
593
|
-
label:
|
|
605
|
+
key: "selected",
|
|
606
|
+
label: labels.selected(selectedValues.size)
|
|
594
607
|
},
|
|
595
|
-
|
|
596
|
-
] : [
|
|
597
|
-
|
|
608
|
+
...selectedEntries
|
|
609
|
+
] : [],
|
|
610
|
+
{
|
|
611
|
+
kind: "group",
|
|
612
|
+
key: "available",
|
|
613
|
+
label: labels.selectMore
|
|
614
|
+
},
|
|
615
|
+
...availableEntries
|
|
616
|
+
] : itemEntries;
|
|
598
617
|
const scrollRef = useRef(null);
|
|
599
618
|
const virtualizer = useVirtualizer({
|
|
600
619
|
count: entries.length,
|
|
@@ -606,6 +625,9 @@ var VirtualizedComboboxList = ({
|
|
|
606
625
|
estimateSize: () => 36,
|
|
607
626
|
overscan: 8
|
|
608
627
|
});
|
|
628
|
+
useEffect(() => {
|
|
629
|
+
itemIndexRef.current = new Map(entries.flatMap((entry, index) => entry.kind === "item" ? [[entry.index, index]] : []));
|
|
630
|
+
});
|
|
609
631
|
useImperativeHandle(virtualizerRef, () => virtualizer, [virtualizer]);
|
|
610
632
|
const handleScrollElementRef = useCallback((element) => {
|
|
611
633
|
scrollRef.current = element;
|
|
@@ -677,6 +699,7 @@ var VirtualizedComboboxContent = ({
|
|
|
677
699
|
contentClassName,
|
|
678
700
|
emptyLabel,
|
|
679
701
|
groupSelections,
|
|
702
|
+
itemIndexRef,
|
|
680
703
|
messages: messageOverrides,
|
|
681
704
|
renderItem,
|
|
682
705
|
selectedValues,
|
|
@@ -705,6 +728,7 @@ var VirtualizedComboboxContent = ({
|
|
|
705
728
|
/* @__PURE__ */ jsx5(VirtualizedComboboxList, {
|
|
706
729
|
emptyLabel,
|
|
707
730
|
groupSelections,
|
|
731
|
+
itemIndexRef,
|
|
708
732
|
messages: messageOverrides,
|
|
709
733
|
renderItem,
|
|
710
734
|
selectedValues,
|
|
@@ -725,7 +749,7 @@ var defaultTrigger = (ariaLabel, ariaInvalid, disabled, label, triggerId) => /*
|
|
|
725
749
|
variant: "outline",
|
|
726
750
|
children: [
|
|
727
751
|
/* @__PURE__ */ jsx5("span", {
|
|
728
|
-
className: "min-w-0 truncate text-left",
|
|
752
|
+
className: "min-w-0 flex-1 truncate pr-7 text-left",
|
|
729
753
|
children: label
|
|
730
754
|
}),
|
|
731
755
|
/* @__PURE__ */ jsx5(ChevronsUpDown, {
|
|
@@ -733,6 +757,14 @@ var defaultTrigger = (ariaLabel, ariaInvalid, disabled, label, triggerId) => /*
|
|
|
733
757
|
})
|
|
734
758
|
]
|
|
735
759
|
});
|
|
760
|
+
var defaultClear = (label) => /* @__PURE__ */ jsx5(ComboboxPrimitive.Clear, {
|
|
761
|
+
"aria-label": label,
|
|
762
|
+
className: "text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute top-1/2 right-7 z-10 flex size-6 -translate-y-1/2 items-center justify-center rounded-sm outline-none focus-visible:border focus-visible:ring-3",
|
|
763
|
+
type: "button",
|
|
764
|
+
children: /* @__PURE__ */ jsx5(X, {
|
|
765
|
+
className: "size-3.5"
|
|
766
|
+
})
|
|
767
|
+
});
|
|
736
768
|
var selectedLabel = (value, placeholder) => {
|
|
737
769
|
if (Array.isArray(value)) {
|
|
738
770
|
return value.length > 0 ? value.map(({ label }) => label).join(", ") : placeholder;
|
|
@@ -745,6 +777,8 @@ var useComboboxVirtualizerRef = (providedRef) => {
|
|
|
745
777
|
};
|
|
746
778
|
var VirtualizedComboboxSingle = (props) => {
|
|
747
779
|
const virtualizerRef = useComboboxVirtualizerRef(props.virtualizerRef);
|
|
780
|
+
const itemIndexRef = useRef(new Map);
|
|
781
|
+
const labels = virtualizedComboboxMessages(props.messages);
|
|
748
782
|
return /* @__PURE__ */ jsxs(ComboboxPrimitive.Root, {
|
|
749
783
|
disabled: props.disabled,
|
|
750
784
|
inputValue: props.searchValue,
|
|
@@ -754,7 +788,7 @@ var VirtualizedComboboxSingle = (props) => {
|
|
|
754
788
|
onInputValueChange: (value) => props.onSearchValueChange?.(value),
|
|
755
789
|
onItemHighlighted: (_, { index, reason }) => {
|
|
756
790
|
if (reason === "keyboard" && index >= 0) {
|
|
757
|
-
virtualizerRef.current?.scrollToIndex(index, { align: "auto" });
|
|
791
|
+
virtualizerRef.current?.scrollToIndex(itemIndexRef.current.get(index) ?? index, { align: "auto" });
|
|
758
792
|
}
|
|
759
793
|
},
|
|
760
794
|
onOpenChange: (open) => props.onOpenChange?.(open),
|
|
@@ -763,12 +797,19 @@ var VirtualizedComboboxSingle = (props) => {
|
|
|
763
797
|
value: props.value,
|
|
764
798
|
virtualized: true,
|
|
765
799
|
children: [
|
|
766
|
-
/* @__PURE__ */
|
|
767
|
-
|
|
800
|
+
/* @__PURE__ */ jsxs("div", {
|
|
801
|
+
className: "relative",
|
|
802
|
+
children: [
|
|
803
|
+
/* @__PURE__ */ jsx5(ComboboxPrimitive.Trigger, {
|
|
804
|
+
render: props.trigger ?? defaultTrigger(props.ariaLabel, props.ariaInvalid, props.disabled, selectedLabel(props.value, props.placeholder), props.triggerId)
|
|
805
|
+
}),
|
|
806
|
+
props.trigger ? null : defaultClear(labels.clear)
|
|
807
|
+
]
|
|
768
808
|
}),
|
|
769
809
|
/* @__PURE__ */ jsx5(VirtualizedComboboxContent, {
|
|
770
810
|
...props,
|
|
771
811
|
groupSelections: false,
|
|
812
|
+
itemIndexRef,
|
|
772
813
|
selectedValues: new Set(props.value ? [props.value.value] : []),
|
|
773
814
|
virtualizerRef
|
|
774
815
|
})
|
|
@@ -777,6 +818,8 @@ var VirtualizedComboboxSingle = (props) => {
|
|
|
777
818
|
};
|
|
778
819
|
var VirtualizedComboboxMultiple = (props) => {
|
|
779
820
|
const virtualizerRef = useComboboxVirtualizerRef(props.virtualizerRef);
|
|
821
|
+
const itemIndexRef = useRef(new Map);
|
|
822
|
+
const labels = virtualizedComboboxMessages(props.messages);
|
|
780
823
|
return /* @__PURE__ */ jsxs(ComboboxPrimitive.Root, {
|
|
781
824
|
disabled: props.disabled,
|
|
782
825
|
inputValue: props.searchValue,
|
|
@@ -787,7 +830,7 @@ var VirtualizedComboboxMultiple = (props) => {
|
|
|
787
830
|
onInputValueChange: (value) => props.onSearchValueChange?.(value),
|
|
788
831
|
onItemHighlighted: (_, { index, reason }) => {
|
|
789
832
|
if (reason === "keyboard" && index >= 0) {
|
|
790
|
-
virtualizerRef.current?.scrollToIndex(index, { align: "auto" });
|
|
833
|
+
virtualizerRef.current?.scrollToIndex(itemIndexRef.current.get(index) ?? index, { align: "auto" });
|
|
791
834
|
}
|
|
792
835
|
},
|
|
793
836
|
onOpenChange: (open) => props.onOpenChange?.(open),
|
|
@@ -796,12 +839,19 @@ var VirtualizedComboboxMultiple = (props) => {
|
|
|
796
839
|
value: [...props.value],
|
|
797
840
|
virtualized: true,
|
|
798
841
|
children: [
|
|
799
|
-
/* @__PURE__ */
|
|
800
|
-
|
|
842
|
+
/* @__PURE__ */ jsxs("div", {
|
|
843
|
+
className: "relative",
|
|
844
|
+
children: [
|
|
845
|
+
/* @__PURE__ */ jsx5(ComboboxPrimitive.Trigger, {
|
|
846
|
+
render: props.trigger ?? defaultTrigger(props.ariaLabel, props.ariaInvalid, props.disabled, selectedLabel(props.value, props.placeholder), props.triggerId)
|
|
847
|
+
}),
|
|
848
|
+
props.trigger ? null : defaultClear(labels.clear)
|
|
849
|
+
]
|
|
801
850
|
}),
|
|
802
851
|
/* @__PURE__ */ jsx5(VirtualizedComboboxContent, {
|
|
803
852
|
...props,
|
|
804
853
|
groupSelections: true,
|
|
854
|
+
itemIndexRef,
|
|
805
855
|
selectedValues: new Set(props.value.map(({ value }) => value)),
|
|
806
856
|
virtualizerRef
|
|
807
857
|
})
|
|
@@ -1648,10 +1698,10 @@ import {
|
|
|
1648
1698
|
Rows3,
|
|
1649
1699
|
Search,
|
|
1650
1700
|
Settings2,
|
|
1651
|
-
X
|
|
1701
|
+
X as X2
|
|
1652
1702
|
} from "lucide-react";
|
|
1653
1703
|
import {
|
|
1654
|
-
useEffect,
|
|
1704
|
+
useEffect as useEffect2,
|
|
1655
1705
|
useMemo,
|
|
1656
1706
|
useState,
|
|
1657
1707
|
createContext
|
|
@@ -1864,7 +1914,7 @@ var snapDragOverlayVerticalCenterToCursor = ({
|
|
|
1864
1914
|
overlayNodeRect,
|
|
1865
1915
|
transform
|
|
1866
1916
|
}) => {
|
|
1867
|
-
if (!(activatorEvent instanceof MouseEvent) || !activeNodeRect || !overlayNodeRect) {
|
|
1917
|
+
if (typeof MouseEvent === "undefined" || !(activatorEvent instanceof MouseEvent) || !activeNodeRect || !overlayNodeRect) {
|
|
1868
1918
|
return transform;
|
|
1869
1919
|
}
|
|
1870
1920
|
return {
|
|
@@ -2668,7 +2718,7 @@ function DataTable({
|
|
|
2668
2718
|
rowSelection
|
|
2669
2719
|
}
|
|
2670
2720
|
});
|
|
2671
|
-
|
|
2721
|
+
useEffect2(() => {
|
|
2672
2722
|
setSearchInput(globalFilter);
|
|
2673
2723
|
}, [globalFilter]);
|
|
2674
2724
|
const activeGroupingFields = useMemo(() => activeGrouping.map((groupId) => grouping?.fields.find((field) => field.id === groupId)).filter((field) => !!field), [activeGrouping, grouping]);
|
|
@@ -2826,7 +2876,7 @@ function DataTable({
|
|
|
2826
2876
|
size: "icon",
|
|
2827
2877
|
type: "button",
|
|
2828
2878
|
variant: "ghost",
|
|
2829
|
-
children: /* @__PURE__ */ jsx16(
|
|
2879
|
+
children: /* @__PURE__ */ jsx16(X2, {
|
|
2830
2880
|
className: "size-4"
|
|
2831
2881
|
})
|
|
2832
2882
|
}) : null
|
|
@@ -3333,7 +3383,7 @@ function DataTableRelationshipCell({
|
|
|
3333
3383
|
const [selectedOptions, setSelectedOptions] = useState(() => [...value]);
|
|
3334
3384
|
const selectedValues = new Set(selectedOptions.map(({ value: value2 }) => value2));
|
|
3335
3385
|
const orderedOptions = [...options].sort((a, b) => Number(selectedValues.has(b.value)) - Number(selectedValues.has(a.value)));
|
|
3336
|
-
|
|
3386
|
+
useEffect2(() => {
|
|
3337
3387
|
setSelectedOptions([...value]);
|
|
3338
3388
|
}, [value]);
|
|
3339
3389
|
return /* @__PURE__ */ jsx16(VirtualizedCombobox, {
|
|
@@ -3555,7 +3605,7 @@ function DataTableColumnHeader({
|
|
|
3555
3605
|
sortDirection ? /* @__PURE__ */ jsxs8(DropdownMenuItem, {
|
|
3556
3606
|
onClick: () => column.clearSorting(),
|
|
3557
3607
|
children: [
|
|
3558
|
-
/* @__PURE__ */ jsx16(
|
|
3608
|
+
/* @__PURE__ */ jsx16(X2, {
|
|
3559
3609
|
className: "text-muted-foreground/70 h-3.5 w-3.5"
|
|
3560
3610
|
}),
|
|
3561
3611
|
labels2.sortClear
|
|
@@ -325,6 +325,14 @@ var routeStrategies = [
|
|
|
325
325
|
{
|
|
326
326
|
match: "/api/:path(.*)?",
|
|
327
327
|
exclude: true
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
match: "/sitemap.xml",
|
|
331
|
+
exclude: true
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
match: "/llms.txt",
|
|
335
|
+
exclude: true
|
|
328
336
|
}
|
|
329
337
|
];
|
|
330
338
|
var urlPatterns = [
|
|
@@ -1316,9 +1324,10 @@ function Textarea({ className, ...props }) {
|
|
|
1316
1324
|
// ../../src/components/ui/virtualized-combobox.tsx
|
|
1317
1325
|
import { Combobox as ComboboxPrimitive } from "@base-ui/react";
|
|
1318
1326
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
1319
|
-
import { Check, ChevronsUpDown } from "lucide-react";
|
|
1327
|
+
import { Check, ChevronsUpDown, X } from "lucide-react";
|
|
1320
1328
|
import {
|
|
1321
1329
|
useCallback,
|
|
1330
|
+
useEffect as useEffect2,
|
|
1322
1331
|
useImperativeHandle,
|
|
1323
1332
|
useRef as useRef2
|
|
1324
1333
|
} from "react";
|
|
@@ -1372,11 +1381,13 @@ import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
|
1372
1381
|
"use client";
|
|
1373
1382
|
var messages2 = {
|
|
1374
1383
|
en: {
|
|
1384
|
+
clear: "Clear selection",
|
|
1375
1385
|
search: "Search...",
|
|
1376
1386
|
selected: (count) => `${count} selected`,
|
|
1377
1387
|
selectMore: "Select more"
|
|
1378
1388
|
},
|
|
1379
1389
|
fr: {
|
|
1390
|
+
clear: "Effacer la sélection",
|
|
1380
1391
|
search: "Rechercher...",
|
|
1381
1392
|
selected: (count) => `${count} sélectionnés`,
|
|
1382
1393
|
selectMore: "Sélectionner davantage"
|
|
@@ -1390,6 +1401,7 @@ var optionEquals = (item, selected) => item.value === selected.value;
|
|
|
1390
1401
|
var VirtualizedComboboxList = ({
|
|
1391
1402
|
emptyLabel,
|
|
1392
1403
|
groupSelections,
|
|
1404
|
+
itemIndexRef,
|
|
1393
1405
|
messages: messageOverrides,
|
|
1394
1406
|
renderItem,
|
|
1395
1407
|
selectedValues,
|
|
@@ -1397,22 +1409,29 @@ var VirtualizedComboboxList = ({
|
|
|
1397
1409
|
}) => {
|
|
1398
1410
|
const filteredItems = ComboboxPrimitive.useFilteredItems();
|
|
1399
1411
|
const labels = virtualizedComboboxMessages(messageOverrides);
|
|
1400
|
-
const
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1412
|
+
const itemEntries = filteredItems.map((item, index) => ({
|
|
1413
|
+
kind: "item",
|
|
1414
|
+
item,
|
|
1415
|
+
index
|
|
1416
|
+
}));
|
|
1417
|
+
const selectedEntries = itemEntries.filter(({ item }) => selectedValues.has(item.value));
|
|
1418
|
+
const availableEntries = itemEntries.filter(({ item }) => !selectedValues.has(item.value));
|
|
1419
|
+
const entries = groupSelections ? [
|
|
1420
|
+
...selectedEntries.length > 0 ? [
|
|
1408
1421
|
{
|
|
1409
1422
|
kind: "group",
|
|
1410
|
-
key:
|
|
1411
|
-
label:
|
|
1423
|
+
key: "selected",
|
|
1424
|
+
label: labels.selected(selectedValues.size)
|
|
1412
1425
|
},
|
|
1413
|
-
|
|
1414
|
-
] : [
|
|
1415
|
-
|
|
1426
|
+
...selectedEntries
|
|
1427
|
+
] : [],
|
|
1428
|
+
{
|
|
1429
|
+
kind: "group",
|
|
1430
|
+
key: "available",
|
|
1431
|
+
label: labels.selectMore
|
|
1432
|
+
},
|
|
1433
|
+
...availableEntries
|
|
1434
|
+
] : itemEntries;
|
|
1416
1435
|
const scrollRef = useRef2(null);
|
|
1417
1436
|
const virtualizer = useVirtualizer({
|
|
1418
1437
|
count: entries.length,
|
|
@@ -1424,6 +1443,9 @@ var VirtualizedComboboxList = ({
|
|
|
1424
1443
|
estimateSize: () => 36,
|
|
1425
1444
|
overscan: 8
|
|
1426
1445
|
});
|
|
1446
|
+
useEffect2(() => {
|
|
1447
|
+
itemIndexRef.current = new Map(entries.flatMap((entry, index) => entry.kind === "item" ? [[entry.index, index]] : []));
|
|
1448
|
+
});
|
|
1427
1449
|
useImperativeHandle(virtualizerRef, () => virtualizer, [virtualizer]);
|
|
1428
1450
|
const handleScrollElementRef = useCallback((element) => {
|
|
1429
1451
|
scrollRef.current = element;
|
|
@@ -1495,6 +1517,7 @@ var VirtualizedComboboxContent = ({
|
|
|
1495
1517
|
contentClassName,
|
|
1496
1518
|
emptyLabel,
|
|
1497
1519
|
groupSelections,
|
|
1520
|
+
itemIndexRef,
|
|
1498
1521
|
messages: messageOverrides,
|
|
1499
1522
|
renderItem,
|
|
1500
1523
|
selectedValues,
|
|
@@ -1523,6 +1546,7 @@ var VirtualizedComboboxContent = ({
|
|
|
1523
1546
|
/* @__PURE__ */ jsx13(VirtualizedComboboxList, {
|
|
1524
1547
|
emptyLabel,
|
|
1525
1548
|
groupSelections,
|
|
1549
|
+
itemIndexRef,
|
|
1526
1550
|
messages: messageOverrides,
|
|
1527
1551
|
renderItem,
|
|
1528
1552
|
selectedValues,
|
|
@@ -1543,7 +1567,7 @@ var defaultTrigger = (ariaLabel, ariaInvalid, disabled, label, triggerId) => /*
|
|
|
1543
1567
|
variant: "outline",
|
|
1544
1568
|
children: [
|
|
1545
1569
|
/* @__PURE__ */ jsx13("span", {
|
|
1546
|
-
className: "min-w-0 truncate text-left",
|
|
1570
|
+
className: "min-w-0 flex-1 truncate pr-7 text-left",
|
|
1547
1571
|
children: label
|
|
1548
1572
|
}),
|
|
1549
1573
|
/* @__PURE__ */ jsx13(ChevronsUpDown, {
|
|
@@ -1551,6 +1575,14 @@ var defaultTrigger = (ariaLabel, ariaInvalid, disabled, label, triggerId) => /*
|
|
|
1551
1575
|
})
|
|
1552
1576
|
]
|
|
1553
1577
|
});
|
|
1578
|
+
var defaultClear = (label) => /* @__PURE__ */ jsx13(ComboboxPrimitive.Clear, {
|
|
1579
|
+
"aria-label": label,
|
|
1580
|
+
className: "text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute top-1/2 right-7 z-10 flex size-6 -translate-y-1/2 items-center justify-center rounded-sm outline-none focus-visible:border focus-visible:ring-3",
|
|
1581
|
+
type: "button",
|
|
1582
|
+
children: /* @__PURE__ */ jsx13(X, {
|
|
1583
|
+
className: "size-3.5"
|
|
1584
|
+
})
|
|
1585
|
+
});
|
|
1554
1586
|
var selectedLabel = (value, placeholder) => {
|
|
1555
1587
|
if (Array.isArray(value)) {
|
|
1556
1588
|
return value.length > 0 ? value.map(({ label }) => label).join(", ") : placeholder;
|
|
@@ -1563,6 +1595,8 @@ var useComboboxVirtualizerRef = (providedRef) => {
|
|
|
1563
1595
|
};
|
|
1564
1596
|
var VirtualizedComboboxSingle = (props) => {
|
|
1565
1597
|
const virtualizerRef = useComboboxVirtualizerRef(props.virtualizerRef);
|
|
1598
|
+
const itemIndexRef = useRef2(new Map);
|
|
1599
|
+
const labels = virtualizedComboboxMessages(props.messages);
|
|
1566
1600
|
return /* @__PURE__ */ jsxs5(ComboboxPrimitive.Root, {
|
|
1567
1601
|
disabled: props.disabled,
|
|
1568
1602
|
inputValue: props.searchValue,
|
|
@@ -1572,7 +1606,7 @@ var VirtualizedComboboxSingle = (props) => {
|
|
|
1572
1606
|
onInputValueChange: (value) => props.onSearchValueChange?.(value),
|
|
1573
1607
|
onItemHighlighted: (_, { index, reason }) => {
|
|
1574
1608
|
if (reason === "keyboard" && index >= 0) {
|
|
1575
|
-
virtualizerRef.current?.scrollToIndex(index, { align: "auto" });
|
|
1609
|
+
virtualizerRef.current?.scrollToIndex(itemIndexRef.current.get(index) ?? index, { align: "auto" });
|
|
1576
1610
|
}
|
|
1577
1611
|
},
|
|
1578
1612
|
onOpenChange: (open) => props.onOpenChange?.(open),
|
|
@@ -1581,12 +1615,19 @@ var VirtualizedComboboxSingle = (props) => {
|
|
|
1581
1615
|
value: props.value,
|
|
1582
1616
|
virtualized: true,
|
|
1583
1617
|
children: [
|
|
1584
|
-
/* @__PURE__ */
|
|
1585
|
-
|
|
1618
|
+
/* @__PURE__ */ jsxs5("div", {
|
|
1619
|
+
className: "relative",
|
|
1620
|
+
children: [
|
|
1621
|
+
/* @__PURE__ */ jsx13(ComboboxPrimitive.Trigger, {
|
|
1622
|
+
render: props.trigger ?? defaultTrigger(props.ariaLabel, props.ariaInvalid, props.disabled, selectedLabel(props.value, props.placeholder), props.triggerId)
|
|
1623
|
+
}),
|
|
1624
|
+
props.trigger ? null : defaultClear(labels.clear)
|
|
1625
|
+
]
|
|
1586
1626
|
}),
|
|
1587
1627
|
/* @__PURE__ */ jsx13(VirtualizedComboboxContent, {
|
|
1588
1628
|
...props,
|
|
1589
1629
|
groupSelections: false,
|
|
1630
|
+
itemIndexRef,
|
|
1590
1631
|
selectedValues: new Set(props.value ? [props.value.value] : []),
|
|
1591
1632
|
virtualizerRef
|
|
1592
1633
|
})
|
|
@@ -1595,6 +1636,8 @@ var VirtualizedComboboxSingle = (props) => {
|
|
|
1595
1636
|
};
|
|
1596
1637
|
var VirtualizedComboboxMultiple = (props) => {
|
|
1597
1638
|
const virtualizerRef = useComboboxVirtualizerRef(props.virtualizerRef);
|
|
1639
|
+
const itemIndexRef = useRef2(new Map);
|
|
1640
|
+
const labels = virtualizedComboboxMessages(props.messages);
|
|
1598
1641
|
return /* @__PURE__ */ jsxs5(ComboboxPrimitive.Root, {
|
|
1599
1642
|
disabled: props.disabled,
|
|
1600
1643
|
inputValue: props.searchValue,
|
|
@@ -1605,7 +1648,7 @@ var VirtualizedComboboxMultiple = (props) => {
|
|
|
1605
1648
|
onInputValueChange: (value) => props.onSearchValueChange?.(value),
|
|
1606
1649
|
onItemHighlighted: (_, { index, reason }) => {
|
|
1607
1650
|
if (reason === "keyboard" && index >= 0) {
|
|
1608
|
-
virtualizerRef.current?.scrollToIndex(index, { align: "auto" });
|
|
1651
|
+
virtualizerRef.current?.scrollToIndex(itemIndexRef.current.get(index) ?? index, { align: "auto" });
|
|
1609
1652
|
}
|
|
1610
1653
|
},
|
|
1611
1654
|
onOpenChange: (open) => props.onOpenChange?.(open),
|
|
@@ -1614,12 +1657,19 @@ var VirtualizedComboboxMultiple = (props) => {
|
|
|
1614
1657
|
value: [...props.value],
|
|
1615
1658
|
virtualized: true,
|
|
1616
1659
|
children: [
|
|
1617
|
-
/* @__PURE__ */
|
|
1618
|
-
|
|
1660
|
+
/* @__PURE__ */ jsxs5("div", {
|
|
1661
|
+
className: "relative",
|
|
1662
|
+
children: [
|
|
1663
|
+
/* @__PURE__ */ jsx13(ComboboxPrimitive.Trigger, {
|
|
1664
|
+
render: props.trigger ?? defaultTrigger(props.ariaLabel, props.ariaInvalid, props.disabled, selectedLabel(props.value, props.placeholder), props.triggerId)
|
|
1665
|
+
}),
|
|
1666
|
+
props.trigger ? null : defaultClear(labels.clear)
|
|
1667
|
+
]
|
|
1619
1668
|
}),
|
|
1620
1669
|
/* @__PURE__ */ jsx13(VirtualizedComboboxContent, {
|
|
1621
1670
|
...props,
|
|
1622
1671
|
groupSelections: true,
|
|
1672
|
+
itemIndexRef,
|
|
1623
1673
|
selectedValues: new Set(props.value.map(({ value }) => value)),
|
|
1624
1674
|
virtualizerRef
|
|
1625
1675
|
})
|