@2urgseui/core 0.1.0 → 0.1.1
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/dist/index.cjs +44 -15
- package/dist/index.d.cts +25 -9
- package/dist/index.d.ts +25 -9
- package/dist/index.js +43 -15
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -226,6 +226,7 @@ __export(index_exports, {
|
|
|
226
226
|
colors: () => colors,
|
|
227
227
|
containerVariants: () => containerVariants,
|
|
228
228
|
dismissToast: () => dismissToast,
|
|
229
|
+
formValueToAsyncSelectOption: () => formValueToAsyncSelectOption,
|
|
229
230
|
getIcon: () => getIcon,
|
|
230
231
|
headingVariants: () => headingVariants,
|
|
231
232
|
inputGroupSelectTriggerTextAlignClass: () => inputGroupSelectTriggerTextAlignClass,
|
|
@@ -638,6 +639,15 @@ function resolveLabel(item, labelKey) {
|
|
|
638
639
|
if (typeof labelKey === "function") return labelKey(item);
|
|
639
640
|
return String(item[labelKey] ?? "");
|
|
640
641
|
}
|
|
642
|
+
function reactNodeToLabelString(node) {
|
|
643
|
+
if (node == null || typeof node === "boolean") return "";
|
|
644
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
645
|
+
if (Array.isArray(node)) return node.map(reactNodeToLabelString).join("");
|
|
646
|
+
return "";
|
|
647
|
+
}
|
|
648
|
+
function resolveStringLabel(item, labelKey) {
|
|
649
|
+
return reactNodeToLabelString(resolveLabel(item, labelKey));
|
|
650
|
+
}
|
|
641
651
|
function AsyncSelectInner(props) {
|
|
642
652
|
const {
|
|
643
653
|
url,
|
|
@@ -653,6 +663,7 @@ function AsyncSelectInner(props) {
|
|
|
653
663
|
disabled = false,
|
|
654
664
|
error: error2 = false,
|
|
655
665
|
name,
|
|
666
|
+
id,
|
|
656
667
|
className,
|
|
657
668
|
fetcher,
|
|
658
669
|
dataPath = "data",
|
|
@@ -674,8 +685,8 @@ function AsyncSelectInner(props) {
|
|
|
674
685
|
const searchInputRef = React6.useRef(null);
|
|
675
686
|
const abortRef = React6.useRef(null);
|
|
676
687
|
React6.useEffect(() => {
|
|
677
|
-
const
|
|
678
|
-
return () => clearTimeout(
|
|
688
|
+
const id2 = setTimeout(() => setDebouncedSearch(search), debounceMs);
|
|
689
|
+
return () => clearTimeout(id2);
|
|
679
690
|
}, [search, debounceMs]);
|
|
680
691
|
React6.useEffect(() => {
|
|
681
692
|
setPage(1);
|
|
@@ -749,38 +760,43 @@ function AsyncSelectInner(props) {
|
|
|
749
760
|
}
|
|
750
761
|
}, [open]);
|
|
751
762
|
React6.useEffect(() => {
|
|
752
|
-
|
|
763
|
+
const v = value?.value;
|
|
764
|
+
if (v == null || v === "") {
|
|
753
765
|
setSelectedItem(null);
|
|
754
766
|
return;
|
|
755
767
|
}
|
|
756
768
|
const found = items.find(
|
|
757
|
-
(it) => String(it[valueKey]) ===
|
|
769
|
+
(it) => String(it[valueKey]) === v
|
|
758
770
|
);
|
|
759
|
-
|
|
771
|
+
setSelectedItem(found ?? null);
|
|
760
772
|
}, [value, items, valueKey]);
|
|
761
773
|
const handleSelect = (item) => {
|
|
762
774
|
const itemValue = String(item[valueKey]);
|
|
763
|
-
if (itemValue === value && clearable) {
|
|
764
|
-
onValueChange?.(
|
|
775
|
+
if (itemValue === value?.value && clearable) {
|
|
776
|
+
onValueChange?.(null);
|
|
765
777
|
setSelectedItem(null);
|
|
766
778
|
} else {
|
|
767
|
-
onValueChange?.(
|
|
779
|
+
onValueChange?.({
|
|
780
|
+
value: itemValue,
|
|
781
|
+
label: resolveStringLabel(item, labelKey)
|
|
782
|
+
});
|
|
768
783
|
setSelectedItem(item);
|
|
769
784
|
}
|
|
770
785
|
setOpen(false);
|
|
771
786
|
};
|
|
772
787
|
const handleClear = (e) => {
|
|
773
788
|
e.stopPropagation();
|
|
774
|
-
onValueChange?.(
|
|
789
|
+
onValueChange?.(null);
|
|
775
790
|
setSelectedItem(null);
|
|
776
791
|
};
|
|
777
|
-
const triggerLabel = selectedItem ? resolveLabel(selectedItem, labelKey) : null;
|
|
792
|
+
const triggerLabel = selectedItem ? resolveLabel(selectedItem, labelKey) : value?.label ? value.label : null;
|
|
778
793
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Popover, { open, onOpenChange: setOpen, children: [
|
|
779
|
-
name && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "hidden", name, value: value ?? "" }),
|
|
794
|
+
name && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "hidden", name, value: value?.value ?? "" }),
|
|
780
795
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
781
796
|
"button",
|
|
782
797
|
{
|
|
783
798
|
ref: innerRef,
|
|
799
|
+
id,
|
|
784
800
|
type: "button",
|
|
785
801
|
role: "combobox",
|
|
786
802
|
"aria-expanded": open,
|
|
@@ -802,7 +818,7 @@ function AsyncSelectInner(props) {
|
|
|
802
818
|
}
|
|
803
819
|
),
|
|
804
820
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
805
|
-
clearable && value && !disabled && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
821
|
+
clearable && value?.value && !disabled && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
806
822
|
"span",
|
|
807
823
|
{
|
|
808
824
|
role: "button",
|
|
@@ -849,7 +865,7 @@ function AsyncSelectInner(props) {
|
|
|
849
865
|
const itemValue = String(
|
|
850
866
|
item[valueKey]
|
|
851
867
|
);
|
|
852
|
-
const isSelected = itemValue === value;
|
|
868
|
+
const isSelected = itemValue === value?.value;
|
|
853
869
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
854
870
|
"button",
|
|
855
871
|
{
|
|
@@ -2814,7 +2830,7 @@ function FormField({
|
|
|
2814
2830
|
};
|
|
2815
2831
|
const controlNode = renderInput ? renderInput({
|
|
2816
2832
|
...sharedInputShell,
|
|
2817
|
-
value: field.value ?? "",
|
|
2833
|
+
value: variant === "async-select" ? formValueToAsyncSelectOption(field.value) ?? null : field.value ?? "",
|
|
2818
2834
|
onChange: field.onChange,
|
|
2819
2835
|
onBlur: field.onBlur,
|
|
2820
2836
|
ref: field.ref
|
|
@@ -2958,6 +2974,17 @@ function FormField({
|
|
|
2958
2974
|
externalError && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Text, { id: `${inputId}-error`, size: "sm", tone: "destructive", children: externalError })
|
|
2959
2975
|
] });
|
|
2960
2976
|
}
|
|
2977
|
+
function formValueToAsyncSelectOption(v) {
|
|
2978
|
+
if (v == null || v === "") return void 0;
|
|
2979
|
+
if (typeof v === "object" && v !== null && "value" in v) {
|
|
2980
|
+
const o = v;
|
|
2981
|
+
return {
|
|
2982
|
+
value: String(o.value ?? ""),
|
|
2983
|
+
label: o.label != null ? String(o.label) : ""
|
|
2984
|
+
};
|
|
2985
|
+
}
|
|
2986
|
+
return { value: String(v), label: "" };
|
|
2987
|
+
}
|
|
2961
2988
|
function FormFieldVariantControl({
|
|
2962
2989
|
variant,
|
|
2963
2990
|
inputId,
|
|
@@ -3082,7 +3109,8 @@ function FormFieldVariantControl({
|
|
|
3082
3109
|
AsyncSelect,
|
|
3083
3110
|
{
|
|
3084
3111
|
...asyncSelectProps,
|
|
3085
|
-
|
|
3112
|
+
id: inputId,
|
|
3113
|
+
value: formValueToAsyncSelectOption(field.value),
|
|
3086
3114
|
onValueChange: field.onChange,
|
|
3087
3115
|
disabled: field.disabled,
|
|
3088
3116
|
error: hasError,
|
|
@@ -5455,6 +5483,7 @@ var typography = {
|
|
|
5455
5483
|
colors,
|
|
5456
5484
|
containerVariants,
|
|
5457
5485
|
dismissToast,
|
|
5486
|
+
formValueToAsyncSelectOption,
|
|
5458
5487
|
getIcon,
|
|
5459
5488
|
headingVariants,
|
|
5460
5489
|
inputGroupSelectTriggerTextAlignClass,
|
package/dist/index.d.cts
CHANGED
|
@@ -64,6 +64,11 @@ declare const AccordionItem: React.ForwardRefExoticComponent<Omit<AccordionPrimi
|
|
|
64
64
|
declare const AccordionTrigger: React.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
65
65
|
declare const AccordionContent: React.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
66
66
|
|
|
67
|
+
/** Controlled value / `onValueChange` payload (same shape for prepopulation and after select). */
|
|
68
|
+
type AsyncSelectOption = {
|
|
69
|
+
value: string;
|
|
70
|
+
label: string;
|
|
71
|
+
};
|
|
67
72
|
interface AsyncSelectPage<T = Record<string, unknown>> {
|
|
68
73
|
data: T[];
|
|
69
74
|
hasMore: boolean;
|
|
@@ -80,10 +85,10 @@ interface AsyncSelectProps<T = Record<string, unknown>> {
|
|
|
80
85
|
valueKey: keyof T & string;
|
|
81
86
|
/** Key (or render fn) for the display label. */
|
|
82
87
|
labelKey: (keyof T & string) | ((item: T) => React.ReactNode);
|
|
83
|
-
/** Controlled value. */
|
|
84
|
-
value?:
|
|
85
|
-
/**
|
|
86
|
-
onValueChange?: (
|
|
88
|
+
/** Controlled value (`value` + `label`, e.g. from the server). */
|
|
89
|
+
value?: AsyncSelectOption | null;
|
|
90
|
+
/** Called with `{ value, label }` for a selection, or `null` when cleared. */
|
|
91
|
+
onValueChange?: (option: AsyncSelectOption | null) => void;
|
|
87
92
|
/** Placeholder shown in the trigger when nothing is selected. */
|
|
88
93
|
placeholder?: string;
|
|
89
94
|
/** Placeholder for the search input inside the dropdown. */
|
|
@@ -97,6 +102,8 @@ interface AsyncSelectProps<T = Record<string, unknown>> {
|
|
|
97
102
|
disabled?: boolean;
|
|
98
103
|
error?: boolean;
|
|
99
104
|
name?: string;
|
|
105
|
+
/** Sets `id` on the combobox trigger (use with `Label htmlFor`). */
|
|
106
|
+
id?: string;
|
|
100
107
|
className?: string;
|
|
101
108
|
/** Custom fetcher. Defaults to a JSON fetch that appends `?search=&page=` to `url`. */
|
|
102
109
|
fetcher?: AsyncSelectFetcher<T>;
|
|
@@ -124,8 +131,8 @@ interface AsyncSelectProps<T = Record<string, unknown>> {
|
|
|
124
131
|
* url="/api/employees"
|
|
125
132
|
* valueKey="id"
|
|
126
133
|
* labelKey="fullName"
|
|
127
|
-
* value={
|
|
128
|
-
* onValueChange={
|
|
134
|
+
* value={{ value: employee.id, label: employee.fullName }}
|
|
135
|
+
* onValueChange={setEmployee}
|
|
129
136
|
* placeholder="Choose an employee…"
|
|
130
137
|
* />
|
|
131
138
|
* ```
|
|
@@ -476,7 +483,11 @@ type FormFieldOtpConfig = {
|
|
|
476
483
|
containerClassName?: string;
|
|
477
484
|
} & Omit<React.ComponentPropsWithoutRef<typeof InputOTP>, "maxLength" | "value" | "onChange" | "containerClassName" | "render" | "invalid">;
|
|
478
485
|
type FormFieldDropzoneConfig = Omit<FileDropzoneProps, "id" | "name" | "onChange" | "onBlur" | "ref" | "disabled" | "error" | "value">;
|
|
479
|
-
|
|
486
|
+
/**
|
|
487
|
+
* Props for `AsyncSelect` when used via `FormField` (`variant="async-select"`).
|
|
488
|
+
* The controlled field value is `{ value, label } | null | undefined` (legacy plain `string` is still read as id-only).
|
|
489
|
+
*/
|
|
490
|
+
type FormFieldAsyncSelectConfig = Omit<AsyncSelectProps, "value" | "onValueChange" | "disabled" | "error" | "name" | "id">;
|
|
480
491
|
interface FormFieldProps<TFieldValues extends FieldValues> {
|
|
481
492
|
name: Path<TFieldValues>;
|
|
482
493
|
/** When omitted, no visible label is rendered; use `aria-label` on controls or descriptions for a11y. */
|
|
@@ -498,16 +509,21 @@ interface FormFieldProps<TFieldValues extends FieldValues> {
|
|
|
498
509
|
otpProps?: FormFieldOtpConfig;
|
|
499
510
|
richTextProps?: Omit<RichTextEditorProps, "value" | "onChange" | "disabled">;
|
|
500
511
|
dropzoneProps?: FormFieldDropzoneConfig;
|
|
512
|
+
/** With `variant="async-select"`: URL fetch config; form state is `AsyncSelectOption | null` (see `FormFieldAsyncSelectConfig`). */
|
|
501
513
|
asyncSelectProps?: FormFieldAsyncSelectConfig;
|
|
502
514
|
className?: string;
|
|
503
|
-
renderInput?: (props: FormFieldRenderProps & {
|
|
515
|
+
renderInput?: (props: Omit<FormFieldRenderProps, "value"> & {
|
|
504
516
|
id: string;
|
|
505
517
|
name: string;
|
|
506
518
|
"aria-describedby"?: string;
|
|
507
519
|
error?: boolean;
|
|
520
|
+
/** With `variant="async-select"`, this is `AsyncSelectOption | null`; otherwise the field primitive value. */
|
|
521
|
+
value?: InputProps["value"] | AsyncSelectOption | null;
|
|
508
522
|
}) => React.ReactNode;
|
|
509
523
|
}
|
|
510
524
|
declare function FormField<TFieldValues extends FieldValues>({ name, label, register, control, rules, description, required, error, variant, inputProps, textareaProps, checkboxProps, switchProps, selectProps, radioProps, otpProps, richTextProps, dropzoneProps, asyncSelectProps, className, renderInput, }: FormFieldProps<TFieldValues>): react_jsx_runtime.JSX.Element;
|
|
525
|
+
/** Maps react-hook-form field values to `AsyncSelect`’s `value` prop (supports `{ value, label }`, legacy `string`, `null`/`undefined`). */
|
|
526
|
+
declare function formValueToAsyncSelectOption(v: unknown): AsyncSelectOption | undefined;
|
|
511
527
|
|
|
512
528
|
/**
|
|
513
529
|
* Heading levels map to the correct HTML element and default size/weight from
|
|
@@ -876,4 +892,4 @@ declare namespace Toaster {
|
|
|
876
892
|
var displayName: string;
|
|
877
893
|
}
|
|
878
894
|
|
|
879
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, AppShell, type AppShellProps, AspectRatio, type AspectRatioProps, AsyncSelect, type AsyncSelectFetcher, type AsyncSelectPage, type AsyncSelectProps, Avatar, AvatarFallback, AvatarImage, type AvatarProps, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, Calendar, CalendarDayButton, Caption, type CaptionProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, type CheckboxProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Container, type ContainerProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FileDropzone, type FileDropzoneProps, FormField, type FormFieldAsyncSelectConfig, type FormFieldDropzoneConfig, type FormFieldOtpConfig, type FormFieldProps, type FormFieldRadioConfig, type FormFieldRadioOption, type FormFieldSelectConfig, type FormFieldSelectItem, type FormFieldVariant, Heading, type HeadingProps, Icon, type IconComponent, type IconComponentProps, type IconProps, Input, InputGroup, InputGroupIcon, InputGroupInput, type InputGroupInputProps, type InputGroupProps, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, Label, type LabelProps, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, type PopoverContentProps, PopoverTrigger, Progress, type ProgressProps, RadioGroup, RadioGroupItem, RichHtml, type RichHtmlProps, RichTextEditor, type RichTextEditorProps, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, type SeparatorProps, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, type SkeletonProps, Slider, type SliderProps, Switch, type SwitchProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Text, type TextProps, Textarea, type TextareaProps, Toast, ToastAction, ToastClose, ToastDescription, type ToastPayload, type ToastProps, ToastProvider, type ToastRecord, ToastTitle, ToastViewport, Toaster, type ToasterProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, captionVariants, checkboxVariants, containerVariants, dismissToast, getIcon, headingVariants, inputGroupSelectTriggerTextAlignClass, inputVariants, labelVariants, registerIcons, separatorVariants, sidebarMenuButtonVariants, skeletonVariants, switchRootVariants, switchThumbVariants, textVariants, toast, toastVariants, useSidebar, useToast };
|
|
895
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, AppShell, type AppShellProps, AspectRatio, type AspectRatioProps, AsyncSelect, type AsyncSelectFetcher, type AsyncSelectOption, type AsyncSelectPage, type AsyncSelectProps, Avatar, AvatarFallback, AvatarImage, type AvatarProps, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, Calendar, CalendarDayButton, Caption, type CaptionProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, type CheckboxProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Container, type ContainerProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FileDropzone, type FileDropzoneProps, FormField, type FormFieldAsyncSelectConfig, type FormFieldDropzoneConfig, type FormFieldOtpConfig, type FormFieldProps, type FormFieldRadioConfig, type FormFieldRadioOption, type FormFieldSelectConfig, type FormFieldSelectItem, type FormFieldVariant, Heading, type HeadingProps, Icon, type IconComponent, type IconComponentProps, type IconProps, Input, InputGroup, InputGroupIcon, InputGroupInput, type InputGroupInputProps, type InputGroupProps, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, Label, type LabelProps, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, type PopoverContentProps, PopoverTrigger, Progress, type ProgressProps, RadioGroup, RadioGroupItem, RichHtml, type RichHtmlProps, RichTextEditor, type RichTextEditorProps, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, type SeparatorProps, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, type SkeletonProps, Slider, type SliderProps, Switch, type SwitchProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Text, type TextProps, Textarea, type TextareaProps, Toast, ToastAction, ToastClose, ToastDescription, type ToastPayload, type ToastProps, ToastProvider, type ToastRecord, ToastTitle, ToastViewport, Toaster, type ToasterProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, captionVariants, checkboxVariants, containerVariants, dismissToast, formValueToAsyncSelectOption, getIcon, headingVariants, inputGroupSelectTriggerTextAlignClass, inputVariants, labelVariants, registerIcons, separatorVariants, sidebarMenuButtonVariants, skeletonVariants, switchRootVariants, switchThumbVariants, textVariants, toast, toastVariants, useSidebar, useToast };
|
package/dist/index.d.ts
CHANGED
|
@@ -64,6 +64,11 @@ declare const AccordionItem: React.ForwardRefExoticComponent<Omit<AccordionPrimi
|
|
|
64
64
|
declare const AccordionTrigger: React.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
65
65
|
declare const AccordionContent: React.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
66
66
|
|
|
67
|
+
/** Controlled value / `onValueChange` payload (same shape for prepopulation and after select). */
|
|
68
|
+
type AsyncSelectOption = {
|
|
69
|
+
value: string;
|
|
70
|
+
label: string;
|
|
71
|
+
};
|
|
67
72
|
interface AsyncSelectPage<T = Record<string, unknown>> {
|
|
68
73
|
data: T[];
|
|
69
74
|
hasMore: boolean;
|
|
@@ -80,10 +85,10 @@ interface AsyncSelectProps<T = Record<string, unknown>> {
|
|
|
80
85
|
valueKey: keyof T & string;
|
|
81
86
|
/** Key (or render fn) for the display label. */
|
|
82
87
|
labelKey: (keyof T & string) | ((item: T) => React.ReactNode);
|
|
83
|
-
/** Controlled value. */
|
|
84
|
-
value?:
|
|
85
|
-
/**
|
|
86
|
-
onValueChange?: (
|
|
88
|
+
/** Controlled value (`value` + `label`, e.g. from the server). */
|
|
89
|
+
value?: AsyncSelectOption | null;
|
|
90
|
+
/** Called with `{ value, label }` for a selection, or `null` when cleared. */
|
|
91
|
+
onValueChange?: (option: AsyncSelectOption | null) => void;
|
|
87
92
|
/** Placeholder shown in the trigger when nothing is selected. */
|
|
88
93
|
placeholder?: string;
|
|
89
94
|
/** Placeholder for the search input inside the dropdown. */
|
|
@@ -97,6 +102,8 @@ interface AsyncSelectProps<T = Record<string, unknown>> {
|
|
|
97
102
|
disabled?: boolean;
|
|
98
103
|
error?: boolean;
|
|
99
104
|
name?: string;
|
|
105
|
+
/** Sets `id` on the combobox trigger (use with `Label htmlFor`). */
|
|
106
|
+
id?: string;
|
|
100
107
|
className?: string;
|
|
101
108
|
/** Custom fetcher. Defaults to a JSON fetch that appends `?search=&page=` to `url`. */
|
|
102
109
|
fetcher?: AsyncSelectFetcher<T>;
|
|
@@ -124,8 +131,8 @@ interface AsyncSelectProps<T = Record<string, unknown>> {
|
|
|
124
131
|
* url="/api/employees"
|
|
125
132
|
* valueKey="id"
|
|
126
133
|
* labelKey="fullName"
|
|
127
|
-
* value={
|
|
128
|
-
* onValueChange={
|
|
134
|
+
* value={{ value: employee.id, label: employee.fullName }}
|
|
135
|
+
* onValueChange={setEmployee}
|
|
129
136
|
* placeholder="Choose an employee…"
|
|
130
137
|
* />
|
|
131
138
|
* ```
|
|
@@ -476,7 +483,11 @@ type FormFieldOtpConfig = {
|
|
|
476
483
|
containerClassName?: string;
|
|
477
484
|
} & Omit<React.ComponentPropsWithoutRef<typeof InputOTP>, "maxLength" | "value" | "onChange" | "containerClassName" | "render" | "invalid">;
|
|
478
485
|
type FormFieldDropzoneConfig = Omit<FileDropzoneProps, "id" | "name" | "onChange" | "onBlur" | "ref" | "disabled" | "error" | "value">;
|
|
479
|
-
|
|
486
|
+
/**
|
|
487
|
+
* Props for `AsyncSelect` when used via `FormField` (`variant="async-select"`).
|
|
488
|
+
* The controlled field value is `{ value, label } | null | undefined` (legacy plain `string` is still read as id-only).
|
|
489
|
+
*/
|
|
490
|
+
type FormFieldAsyncSelectConfig = Omit<AsyncSelectProps, "value" | "onValueChange" | "disabled" | "error" | "name" | "id">;
|
|
480
491
|
interface FormFieldProps<TFieldValues extends FieldValues> {
|
|
481
492
|
name: Path<TFieldValues>;
|
|
482
493
|
/** When omitted, no visible label is rendered; use `aria-label` on controls or descriptions for a11y. */
|
|
@@ -498,16 +509,21 @@ interface FormFieldProps<TFieldValues extends FieldValues> {
|
|
|
498
509
|
otpProps?: FormFieldOtpConfig;
|
|
499
510
|
richTextProps?: Omit<RichTextEditorProps, "value" | "onChange" | "disabled">;
|
|
500
511
|
dropzoneProps?: FormFieldDropzoneConfig;
|
|
512
|
+
/** With `variant="async-select"`: URL fetch config; form state is `AsyncSelectOption | null` (see `FormFieldAsyncSelectConfig`). */
|
|
501
513
|
asyncSelectProps?: FormFieldAsyncSelectConfig;
|
|
502
514
|
className?: string;
|
|
503
|
-
renderInput?: (props: FormFieldRenderProps & {
|
|
515
|
+
renderInput?: (props: Omit<FormFieldRenderProps, "value"> & {
|
|
504
516
|
id: string;
|
|
505
517
|
name: string;
|
|
506
518
|
"aria-describedby"?: string;
|
|
507
519
|
error?: boolean;
|
|
520
|
+
/** With `variant="async-select"`, this is `AsyncSelectOption | null`; otherwise the field primitive value. */
|
|
521
|
+
value?: InputProps["value"] | AsyncSelectOption | null;
|
|
508
522
|
}) => React.ReactNode;
|
|
509
523
|
}
|
|
510
524
|
declare function FormField<TFieldValues extends FieldValues>({ name, label, register, control, rules, description, required, error, variant, inputProps, textareaProps, checkboxProps, switchProps, selectProps, radioProps, otpProps, richTextProps, dropzoneProps, asyncSelectProps, className, renderInput, }: FormFieldProps<TFieldValues>): react_jsx_runtime.JSX.Element;
|
|
525
|
+
/** Maps react-hook-form field values to `AsyncSelect`’s `value` prop (supports `{ value, label }`, legacy `string`, `null`/`undefined`). */
|
|
526
|
+
declare function formValueToAsyncSelectOption(v: unknown): AsyncSelectOption | undefined;
|
|
511
527
|
|
|
512
528
|
/**
|
|
513
529
|
* Heading levels map to the correct HTML element and default size/weight from
|
|
@@ -876,4 +892,4 @@ declare namespace Toaster {
|
|
|
876
892
|
var displayName: string;
|
|
877
893
|
}
|
|
878
894
|
|
|
879
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, AppShell, type AppShellProps, AspectRatio, type AspectRatioProps, AsyncSelect, type AsyncSelectFetcher, type AsyncSelectPage, type AsyncSelectProps, Avatar, AvatarFallback, AvatarImage, type AvatarProps, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, Calendar, CalendarDayButton, Caption, type CaptionProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, type CheckboxProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Container, type ContainerProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FileDropzone, type FileDropzoneProps, FormField, type FormFieldAsyncSelectConfig, type FormFieldDropzoneConfig, type FormFieldOtpConfig, type FormFieldProps, type FormFieldRadioConfig, type FormFieldRadioOption, type FormFieldSelectConfig, type FormFieldSelectItem, type FormFieldVariant, Heading, type HeadingProps, Icon, type IconComponent, type IconComponentProps, type IconProps, Input, InputGroup, InputGroupIcon, InputGroupInput, type InputGroupInputProps, type InputGroupProps, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, Label, type LabelProps, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, type PopoverContentProps, PopoverTrigger, Progress, type ProgressProps, RadioGroup, RadioGroupItem, RichHtml, type RichHtmlProps, RichTextEditor, type RichTextEditorProps, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, type SeparatorProps, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, type SkeletonProps, Slider, type SliderProps, Switch, type SwitchProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Text, type TextProps, Textarea, type TextareaProps, Toast, ToastAction, ToastClose, ToastDescription, type ToastPayload, type ToastProps, ToastProvider, type ToastRecord, ToastTitle, ToastViewport, Toaster, type ToasterProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, captionVariants, checkboxVariants, containerVariants, dismissToast, getIcon, headingVariants, inputGroupSelectTriggerTextAlignClass, inputVariants, labelVariants, registerIcons, separatorVariants, sidebarMenuButtonVariants, skeletonVariants, switchRootVariants, switchThumbVariants, textVariants, toast, toastVariants, useSidebar, useToast };
|
|
895
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, AppShell, type AppShellProps, AspectRatio, type AspectRatioProps, AsyncSelect, type AsyncSelectFetcher, type AsyncSelectOption, type AsyncSelectPage, type AsyncSelectProps, Avatar, AvatarFallback, AvatarImage, type AvatarProps, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, Calendar, CalendarDayButton, Caption, type CaptionProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, type CheckboxProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Container, type ContainerProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FileDropzone, type FileDropzoneProps, FormField, type FormFieldAsyncSelectConfig, type FormFieldDropzoneConfig, type FormFieldOtpConfig, type FormFieldProps, type FormFieldRadioConfig, type FormFieldRadioOption, type FormFieldSelectConfig, type FormFieldSelectItem, type FormFieldVariant, Heading, type HeadingProps, Icon, type IconComponent, type IconComponentProps, type IconProps, Input, InputGroup, InputGroupIcon, InputGroupInput, type InputGroupInputProps, type InputGroupProps, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, Label, type LabelProps, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, type PopoverContentProps, PopoverTrigger, Progress, type ProgressProps, RadioGroup, RadioGroupItem, RichHtml, type RichHtmlProps, RichTextEditor, type RichTextEditorProps, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, type SeparatorProps, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, type SkeletonProps, Slider, type SliderProps, Switch, type SwitchProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Text, type TextProps, Textarea, type TextareaProps, Toast, ToastAction, ToastClose, ToastDescription, type ToastPayload, type ToastProps, ToastProvider, type ToastRecord, ToastTitle, ToastViewport, Toaster, type ToasterProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, captionVariants, checkboxVariants, containerVariants, dismissToast, formValueToAsyncSelectOption, getIcon, headingVariants, inputGroupSelectTriggerTextAlignClass, inputVariants, labelVariants, registerIcons, separatorVariants, sidebarMenuButtonVariants, skeletonVariants, switchRootVariants, switchThumbVariants, textVariants, toast, toastVariants, useSidebar, useToast };
|
package/dist/index.js
CHANGED
|
@@ -398,6 +398,15 @@ function resolveLabel(item, labelKey) {
|
|
|
398
398
|
if (typeof labelKey === "function") return labelKey(item);
|
|
399
399
|
return String(item[labelKey] ?? "");
|
|
400
400
|
}
|
|
401
|
+
function reactNodeToLabelString(node) {
|
|
402
|
+
if (node == null || typeof node === "boolean") return "";
|
|
403
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
404
|
+
if (Array.isArray(node)) return node.map(reactNodeToLabelString).join("");
|
|
405
|
+
return "";
|
|
406
|
+
}
|
|
407
|
+
function resolveStringLabel(item, labelKey) {
|
|
408
|
+
return reactNodeToLabelString(resolveLabel(item, labelKey));
|
|
409
|
+
}
|
|
401
410
|
function AsyncSelectInner(props) {
|
|
402
411
|
const {
|
|
403
412
|
url,
|
|
@@ -413,6 +422,7 @@ function AsyncSelectInner(props) {
|
|
|
413
422
|
disabled = false,
|
|
414
423
|
error = false,
|
|
415
424
|
name,
|
|
425
|
+
id,
|
|
416
426
|
className,
|
|
417
427
|
fetcher,
|
|
418
428
|
dataPath = "data",
|
|
@@ -434,8 +444,8 @@ function AsyncSelectInner(props) {
|
|
|
434
444
|
const searchInputRef = React6.useRef(null);
|
|
435
445
|
const abortRef = React6.useRef(null);
|
|
436
446
|
React6.useEffect(() => {
|
|
437
|
-
const
|
|
438
|
-
return () => clearTimeout(
|
|
447
|
+
const id2 = setTimeout(() => setDebouncedSearch(search), debounceMs);
|
|
448
|
+
return () => clearTimeout(id2);
|
|
439
449
|
}, [search, debounceMs]);
|
|
440
450
|
React6.useEffect(() => {
|
|
441
451
|
setPage(1);
|
|
@@ -509,38 +519,43 @@ function AsyncSelectInner(props) {
|
|
|
509
519
|
}
|
|
510
520
|
}, [open]);
|
|
511
521
|
React6.useEffect(() => {
|
|
512
|
-
|
|
522
|
+
const v = value?.value;
|
|
523
|
+
if (v == null || v === "") {
|
|
513
524
|
setSelectedItem(null);
|
|
514
525
|
return;
|
|
515
526
|
}
|
|
516
527
|
const found = items.find(
|
|
517
|
-
(it) => String(it[valueKey]) ===
|
|
528
|
+
(it) => String(it[valueKey]) === v
|
|
518
529
|
);
|
|
519
|
-
|
|
530
|
+
setSelectedItem(found ?? null);
|
|
520
531
|
}, [value, items, valueKey]);
|
|
521
532
|
const handleSelect = (item) => {
|
|
522
533
|
const itemValue = String(item[valueKey]);
|
|
523
|
-
if (itemValue === value && clearable) {
|
|
524
|
-
onValueChange?.(
|
|
534
|
+
if (itemValue === value?.value && clearable) {
|
|
535
|
+
onValueChange?.(null);
|
|
525
536
|
setSelectedItem(null);
|
|
526
537
|
} else {
|
|
527
|
-
onValueChange?.(
|
|
538
|
+
onValueChange?.({
|
|
539
|
+
value: itemValue,
|
|
540
|
+
label: resolveStringLabel(item, labelKey)
|
|
541
|
+
});
|
|
528
542
|
setSelectedItem(item);
|
|
529
543
|
}
|
|
530
544
|
setOpen(false);
|
|
531
545
|
};
|
|
532
546
|
const handleClear = (e) => {
|
|
533
547
|
e.stopPropagation();
|
|
534
|
-
onValueChange?.(
|
|
548
|
+
onValueChange?.(null);
|
|
535
549
|
setSelectedItem(null);
|
|
536
550
|
};
|
|
537
|
-
const triggerLabel = selectedItem ? resolveLabel(selectedItem, labelKey) : null;
|
|
551
|
+
const triggerLabel = selectedItem ? resolveLabel(selectedItem, labelKey) : value?.label ? value.label : null;
|
|
538
552
|
return /* @__PURE__ */ jsxs5(Popover, { open, onOpenChange: setOpen, children: [
|
|
539
|
-
name && /* @__PURE__ */ jsx6("input", { type: "hidden", name, value: value ?? "" }),
|
|
553
|
+
name && /* @__PURE__ */ jsx6("input", { type: "hidden", name, value: value?.value ?? "" }),
|
|
540
554
|
/* @__PURE__ */ jsx6(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs5(
|
|
541
555
|
"button",
|
|
542
556
|
{
|
|
543
557
|
ref: innerRef,
|
|
558
|
+
id,
|
|
544
559
|
type: "button",
|
|
545
560
|
role: "combobox",
|
|
546
561
|
"aria-expanded": open,
|
|
@@ -562,7 +577,7 @@ function AsyncSelectInner(props) {
|
|
|
562
577
|
}
|
|
563
578
|
),
|
|
564
579
|
/* @__PURE__ */ jsxs5("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
565
|
-
clearable && value && !disabled && /* @__PURE__ */ jsx6(
|
|
580
|
+
clearable && value?.value && !disabled && /* @__PURE__ */ jsx6(
|
|
566
581
|
"span",
|
|
567
582
|
{
|
|
568
583
|
role: "button",
|
|
@@ -609,7 +624,7 @@ function AsyncSelectInner(props) {
|
|
|
609
624
|
const itemValue = String(
|
|
610
625
|
item[valueKey]
|
|
611
626
|
);
|
|
612
|
-
const isSelected = itemValue === value;
|
|
627
|
+
const isSelected = itemValue === value?.value;
|
|
613
628
|
return /* @__PURE__ */ jsxs5(
|
|
614
629
|
"button",
|
|
615
630
|
{
|
|
@@ -2580,7 +2595,7 @@ function FormField({
|
|
|
2580
2595
|
};
|
|
2581
2596
|
const controlNode = renderInput ? renderInput({
|
|
2582
2597
|
...sharedInputShell,
|
|
2583
|
-
value: field.value ?? "",
|
|
2598
|
+
value: variant === "async-select" ? formValueToAsyncSelectOption(field.value) ?? null : field.value ?? "",
|
|
2584
2599
|
onChange: field.onChange,
|
|
2585
2600
|
onBlur: field.onBlur,
|
|
2586
2601
|
ref: field.ref
|
|
@@ -2724,6 +2739,17 @@ function FormField({
|
|
|
2724
2739
|
externalError && /* @__PURE__ */ jsx32(Text, { id: `${inputId}-error`, size: "sm", tone: "destructive", children: externalError })
|
|
2725
2740
|
] });
|
|
2726
2741
|
}
|
|
2742
|
+
function formValueToAsyncSelectOption(v) {
|
|
2743
|
+
if (v == null || v === "") return void 0;
|
|
2744
|
+
if (typeof v === "object" && v !== null && "value" in v) {
|
|
2745
|
+
const o = v;
|
|
2746
|
+
return {
|
|
2747
|
+
value: String(o.value ?? ""),
|
|
2748
|
+
label: o.label != null ? String(o.label) : ""
|
|
2749
|
+
};
|
|
2750
|
+
}
|
|
2751
|
+
return { value: String(v), label: "" };
|
|
2752
|
+
}
|
|
2727
2753
|
function FormFieldVariantControl({
|
|
2728
2754
|
variant,
|
|
2729
2755
|
inputId,
|
|
@@ -2848,7 +2874,8 @@ function FormFieldVariantControl({
|
|
|
2848
2874
|
AsyncSelect,
|
|
2849
2875
|
{
|
|
2850
2876
|
...asyncSelectProps,
|
|
2851
|
-
|
|
2877
|
+
id: inputId,
|
|
2878
|
+
value: formValueToAsyncSelectOption(field.value),
|
|
2852
2879
|
onValueChange: field.onChange,
|
|
2853
2880
|
disabled: field.disabled,
|
|
2854
2881
|
error: hasError,
|
|
@@ -4913,6 +4940,7 @@ export {
|
|
|
4913
4940
|
colors,
|
|
4914
4941
|
containerVariants,
|
|
4915
4942
|
dismissToast,
|
|
4943
|
+
formValueToAsyncSelectOption,
|
|
4916
4944
|
getIcon,
|
|
4917
4945
|
headingVariants,
|
|
4918
4946
|
inputGroupSelectTriggerTextAlignClass,
|