@algodomain/smart-forms 0.1.0
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 +313 -0
- package/dist/SmartFormProvider-B-BTl4wO.d.cts +94 -0
- package/dist/SmartFormProvider-B-BTl4wO.d.ts +94 -0
- package/dist/SmartTags-HmvmCJPT.d.cts +111 -0
- package/dist/SmartTags-HmvmCJPT.d.ts +111 -0
- package/dist/chunk-6WAEAWTD.js +949 -0
- package/dist/chunk-6WAEAWTD.js.map +1 -0
- package/dist/chunk-IG4XDQMV.js +604 -0
- package/dist/chunk-IG4XDQMV.js.map +1 -0
- package/dist/chunk-Y6NGPMDH.cjs +982 -0
- package/dist/chunk-Y6NGPMDH.cjs.map +1 -0
- package/dist/chunk-YV7RVYMD.cjs +639 -0
- package/dist/chunk-YV7RVYMD.cjs.map +1 -0
- package/dist/fields.cjs +1445 -0
- package/dist/fields.cjs.map +1 -0
- package/dist/fields.d.cts +119 -0
- package/dist/fields.d.ts +119 -0
- package/dist/fields.js +1384 -0
- package/dist/fields.js.map +1 -0
- package/dist/index.cjs +906 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +165 -0
- package/dist/index.d.ts +165 -0
- package/dist/index.js +821 -0
- package/dist/index.js.map +1 -0
- package/dist/opinionated.cjs +408 -0
- package/dist/opinionated.cjs.map +1 -0
- package/dist/opinionated.d.cts +274 -0
- package/dist/opinionated.d.ts +274 -0
- package/dist/opinionated.js +382 -0
- package/dist/opinionated.js.map +1 -0
- package/dist/style.css +114 -0
- package/package.json +90 -0
|
@@ -0,0 +1,949 @@
|
|
|
1
|
+
import { useFormField, useFieldDetection, Label, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, cn, Input } from './chunk-IG4XDQMV.js';
|
|
2
|
+
import * as React4 from 'react';
|
|
3
|
+
import { useRef, useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
5
|
+
import { InfoIcon, Calendar as Calendar$1, X, CheckIcon, CircleIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon } from 'lucide-react';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
8
|
+
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
9
|
+
import { format } from 'date-fns';
|
|
10
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
11
|
+
import { cva } from 'class-variance-authority';
|
|
12
|
+
import { getDefaultClassNames, DayPicker } from 'react-day-picker';
|
|
13
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
14
|
+
|
|
15
|
+
function Checkbox({
|
|
16
|
+
className,
|
|
17
|
+
...props
|
|
18
|
+
}) {
|
|
19
|
+
return /* @__PURE__ */ jsx(
|
|
20
|
+
CheckboxPrimitive.Root,
|
|
21
|
+
{
|
|
22
|
+
"data-slot": "checkbox",
|
|
23
|
+
className: cn(
|
|
24
|
+
"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
25
|
+
className
|
|
26
|
+
),
|
|
27
|
+
...props,
|
|
28
|
+
children: /* @__PURE__ */ jsx(
|
|
29
|
+
CheckboxPrimitive.Indicator,
|
|
30
|
+
{
|
|
31
|
+
"data-slot": "checkbox-indicator",
|
|
32
|
+
className: "flex items-center justify-center text-current transition-none",
|
|
33
|
+
children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5" })
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
var SmartCheckbox = ({
|
|
40
|
+
field,
|
|
41
|
+
label,
|
|
42
|
+
className = "",
|
|
43
|
+
validation,
|
|
44
|
+
required = false,
|
|
45
|
+
defaultValue,
|
|
46
|
+
info,
|
|
47
|
+
subLabel
|
|
48
|
+
}) => {
|
|
49
|
+
const { value, error, onChange, fieldRef, registerValidation } = useFormField(field);
|
|
50
|
+
const fieldDetection = useFieldDetection();
|
|
51
|
+
const hasRegistered = useRef(false);
|
|
52
|
+
const hasSetDefault = useRef(false);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (validation && !hasRegistered.current) {
|
|
55
|
+
hasRegistered.current = true;
|
|
56
|
+
registerValidation(field, validation);
|
|
57
|
+
}
|
|
58
|
+
}, [validation, field, registerValidation]);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (fieldDetection?.registerField) {
|
|
61
|
+
fieldDetection.registerField(field);
|
|
62
|
+
}
|
|
63
|
+
}, [field, fieldDetection]);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (defaultValue !== void 0 && !hasSetDefault.current && (value === void 0 || value === null || value === "")) {
|
|
66
|
+
onChange(defaultValue);
|
|
67
|
+
hasSetDefault.current = true;
|
|
68
|
+
}
|
|
69
|
+
}, [defaultValue, value, onChange]);
|
|
70
|
+
return /* @__PURE__ */ jsxs("div", { className: `flex-1 min-w-0 ${className}`, children: [
|
|
71
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
72
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
73
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
74
|
+
/* @__PURE__ */ jsx(
|
|
75
|
+
Checkbox,
|
|
76
|
+
{
|
|
77
|
+
ref: fieldRef,
|
|
78
|
+
checked: value || false,
|
|
79
|
+
onCheckedChange: (checked) => onChange(!!checked),
|
|
80
|
+
className: error ? "border-destructive" : "",
|
|
81
|
+
"data-field": field,
|
|
82
|
+
id: `${field}-checkbox`
|
|
83
|
+
}
|
|
84
|
+
),
|
|
85
|
+
/* @__PURE__ */ jsxs(Label, { htmlFor: `${field}-checkbox`, className: "text-sm font-normal cursor-pointer", children: [
|
|
86
|
+
label || field,
|
|
87
|
+
" ",
|
|
88
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: "*" })
|
|
89
|
+
] })
|
|
90
|
+
] }),
|
|
91
|
+
info && /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
92
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4 text-muted-foreground cursor-pointer mr-2" }) }),
|
|
93
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { className: "max-w-xs", children: info }) })
|
|
94
|
+
] }) })
|
|
95
|
+
] }),
|
|
96
|
+
subLabel && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground ml-6", children: subLabel })
|
|
97
|
+
] }),
|
|
98
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm mt-1", children: error })
|
|
99
|
+
] });
|
|
100
|
+
};
|
|
101
|
+
function RadioGroup({
|
|
102
|
+
className,
|
|
103
|
+
...props
|
|
104
|
+
}) {
|
|
105
|
+
return /* @__PURE__ */ jsx(
|
|
106
|
+
RadioGroupPrimitive.Root,
|
|
107
|
+
{
|
|
108
|
+
"data-slot": "radio-group",
|
|
109
|
+
className: cn("grid gap-3", className),
|
|
110
|
+
...props
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
function RadioGroupItem({
|
|
115
|
+
className,
|
|
116
|
+
...props
|
|
117
|
+
}) {
|
|
118
|
+
return /* @__PURE__ */ jsx(
|
|
119
|
+
RadioGroupPrimitive.Item,
|
|
120
|
+
{
|
|
121
|
+
"data-slot": "radio-group-item",
|
|
122
|
+
className: cn(
|
|
123
|
+
"border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
124
|
+
className
|
|
125
|
+
),
|
|
126
|
+
...props,
|
|
127
|
+
children: /* @__PURE__ */ jsx(
|
|
128
|
+
RadioGroupPrimitive.Indicator,
|
|
129
|
+
{
|
|
130
|
+
"data-slot": "radio-group-indicator",
|
|
131
|
+
className: "relative flex items-center justify-center",
|
|
132
|
+
children: /* @__PURE__ */ jsx(CircleIcon, { className: "fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2" })
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
var SmartRadioGroup = ({
|
|
139
|
+
field,
|
|
140
|
+
label,
|
|
141
|
+
options,
|
|
142
|
+
name,
|
|
143
|
+
alignment = "vertical",
|
|
144
|
+
className = "",
|
|
145
|
+
validation,
|
|
146
|
+
required = false,
|
|
147
|
+
defaultValue,
|
|
148
|
+
info,
|
|
149
|
+
subLabel
|
|
150
|
+
}) => {
|
|
151
|
+
const { value, error, onChange, fieldRef, registerValidation } = useFormField(field);
|
|
152
|
+
const fieldDetection = useFieldDetection();
|
|
153
|
+
const hasRegistered = useRef(false);
|
|
154
|
+
const hasSetDefault = useRef(false);
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
if (validation && !hasRegistered.current) {
|
|
157
|
+
hasRegistered.current = true;
|
|
158
|
+
registerValidation(field, validation);
|
|
159
|
+
}
|
|
160
|
+
}, [validation, field, registerValidation]);
|
|
161
|
+
useEffect(() => {
|
|
162
|
+
if (fieldDetection?.registerField) {
|
|
163
|
+
fieldDetection.registerField(field);
|
|
164
|
+
}
|
|
165
|
+
}, [field, fieldDetection]);
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
if (defaultValue !== void 0 && !hasSetDefault.current && (value === void 0 || value === null || value === "")) {
|
|
168
|
+
onChange(defaultValue);
|
|
169
|
+
hasSetDefault.current = true;
|
|
170
|
+
}
|
|
171
|
+
}, [defaultValue, value, onChange]);
|
|
172
|
+
return /* @__PURE__ */ jsxs("div", { className: `flex-1 min-w-0 ${className}`, children: [
|
|
173
|
+
label && /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
174
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
175
|
+
/* @__PURE__ */ jsxs(Label, { className: "text-sm font-medium text-foreground", children: [
|
|
176
|
+
label,
|
|
177
|
+
" ",
|
|
178
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: "*" })
|
|
179
|
+
] }),
|
|
180
|
+
info && /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
181
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4 text-muted-foreground cursor-pointer mr-2" }) }),
|
|
182
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { className: "max-w-xs", children: info }) })
|
|
183
|
+
] }) })
|
|
184
|
+
] }),
|
|
185
|
+
subLabel && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: subLabel })
|
|
186
|
+
] }),
|
|
187
|
+
/* @__PURE__ */ jsx(
|
|
188
|
+
RadioGroup,
|
|
189
|
+
{
|
|
190
|
+
value: value || "",
|
|
191
|
+
onValueChange: (newValue) => onChange(newValue),
|
|
192
|
+
className: alignment === "horizontal" ? "flex flex-wrap gap-4" : "grid gap-3",
|
|
193
|
+
ref: fieldRef,
|
|
194
|
+
"data-field": field,
|
|
195
|
+
name: name || field,
|
|
196
|
+
children: options.map((option) => /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
197
|
+
/* @__PURE__ */ jsx(
|
|
198
|
+
RadioGroupItem,
|
|
199
|
+
{
|
|
200
|
+
value: option.value,
|
|
201
|
+
id: `${field}-${option.value}`
|
|
202
|
+
}
|
|
203
|
+
),
|
|
204
|
+
/* @__PURE__ */ jsx(
|
|
205
|
+
Label,
|
|
206
|
+
{
|
|
207
|
+
htmlFor: `${field}-${option.value}`,
|
|
208
|
+
className: "text-sm font-normal cursor-pointer",
|
|
209
|
+
children: option.label
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
] }, option.value))
|
|
213
|
+
}
|
|
214
|
+
),
|
|
215
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm mt-1", children: error })
|
|
216
|
+
] });
|
|
217
|
+
};
|
|
218
|
+
function Select({
|
|
219
|
+
...props
|
|
220
|
+
}) {
|
|
221
|
+
return /* @__PURE__ */ jsx(SelectPrimitive.Root, { "data-slot": "select", ...props });
|
|
222
|
+
}
|
|
223
|
+
function SelectValue({
|
|
224
|
+
...props
|
|
225
|
+
}) {
|
|
226
|
+
return /* @__PURE__ */ jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
|
|
227
|
+
}
|
|
228
|
+
function SelectTrigger({
|
|
229
|
+
className,
|
|
230
|
+
size = "default",
|
|
231
|
+
children,
|
|
232
|
+
...props
|
|
233
|
+
}) {
|
|
234
|
+
return /* @__PURE__ */ jsxs(
|
|
235
|
+
SelectPrimitive.Trigger,
|
|
236
|
+
{
|
|
237
|
+
"data-slot": "select-trigger",
|
|
238
|
+
"data-size": size,
|
|
239
|
+
className: cn(
|
|
240
|
+
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
241
|
+
className
|
|
242
|
+
),
|
|
243
|
+
...props,
|
|
244
|
+
children: [
|
|
245
|
+
children,
|
|
246
|
+
/* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" }) })
|
|
247
|
+
]
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
function SelectContent({
|
|
252
|
+
className,
|
|
253
|
+
children,
|
|
254
|
+
position = "popper",
|
|
255
|
+
...props
|
|
256
|
+
}) {
|
|
257
|
+
return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
258
|
+
SelectPrimitive.Content,
|
|
259
|
+
{
|
|
260
|
+
"data-slot": "select-content",
|
|
261
|
+
className: cn(
|
|
262
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
|
|
263
|
+
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
264
|
+
className
|
|
265
|
+
),
|
|
266
|
+
position,
|
|
267
|
+
...props,
|
|
268
|
+
children: [
|
|
269
|
+
/* @__PURE__ */ jsx(SelectScrollUpButton, {}),
|
|
270
|
+
/* @__PURE__ */ jsx(
|
|
271
|
+
SelectPrimitive.Viewport,
|
|
272
|
+
{
|
|
273
|
+
className: cn(
|
|
274
|
+
"p-1",
|
|
275
|
+
position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
|
|
276
|
+
),
|
|
277
|
+
children
|
|
278
|
+
}
|
|
279
|
+
),
|
|
280
|
+
/* @__PURE__ */ jsx(SelectScrollDownButton, {})
|
|
281
|
+
]
|
|
282
|
+
}
|
|
283
|
+
) });
|
|
284
|
+
}
|
|
285
|
+
function SelectItem({
|
|
286
|
+
className,
|
|
287
|
+
children,
|
|
288
|
+
...props
|
|
289
|
+
}) {
|
|
290
|
+
return /* @__PURE__ */ jsxs(
|
|
291
|
+
SelectPrimitive.Item,
|
|
292
|
+
{
|
|
293
|
+
"data-slot": "select-item",
|
|
294
|
+
className: cn(
|
|
295
|
+
"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
296
|
+
className
|
|
297
|
+
),
|
|
298
|
+
...props,
|
|
299
|
+
children: [
|
|
300
|
+
/* @__PURE__ */ jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
|
|
301
|
+
/* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
function SelectScrollUpButton({
|
|
307
|
+
className,
|
|
308
|
+
...props
|
|
309
|
+
}) {
|
|
310
|
+
return /* @__PURE__ */ jsx(
|
|
311
|
+
SelectPrimitive.ScrollUpButton,
|
|
312
|
+
{
|
|
313
|
+
"data-slot": "select-scroll-up-button",
|
|
314
|
+
className: cn(
|
|
315
|
+
"flex cursor-default items-center justify-center py-1",
|
|
316
|
+
className
|
|
317
|
+
),
|
|
318
|
+
...props,
|
|
319
|
+
children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "size-4" })
|
|
320
|
+
}
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
function SelectScrollDownButton({
|
|
324
|
+
className,
|
|
325
|
+
...props
|
|
326
|
+
}) {
|
|
327
|
+
return /* @__PURE__ */ jsx(
|
|
328
|
+
SelectPrimitive.ScrollDownButton,
|
|
329
|
+
{
|
|
330
|
+
"data-slot": "select-scroll-down-button",
|
|
331
|
+
className: cn(
|
|
332
|
+
"flex cursor-default items-center justify-center py-1",
|
|
333
|
+
className
|
|
334
|
+
),
|
|
335
|
+
...props,
|
|
336
|
+
children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" })
|
|
337
|
+
}
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
var SmartSelect = ({
|
|
341
|
+
field,
|
|
342
|
+
label,
|
|
343
|
+
options,
|
|
344
|
+
className = "",
|
|
345
|
+
placeholder,
|
|
346
|
+
validation,
|
|
347
|
+
required = false,
|
|
348
|
+
defaultValue,
|
|
349
|
+
info,
|
|
350
|
+
subLabel
|
|
351
|
+
}) => {
|
|
352
|
+
const { value, error, onChange, fieldRef, registerValidation } = useFormField(field);
|
|
353
|
+
const fieldDetection = useFieldDetection();
|
|
354
|
+
const hasRegistered = useRef(false);
|
|
355
|
+
const hasSetDefault = useRef(false);
|
|
356
|
+
useEffect(() => {
|
|
357
|
+
if (validation && !hasRegistered.current) {
|
|
358
|
+
hasRegistered.current = true;
|
|
359
|
+
registerValidation(field, validation);
|
|
360
|
+
}
|
|
361
|
+
}, [validation, field, registerValidation]);
|
|
362
|
+
useEffect(() => {
|
|
363
|
+
if (fieldDetection?.registerField) {
|
|
364
|
+
fieldDetection.registerField(field);
|
|
365
|
+
}
|
|
366
|
+
}, [field, fieldDetection]);
|
|
367
|
+
useEffect(() => {
|
|
368
|
+
if (defaultValue !== void 0 && !hasSetDefault.current && (value === void 0 || value === null || value === "")) {
|
|
369
|
+
onChange(defaultValue);
|
|
370
|
+
hasSetDefault.current = true;
|
|
371
|
+
}
|
|
372
|
+
}, [defaultValue, value, onChange]);
|
|
373
|
+
return /* @__PURE__ */ jsxs("div", { className: `flex-1 min-w-0 ${className}`, children: [
|
|
374
|
+
label && /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
375
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
376
|
+
/* @__PURE__ */ jsxs(Label, { className: "text-sm font-medium text-foreground", children: [
|
|
377
|
+
label,
|
|
378
|
+
" ",
|
|
379
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: "*" })
|
|
380
|
+
] }),
|
|
381
|
+
info && /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
382
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4 text-muted-foreground cursor-pointer mr-2" }) }),
|
|
383
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { className: "max-w-xs", children: info }) })
|
|
384
|
+
] }) })
|
|
385
|
+
] }),
|
|
386
|
+
subLabel && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: subLabel })
|
|
387
|
+
] }),
|
|
388
|
+
/* @__PURE__ */ jsxs(
|
|
389
|
+
Select,
|
|
390
|
+
{
|
|
391
|
+
value: value || "",
|
|
392
|
+
onValueChange: (newValue) => onChange(newValue),
|
|
393
|
+
children: [
|
|
394
|
+
/* @__PURE__ */ jsx(
|
|
395
|
+
SelectTrigger,
|
|
396
|
+
{
|
|
397
|
+
ref: fieldRef,
|
|
398
|
+
className: `w-full ${error ? "border-destructive" : ""} ${className}`,
|
|
399
|
+
"data-field": field,
|
|
400
|
+
children: /* @__PURE__ */ jsx(SelectValue, { placeholder: placeholder || `Select ${label || field}` })
|
|
401
|
+
}
|
|
402
|
+
),
|
|
403
|
+
/* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
|
|
404
|
+
]
|
|
405
|
+
}
|
|
406
|
+
),
|
|
407
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm mt-1", children: error })
|
|
408
|
+
] });
|
|
409
|
+
};
|
|
410
|
+
var buttonVariants = cva(
|
|
411
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
412
|
+
{
|
|
413
|
+
variants: {
|
|
414
|
+
variant: {
|
|
415
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
416
|
+
destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
417
|
+
outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
|
418
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
419
|
+
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
|
420
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
421
|
+
},
|
|
422
|
+
size: {
|
|
423
|
+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
424
|
+
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
425
|
+
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
|
426
|
+
icon: "size-9"
|
|
427
|
+
}
|
|
428
|
+
},
|
|
429
|
+
defaultVariants: {
|
|
430
|
+
variant: "default",
|
|
431
|
+
size: "default"
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
);
|
|
435
|
+
function Button({
|
|
436
|
+
className,
|
|
437
|
+
variant,
|
|
438
|
+
size,
|
|
439
|
+
asChild = false,
|
|
440
|
+
...props
|
|
441
|
+
}) {
|
|
442
|
+
const Comp = asChild ? Slot : "button";
|
|
443
|
+
return /* @__PURE__ */ jsx(
|
|
444
|
+
Comp,
|
|
445
|
+
{
|
|
446
|
+
"data-slot": "button",
|
|
447
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
448
|
+
...props
|
|
449
|
+
}
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
function Calendar({
|
|
453
|
+
className,
|
|
454
|
+
classNames,
|
|
455
|
+
showOutsideDays = true,
|
|
456
|
+
captionLayout = "label",
|
|
457
|
+
buttonVariant = "ghost",
|
|
458
|
+
formatters,
|
|
459
|
+
components,
|
|
460
|
+
...props
|
|
461
|
+
}) {
|
|
462
|
+
const defaultClassNames = getDefaultClassNames();
|
|
463
|
+
return /* @__PURE__ */ jsx(
|
|
464
|
+
DayPicker,
|
|
465
|
+
{
|
|
466
|
+
showOutsideDays,
|
|
467
|
+
className: cn(
|
|
468
|
+
"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
|
469
|
+
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
470
|
+
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
|
471
|
+
className
|
|
472
|
+
),
|
|
473
|
+
captionLayout,
|
|
474
|
+
formatters: {
|
|
475
|
+
formatMonthDropdown: (date) => date.toLocaleString("default", { month: "short" }),
|
|
476
|
+
...formatters
|
|
477
|
+
},
|
|
478
|
+
classNames: {
|
|
479
|
+
root: cn("w-fit", defaultClassNames.root),
|
|
480
|
+
months: cn(
|
|
481
|
+
"flex gap-4 flex-col md:flex-row relative",
|
|
482
|
+
defaultClassNames.months
|
|
483
|
+
),
|
|
484
|
+
month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
|
|
485
|
+
nav: cn(
|
|
486
|
+
"flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
|
|
487
|
+
defaultClassNames.nav
|
|
488
|
+
),
|
|
489
|
+
button_previous: cn(
|
|
490
|
+
buttonVariants({ variant: buttonVariant }),
|
|
491
|
+
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
|
|
492
|
+
defaultClassNames.button_previous
|
|
493
|
+
),
|
|
494
|
+
button_next: cn(
|
|
495
|
+
buttonVariants({ variant: buttonVariant }),
|
|
496
|
+
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
|
|
497
|
+
defaultClassNames.button_next
|
|
498
|
+
),
|
|
499
|
+
month_caption: cn(
|
|
500
|
+
"flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)",
|
|
501
|
+
defaultClassNames.month_caption
|
|
502
|
+
),
|
|
503
|
+
dropdowns: cn(
|
|
504
|
+
"w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5",
|
|
505
|
+
defaultClassNames.dropdowns
|
|
506
|
+
),
|
|
507
|
+
dropdown_root: cn(
|
|
508
|
+
"relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
|
|
509
|
+
defaultClassNames.dropdown_root
|
|
510
|
+
),
|
|
511
|
+
dropdown: cn(
|
|
512
|
+
"absolute bg-popover inset-0 opacity-0",
|
|
513
|
+
defaultClassNames.dropdown
|
|
514
|
+
),
|
|
515
|
+
caption_label: cn(
|
|
516
|
+
"select-none font-medium",
|
|
517
|
+
captionLayout === "label" ? "text-sm" : "rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5",
|
|
518
|
+
defaultClassNames.caption_label
|
|
519
|
+
),
|
|
520
|
+
table: "w-full border-collapse",
|
|
521
|
+
weekdays: cn("flex", defaultClassNames.weekdays),
|
|
522
|
+
weekday: cn(
|
|
523
|
+
"text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none",
|
|
524
|
+
defaultClassNames.weekday
|
|
525
|
+
),
|
|
526
|
+
week: cn("flex w-full mt-2", defaultClassNames.week),
|
|
527
|
+
week_number_header: cn(
|
|
528
|
+
"select-none w-(--cell-size)",
|
|
529
|
+
defaultClassNames.week_number_header
|
|
530
|
+
),
|
|
531
|
+
week_number: cn(
|
|
532
|
+
"text-[0.8rem] select-none text-muted-foreground",
|
|
533
|
+
defaultClassNames.week_number
|
|
534
|
+
),
|
|
535
|
+
day: cn(
|
|
536
|
+
"relative w-full h-full p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none",
|
|
537
|
+
defaultClassNames.day
|
|
538
|
+
),
|
|
539
|
+
range_start: cn(
|
|
540
|
+
"rounded-l-md bg-accent",
|
|
541
|
+
defaultClassNames.range_start
|
|
542
|
+
),
|
|
543
|
+
range_middle: cn("rounded-none", defaultClassNames.range_middle),
|
|
544
|
+
range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
|
|
545
|
+
today: cn(
|
|
546
|
+
"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
|
|
547
|
+
defaultClassNames.today
|
|
548
|
+
),
|
|
549
|
+
outside: cn(
|
|
550
|
+
"text-muted-foreground aria-selected:text-muted-foreground",
|
|
551
|
+
defaultClassNames.outside
|
|
552
|
+
),
|
|
553
|
+
disabled: cn(
|
|
554
|
+
"text-muted-foreground opacity-50",
|
|
555
|
+
defaultClassNames.disabled
|
|
556
|
+
),
|
|
557
|
+
hidden: cn("invisible", defaultClassNames.hidden),
|
|
558
|
+
...classNames
|
|
559
|
+
},
|
|
560
|
+
components: {
|
|
561
|
+
Root: ({ className: className2, rootRef, ...props2 }) => {
|
|
562
|
+
return /* @__PURE__ */ jsx(
|
|
563
|
+
"div",
|
|
564
|
+
{
|
|
565
|
+
"data-slot": "calendar",
|
|
566
|
+
ref: rootRef,
|
|
567
|
+
className: cn(className2),
|
|
568
|
+
...props2
|
|
569
|
+
}
|
|
570
|
+
);
|
|
571
|
+
},
|
|
572
|
+
Chevron: ({ className: className2, orientation, ...props2 }) => {
|
|
573
|
+
if (orientation === "left") {
|
|
574
|
+
return /* @__PURE__ */ jsx(ChevronLeftIcon, { className: cn("size-4", className2), ...props2 });
|
|
575
|
+
}
|
|
576
|
+
if (orientation === "right") {
|
|
577
|
+
return /* @__PURE__ */ jsx(
|
|
578
|
+
ChevronRightIcon,
|
|
579
|
+
{
|
|
580
|
+
className: cn("size-4", className2),
|
|
581
|
+
...props2
|
|
582
|
+
}
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
return /* @__PURE__ */ jsx(ChevronDownIcon, { className: cn("size-4", className2), ...props2 });
|
|
586
|
+
},
|
|
587
|
+
DayButton: CalendarDayButton,
|
|
588
|
+
WeekNumber: ({ children, ...props2 }) => {
|
|
589
|
+
return /* @__PURE__ */ jsx("td", { ...props2, children: /* @__PURE__ */ jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children }) });
|
|
590
|
+
},
|
|
591
|
+
...components
|
|
592
|
+
},
|
|
593
|
+
...props
|
|
594
|
+
}
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
function CalendarDayButton({
|
|
598
|
+
className,
|
|
599
|
+
day,
|
|
600
|
+
modifiers,
|
|
601
|
+
...props
|
|
602
|
+
}) {
|
|
603
|
+
const defaultClassNames = getDefaultClassNames();
|
|
604
|
+
const ref = React4.useRef(null);
|
|
605
|
+
React4.useEffect(() => {
|
|
606
|
+
if (modifiers.focused) ref.current?.focus();
|
|
607
|
+
}, [modifiers.focused]);
|
|
608
|
+
return /* @__PURE__ */ jsx(
|
|
609
|
+
Button,
|
|
610
|
+
{
|
|
611
|
+
ref,
|
|
612
|
+
variant: "ghost",
|
|
613
|
+
size: "icon",
|
|
614
|
+
"data-day": day.date.toLocaleDateString(),
|
|
615
|
+
"data-selected-single": modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle,
|
|
616
|
+
"data-range-start": modifiers.range_start,
|
|
617
|
+
"data-range-end": modifiers.range_end,
|
|
618
|
+
"data-range-middle": modifiers.range_middle,
|
|
619
|
+
className: cn(
|
|
620
|
+
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70",
|
|
621
|
+
defaultClassNames.day,
|
|
622
|
+
className
|
|
623
|
+
),
|
|
624
|
+
...props
|
|
625
|
+
}
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
function Popover({
|
|
629
|
+
...props
|
|
630
|
+
}) {
|
|
631
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
|
|
632
|
+
}
|
|
633
|
+
function PopoverTrigger({
|
|
634
|
+
...props
|
|
635
|
+
}) {
|
|
636
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
637
|
+
}
|
|
638
|
+
function PopoverContent({
|
|
639
|
+
className,
|
|
640
|
+
align = "center",
|
|
641
|
+
sideOffset = 4,
|
|
642
|
+
...props
|
|
643
|
+
}) {
|
|
644
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
645
|
+
PopoverPrimitive.Content,
|
|
646
|
+
{
|
|
647
|
+
"data-slot": "popover-content",
|
|
648
|
+
align,
|
|
649
|
+
sideOffset,
|
|
650
|
+
className: cn(
|
|
651
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
|
|
652
|
+
className
|
|
653
|
+
),
|
|
654
|
+
...props
|
|
655
|
+
}
|
|
656
|
+
) });
|
|
657
|
+
}
|
|
658
|
+
var SmartDatePicker = ({
|
|
659
|
+
field,
|
|
660
|
+
label,
|
|
661
|
+
className = "",
|
|
662
|
+
placeholder,
|
|
663
|
+
validation,
|
|
664
|
+
required = false,
|
|
665
|
+
allowPast = true,
|
|
666
|
+
allowFuture = true,
|
|
667
|
+
valueAsString = true,
|
|
668
|
+
minDate,
|
|
669
|
+
maxDate,
|
|
670
|
+
defaultValue,
|
|
671
|
+
info,
|
|
672
|
+
subLabel
|
|
673
|
+
}) => {
|
|
674
|
+
const { value, error, onChange, fieldRef, registerValidation } = useFormField(field);
|
|
675
|
+
const fieldDetection = useFieldDetection();
|
|
676
|
+
const hasRegistered = useRef(false);
|
|
677
|
+
const hasSetDefault = useRef(false);
|
|
678
|
+
const parsedValue = useMemo(() => {
|
|
679
|
+
if (!value) return void 0;
|
|
680
|
+
if (value instanceof Date) return value;
|
|
681
|
+
const d = new Date(value);
|
|
682
|
+
return isNaN(d.getTime()) ? void 0 : d;
|
|
683
|
+
}, [value]);
|
|
684
|
+
const [open, setOpen] = useState(false);
|
|
685
|
+
useEffect(() => {
|
|
686
|
+
if (validation && !hasRegistered.current) {
|
|
687
|
+
hasRegistered.current = true;
|
|
688
|
+
registerValidation(field, validation);
|
|
689
|
+
}
|
|
690
|
+
}, [validation, field, registerValidation]);
|
|
691
|
+
useEffect(() => {
|
|
692
|
+
if (fieldDetection?.registerField) {
|
|
693
|
+
fieldDetection.registerField(field);
|
|
694
|
+
}
|
|
695
|
+
}, [field, fieldDetection]);
|
|
696
|
+
useEffect(() => {
|
|
697
|
+
if (defaultValue !== void 0 && !hasSetDefault.current && (value === void 0 || value === null || value === "")) {
|
|
698
|
+
onChange(defaultValue);
|
|
699
|
+
hasSetDefault.current = true;
|
|
700
|
+
}
|
|
701
|
+
}, [defaultValue, value, onChange]);
|
|
702
|
+
const today = useMemo(() => /* @__PURE__ */ new Date(), []);
|
|
703
|
+
const disabledMatcher = (date) => {
|
|
704
|
+
if (!allowPast) {
|
|
705
|
+
const startOfToday = new Date(today.getFullYear(), today.getMonth(), today.getDate());
|
|
706
|
+
if (date < startOfToday) return true;
|
|
707
|
+
}
|
|
708
|
+
if (!allowFuture) {
|
|
709
|
+
const startOfTomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
|
|
710
|
+
if (date >= startOfTomorrow) return true;
|
|
711
|
+
}
|
|
712
|
+
if (minDate && date < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())) return true;
|
|
713
|
+
if (maxDate && date > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())) return true;
|
|
714
|
+
return false;
|
|
715
|
+
};
|
|
716
|
+
const handleSelect = (selected) => {
|
|
717
|
+
if (!selected) {
|
|
718
|
+
onChange(void 0);
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
if (valueAsString) {
|
|
722
|
+
const iso = format(selected, "yyyy-MM-dd");
|
|
723
|
+
onChange(iso);
|
|
724
|
+
} else {
|
|
725
|
+
onChange(selected);
|
|
726
|
+
}
|
|
727
|
+
setOpen(false);
|
|
728
|
+
};
|
|
729
|
+
const buttonText = useMemo(() => {
|
|
730
|
+
if (!parsedValue) return placeholder || `Select ${label || field}`;
|
|
731
|
+
return format(parsedValue, "dd/MM/yyyy");
|
|
732
|
+
}, [parsedValue, placeholder, label, field]);
|
|
733
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex-1 min-w-0", className), children: [
|
|
734
|
+
label && /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
735
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
736
|
+
/* @__PURE__ */ jsxs(Label, { className: "text-sm font-medium text-foreground", children: [
|
|
737
|
+
label,
|
|
738
|
+
" ",
|
|
739
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: "*" })
|
|
740
|
+
] }),
|
|
741
|
+
info && /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
742
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4 text-muted-foreground cursor-pointer mr-2" }) }),
|
|
743
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { className: "max-w-xs", children: info }) })
|
|
744
|
+
] }) })
|
|
745
|
+
] }),
|
|
746
|
+
subLabel && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: subLabel })
|
|
747
|
+
] }),
|
|
748
|
+
/* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
749
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
750
|
+
Button,
|
|
751
|
+
{
|
|
752
|
+
ref: fieldRef,
|
|
753
|
+
variant: "outline",
|
|
754
|
+
className: cn(
|
|
755
|
+
"w-full justify-start text-left font-normal",
|
|
756
|
+
!parsedValue && "text-muted-foreground",
|
|
757
|
+
error && "border-destructive"
|
|
758
|
+
),
|
|
759
|
+
"data-field": field,
|
|
760
|
+
children: [
|
|
761
|
+
/* @__PURE__ */ jsx(Calendar$1, { className: "mr-2 h-4 w-4" }),
|
|
762
|
+
buttonText
|
|
763
|
+
]
|
|
764
|
+
}
|
|
765
|
+
) }),
|
|
766
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx(
|
|
767
|
+
Calendar,
|
|
768
|
+
{
|
|
769
|
+
mode: "single",
|
|
770
|
+
selected: parsedValue,
|
|
771
|
+
onSelect: handleSelect,
|
|
772
|
+
disabled: disabledMatcher,
|
|
773
|
+
initialFocus: true
|
|
774
|
+
}
|
|
775
|
+
) })
|
|
776
|
+
] }),
|
|
777
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm mt-1", children: error })
|
|
778
|
+
] });
|
|
779
|
+
};
|
|
780
|
+
var SmartTags = ({
|
|
781
|
+
field,
|
|
782
|
+
label,
|
|
783
|
+
className = "",
|
|
784
|
+
placeholder = "Type and press Enter...",
|
|
785
|
+
validation,
|
|
786
|
+
required = false,
|
|
787
|
+
maxTags,
|
|
788
|
+
defaultValue,
|
|
789
|
+
maxLength,
|
|
790
|
+
minLength,
|
|
791
|
+
allowDuplicates = false,
|
|
792
|
+
disabled = false,
|
|
793
|
+
onTagAdd,
|
|
794
|
+
onTagRemove,
|
|
795
|
+
info,
|
|
796
|
+
subLabel
|
|
797
|
+
}) => {
|
|
798
|
+
const { value, error, onChange, fieldRef, registerValidation } = useFormField(field);
|
|
799
|
+
const fieldDetection = useFieldDetection();
|
|
800
|
+
const hasRegistered = useRef(false);
|
|
801
|
+
const hasSetDefault = useRef(false);
|
|
802
|
+
const [tags, setTags] = useState([]);
|
|
803
|
+
const [inputValue, setInputValue] = useState("");
|
|
804
|
+
const inputRef = useRef(null);
|
|
805
|
+
useEffect(() => {
|
|
806
|
+
if (validation && !hasRegistered.current) {
|
|
807
|
+
hasRegistered.current = true;
|
|
808
|
+
registerValidation(field, validation);
|
|
809
|
+
}
|
|
810
|
+
}, [validation, field, registerValidation]);
|
|
811
|
+
useEffect(() => {
|
|
812
|
+
if (fieldDetection?.registerField) {
|
|
813
|
+
fieldDetection.registerField(field);
|
|
814
|
+
}
|
|
815
|
+
}, [field, fieldDetection]);
|
|
816
|
+
useEffect(() => {
|
|
817
|
+
if (defaultValue !== void 0 && !hasSetDefault.current && (!value || Array.isArray(value) && value.length === 0)) {
|
|
818
|
+
setTags(defaultValue);
|
|
819
|
+
onChange(defaultValue);
|
|
820
|
+
hasSetDefault.current = true;
|
|
821
|
+
}
|
|
822
|
+
}, [defaultValue, value, onChange]);
|
|
823
|
+
useEffect(() => {
|
|
824
|
+
if (Array.isArray(value)) {
|
|
825
|
+
setTags(value);
|
|
826
|
+
}
|
|
827
|
+
}, [value]);
|
|
828
|
+
const addTag = (text) => {
|
|
829
|
+
const trimmedText = text.trim();
|
|
830
|
+
if (!trimmedText) return;
|
|
831
|
+
if (minLength && trimmedText.length < minLength) return;
|
|
832
|
+
if (maxLength && trimmedText.length > maxLength) return;
|
|
833
|
+
if (maxTags && tags.length >= maxTags) return;
|
|
834
|
+
if (!allowDuplicates && tags.some((tag) => tag.toLowerCase() === trimmedText.toLowerCase())) {
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
const newTags = [...tags, trimmedText];
|
|
838
|
+
setTags(newTags);
|
|
839
|
+
onChange(newTags);
|
|
840
|
+
if (onTagAdd) {
|
|
841
|
+
onTagAdd(trimmedText);
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
const removeTag = (tagText) => {
|
|
845
|
+
const newTags = tags.filter((tag) => tag !== tagText);
|
|
846
|
+
setTags(newTags);
|
|
847
|
+
onChange(newTags);
|
|
848
|
+
if (onTagRemove) {
|
|
849
|
+
onTagRemove(tagText);
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
const handleKeyDown = (e) => {
|
|
853
|
+
if (e.key === "Enter" || e.key === ",") {
|
|
854
|
+
e.preventDefault();
|
|
855
|
+
addTag(inputValue);
|
|
856
|
+
setInputValue("");
|
|
857
|
+
} else if (e.key === "Backspace" && !inputValue && tags.length > 0) {
|
|
858
|
+
removeTag(tags[tags.length - 1]);
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
const handleInputChange = (e) => {
|
|
862
|
+
const value2 = e.target.value;
|
|
863
|
+
setInputValue(value2);
|
|
864
|
+
};
|
|
865
|
+
return /* @__PURE__ */ jsxs("div", { className: `flex-1 min-w-0 ${className}`, children: [
|
|
866
|
+
label && /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
867
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
868
|
+
/* @__PURE__ */ jsxs(Label, { className: "text-sm font-medium text-foreground", children: [
|
|
869
|
+
label,
|
|
870
|
+
" ",
|
|
871
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: "*" }),
|
|
872
|
+
maxTags && /* @__PURE__ */ jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: [
|
|
873
|
+
"(",
|
|
874
|
+
tags.length,
|
|
875
|
+
"/",
|
|
876
|
+
maxTags,
|
|
877
|
+
")"
|
|
878
|
+
] })
|
|
879
|
+
] }),
|
|
880
|
+
info && /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
881
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4 text-muted-foreground cursor-pointer mr-2" }) }),
|
|
882
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { className: "max-w-xs", children: info }) })
|
|
883
|
+
] }) })
|
|
884
|
+
] }),
|
|
885
|
+
subLabel && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: subLabel })
|
|
886
|
+
] }),
|
|
887
|
+
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
888
|
+
"div",
|
|
889
|
+
{
|
|
890
|
+
ref: fieldRef,
|
|
891
|
+
className: cn(
|
|
892
|
+
"min-h-[40px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background",
|
|
893
|
+
"focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",
|
|
894
|
+
"flex flex-wrap items-center gap-2 cursor-text",
|
|
895
|
+
error && "border-destructive focus-within:ring-destructive",
|
|
896
|
+
disabled && "cursor-not-allowed opacity-50"
|
|
897
|
+
),
|
|
898
|
+
"data-field": field,
|
|
899
|
+
onClick: () => inputRef.current?.focus(),
|
|
900
|
+
children: [
|
|
901
|
+
tags.map((tagText, index) => /* @__PURE__ */ jsxs(
|
|
902
|
+
"div",
|
|
903
|
+
{
|
|
904
|
+
className: "inline-flex items-center gap-1 px-2 py-1 bg-primary text-primary-foreground rounded-md text-sm",
|
|
905
|
+
children: [
|
|
906
|
+
/* @__PURE__ */ jsx("span", { children: tagText }),
|
|
907
|
+
/* @__PURE__ */ jsx(
|
|
908
|
+
Button,
|
|
909
|
+
{
|
|
910
|
+
type: "button",
|
|
911
|
+
variant: "ghost",
|
|
912
|
+
size: "sm",
|
|
913
|
+
className: "h-4 w-4 p-0 hover:bg-primary-foreground/20 text-primary-foreground",
|
|
914
|
+
onClick: (e) => {
|
|
915
|
+
e.stopPropagation();
|
|
916
|
+
removeTag(tagText);
|
|
917
|
+
},
|
|
918
|
+
disabled,
|
|
919
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
|
|
920
|
+
}
|
|
921
|
+
)
|
|
922
|
+
]
|
|
923
|
+
},
|
|
924
|
+
`${tagText}-${index}`
|
|
925
|
+
)),
|
|
926
|
+
/* @__PURE__ */ jsx(
|
|
927
|
+
Input,
|
|
928
|
+
{
|
|
929
|
+
ref: inputRef,
|
|
930
|
+
type: "text",
|
|
931
|
+
value: inputValue,
|
|
932
|
+
onChange: handleInputChange,
|
|
933
|
+
onKeyDown: handleKeyDown,
|
|
934
|
+
placeholder: tags.length === 0 ? placeholder : "",
|
|
935
|
+
className: "flex-1 min-w-[120px] border-0 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 p-0 h-auto",
|
|
936
|
+
disabled,
|
|
937
|
+
maxLength
|
|
938
|
+
}
|
|
939
|
+
)
|
|
940
|
+
]
|
|
941
|
+
}
|
|
942
|
+
) }),
|
|
943
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm mt-1", children: error })
|
|
944
|
+
] });
|
|
945
|
+
};
|
|
946
|
+
|
|
947
|
+
export { Button, Popover, PopoverContent, PopoverTrigger, SmartCheckbox, SmartDatePicker, SmartRadioGroup, SmartSelect, SmartTags };
|
|
948
|
+
//# sourceMappingURL=chunk-6WAEAWTD.js.map
|
|
949
|
+
//# sourceMappingURL=chunk-6WAEAWTD.js.map
|