@skybin-tech/nebula-ui 0.0.28 → 0.0.30
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 +422 -356
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -1
- package/dist/cjs/components/Accordion/Accordion.cjs.map +1 -1
- package/dist/cjs/components/Alert/Alert.cjs.map +1 -1
- package/dist/cjs/components/Avatar/Avatar.cjs.map +1 -1
- package/dist/cjs/components/Badge/Badge.cjs.map +1 -1
- package/dist/cjs/components/Button/Button.cjs +1 -1
- package/dist/cjs/components/Button/Button.cjs.map +1 -1
- package/dist/cjs/components/Card/Card.cjs.map +1 -1
- package/dist/cjs/components/Checkbox/Checkbox.cjs.map +1 -1
- package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs.map +1 -1
- package/dist/cjs/components/Form/Checkbox.cjs.map +1 -1
- package/dist/cjs/components/Form/Combobox.cjs +124 -0
- package/dist/cjs/components/Form/Combobox.cjs.map +1 -0
- package/dist/cjs/components/Form/CountryPicker.cjs +101 -0
- package/dist/cjs/components/Form/CountryPicker.cjs.map +1 -0
- package/dist/cjs/components/Form/CountrySelect.cjs +111 -0
- package/dist/cjs/components/Form/CountrySelect.cjs.map +1 -0
- package/dist/cjs/components/Form/DatePicker.cjs +122 -0
- package/dist/cjs/components/Form/DatePicker.cjs.map +1 -0
- package/dist/cjs/components/Form/FieldLayout.cjs +65 -0
- package/dist/cjs/components/Form/FieldLayout.cjs.map +1 -0
- package/dist/cjs/components/Form/Form.cjs +12 -9
- package/dist/cjs/components/Form/Form.cjs.map +1 -1
- package/dist/cjs/components/Form/FormSwitch.cjs.map +1 -1
- package/dist/cjs/components/Form/PhoneInput.cjs +170 -0
- package/dist/cjs/components/Form/PhoneInput.cjs.map +1 -0
- package/dist/cjs/components/Form/Radio.cjs.map +1 -1
- package/dist/cjs/components/Form/Select.cjs +35 -47
- package/dist/cjs/components/Form/Select.cjs.map +1 -1
- package/dist/cjs/components/Form/TextArea.cjs +1 -1
- package/dist/cjs/components/Form/TextArea.cjs.map +1 -1
- package/dist/cjs/components/Form/TextBox.cjs +50 -61
- package/dist/cjs/components/Form/TextBox.cjs.map +1 -1
- package/dist/cjs/components/Form/context.cjs +25 -11
- package/dist/cjs/components/Form/context.cjs.map +1 -1
- package/dist/cjs/components/Form/hooks.cjs.map +1 -1
- package/dist/cjs/components/Form/index.cjs +16 -0
- package/dist/cjs/components/Form/variants.cjs.map +1 -1
- package/dist/cjs/components/Input/Input.cjs +2 -2
- package/dist/cjs/components/Input/Input.cjs.map +1 -1
- package/dist/cjs/components/Label/Label.cjs.map +1 -1
- package/dist/cjs/components/Pagination/Pagination.cjs +4 -4
- package/dist/cjs/components/Pagination/Pagination.cjs.map +1 -1
- package/dist/cjs/components/Separator/Separator.cjs.map +1 -1
- package/dist/cjs/components/Switch/Switch.cjs.map +1 -1
- package/dist/cjs/components/Tabs/Tabs.cjs.map +1 -1
- package/dist/cjs/components/Textarea/Textarea.cjs.map +1 -1
- package/dist/cjs/components/Tooltip/Tooltip.cjs.map +1 -1
- package/dist/cjs/data/countries.cjs +1062 -0
- package/dist/cjs/data/countries.cjs.map +1 -0
- package/dist/cjs/hooks/useDebounce.cjs.map +1 -1
- package/dist/cjs/hooks/useToast.cjs.map +1 -1
- package/dist/cjs/hooks/useToggle.cjs.map +1 -1
- package/dist/cjs/index.cjs +64 -4
- package/dist/cjs/primitives/accordion.cjs.map +1 -1
- package/dist/cjs/primitives/alert-dialog.cjs +73 -0
- package/dist/cjs/primitives/alert-dialog.cjs.map +1 -0
- package/dist/cjs/primitives/alert.cjs.map +1 -1
- package/dist/cjs/primitives/avatar.cjs.map +1 -1
- package/dist/cjs/primitives/badge.cjs.map +1 -1
- package/dist/cjs/primitives/breadcrumb.cjs +73 -0
- package/dist/cjs/primitives/breadcrumb.cjs.map +1 -0
- package/dist/cjs/primitives/button.cjs +8 -7
- package/dist/cjs/primitives/button.cjs.map +1 -1
- package/dist/cjs/primitives/calendar.cjs.map +1 -1
- package/dist/cjs/primitives/card.cjs.map +1 -1
- package/dist/cjs/primitives/checkbox.cjs.map +1 -1
- package/dist/cjs/primitives/command.cjs.map +1 -1
- package/dist/cjs/primitives/dialog.cjs.map +1 -1
- package/dist/cjs/primitives/dropdown-menu.cjs.map +1 -1
- package/dist/cjs/primitives/input-otp.cjs +49 -0
- package/dist/cjs/primitives/input-otp.cjs.map +1 -0
- package/dist/cjs/primitives/label.cjs.map +1 -1
- package/dist/cjs/primitives/popover.cjs.map +1 -1
- package/dist/cjs/primitives/progress.cjs +24 -0
- package/dist/cjs/primitives/progress.cjs.map +1 -0
- package/dist/cjs/primitives/radio-group.cjs.map +1 -1
- package/dist/cjs/primitives/scroll-area.cjs.map +1 -1
- package/dist/cjs/primitives/select.cjs.map +1 -1
- package/dist/cjs/primitives/separator.cjs.map +1 -1
- package/dist/cjs/primitives/sheet.cjs +78 -0
- package/dist/cjs/primitives/sheet.cjs.map +1 -0
- package/dist/cjs/primitives/slider.cjs +23 -0
- package/dist/cjs/primitives/slider.cjs.map +1 -0
- package/dist/cjs/primitives/sonner.cjs.map +1 -1
- package/dist/cjs/primitives/switch.cjs.map +1 -1
- package/dist/cjs/primitives/table.cjs.map +1 -1
- package/dist/cjs/primitives/tabs.cjs.map +1 -1
- package/dist/cjs/primitives/textarea.cjs +1 -1
- package/dist/cjs/primitives/textarea.cjs.map +1 -1
- package/dist/cjs/primitives/textbox.cjs +1 -1
- package/dist/cjs/primitives/textbox.cjs.map +1 -1
- package/dist/cjs/primitives/toast.cjs.map +1 -1
- package/dist/cjs/primitives/toggle.cjs.map +1 -1
- package/dist/cjs/utils/cn.cjs.map +1 -1
- package/dist/components/Alert/Alert.js.map +1 -1
- package/dist/components/AlertDialog/AlertDialog.d.ts +2 -0
- package/dist/components/AlertDialog/AlertDialog.d.ts.map +1 -0
- package/dist/components/AlertDialog/index.d.ts +2 -0
- package/dist/components/AlertDialog/index.d.ts.map +1 -0
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/Breadcrumb/Breadcrumb.d.ts +2 -0
- package/dist/components/Breadcrumb/Breadcrumb.d.ts.map +1 -0
- package/dist/components/Breadcrumb/index.d.ts +2 -0
- package/dist/components/Breadcrumb/index.d.ts.map +1 -0
- package/dist/components/Button/Button.d.ts.map +1 -1
- package/dist/components/Button/Button.js +2 -2
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Card/Card.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/Form/Checkbox.js.map +1 -1
- package/dist/components/Form/Combobox.d.ts +31 -0
- package/dist/components/Form/Combobox.d.ts.map +1 -0
- package/dist/components/Form/Combobox.js +124 -0
- package/dist/components/Form/Combobox.js.map +1 -0
- package/dist/components/Form/CountryPicker.d.ts +17 -0
- package/dist/components/Form/CountryPicker.d.ts.map +1 -0
- package/dist/components/Form/CountryPicker.js +101 -0
- package/dist/components/Form/CountryPicker.js.map +1 -0
- package/dist/components/Form/CountrySelect.d.ts +32 -0
- package/dist/components/Form/CountrySelect.d.ts.map +1 -0
- package/dist/components/Form/CountrySelect.js +111 -0
- package/dist/components/Form/CountrySelect.js.map +1 -0
- package/dist/components/Form/DatePicker.d.ts +27 -0
- package/dist/components/Form/DatePicker.d.ts.map +1 -0
- package/dist/components/Form/DatePicker.js +122 -0
- package/dist/components/Form/DatePicker.js.map +1 -0
- package/dist/components/Form/FieldLayout.d.ts +15 -0
- package/dist/components/Form/FieldLayout.d.ts.map +1 -0
- package/dist/components/Form/FieldLayout.js +65 -0
- package/dist/components/Form/FieldLayout.js.map +1 -0
- package/dist/components/Form/Form.d.ts +1 -1
- package/dist/components/Form/Form.d.ts.map +1 -1
- package/dist/components/Form/Form.js +12 -9
- package/dist/components/Form/Form.js.map +1 -1
- package/dist/components/Form/FormSwitch.js.map +1 -1
- package/dist/components/Form/PhoneInput.d.ts +38 -0
- package/dist/components/Form/PhoneInput.d.ts.map +1 -0
- package/dist/components/Form/PhoneInput.js +170 -0
- package/dist/components/Form/PhoneInput.js.map +1 -0
- package/dist/components/Form/Radio.js.map +1 -1
- package/dist/components/Form/Select.d.ts.map +1 -1
- package/dist/components/Form/Select.js +35 -47
- package/dist/components/Form/Select.js.map +1 -1
- package/dist/components/Form/TextArea.js +1 -1
- package/dist/components/Form/TextArea.js.map +1 -1
- package/dist/components/Form/TextBox.d.ts.map +1 -1
- package/dist/components/Form/TextBox.js +50 -61
- package/dist/components/Form/TextBox.js.map +1 -1
- package/dist/components/Form/context.d.ts.map +1 -1
- package/dist/components/Form/context.js +25 -11
- package/dist/components/Form/context.js.map +1 -1
- package/dist/components/Form/context.test.d.ts +2 -0
- package/dist/components/Form/context.test.d.ts.map +1 -0
- package/dist/components/Form/hooks.js.map +1 -1
- package/dist/components/Form/index.d.ts +12 -0
- package/dist/components/Form/index.d.ts.map +1 -1
- package/dist/components/Form/index.js +7 -1
- package/dist/components/Input/Input.js +2 -2
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/InputOTP/InputOTP.d.ts +2 -0
- package/dist/components/InputOTP/InputOTP.d.ts.map +1 -0
- package/dist/components/InputOTP/index.d.ts +2 -0
- package/dist/components/InputOTP/index.d.ts.map +1 -0
- package/dist/components/Label/Label.js.map +1 -1
- package/dist/components/Pagination/Pagination.d.ts +2 -2
- package/dist/components/Pagination/Pagination.d.ts.map +1 -1
- package/dist/components/Pagination/Pagination.js +4 -4
- package/dist/components/Pagination/Pagination.js.map +1 -1
- package/dist/components/Progress/Progress.d.ts +2 -0
- package/dist/components/Progress/Progress.d.ts.map +1 -0
- package/dist/components/Progress/index.d.ts +2 -0
- package/dist/components/Progress/index.d.ts.map +1 -0
- package/dist/components/Separator/Separator.js.map +1 -1
- package/dist/components/Sheet/Sheet.d.ts +2 -0
- package/dist/components/Sheet/Sheet.d.ts.map +1 -0
- package/dist/components/Sheet/index.d.ts +2 -0
- package/dist/components/Sheet/index.d.ts.map +1 -0
- package/dist/components/Slider/Slider.d.ts +2 -0
- package/dist/components/Slider/Slider.d.ts.map +1 -0
- package/dist/components/Slider/index.d.ts +2 -0
- package/dist/components/Slider/index.d.ts.map +1 -0
- package/dist/components/Switch/Switch.js.map +1 -1
- package/dist/components/Tabs/Tabs.js.map +1 -1
- package/dist/components/Textarea/Textarea.js.map +1 -1
- package/dist/data/countries.d.ts +18 -0
- package/dist/data/countries.d.ts.map +1 -0
- package/dist/data/countries.js +1054 -0
- package/dist/data/countries.js.map +1 -0
- package/dist/hooks/useDebounce.js.map +1 -1
- package/dist/hooks/useToast.js.map +1 -1
- package/dist/hooks/useToggle.js.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -5
- package/dist/primitives/accordion.js.map +1 -1
- package/dist/primitives/alert-dialog.d.ts +21 -0
- package/dist/primitives/alert-dialog.d.ts.map +1 -0
- package/dist/primitives/alert-dialog.js +60 -0
- package/dist/primitives/alert-dialog.js.map +1 -0
- package/dist/primitives/alert.js.map +1 -1
- package/dist/primitives/avatar.js.map +1 -1
- package/dist/primitives/breadcrumb.d.ts +20 -0
- package/dist/primitives/breadcrumb.d.ts.map +1 -0
- package/dist/primitives/breadcrumb.js +65 -0
- package/dist/primitives/breadcrumb.js.map +1 -0
- package/dist/primitives/button.d.ts +4 -3
- package/dist/primitives/button.d.ts.map +1 -1
- package/dist/primitives/button.js +7 -7
- package/dist/primitives/button.js.map +1 -1
- package/dist/primitives/calendar.js.map +1 -1
- package/dist/primitives/card.js.map +1 -1
- package/dist/primitives/checkbox.js.map +1 -1
- package/dist/primitives/command.js.map +1 -1
- package/dist/primitives/dialog.js.map +1 -1
- package/dist/primitives/dropdown-menu.js.map +1 -1
- package/dist/primitives/index.d.ts +6 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/input-otp.d.ts +35 -0
- package/dist/primitives/input-otp.d.ts.map +1 -0
- package/dist/primitives/input-otp.js +44 -0
- package/dist/primitives/input-otp.js.map +1 -0
- package/dist/primitives/input.d.ts +1 -3
- package/dist/primitives/input.d.ts.map +1 -1
- package/dist/primitives/label.js.map +1 -1
- package/dist/primitives/popover.js.map +1 -1
- package/dist/primitives/progress.d.ts +5 -0
- package/dist/primitives/progress.d.ts.map +1 -0
- package/dist/primitives/progress.js +21 -0
- package/dist/primitives/progress.js.map +1 -0
- package/dist/primitives/radio-group.js.map +1 -1
- package/dist/primitives/scroll-area.js.map +1 -1
- package/dist/primitives/select.js.map +1 -1
- package/dist/primitives/separator.js.map +1 -1
- package/dist/primitives/sheet.d.ts +26 -0
- package/dist/primitives/sheet.d.ts.map +1 -0
- package/dist/primitives/sheet.js +66 -0
- package/dist/primitives/sheet.js.map +1 -0
- package/dist/primitives/slider.d.ts +5 -0
- package/dist/primitives/slider.d.ts.map +1 -0
- package/dist/primitives/slider.js +20 -0
- package/dist/primitives/slider.js.map +1 -0
- package/dist/primitives/sonner.js.map +1 -1
- package/dist/primitives/switch.js.map +1 -1
- package/dist/primitives/table.js.map +1 -1
- package/dist/primitives/tabs.js.map +1 -1
- package/dist/primitives/textarea.js +1 -1
- package/dist/primitives/textarea.js.map +1 -1
- package/dist/primitives/textbox.js +1 -1
- package/dist/primitives/textbox.js.map +1 -1
- package/dist/primitives/toast.js.map +1 -1
- package/dist/primitives/toggle.js.map +1 -1
- package/package.json +168 -60
- package/src/styles/index.css +107 -0
- package/dist/cjs/primitives/input.cjs +0 -20
- package/dist/cjs/primitives/input.cjs.map +0 -1
- package/dist/primitives/input.js +0 -18
- package/dist/primitives/input.js.map +0 -1
- package/dist/stories/Button.d.ts +0 -15
- package/dist/stories/Button.d.ts.map +0 -1
- package/dist/stories/Button.stories.d.ts +0 -24
- package/dist/stories/Button.stories.d.ts.map +0 -1
- package/dist/stories/Header.d.ts +0 -12
- package/dist/stories/Header.d.ts.map +0 -1
- package/dist/stories/Header.stories.d.ts +0 -19
- package/dist/stories/Header.stories.d.ts.map +0 -1
- package/dist/stories/Page.d.ts +0 -3
- package/dist/stories/Page.d.ts.map +0 -1
- package/dist/stories/Page.stories.d.ts +0 -13
- package/dist/stories/Page.stories.d.ts.map +0 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
import { Button } from "../../primitives/button.js";
|
|
5
|
+
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "../../primitives/command.js";
|
|
6
|
+
import { Popover, PopoverContent, PopoverTrigger } from "../../primitives/popover.js";
|
|
7
|
+
import { COUNTRIES, filterCountries, getCountryByCode, getCountryFlag, sortCountriesWithPriority } from "../../data/countries.js";
|
|
8
|
+
import { useMemo, useState } from "react";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { Check, ChevronsUpDown } from "lucide-react";
|
|
11
|
+
//#region src/components/Form/CountryPicker.tsx
|
|
12
|
+
function resolveCountries(include, exclude, priorityCountries) {
|
|
13
|
+
let countries = COUNTRIES;
|
|
14
|
+
if (include?.length) {
|
|
15
|
+
const includeSet = new Set(include.map((code) => code.toUpperCase()));
|
|
16
|
+
countries = countries.filter((country) => includeSet.has(country.code));
|
|
17
|
+
}
|
|
18
|
+
if (exclude?.length) {
|
|
19
|
+
const excludeSet = new Set(exclude.map((code) => code.toUpperCase()));
|
|
20
|
+
countries = countries.filter((country) => !excludeSet.has(country.code));
|
|
21
|
+
}
|
|
22
|
+
return sortCountriesWithPriority(countries, priorityCountries);
|
|
23
|
+
}
|
|
24
|
+
function CountryPicker({ value, onValueChange, placeholder = "Select country", disabled, compact = false, include, exclude, priorityCountries, className, id, required, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy }) {
|
|
25
|
+
const [open, setOpen] = useState(false);
|
|
26
|
+
const countries = useMemo(() => resolveCountries(include, exclude, priorityCountries), [
|
|
27
|
+
include,
|
|
28
|
+
exclude,
|
|
29
|
+
priorityCountries
|
|
30
|
+
]);
|
|
31
|
+
const selectedCountry = value ? getCountryByCode(value) : void 0;
|
|
32
|
+
return /* @__PURE__ */ jsxs(Popover, {
|
|
33
|
+
open,
|
|
34
|
+
onOpenChange: setOpen,
|
|
35
|
+
children: [/* @__PURE__ */ jsx(PopoverTrigger, {
|
|
36
|
+
asChild: true,
|
|
37
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
38
|
+
id,
|
|
39
|
+
type: "button",
|
|
40
|
+
variant: "outline",
|
|
41
|
+
role: "combobox",
|
|
42
|
+
"aria-expanded": open,
|
|
43
|
+
"aria-required": required,
|
|
44
|
+
"aria-invalid": ariaInvalid,
|
|
45
|
+
"aria-describedby": ariaDescribedBy,
|
|
46
|
+
disabled,
|
|
47
|
+
className: cn("justify-between font-normal", compact ? "h-full w-auto shrink-0 border-0 bg-transparent px-2 shadow-none hover:bg-transparent" : "w-full", !value && "text-muted-foreground", className),
|
|
48
|
+
children: [selectedCountry ? /* @__PURE__ */ jsxs("span", {
|
|
49
|
+
className: "flex min-w-0 items-center gap-2 truncate",
|
|
50
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
51
|
+
"aria-hidden": "true",
|
|
52
|
+
children: getCountryFlag(selectedCountry.code)
|
|
53
|
+
}), !compact && /* @__PURE__ */ jsx("span", {
|
|
54
|
+
className: "truncate",
|
|
55
|
+
children: selectedCountry.name
|
|
56
|
+
})]
|
|
57
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
58
|
+
className: "truncate",
|
|
59
|
+
children: compact ? "…" : placeholder
|
|
60
|
+
}), !compact && /* @__PURE__ */ jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })]
|
|
61
|
+
})
|
|
62
|
+
}), /* @__PURE__ */ jsx(PopoverContent, {
|
|
63
|
+
className: "w-[320px] p-0",
|
|
64
|
+
align: "start",
|
|
65
|
+
children: /* @__PURE__ */ jsxs(Command, {
|
|
66
|
+
filter: (itemValue, search) => {
|
|
67
|
+
const country = countries.find((entry) => entry.code.toLowerCase() === itemValue.toLowerCase());
|
|
68
|
+
if (!country) return 0;
|
|
69
|
+
return filterCountries([country], search).length > 0 ? 1 : 0;
|
|
70
|
+
},
|
|
71
|
+
children: [/* @__PURE__ */ jsx(CommandInput, { placeholder: "Search country..." }), /* @__PURE__ */ jsxs(CommandList, { children: [/* @__PURE__ */ jsx(CommandEmpty, { children: "No country found." }), /* @__PURE__ */ jsx(CommandGroup, { children: countries.map((country) => /* @__PURE__ */ jsxs(CommandItem, {
|
|
72
|
+
value: country.code,
|
|
73
|
+
onSelect: (currentValue) => {
|
|
74
|
+
onValueChange(currentValue.toUpperCase());
|
|
75
|
+
setOpen(false);
|
|
76
|
+
},
|
|
77
|
+
children: [
|
|
78
|
+
/* @__PURE__ */ jsx(Check, { className: cn("mr-2 h-4 w-4", value === country.code ? "opacity-100" : "opacity-0") }),
|
|
79
|
+
/* @__PURE__ */ jsx("span", {
|
|
80
|
+
"aria-hidden": "true",
|
|
81
|
+
className: "mr-2",
|
|
82
|
+
children: getCountryFlag(country.code)
|
|
83
|
+
}),
|
|
84
|
+
/* @__PURE__ */ jsx("span", {
|
|
85
|
+
className: "truncate",
|
|
86
|
+
children: country.name
|
|
87
|
+
}),
|
|
88
|
+
/* @__PURE__ */ jsx("span", {
|
|
89
|
+
className: "ml-auto text-xs text-muted-foreground",
|
|
90
|
+
children: country.dialCode
|
|
91
|
+
})
|
|
92
|
+
]
|
|
93
|
+
}, country.code)) })] })]
|
|
94
|
+
})
|
|
95
|
+
})]
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
export { CountryPicker };
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=CountryPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CountryPicker.js","names":[],"sources":["../../../src/components/Form/CountryPicker.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useMemo, useState } from \"react\";\r\nimport { Check, ChevronsUpDown } from \"lucide-react\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport {\r\n Command,\r\n CommandEmpty,\r\n CommandGroup,\r\n CommandInput,\r\n CommandItem,\r\n CommandList,\r\n} from \"../../primitives/command\";\r\nimport { Popover, PopoverContent, PopoverTrigger } from \"../../primitives/popover\";\r\nimport {\r\n COUNTRIES,\r\n filterCountries,\r\n getCountryByCode,\r\n getCountryFlag,\r\n sortCountriesWithPriority,\r\n type Country,\r\n} from \"../../data/countries\";\r\n\r\nexport interface CountryPickerProps {\r\n value?: string;\r\n onValueChange: (value: string) => void;\r\n placeholder?: string;\r\n disabled?: boolean;\r\n compact?: boolean;\r\n include?: string[];\r\n exclude?: string[];\r\n priorityCountries?: string[];\r\n className?: string;\r\n id?: string;\r\n required?: boolean;\r\n \"aria-invalid\"?: boolean;\r\n \"aria-describedby\"?: string;\r\n}\r\n\r\nfunction resolveCountries(\r\n include?: string[],\r\n exclude?: string[],\r\n priorityCountries?: string[]\r\n): Country[] {\r\n let countries = COUNTRIES;\r\n\r\n if (include?.length) {\r\n const includeSet = new Set(include.map((code) => code.toUpperCase()));\r\n countries = countries.filter((country) => includeSet.has(country.code));\r\n }\r\n\r\n if (exclude?.length) {\r\n const excludeSet = new Set(exclude.map((code) => code.toUpperCase()));\r\n countries = countries.filter((country) => !excludeSet.has(country.code));\r\n }\r\n\r\n return sortCountriesWithPriority(countries, priorityCountries);\r\n}\r\n\r\nexport function CountryPicker({\r\n value,\r\n onValueChange,\r\n placeholder = \"Select country\",\r\n disabled,\r\n compact = false,\r\n include,\r\n exclude,\r\n priorityCountries,\r\n className,\r\n id,\r\n required,\r\n \"aria-invalid\": ariaInvalid,\r\n \"aria-describedby\": ariaDescribedBy,\r\n}: CountryPickerProps) {\r\n const [open, setOpen] = useState(false);\r\n const countries = useMemo(\r\n () => resolveCountries(include, exclude, priorityCountries),\r\n [include, exclude, priorityCountries]\r\n );\r\n const selectedCountry = value ? getCountryByCode(value) : undefined;\r\n\r\n return (\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger asChild>\r\n <Button\r\n id={id}\r\n type=\"button\"\r\n variant=\"outline\"\r\n role=\"combobox\"\r\n aria-expanded={open}\r\n aria-required={required}\r\n aria-invalid={ariaInvalid}\r\n aria-describedby={ariaDescribedBy}\r\n disabled={disabled}\r\n className={cn(\r\n \"justify-between font-normal\",\r\n compact ? \"h-full w-auto shrink-0 border-0 bg-transparent px-2 shadow-none hover:bg-transparent\" : \"w-full\",\r\n !value && \"text-muted-foreground\",\r\n className\r\n )}\r\n >\r\n {selectedCountry ? (\r\n <span className=\"flex min-w-0 items-center gap-2 truncate\">\r\n <span aria-hidden=\"true\">{getCountryFlag(selectedCountry.code)}</span>\r\n {!compact && <span className=\"truncate\">{selectedCountry.name}</span>}\r\n </span>\r\n ) : (\r\n <span className=\"truncate\">{compact ? \"…\" : placeholder}</span>\r\n )}\r\n {!compact && <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />}\r\n </Button>\r\n </PopoverTrigger>\r\n <PopoverContent className=\"w-[320px] p-0\" align=\"start\">\r\n <Command\r\n filter={(itemValue, search) => {\r\n const country = countries.find(\r\n (entry) => entry.code.toLowerCase() === itemValue.toLowerCase()\r\n );\r\n if (!country) {\r\n return 0;\r\n }\r\n\r\n return filterCountries([country], search).length > 0 ? 1 : 0;\r\n }}\r\n >\r\n <CommandInput placeholder=\"Search country...\" />\r\n <CommandList>\r\n <CommandEmpty>No country found.</CommandEmpty>\r\n <CommandGroup>\r\n {countries.map((country) => (\r\n <CommandItem\r\n key={country.code}\r\n value={country.code}\r\n onSelect={(currentValue) => {\r\n onValueChange(currentValue.toUpperCase());\r\n setOpen(false);\r\n }}\r\n >\r\n <Check\r\n className={cn(\r\n \"mr-2 h-4 w-4\",\r\n value === country.code ? \"opacity-100\" : \"opacity-0\"\r\n )}\r\n />\r\n <span aria-hidden=\"true\" className=\"mr-2\">\r\n {getCountryFlag(country.code)}\r\n </span>\r\n <span className=\"truncate\">{country.name}</span>\r\n <span className=\"ml-auto text-xs text-muted-foreground\">\r\n {country.dialCode}\r\n </span>\r\n </CommandItem>\r\n ))}\r\n </CommandGroup>\r\n </CommandList>\r\n </Command>\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n\r\n"],"mappings":";;;;;;;;;;;AAwCA,SAAS,iBACP,SACA,SACA,mBACW;CACX,IAAI,YAAY;CAEhB,IAAI,SAAS,QAAQ;EACnB,MAAM,aAAa,IAAI,IAAI,QAAQ,KAAK,SAAS,KAAK,YAAY,CAAC,CAAC;EACpE,YAAY,UAAU,QAAQ,YAAY,WAAW,IAAI,QAAQ,IAAI,CAAC;CACxE;CAEA,IAAI,SAAS,QAAQ;EACnB,MAAM,aAAa,IAAI,IAAI,QAAQ,KAAK,SAAS,KAAK,YAAY,CAAC,CAAC;EACpE,YAAY,UAAU,QAAQ,YAAY,CAAC,WAAW,IAAI,QAAQ,IAAI,CAAC;CACzE;CAEA,OAAO,0BAA0B,WAAW,iBAAiB;AAC/D;AAEA,SAAgB,cAAc,EAC5B,OACA,eACA,cAAc,kBACd,UACA,UAAU,OACV,SACA,SACA,mBACA,WACA,IACA,UACA,gBAAgB,aAChB,oBAAoB,mBACC;CACrB,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,YAAY,cACV,iBAAiB,SAAS,SAAS,iBAAiB,GAC1D;EAAC;EAAS;EAAS;CAAiB,CACtC;CACA,MAAM,kBAAkB,QAAQ,iBAAiB,KAAK,IAAI,KAAA;CAE1D,OACE,qBAAC,SAAD;EAAe;EAAM,cAAc;EAAnC,UAAA,CACE,oBAAC,gBAAD;GAAgB,SAAA;GACd,UAAA,qBAAC,QAAD;IACM;IACJ,MAAK;IACL,SAAQ;IACR,MAAK;IACL,iBAAe;IACf,iBAAe;IACf,gBAAc;IACd,oBAAkB;IACR;IACV,WAAW,GACT,+BACA,UAAU,yFAAyF,UACnG,CAAC,SAAS,yBACV,SACF;IAfF,UAAA,CAiBG,kBACC,qBAAC,QAAD;KAAM,WAAU;KAAhB,UAAA,CACE,oBAAC,QAAD;MAAM,eAAY;MAAQ,UAAA,eAAe,gBAAgB,IAAI;KAAQ,CAAA,GACpE,CAAC,WAAW,oBAAC,QAAD;MAAM,WAAU;MAAY,UAAA,gBAAgB;KAAW,CAAA,CAChE;IAEN,CAAA,IAAA,oBAAC,QAAD;KAAM,WAAU;KAAY,UAAA,UAAU,MAAM;IAAkB,CAAA,GAE/D,CAAC,WAAW,oBAAC,gBAAD,EAAgB,WAAU,mCAAoC,CAAA,CACrE;;EACM,CAAA,GAChB,oBAAC,gBAAD;GAAgB,WAAU;GAAgB,OAAM;GAC9C,UAAA,qBAAC,SAAD;IACE,SAAS,WAAW,WAAW;KAC7B,MAAM,UAAU,UAAU,MACvB,UAAU,MAAM,KAAK,YAAY,MAAM,UAAU,YAAY,CAChE;KACA,IAAI,CAAC,SACH,OAAO;KAGT,OAAO,gBAAgB,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,SAAS,IAAI,IAAI;IAC7D;IAVF,UAAA,CAYE,oBAAC,cAAD,EAAc,aAAY,oBAAqB,CAAA,GAC/C,qBAAC,aAAD,EAAA,UAAA,CACE,oBAAC,cAAD,EAAA,UAAc,oBAA+B,CAAA,GAC7C,oBAAC,cAAD,EAAA,UACG,UAAU,KAAK,YACd,qBAAC,aAAD;KAEE,OAAO,QAAQ;KACf,WAAW,iBAAiB;MAC1B,cAAc,aAAa,YAAY,CAAC;MACxC,QAAQ,KAAK;KACf;KANF,UAAA;MAQE,oBAAC,OAAD,EACE,WAAW,GACT,gBACA,UAAU,QAAQ,OAAO,gBAAgB,WAC3C,EACD,CAAA;MACD,oBAAC,QAAD;OAAM,eAAY;OAAO,WAAU;OAChC,UAAA,eAAe,QAAQ,IAAI;MACxB,CAAA;MACN,oBAAC,QAAD;OAAM,WAAU;OAAY,UAAA,QAAQ;MAAW,CAAA;MAC/C,oBAAC,QAAD;OAAM,WAAU;OACb,UAAA,QAAQ;MACL,CAAA;KACK;IApBN,GAAA,QAAQ,IAoBF,CACd,EACW,CAAA,CACH,EAAA,CAAA,CACN;;EACK,CAAA,CACT;;AAEb"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Control, FieldPath, FieldValues } from 'react-hook-form';
|
|
2
|
+
import { VariantProps } from 'class-variance-authority';
|
|
3
|
+
declare const countrySelectVariants: (props?: ({
|
|
4
|
+
size?: "sm" | "lg" | "md" | null | undefined;
|
|
5
|
+
variant?: "default" | "error" | "success" | null | undefined;
|
|
6
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
7
|
+
export interface CountrySelectProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> extends VariantProps<typeof countrySelectVariants> {
|
|
8
|
+
name: TName;
|
|
9
|
+
label?: string;
|
|
10
|
+
helperText?: string;
|
|
11
|
+
showError?: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
fullWidth?: boolean;
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
allowClear?: boolean;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
className?: string;
|
|
18
|
+
id?: string;
|
|
19
|
+
control?: Control<TFieldValues>;
|
|
20
|
+
include?: string[];
|
|
21
|
+
exclude?: string[];
|
|
22
|
+
priorityCountries?: string[];
|
|
23
|
+
/** Field is required (`true` or custom error message string) */
|
|
24
|
+
required?: boolean | string;
|
|
25
|
+
validate?: (value: unknown) => boolean | string | Promise<boolean | string>;
|
|
26
|
+
}
|
|
27
|
+
export declare function CountrySelect<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ name, label, helperText, showError, error: customError, size, variant, fullWidth, placeholder, allowClear, disabled, className, id: providedId, control: externalControl, include, exclude, priorityCountries, required, validate, }: CountrySelectProps<TFieldValues, TName>): import("react").JSX.Element;
|
|
28
|
+
export declare namespace CountrySelect {
|
|
29
|
+
var displayName: string;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=CountrySelect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CountrySelect.d.ts","sourceRoot":"","sources":["../../../src/components/Form/CountrySelect.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAsD,KAAK,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACrI,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAMlE,QAAA,MAAM,qBAAqB;;;8EAiBzB,CAAC;AAEH,MAAM,WAAW,kBAAkB,CACjC,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,CAC/D,SAAQ,YAAY,CAAC,OAAO,qBAAqB,CAAC;IAClD,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;CAC7E;AAED,wBAAgB,aAAa,CAC3B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,EAC/D,EACA,IAAI,EACJ,KAAK,EACL,UAAU,EACV,SAAgB,EAChB,KAAK,EAAE,WAAW,EAClB,IAAI,EACJ,OAAO,EACP,SAAgB,EAChB,WAAgC,EAChC,UAAU,EACV,QAAQ,EACR,SAAS,EACT,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,eAAe,EACxB,OAAO,EACP,OAAO,EACP,iBAAiB,EACjB,QAAQ,EACR,QAAQ,GACT,EAAE,kBAAkB,CAAC,YAAY,EAAE,KAAK,CAAC,+BA+FzC;yBAtHe,aAAa"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
import { FormConfigContext } from "./context.js";
|
|
5
|
+
import { FieldLayout } from "./FieldLayout.js";
|
|
6
|
+
import { CountryPicker } from "./CountryPicker.js";
|
|
7
|
+
import { useContext, useEffect, useId } from "react";
|
|
8
|
+
import { cva } from "class-variance-authority";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { useController, useFormContext } from "react-hook-form";
|
|
11
|
+
//#region src/components/Form/CountrySelect.tsx
|
|
12
|
+
var countrySelectVariants = cva("", {
|
|
13
|
+
variants: {
|
|
14
|
+
size: {
|
|
15
|
+
sm: "h-8 text-xs",
|
|
16
|
+
md: "h-10 text-sm",
|
|
17
|
+
lg: "h-12 text-base"
|
|
18
|
+
},
|
|
19
|
+
variant: {
|
|
20
|
+
default: "border-input focus-visible:ring-ring",
|
|
21
|
+
error: "border-destructive focus-visible:ring-destructive",
|
|
22
|
+
success: "border-green-500 focus-visible:ring-green-500"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
defaultVariants: {
|
|
26
|
+
size: "md",
|
|
27
|
+
variant: "default"
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
function CountrySelect({ name, label, helperText, showError = true, error: customError, size, variant, fullWidth = true, placeholder = "Select a country", allowClear, disabled, className, id: providedId, control: externalControl, include, exclude, priorityCountries, required, validate }) {
|
|
31
|
+
const generatedId = useId();
|
|
32
|
+
const inputId = providedId ?? generatedId;
|
|
33
|
+
const formConfigContext = useContext(FormConfigContext);
|
|
34
|
+
const formConfig = formConfigContext ?? {};
|
|
35
|
+
const rhfContext = useFormContext();
|
|
36
|
+
const control = externalControl ?? rhfContext?.control;
|
|
37
|
+
const registerFieldValidation = formConfigContext?.registerFieldValidation;
|
|
38
|
+
const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (registerFieldValidation) {
|
|
41
|
+
const rules = {};
|
|
42
|
+
if (required !== void 0) rules.required = required;
|
|
43
|
+
if (validate !== void 0) rules.validate = validate;
|
|
44
|
+
registerFieldValidation({
|
|
45
|
+
name,
|
|
46
|
+
type: "string",
|
|
47
|
+
rules
|
|
48
|
+
});
|
|
49
|
+
return () => {
|
|
50
|
+
unregisterFieldValidation?.(name);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}, [
|
|
54
|
+
registerFieldValidation,
|
|
55
|
+
unregisterFieldValidation,
|
|
56
|
+
name,
|
|
57
|
+
required,
|
|
58
|
+
validate
|
|
59
|
+
]);
|
|
60
|
+
const { field, fieldState } = useController({
|
|
61
|
+
name,
|
|
62
|
+
control
|
|
63
|
+
});
|
|
64
|
+
const fieldError = fieldState.error?.message;
|
|
65
|
+
const errorMessage = customError ?? fieldError;
|
|
66
|
+
const hasError = !!errorMessage;
|
|
67
|
+
const effectiveSize = size ?? formConfig.size ?? "md";
|
|
68
|
+
const effectiveDisabled = disabled ?? formConfig.disabled;
|
|
69
|
+
const effectiveVariant = hasError ? "error" : variant;
|
|
70
|
+
return /* @__PURE__ */ jsx(FieldLayout, {
|
|
71
|
+
inputId,
|
|
72
|
+
label,
|
|
73
|
+
required: !!required,
|
|
74
|
+
helperText,
|
|
75
|
+
errorMessage: showError ? errorMessage : void 0,
|
|
76
|
+
showError,
|
|
77
|
+
fullWidth,
|
|
78
|
+
formConfig,
|
|
79
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
80
|
+
className: "flex gap-2",
|
|
81
|
+
children: [/* @__PURE__ */ jsx(CountryPicker, {
|
|
82
|
+
id: inputId,
|
|
83
|
+
value: field.value ?? "",
|
|
84
|
+
onValueChange: (value) => field.onChange(value),
|
|
85
|
+
placeholder,
|
|
86
|
+
disabled: effectiveDisabled,
|
|
87
|
+
include,
|
|
88
|
+
exclude,
|
|
89
|
+
priorityCountries,
|
|
90
|
+
required: !!required,
|
|
91
|
+
"aria-invalid": hasError,
|
|
92
|
+
"aria-describedby": hasError ? `${inputId}-error` : helperText ? `${inputId}-helper` : void 0,
|
|
93
|
+
className: cn(countrySelectVariants({
|
|
94
|
+
size: effectiveSize,
|
|
95
|
+
variant: effectiveVariant
|
|
96
|
+
}), className)
|
|
97
|
+
}), allowClear && field.value && /* @__PURE__ */ jsx("button", {
|
|
98
|
+
type: "button",
|
|
99
|
+
className: "text-sm text-muted-foreground hover:text-foreground",
|
|
100
|
+
onClick: () => field.onChange(""),
|
|
101
|
+
disabled: effectiveDisabled,
|
|
102
|
+
children: "Clear"
|
|
103
|
+
})]
|
|
104
|
+
})
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
CountrySelect.displayName = "CountrySelect";
|
|
108
|
+
//#endregion
|
|
109
|
+
export { CountrySelect };
|
|
110
|
+
|
|
111
|
+
//# sourceMappingURL=CountrySelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CountrySelect.js","names":[],"sources":["../../../src/components/Form/CountrySelect.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useContext, useEffect, useId } from \"react\";\r\nimport { useController, useFormContext as useRHFFormContext, type Control, type FieldPath, type FieldValues } from \"react-hook-form\";\r\nimport { cva, type VariantProps } from \"class-variance-authority\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { FormConfigContext, type FieldValidationRules, type FormConfig } from \"./context\";\r\nimport { FieldLayout } from \"./FieldLayout\";\r\nimport { CountryPicker } from \"./CountryPicker\";\r\n\r\nconst countrySelectVariants = cva(\"\", {\r\n variants: {\r\n size: {\r\n sm: \"h-8 text-xs\",\r\n md: \"h-10 text-sm\",\r\n lg: \"h-12 text-base\",\r\n },\r\n variant: {\r\n default: \"border-input focus-visible:ring-ring\",\r\n error: \"border-destructive focus-visible:ring-destructive\",\r\n success: \"border-green-500 focus-visible:ring-green-500\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n variant: \"default\",\r\n },\r\n});\r\n\r\nexport interface CountrySelectProps<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\r\n> extends VariantProps<typeof countrySelectVariants> {\r\n name: TName;\r\n label?: string;\r\n helperText?: string;\r\n showError?: boolean;\r\n error?: string;\r\n fullWidth?: boolean;\r\n placeholder?: string;\r\n allowClear?: boolean;\r\n disabled?: boolean;\r\n className?: string;\r\n id?: string;\r\n control?: Control<TFieldValues>;\r\n include?: string[];\r\n exclude?: string[];\r\n priorityCountries?: string[];\r\n /** Field is required (`true` or custom error message string) */\r\n required?: boolean | string;\r\n validate?: (value: unknown) => boolean | string | Promise<boolean | string>;\r\n}\r\n\r\nexport function CountrySelect<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\r\n>({\r\n name,\r\n label,\r\n helperText,\r\n showError = true,\r\n error: customError,\r\n size,\r\n variant,\r\n fullWidth = true,\r\n placeholder = \"Select a country\",\r\n allowClear,\r\n disabled,\r\n className,\r\n id: providedId,\r\n control: externalControl,\r\n include,\r\n exclude,\r\n priorityCountries,\r\n required,\r\n validate,\r\n}: CountrySelectProps<TFieldValues, TName>) {\r\n const generatedId = useId();\r\n const inputId = providedId ?? generatedId;\r\n const formConfigContext = useContext(FormConfigContext);\r\n const formConfig: FormConfig = formConfigContext ?? {};\r\n const rhfContext = useRHFFormContext<TFieldValues>();\r\n const control = externalControl ?? rhfContext?.control;\r\n\r\n const registerFieldValidation = formConfigContext?.registerFieldValidation;\r\n const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;\r\n\r\n useEffect(() => {\r\n if (registerFieldValidation) {\r\n const rules: FieldValidationRules = {};\r\n if (required !== undefined) rules.required = required;\r\n if (validate !== undefined) rules.validate = validate;\r\n\r\n registerFieldValidation({\r\n name: name as string,\r\n type: \"string\",\r\n rules,\r\n });\r\n\r\n return () => {\r\n unregisterFieldValidation?.(name as string);\r\n };\r\n }\r\n }, [\r\n registerFieldValidation,\r\n unregisterFieldValidation,\r\n name,\r\n required,\r\n validate,\r\n ]);\r\n\r\n const { field, fieldState } = useController<TFieldValues, TName>({\r\n name,\r\n control,\r\n });\r\n\r\n const fieldError = fieldState.error?.message;\r\n const errorMessage = customError ?? fieldError;\r\n const hasError = !!errorMessage;\r\n const effectiveSize = size ?? formConfig.size ?? \"md\";\r\n const effectiveDisabled = disabled ?? formConfig.disabled;\r\n const effectiveVariant = hasError ? \"error\" : variant;\r\n\r\n return (\r\n <FieldLayout\r\n inputId={inputId}\r\n label={label}\r\n required={!!required}\r\n helperText={helperText}\r\n errorMessage={showError ? errorMessage : undefined}\r\n showError={showError}\r\n fullWidth={fullWidth}\r\n formConfig={formConfig}\r\n >\r\n <div className=\"flex gap-2\">\r\n <CountryPicker\r\n id={inputId}\r\n value={field.value ?? \"\"}\r\n onValueChange={(value) => field.onChange(value)}\r\n placeholder={placeholder}\r\n disabled={effectiveDisabled}\r\n include={include}\r\n exclude={exclude}\r\n priorityCountries={priorityCountries}\r\n required={!!required}\r\n aria-invalid={hasError}\r\n aria-describedby={\r\n hasError\r\n ? `${inputId}-error`\r\n : helperText\r\n ? `${inputId}-helper`\r\n : undefined\r\n }\r\n className={cn(\r\n countrySelectVariants({ size: effectiveSize, variant: effectiveVariant }),\r\n className\r\n )}\r\n />\r\n {allowClear && field.value && (\r\n <button\r\n type=\"button\"\r\n className=\"text-sm text-muted-foreground hover:text-foreground\"\r\n onClick={() => field.onChange(\"\")}\r\n disabled={effectiveDisabled}\r\n >\r\n Clear\r\n </button>\r\n )}\r\n </div>\r\n </FieldLayout>\r\n );\r\n}\r\n\r\nCountrySelect.displayName = \"CountrySelect\";\r\n"],"mappings":";;;;;;;;;;;AAUA,IAAM,wBAAwB,IAAI,IAAI;CACpC,UAAU;EACR,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,SAAS;GACP,SAAS;GACT,OAAO;GACP,SAAS;EACX;CACF;CACA,iBAAiB;EACf,MAAM;EACN,SAAS;CACX;AACF,CAAC;AA0BD,SAAgB,cAGd,EACA,MACA,OACA,YACA,YAAY,MACZ,OAAO,aACP,MACA,SACA,YAAY,MACZ,cAAc,oBACd,YACA,UACA,WACA,IAAI,YACJ,SAAS,iBACT,SACA,SACA,mBACA,UACA,YAC0C;CAC1C,MAAM,cAAc,MAAM;CAC1B,MAAM,UAAU,cAAc;CAC9B,MAAM,oBAAoB,WAAW,iBAAiB;CACtD,MAAM,aAAyB,qBAAqB,CAAC;CACrD,MAAM,aAAa,eAAgC;CACnD,MAAM,UAAU,mBAAmB,YAAY;CAE/C,MAAM,0BAA0B,mBAAmB;CACnD,MAAM,4BAA4B,mBAAmB;CAErD,gBAAgB;EACd,IAAI,yBAAyB;GAC3B,MAAM,QAA8B,CAAC;GACrC,IAAI,aAAa,KAAA,GAAW,MAAM,WAAW;GAC7C,IAAI,aAAa,KAAA,GAAW,MAAM,WAAW;GAE7C,wBAAwB;IAChB;IACN,MAAM;IACN;GACF,CAAC;GAED,aAAa;IACX,4BAA4B,IAAc;GAC5C;EACF;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,EAAE,OAAO,eAAe,cAAmC;EAC/D;EACA;CACF,CAAC;CAED,MAAM,aAAa,WAAW,OAAO;CACrC,MAAM,eAAe,eAAe;CACpC,MAAM,WAAW,CAAC,CAAC;CACnB,MAAM,gBAAgB,QAAQ,WAAW,QAAQ;CACjD,MAAM,oBAAoB,YAAY,WAAW;CACjD,MAAM,mBAAmB,WAAW,UAAU;CAE9C,OACE,oBAAC,aAAD;EACW;EACF;EACP,UAAU,CAAC,CAAC;EACA;EACZ,cAAc,YAAY,eAAe,KAAA;EAC9B;EACA;EACC;EAEZ,UAAA,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,eAAD;IACE,IAAI;IACJ,OAAO,MAAM,SAAS;IACtB,gBAAgB,UAAU,MAAM,SAAS,KAAK;IACjC;IACb,UAAU;IACD;IACA;IACU;IACnB,UAAU,CAAC,CAAC;IACZ,gBAAc;IACd,oBACE,WACI,GAAG,QAAQ,UACX,aACE,GAAG,QAAQ,WACX,KAAA;IAER,WAAW,GACT,sBAAsB;KAAE,MAAM;KAAe,SAAS;IAAiB,CAAC,GACxE,SACF;GACD,CAAA,GACA,cAAc,MAAM,SACnB,oBAAC,UAAD;IACE,MAAK;IACL,WAAU;IACV,eAAe,MAAM,SAAS,EAAE;IAChC,UAAU;IACX,UAAA;GAEO,CAAA,CAEP;;CACM,CAAA;AAEjB;AAEA,cAAc,cAAc"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Control, FieldPath, FieldValues } from 'react-hook-form';
|
|
2
|
+
import { VariantProps } from 'class-variance-authority';
|
|
3
|
+
declare const datePickerVariants: (props?: ({
|
|
4
|
+
size?: "sm" | "lg" | "md" | null | undefined;
|
|
5
|
+
variant?: "default" | "error" | "success" | null | undefined;
|
|
6
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
7
|
+
export interface DatePickerProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> extends VariantProps<typeof datePickerVariants> {
|
|
8
|
+
name: TName;
|
|
9
|
+
label?: string;
|
|
10
|
+
helperText?: string;
|
|
11
|
+
showError?: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
fullWidth?: boolean;
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
className?: string;
|
|
17
|
+
id?: string;
|
|
18
|
+
control?: Control<TFieldValues>;
|
|
19
|
+
required?: boolean | string;
|
|
20
|
+
validate?: (value: unknown) => boolean | string | Promise<boolean | string>;
|
|
21
|
+
}
|
|
22
|
+
export declare function DatePicker<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ name, label, helperText, showError, error: customError, size, variant, fullWidth, placeholder, disabled, className, id: providedId, control: externalControl, required, validate, }: DatePickerProps<TFieldValues, TName>): import("react").JSX.Element;
|
|
23
|
+
export declare namespace DatePicker {
|
|
24
|
+
var displayName: string;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=DatePicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../src/components/Form/DatePicker.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAsD,KAAK,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACrI,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAQlE,QAAA,MAAM,kBAAkB;;;8EAiBtB,CAAC;AAEH,MAAM,WAAW,eAAe,CAC9B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,CAC/D,SAAQ,YAAY,CAAC,OAAO,kBAAkB,CAAC;IAC/C,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;CAC7E;AAED,wBAAgB,UAAU,CACxB,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,EAC/D,EACA,IAAI,EACJ,KAAK,EACL,UAAU,EACV,SAAgB,EAChB,KAAK,EAAE,WAAW,EAClB,IAAI,EACJ,OAAO,EACP,SAAgB,EAChB,WAA2B,EAC3B,QAAQ,EACR,SAAS,EACT,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,eAAe,EACxB,QAAQ,EACR,QAAQ,GACT,EAAE,eAAe,CAAC,YAAY,EAAE,KAAK,CAAC,+BAkGtC;yBArHe,UAAU"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
import { Button } from "../../primitives/button.js";
|
|
5
|
+
import { FormConfigContext } from "./context.js";
|
|
6
|
+
import { FieldLayout } from "./FieldLayout.js";
|
|
7
|
+
import { Popover, PopoverContent, PopoverTrigger } from "../../primitives/popover.js";
|
|
8
|
+
import { Calendar } from "../../primitives/calendar.js";
|
|
9
|
+
import { useContext, useEffect, useId, useState } from "react";
|
|
10
|
+
import { cva } from "class-variance-authority";
|
|
11
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
import { useController, useFormContext } from "react-hook-form";
|
|
13
|
+
import { CalendarIcon } from "lucide-react";
|
|
14
|
+
import { format } from "date-fns";
|
|
15
|
+
//#region src/components/Form/DatePicker.tsx
|
|
16
|
+
var datePickerVariants = cva("w-full justify-start text-left font-normal", {
|
|
17
|
+
variants: {
|
|
18
|
+
size: {
|
|
19
|
+
sm: "h-8 text-xs",
|
|
20
|
+
md: "h-10 text-sm",
|
|
21
|
+
lg: "h-12 text-base"
|
|
22
|
+
},
|
|
23
|
+
variant: {
|
|
24
|
+
default: "border-input",
|
|
25
|
+
error: "border-destructive",
|
|
26
|
+
success: "border-green-500"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
defaultVariants: {
|
|
30
|
+
size: "md",
|
|
31
|
+
variant: "default"
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
function DatePicker({ name, label, helperText, showError = true, error: customError, size, variant, fullWidth = true, placeholder = "Pick a date", disabled, className, id: providedId, control: externalControl, required, validate }) {
|
|
35
|
+
const generatedId = useId();
|
|
36
|
+
const inputId = providedId ?? generatedId;
|
|
37
|
+
const [open, setOpen] = useState(false);
|
|
38
|
+
const formConfigContext = useContext(FormConfigContext);
|
|
39
|
+
const formConfig = formConfigContext ?? {};
|
|
40
|
+
const rhfContext = useFormContext();
|
|
41
|
+
const control = externalControl ?? rhfContext?.control;
|
|
42
|
+
const registerFieldValidation = formConfigContext?.registerFieldValidation;
|
|
43
|
+
const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (registerFieldValidation) {
|
|
46
|
+
const rules = {};
|
|
47
|
+
if (required !== void 0) rules.required = required;
|
|
48
|
+
if (validate !== void 0) rules.validate = validate;
|
|
49
|
+
registerFieldValidation({
|
|
50
|
+
name,
|
|
51
|
+
type: "date",
|
|
52
|
+
rules
|
|
53
|
+
});
|
|
54
|
+
return () => {
|
|
55
|
+
unregisterFieldValidation?.(name);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}, [
|
|
59
|
+
registerFieldValidation,
|
|
60
|
+
unregisterFieldValidation,
|
|
61
|
+
name,
|
|
62
|
+
required,
|
|
63
|
+
validate
|
|
64
|
+
]);
|
|
65
|
+
const { field, fieldState } = useController({
|
|
66
|
+
name,
|
|
67
|
+
control
|
|
68
|
+
});
|
|
69
|
+
const selectedDate = field.value ? new Date(field.value) : void 0;
|
|
70
|
+
const fieldError = fieldState.error?.message;
|
|
71
|
+
const errorMessage = customError ?? fieldError;
|
|
72
|
+
const hasError = !!errorMessage;
|
|
73
|
+
const effectiveSize = size ?? formConfig.size ?? "md";
|
|
74
|
+
const effectiveDisabled = disabled ?? formConfig.disabled;
|
|
75
|
+
const effectiveVariant = hasError ? "error" : variant;
|
|
76
|
+
return /* @__PURE__ */ jsx(FieldLayout, {
|
|
77
|
+
inputId,
|
|
78
|
+
label,
|
|
79
|
+
required: !!required,
|
|
80
|
+
helperText,
|
|
81
|
+
errorMessage: showError ? errorMessage : void 0,
|
|
82
|
+
showError,
|
|
83
|
+
fullWidth,
|
|
84
|
+
formConfig,
|
|
85
|
+
children: /* @__PURE__ */ jsxs(Popover, {
|
|
86
|
+
open,
|
|
87
|
+
onOpenChange: setOpen,
|
|
88
|
+
children: [/* @__PURE__ */ jsx(PopoverTrigger, {
|
|
89
|
+
asChild: true,
|
|
90
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
91
|
+
id: inputId,
|
|
92
|
+
type: "button",
|
|
93
|
+
variant: "outline",
|
|
94
|
+
disabled: effectiveDisabled,
|
|
95
|
+
"aria-invalid": hasError,
|
|
96
|
+
"aria-describedby": hasError ? `${inputId}-error` : helperText ? `${inputId}-helper` : void 0,
|
|
97
|
+
className: cn(datePickerVariants({
|
|
98
|
+
size: effectiveSize,
|
|
99
|
+
variant: effectiveVariant
|
|
100
|
+
}), !selectedDate && "text-muted-foreground", className),
|
|
101
|
+
children: [/* @__PURE__ */ jsx(CalendarIcon, { className: "mr-2 h-4 w-4" }), selectedDate ? format(selectedDate, "PPP") : placeholder]
|
|
102
|
+
})
|
|
103
|
+
}), /* @__PURE__ */ jsx(PopoverContent, {
|
|
104
|
+
className: "w-auto p-0",
|
|
105
|
+
align: "start",
|
|
106
|
+
children: /* @__PURE__ */ jsx(Calendar, {
|
|
107
|
+
mode: "single",
|
|
108
|
+
selected: selectedDate,
|
|
109
|
+
onSelect: (date) => {
|
|
110
|
+
field.onChange(date ?? "");
|
|
111
|
+
setOpen(false);
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
})]
|
|
115
|
+
})
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
DatePicker.displayName = "DatePicker";
|
|
119
|
+
//#endregion
|
|
120
|
+
export { DatePicker };
|
|
121
|
+
|
|
122
|
+
//# sourceMappingURL=DatePicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.js","names":[],"sources":["../../../src/components/Form/DatePicker.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useContext, useEffect, useId, useState } from \"react\";\r\nimport { format } from \"date-fns\";\r\nimport { CalendarIcon } from \"lucide-react\";\r\nimport { useController, useFormContext as useRHFFormContext, type Control, type FieldPath, type FieldValues } from \"react-hook-form\";\r\nimport { cva, type VariantProps } from \"class-variance-authority\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { Calendar } from \"../../primitives/calendar\";\r\nimport { Popover, PopoverContent, PopoverTrigger } from \"../../primitives/popover\";\r\nimport { FormConfigContext, type FieldValidationRules, type FormConfig } from \"./context\";\r\nimport { FieldLayout } from \"./FieldLayout\";\r\n\r\nconst datePickerVariants = cva(\"w-full justify-start text-left font-normal\", {\r\n variants: {\r\n size: {\r\n sm: \"h-8 text-xs\",\r\n md: \"h-10 text-sm\",\r\n lg: \"h-12 text-base\",\r\n },\r\n variant: {\r\n default: \"border-input\",\r\n error: \"border-destructive\",\r\n success: \"border-green-500\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n variant: \"default\",\r\n },\r\n});\r\n\r\nexport interface DatePickerProps<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\r\n> extends VariantProps<typeof datePickerVariants> {\r\n name: TName;\r\n label?: string;\r\n helperText?: string;\r\n showError?: boolean;\r\n error?: string;\r\n fullWidth?: boolean;\r\n placeholder?: string;\r\n disabled?: boolean;\r\n className?: string;\r\n id?: string;\r\n control?: Control<TFieldValues>;\r\n required?: boolean | string;\r\n validate?: (value: unknown) => boolean | string | Promise<boolean | string>;\r\n}\r\n\r\nexport function DatePicker<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\r\n>({\r\n name,\r\n label,\r\n helperText,\r\n showError = true,\r\n error: customError,\r\n size,\r\n variant,\r\n fullWidth = true,\r\n placeholder = \"Pick a date\",\r\n disabled,\r\n className,\r\n id: providedId,\r\n control: externalControl,\r\n required,\r\n validate,\r\n}: DatePickerProps<TFieldValues, TName>) {\r\n const generatedId = useId();\r\n const inputId = providedId ?? generatedId;\r\n const [open, setOpen] = useState(false);\r\n const formConfigContext = useContext(FormConfigContext);\r\n const formConfig: FormConfig = formConfigContext ?? {};\r\n const rhfContext = useRHFFormContext<TFieldValues>();\r\n const control = externalControl ?? rhfContext?.control;\r\n\r\n const registerFieldValidation = formConfigContext?.registerFieldValidation;\r\n const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;\r\n\r\n useEffect(() => {\r\n if (registerFieldValidation) {\r\n const rules: FieldValidationRules = {};\r\n if (required !== undefined) rules.required = required;\r\n if (validate !== undefined) rules.validate = validate;\r\n\r\n registerFieldValidation({\r\n name: name as string,\r\n type: \"date\",\r\n rules,\r\n });\r\n\r\n return () => {\r\n unregisterFieldValidation?.(name as string);\r\n };\r\n }\r\n }, [\r\n registerFieldValidation,\r\n unregisterFieldValidation,\r\n name,\r\n required,\r\n validate,\r\n ]);\r\n\r\n const { field, fieldState } = useController<TFieldValues, TName>({\r\n name,\r\n control,\r\n });\r\n\r\n const selectedDate = field.value ? new Date(field.value) : undefined;\r\n const fieldError = fieldState.error?.message;\r\n const errorMessage = customError ?? fieldError;\r\n const hasError = !!errorMessage;\r\n const effectiveSize = size ?? formConfig.size ?? \"md\";\r\n const effectiveDisabled = disabled ?? formConfig.disabled;\r\n const effectiveVariant = hasError ? \"error\" : variant;\r\n\r\n return (\r\n <FieldLayout\r\n inputId={inputId}\r\n label={label}\r\n required={!!required}\r\n helperText={helperText}\r\n errorMessage={showError ? errorMessage : undefined}\r\n showError={showError}\r\n fullWidth={fullWidth}\r\n formConfig={formConfig}\r\n >\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger asChild>\r\n <Button\r\n id={inputId}\r\n type=\"button\"\r\n variant=\"outline\"\r\n disabled={effectiveDisabled}\r\n aria-invalid={hasError}\r\n aria-describedby={\r\n hasError\r\n ? `${inputId}-error`\r\n : helperText\r\n ? `${inputId}-helper`\r\n : undefined\r\n }\r\n className={cn(\r\n datePickerVariants({ size: effectiveSize, variant: effectiveVariant }),\r\n !selectedDate && \"text-muted-foreground\",\r\n className\r\n )}\r\n >\r\n <CalendarIcon className=\"mr-2 h-4 w-4\" />\r\n {selectedDate ? format(selectedDate, \"PPP\") : placeholder}\r\n </Button>\r\n </PopoverTrigger>\r\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\r\n <Calendar\r\n mode=\"single\"\r\n selected={selectedDate}\r\n onSelect={(date) => {\r\n field.onChange(date ?? \"\");\r\n setOpen(false);\r\n }}\r\n />\r\n </PopoverContent>\r\n </Popover>\r\n </FieldLayout>\r\n );\r\n}\r\n\r\nDatePicker.displayName = \"DatePicker\";\r\n"],"mappings":";;;;;;;;;;;;;;;AAcA,IAAM,qBAAqB,IAAI,8CAA8C;CAC3E,UAAU;EACR,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,SAAS;GACP,SAAS;GACT,OAAO;GACP,SAAS;EACX;CACF;CACA,iBAAiB;EACf,MAAM;EACN,SAAS;CACX;AACF,CAAC;AAqBD,SAAgB,WAGd,EACA,MACA,OACA,YACA,YAAY,MACZ,OAAO,aACP,MACA,SACA,YAAY,MACZ,cAAc,eACd,UACA,WACA,IAAI,YACJ,SAAS,iBACT,UACA,YACuC;CACvC,MAAM,cAAc,MAAM;CAC1B,MAAM,UAAU,cAAc;CAC9B,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,oBAAoB,WAAW,iBAAiB;CACtD,MAAM,aAAyB,qBAAqB,CAAC;CACrD,MAAM,aAAa,eAAgC;CACnD,MAAM,UAAU,mBAAmB,YAAY;CAE/C,MAAM,0BAA0B,mBAAmB;CACnD,MAAM,4BAA4B,mBAAmB;CAErD,gBAAgB;EACd,IAAI,yBAAyB;GAC3B,MAAM,QAA8B,CAAC;GACrC,IAAI,aAAa,KAAA,GAAW,MAAM,WAAW;GAC7C,IAAI,aAAa,KAAA,GAAW,MAAM,WAAW;GAE7C,wBAAwB;IAChB;IACN,MAAM;IACN;GACF,CAAC;GAED,aAAa;IACX,4BAA4B,IAAc;GAC5C;EACF;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,EAAE,OAAO,eAAe,cAAmC;EAC/D;EACA;CACF,CAAC;CAED,MAAM,eAAe,MAAM,QAAQ,IAAI,KAAK,MAAM,KAAK,IAAI,KAAA;CAC3D,MAAM,aAAa,WAAW,OAAO;CACrC,MAAM,eAAe,eAAe;CACpC,MAAM,WAAW,CAAC,CAAC;CACnB,MAAM,gBAAgB,QAAQ,WAAW,QAAQ;CACjD,MAAM,oBAAoB,YAAY,WAAW;CACjD,MAAM,mBAAmB,WAAW,UAAU;CAE9C,OACE,oBAAC,aAAD;EACW;EACF;EACP,UAAU,CAAC,CAAC;EACA;EACZ,cAAc,YAAY,eAAe,KAAA;EAC9B;EACA;EACC;EAEZ,UAAA,qBAAC,SAAD;GAAe;GAAM,cAAc;GAAnC,UAAA,CACE,oBAAC,gBAAD;IAAgB,SAAA;IACd,UAAA,qBAAC,QAAD;KACE,IAAI;KACJ,MAAK;KACL,SAAQ;KACR,UAAU;KACV,gBAAc;KACd,oBACE,WACI,GAAG,QAAQ,UACX,aACE,GAAG,QAAQ,WACX,KAAA;KAER,WAAW,GACT,mBAAmB;MAAE,MAAM;MAAe,SAAS;KAAiB,CAAC,GACrE,CAAC,gBAAgB,yBACjB,SACF;KAjBF,UAAA,CAmBE,oBAAC,cAAD,EAAc,WAAU,eAAgB,CAAA,GACvC,eAAe,OAAO,cAAc,KAAK,IAAI,WACxC;;GACM,CAAA,GAChB,oBAAC,gBAAD;IAAgB,WAAU;IAAa,OAAM;IAC3C,UAAA,oBAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,WAAW,SAAS;MAClB,MAAM,SAAS,QAAQ,EAAE;MACzB,QAAQ,KAAK;KACf;IACD,CAAA;GACa,CAAA,CACT;;CACE,CAAA;AAEjB;AAEA,WAAW,cAAc"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { FormConfig } from './context';
|
|
3
|
+
export interface FieldLayoutProps {
|
|
4
|
+
inputId: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
required?: boolean;
|
|
7
|
+
helperText?: string;
|
|
8
|
+
errorMessage?: string;
|
|
9
|
+
showError?: boolean;
|
|
10
|
+
fullWidth?: boolean;
|
|
11
|
+
formConfig?: FormConfig;
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
export declare function FieldLayout({ inputId, label, required, helperText, errorMessage, showError, fullWidth, formConfig, children, }: FieldLayoutProps): import("react").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=FieldLayout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldLayout.d.ts","sourceRoot":"","sources":["../../../src/components/Form/FieldLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAUD,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,KAAK,EACL,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,SAAgB,EAChB,SAAgB,EAChB,UAAe,EACf,QAAQ,GACT,EAAE,gBAAgB,+BA6ElB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
import { Label } from "../../primitives/label.js";
|
|
5
|
+
import { labelVariants } from "./variants.js";
|
|
6
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/components/Form/FieldLayout.tsx
|
|
8
|
+
function resolveLabelWidth(labelWidth) {
|
|
9
|
+
if (labelWidth === void 0) return;
|
|
10
|
+
return typeof labelWidth === "number" ? `${labelWidth}px` : labelWidth;
|
|
11
|
+
}
|
|
12
|
+
function FieldLayout({ inputId, label, required, helperText, errorMessage, showError = true, fullWidth = true, formConfig = {}, children }) {
|
|
13
|
+
const layout = formConfig.layout ?? "vertical";
|
|
14
|
+
const labelWidth = resolveLabelWidth(formConfig.labelWidth);
|
|
15
|
+
const hasError = !!errorMessage;
|
|
16
|
+
const showHelper = !!helperText && !hasError;
|
|
17
|
+
const labelNode = label ? /* @__PURE__ */ jsxs(Label, {
|
|
18
|
+
htmlFor: inputId,
|
|
19
|
+
className: cn(labelVariants({ required: !!required }), layout === "horizontal" && "mb-0 shrink-0 pt-2", layout === "inline" && "mb-0 shrink-0"),
|
|
20
|
+
style: layout === "horizontal" && labelWidth ? { width: labelWidth } : void 0,
|
|
21
|
+
children: [label, formConfig.colon && ":"]
|
|
22
|
+
}) : null;
|
|
23
|
+
const messages = /* @__PURE__ */ jsxs(Fragment, { children: [showError && hasError && /* @__PURE__ */ jsx("p", {
|
|
24
|
+
id: `${inputId}-error`,
|
|
25
|
+
className: "text-sm text-destructive",
|
|
26
|
+
role: "alert",
|
|
27
|
+
children: errorMessage
|
|
28
|
+
}), showHelper && /* @__PURE__ */ jsx("p", {
|
|
29
|
+
id: `${inputId}-helper`,
|
|
30
|
+
className: "text-sm text-muted-foreground",
|
|
31
|
+
children: helperText
|
|
32
|
+
})] });
|
|
33
|
+
if (layout === "horizontal") return /* @__PURE__ */ jsx("div", {
|
|
34
|
+
className: cn("space-y-1.5", fullWidth && "w-full"),
|
|
35
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
36
|
+
className: "flex items-start gap-4",
|
|
37
|
+
children: [labelNode, /* @__PURE__ */ jsxs("div", {
|
|
38
|
+
className: "min-w-0 flex-1 space-y-1.5",
|
|
39
|
+
children: [children, messages]
|
|
40
|
+
})]
|
|
41
|
+
})
|
|
42
|
+
});
|
|
43
|
+
if (layout === "inline") return /* @__PURE__ */ jsxs("div", {
|
|
44
|
+
className: cn("space-y-1.5", fullWidth && "w-full"),
|
|
45
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
46
|
+
className: "flex flex-wrap items-center gap-3",
|
|
47
|
+
children: [labelNode, /* @__PURE__ */ jsx("div", {
|
|
48
|
+
className: "min-w-0 flex-1",
|
|
49
|
+
children
|
|
50
|
+
})]
|
|
51
|
+
}), messages]
|
|
52
|
+
});
|
|
53
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
54
|
+
className: cn("space-y-1.5", fullWidth && "w-full"),
|
|
55
|
+
children: [
|
|
56
|
+
labelNode,
|
|
57
|
+
children,
|
|
58
|
+
messages
|
|
59
|
+
]
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { FieldLayout };
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=FieldLayout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldLayout.js","names":[],"sources":["../../../src/components/Form/FieldLayout.tsx"],"sourcesContent":["'use client';\r\n\r\nimport type { ReactNode } from \"react\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { Label } from \"../../primitives/label\";\r\nimport { labelVariants } from \"./variants\";\r\nimport type { FormConfig } from \"./context\";\r\n\r\nexport interface FieldLayoutProps {\r\n inputId: string;\r\n label?: string;\r\n required?: boolean;\r\n helperText?: string;\r\n errorMessage?: string;\r\n showError?: boolean;\r\n fullWidth?: boolean;\r\n formConfig?: FormConfig;\r\n children: ReactNode;\r\n}\r\n\r\nfunction resolveLabelWidth(labelWidth?: string | number): string | undefined {\r\n if (labelWidth === undefined) {\r\n return undefined;\r\n }\r\n\r\n return typeof labelWidth === \"number\" ? `${labelWidth}px` : labelWidth;\r\n}\r\n\r\nexport function FieldLayout({\r\n inputId,\r\n label,\r\n required,\r\n helperText,\r\n errorMessage,\r\n showError = true,\r\n fullWidth = true,\r\n formConfig = {},\r\n children,\r\n}: FieldLayoutProps) {\r\n const layout = formConfig.layout ?? \"vertical\";\r\n const labelWidth = resolveLabelWidth(formConfig.labelWidth);\r\n const hasError = !!errorMessage;\r\n const showHelper = !!helperText && !hasError;\r\n\r\n const labelNode = label ? (\r\n <Label\r\n htmlFor={inputId}\r\n className={cn(\r\n labelVariants({ required: !!required }),\r\n layout === \"horizontal\" && \"mb-0 shrink-0 pt-2\",\r\n layout === \"inline\" && \"mb-0 shrink-0\"\r\n )}\r\n style={layout === \"horizontal\" && labelWidth ? { width: labelWidth } : undefined}\r\n >\r\n {label}\r\n {formConfig.colon && \":\"}\r\n </Label>\r\n ) : null;\r\n\r\n const messages = (\r\n <>\r\n {showError && hasError && (\r\n <p\r\n id={`${inputId}-error`}\r\n className=\"text-sm text-destructive\"\r\n role=\"alert\"\r\n >\r\n {errorMessage}\r\n </p>\r\n )}\r\n\r\n {showHelper && (\r\n <p\r\n id={`${inputId}-helper`}\r\n className=\"text-sm text-muted-foreground\"\r\n >\r\n {helperText}\r\n </p>\r\n )}\r\n </>\r\n );\r\n\r\n if (layout === \"horizontal\") {\r\n return (\r\n <div className={cn(\"space-y-1.5\", fullWidth && \"w-full\")}>\r\n <div className=\"flex items-start gap-4\">\r\n {labelNode}\r\n <div className=\"min-w-0 flex-1 space-y-1.5\">\r\n {children}\r\n {messages}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (layout === \"inline\") {\r\n return (\r\n <div className={cn(\"space-y-1.5\", fullWidth && \"w-full\")}>\r\n <div className=\"flex flex-wrap items-center gap-3\">\r\n {labelNode}\r\n <div className=\"min-w-0 flex-1\">{children}</div>\r\n </div>\r\n {messages}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={cn(\"space-y-1.5\", fullWidth && \"w-full\")}>\r\n {labelNode}\r\n {children}\r\n {messages}\r\n </div>\r\n );\r\n}\r\n"],"mappings":";;;;;;;AAoBA,SAAS,kBAAkB,YAAkD;CAC3E,IAAI,eAAe,KAAA,GACjB;CAGF,OAAO,OAAO,eAAe,WAAW,GAAG,WAAW,MAAM;AAC9D;AAEA,SAAgB,YAAY,EAC1B,SACA,OACA,UACA,YACA,cACA,YAAY,MACZ,YAAY,MACZ,aAAa,CAAC,GACd,YACmB;CACnB,MAAM,SAAS,WAAW,UAAU;CACpC,MAAM,aAAa,kBAAkB,WAAW,UAAU;CAC1D,MAAM,WAAW,CAAC,CAAC;CACnB,MAAM,aAAa,CAAC,CAAC,cAAc,CAAC;CAEpC,MAAM,YAAY,QAChB,qBAAC,OAAD;EACE,SAAS;EACT,WAAW,GACT,cAAc,EAAE,UAAU,CAAC,CAAC,SAAS,CAAC,GACtC,WAAW,gBAAgB,sBAC3B,WAAW,YAAY,eACzB;EACA,OAAO,WAAW,gBAAgB,aAAa,EAAE,OAAO,WAAW,IAAI,KAAA;EAPzE,UAAA,CASG,OACA,WAAW,SAAS,GAChB;CACL,CAAA,IAAA;CAEJ,MAAM,WACJ,qBAAA,UAAA,EAAA,UAAA,CACG,aAAa,YACZ,oBAAC,KAAD;EACE,IAAI,GAAG,QAAQ;EACf,WAAU;EACV,MAAK;EAEJ,UAAA;CACA,CAAA,GAGJ,cACC,oBAAC,KAAD;EACE,IAAI,GAAG,QAAQ;EACf,WAAU;EAET,UAAA;CACA,CAAA,CAEL,EAAA,CAAA;CAGJ,IAAI,WAAW,cACb,OACE,oBAAC,OAAD;EAAK,WAAW,GAAG,eAAe,aAAa,QAAQ;EACrD,UAAA,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACG,WACD,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACG,UACA,QACE;GACF,CAAA,CAAA;;CACF,CAAA;CAIT,IAAI,WAAW,UACb,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,eAAe,aAAa,QAAQ;EAAvD,UAAA,CACE,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACG,WACD,oBAAC,OAAD;IAAK,WAAU;IAAkB;GAAc,CAAA,CAC5C;EACJ,CAAA,GAAA,QACE;;CAIT,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,eAAe,aAAa,QAAQ;EAAvD,UAAA;GACG;GACA;GACA;EACE;;AAET"}
|
|
@@ -55,7 +55,7 @@ export interface FormProps<TFieldValues extends FieldValues = FieldValues, TCont
|
|
|
55
55
|
* </Form>
|
|
56
56
|
* ```
|
|
57
57
|
*/
|
|
58
|
-
export declare function Form<TFieldValues extends FieldValues = FieldValues, TContext = unknown>({ schema: baseSchema, defaultValues, values, onSubmit, onError, config, children, form: externalForm, mode, reValidateMode, resolver: customResolver, ...formProps }: FormProps<TFieldValues, TContext>): import("react").JSX.Element;
|
|
58
|
+
export declare function Form<TFieldValues extends FieldValues = FieldValues, TContext = unknown>({ schema: baseSchema, defaultValues, values, onSubmit, onError, config, children, form: externalForm, mode: modeProp, reValidateMode: reValidateModeProp, resolver: customResolver, ...formProps }: FormProps<TFieldValues, TContext>): import("react").JSX.Element;
|
|
59
59
|
export declare namespace Form {
|
|
60
60
|
var displayName: string;
|
|
61
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Form.d.ts","sourceRoot":"","sources":["../../../src/components/Form/Form.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,QAAQ,EAEd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAIL,KAAK,UAAU,EAEhB,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,SAAS,CACxB,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,QAAQ,GAAG,OAAO,CAClB,SAAQ,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,eAAe,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/E,uEAAuE;IAEvE,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC3C,kCAAkC;IAClC,aAAa,CAAC,EAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAC;IACtE,kCAAkC;IAClC,MAAM,CAAC,EAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC;IACxD,qBAAqB;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACvC,oBAAoB;IACpB,OAAO,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAC3C,yBAAyB;IACzB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,eAAe;IACf,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,oDAAoD;IACpD,IAAI,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACnC,sBAAsB;IACtB,IAAI,CAAC,EAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;IACpD,wBAAwB;IACxB,cAAc,CAAC,EAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACxE,yCAAyC;IACzC,QAAQ,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,IAAI,CAClB,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,QAAQ,GAAG,OAAO,EAClB,EACA,MAAM,EAAE,UAAU,EAClB,aAAa,EACb,MAAM,EACN,QAAQ,EACR,OAAO,EACP,MAAM,EACN,QAAQ,EACR,IAAI,EAAE,YAAY,EAClB,
|
|
1
|
+
{"version":3,"file":"Form.d.ts","sourceRoot":"","sources":["../../../src/components/Form/Form.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,QAAQ,EAEd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAIL,KAAK,UAAU,EAEhB,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,SAAS,CACxB,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,QAAQ,GAAG,OAAO,CAClB,SAAQ,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,eAAe,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/E,uEAAuE;IAEvE,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC3C,kCAAkC;IAClC,aAAa,CAAC,EAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAC;IACtE,kCAAkC;IAClC,MAAM,CAAC,EAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC;IACxD,qBAAqB;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACvC,oBAAoB;IACpB,OAAO,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAC3C,yBAAyB;IACzB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,eAAe;IACf,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,oDAAoD;IACpD,IAAI,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACnC,sBAAsB;IACtB,IAAI,CAAC,EAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;IACpD,wBAAwB;IACxB,cAAc,CAAC,EAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACxE,yCAAyC;IACzC,QAAQ,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,IAAI,CAClB,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,QAAQ,GAAG,OAAO,EAClB,EACA,MAAM,EAAE,UAAU,EAClB,aAAa,EACb,MAAM,EACN,QAAQ,EACR,OAAO,EACP,MAAM,EACN,QAAQ,EACR,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,QAAQ,EACd,cAAc,EAAE,kBAAkB,EAClC,QAAQ,EAAE,cAAc,EACxB,GAAG,SAAS,EACb,EAAE,SAAS,CAAC,YAAY,EAAE,QAAQ,CAAC,+BA+GnC;yBA/He,IAAI"}
|
|
@@ -33,21 +33,24 @@ import { z } from "zod";
|
|
|
33
33
|
* </Form>
|
|
34
34
|
* ```
|
|
35
35
|
*/
|
|
36
|
-
function Form({ schema: baseSchema, defaultValues, values, onSubmit, onError, config, children, form: externalForm, mode
|
|
36
|
+
function Form({ schema: baseSchema, defaultValues, values, onSubmit, onError, config, children, form: externalForm, mode: modeProp, reValidateMode: reValidateModeProp, resolver: customResolver, ...formProps }) {
|
|
37
37
|
const mergedConfig = {
|
|
38
38
|
...defaultFormConfig,
|
|
39
39
|
...config
|
|
40
40
|
};
|
|
41
|
+
const mode = modeProp ?? (mergedConfig.validateOnChange ? "onChange" : mergedConfig.validateOnBlur !== false ? "onBlur" : "onSubmit");
|
|
42
|
+
const reValidateMode = reValidateModeProp ?? (mergedConfig.validateOnChange ? "onChange" : "onBlur");
|
|
41
43
|
const { registerFieldValidation, unregisterFieldValidation, getValidationSchema } = useFieldValidationRegistry();
|
|
44
|
+
const dynamicResolver = useCallback(async (vals, context, options) => {
|
|
45
|
+
if (customResolver) return customResolver(vals, context, options);
|
|
46
|
+
const fieldSchema = getValidationSchema();
|
|
47
|
+
let finalSchema;
|
|
48
|
+
if (baseSchema instanceof z.ZodObject) finalSchema = baseSchema.merge(fieldSchema);
|
|
49
|
+
else finalSchema = baseSchema ?? fieldSchema;
|
|
50
|
+
return zodResolver(finalSchema)(vals, context, options);
|
|
51
|
+
}, [baseSchema, customResolver]);
|
|
42
52
|
const internalForm = useForm({
|
|
43
|
-
resolver:
|
|
44
|
-
if (customResolver) return customResolver(vals, context, options);
|
|
45
|
-
const fieldSchema = getValidationSchema();
|
|
46
|
-
let finalSchema;
|
|
47
|
-
if (baseSchema instanceof z.ZodObject) finalSchema = baseSchema.merge(fieldSchema);
|
|
48
|
-
else finalSchema = baseSchema ?? fieldSchema;
|
|
49
|
-
return zodResolver(finalSchema)(vals, context, options);
|
|
50
|
-
}, [baseSchema, customResolver]),
|
|
53
|
+
resolver: dynamicResolver,
|
|
51
54
|
defaultValues,
|
|
52
55
|
values,
|
|
53
56
|
mode,
|