@page-speed/forms 0.4.7 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/inputs.js CHANGED
@@ -1,6 +1,7 @@
1
- import * as React9 from 'react';
1
+ import * as React17 from 'react';
2
2
  import { clsx } from 'clsx';
3
3
  import { twMerge } from 'tailwind-merge';
4
+ import { Checkbox as Checkbox$1, Label as Label$1, RadioGroup as RadioGroup$1, Switch as Switch$1, Select as Select$1 } from 'radix-ui';
4
5
  import { useOnClickOutside } from '@opensite/hooks/useOnClickOutside';
5
6
 
6
7
  // src/inputs/TextInput.tsx
@@ -9,6 +10,36 @@ function cn(...inputs) {
9
10
  }
10
11
  var INPUT_AUTOFILL_RESET_CLASSES = "autofill:bg-transparent autofill:text-foreground [&:-webkit-autofill]:[-webkit-text-fill-color:hsl(var(--foreground))] [&:-webkit-autofill]:[caret-color:hsl(var(--foreground))] [&:-webkit-autofill]:[box-shadow:0_0_0px_1000px_hsl(var(--background))_inset] [&:-webkit-autofill:hover]:[box-shadow:0_0_0px_1000px_hsl(var(--background))_inset] [&:-webkit-autofill:focus]:[box-shadow:0_0_0px_1000px_hsl(var(--background))_inset] [&:-webkit-autofill]:[transition:background-color_9999s_ease-out,color_9999s_ease-out]";
11
12
 
13
+ // src/components/ui/input.tsx
14
+ function Input({ className, type, ...props }) {
15
+ return /* @__PURE__ */ React17.createElement(
16
+ "input",
17
+ {
18
+ type,
19
+ "data-slot": "input",
20
+ className: cn(
21
+ // Core structure - no hardcoded colors, uses CSS variables
22
+ "flex h-9 w-full min-w-0 rounded-md border border-input",
23
+ "bg-transparent px-3 py-1 text-base shadow-sm",
24
+ "transition-colors outline-none md:text-sm",
25
+ // Focus state - uses ring-ring CSS variable (adapts to theme)
26
+ "focus-visible:ring-1 focus-visible:ring-ring",
27
+ // Error state - uses destructive CSS variables (adapts to theme)
28
+ "aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive",
29
+ // Disabled state - no color hardcoding
30
+ "disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
31
+ // File input specific - inherits text color from parent
32
+ "file:inline-flex file:h-7 file:border-0 file:bg-transparent",
33
+ "file:text-sm file:font-medium",
34
+ // Autofill reset - prevents browser from overriding our dynamic colors
35
+ INPUT_AUTOFILL_RESET_CLASSES,
36
+ className
37
+ ),
38
+ ...props
39
+ }
40
+ );
41
+ }
42
+
12
43
  // src/inputs/TextInput.tsx
13
44
  function TextInput({
14
45
  name,
@@ -31,17 +62,8 @@ function TextInput({
31
62
  onBlur?.();
32
63
  };
33
64
  const hasValue = String(value ?? "").trim().length > 0;
34
- const combinedClassName = cn(
35
- "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors",
36
- "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
37
- "disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
38
- INPUT_AUTOFILL_RESET_CLASSES,
39
- !error && hasValue && "ring-2 ring-ring",
40
- error && "border-destructive ring-1 ring-destructive",
41
- className
42
- );
43
- return /* @__PURE__ */ React9.createElement(
44
- "input",
65
+ return /* @__PURE__ */ React17.createElement(
66
+ Input,
45
67
  {
46
68
  type,
47
69
  id,
@@ -52,7 +74,12 @@ function TextInput({
52
74
  placeholder,
53
75
  disabled,
54
76
  required,
55
- className: combinedClassName,
77
+ className: cn(
78
+ // Valid value indicator - ring-2 when has value and no error
79
+ !error && hasValue && "ring-2 ring-ring",
80
+ // Error state - handled by Input component via aria-invalid
81
+ className
82
+ ),
56
83
  "aria-invalid": error || props["aria-invalid"],
57
84
  "aria-describedby": props["aria-describedby"],
58
85
  "aria-required": required || props["aria-required"],
@@ -61,6 +88,30 @@ function TextInput({
61
88
  );
62
89
  }
63
90
  TextInput.displayName = "TextInput";
91
+ function Textarea({ className, ...props }) {
92
+ return /* @__PURE__ */ React17.createElement(
93
+ "textarea",
94
+ {
95
+ "data-slot": "textarea",
96
+ className: cn(
97
+ // Core structure - uses CSS variables only
98
+ "flex field-sizing-content min-h-16 w-full rounded-md border border-input",
99
+ "bg-transparent px-3 py-2 text-base shadow-xs",
100
+ "transition-[color,box-shadow] outline-none md:text-sm",
101
+ // Focus state - uses ring-ring CSS variable
102
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
103
+ // Error state - uses destructive CSS variables
104
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20",
105
+ // Disabled state
106
+ "disabled:cursor-not-allowed disabled:opacity-50",
107
+ className
108
+ ),
109
+ ...props
110
+ }
111
+ );
112
+ }
113
+
114
+ // src/inputs/TextArea.tsx
64
115
  function TextArea({
65
116
  name,
66
117
  value,
@@ -85,17 +136,8 @@ function TextArea({
85
136
  onBlur?.();
86
137
  };
87
138
  const hasValue = String(value ?? "").trim().length > 0;
88
- const combinedClassName = cn(
89
- "flex min-h-20 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm transition-colors",
90
- "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
91
- "disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
92
- INPUT_AUTOFILL_RESET_CLASSES,
93
- !error && hasValue && "ring-2 ring-ring",
94
- error && "border-destructive ring-1 ring-destructive",
95
- className
96
- );
97
- return /* @__PURE__ */ React9.createElement(
98
- "textarea",
139
+ return /* @__PURE__ */ React17.createElement(
140
+ Textarea,
99
141
  {
100
142
  name,
101
143
  value: value ?? "",
@@ -104,7 +146,12 @@ function TextArea({
104
146
  placeholder,
105
147
  disabled,
106
148
  required,
107
- className: combinedClassName,
149
+ className: cn(
150
+ // Valid value indicator - ring-2 when has value and no error
151
+ !error && hasValue && "ring-2 ring-ring",
152
+ // Error state - handled by Textarea component via aria-invalid
153
+ className
154
+ ),
108
155
  rows,
109
156
  cols,
110
157
  maxLength,
@@ -118,6 +165,175 @@ function TextArea({
118
165
  );
119
166
  }
120
167
  TextArea.displayName = "TextArea";
168
+ function Checkbox({
169
+ className,
170
+ ...props
171
+ }) {
172
+ return /* @__PURE__ */ React17.createElement(
173
+ Checkbox$1.Root,
174
+ {
175
+ "data-slot": "checkbox",
176
+ className: cn(
177
+ // Core structure - uses CSS variables
178
+ "peer size-4 shrink-0 rounded-[4px] border border-input bg-transparent shadow-xs",
179
+ "transition-shadow outline-none",
180
+ // Checked state - uses primary CSS variables
181
+ "data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
182
+ "data-[state=checked]:border-primary",
183
+ // Focus state - uses ring-ring CSS variable
184
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
185
+ // Error state - uses destructive CSS variables
186
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20",
187
+ // Disabled state
188
+ "disabled:cursor-not-allowed disabled:opacity-50",
189
+ className
190
+ ),
191
+ ...props
192
+ },
193
+ /* @__PURE__ */ React17.createElement(
194
+ Checkbox$1.Indicator,
195
+ {
196
+ "data-slot": "checkbox-indicator",
197
+ className: "grid place-content-center text-current transition-none"
198
+ },
199
+ /* @__PURE__ */ React17.createElement(
200
+ "svg",
201
+ {
202
+ className: "size-3.5",
203
+ viewBox: "0 0 24 24",
204
+ fill: "none",
205
+ stroke: "currentColor",
206
+ strokeWidth: "3",
207
+ strokeLinecap: "round",
208
+ strokeLinejoin: "round"
209
+ },
210
+ /* @__PURE__ */ React17.createElement("polyline", { points: "20 6 9 17 4 12" })
211
+ )
212
+ )
213
+ );
214
+ }
215
+ function Label({
216
+ className,
217
+ ...props
218
+ }) {
219
+ return /* @__PURE__ */ React17.createElement(
220
+ Label$1.Root,
221
+ {
222
+ "data-slot": "label",
223
+ className: cn(
224
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
225
+ className
226
+ ),
227
+ ...props
228
+ }
229
+ );
230
+ }
231
+
232
+ // src/inputs/Checkbox.tsx
233
+ function Checkbox2({
234
+ name,
235
+ value,
236
+ onChange,
237
+ onBlur,
238
+ disabled = false,
239
+ required = false,
240
+ error = false,
241
+ className = "",
242
+ label,
243
+ description,
244
+ useChoiceCard = false,
245
+ ...props
246
+ }) {
247
+ const checkboxId = props.id || `checkbox-${name}`;
248
+ const handleCheckedChange = (checked) => {
249
+ onChange(checked);
250
+ };
251
+ const handleBlur = () => {
252
+ onBlur?.();
253
+ };
254
+ const showChoiceCard = useChoiceCard || !!description;
255
+ const checkbox = /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(
256
+ "input",
257
+ {
258
+ type: "checkbox",
259
+ name,
260
+ checked: value,
261
+ onChange: () => {
262
+ },
263
+ disabled,
264
+ required,
265
+ tabIndex: -1,
266
+ "aria-hidden": "true",
267
+ style: {
268
+ position: "absolute",
269
+ width: "1px",
270
+ height: "1px",
271
+ padding: 0,
272
+ margin: "-1px",
273
+ overflow: "hidden",
274
+ clip: "rect(0, 0, 0, 0)",
275
+ whiteSpace: "nowrap",
276
+ border: 0
277
+ }
278
+ }
279
+ ), /* @__PURE__ */ React17.createElement(
280
+ Checkbox,
281
+ {
282
+ id: checkboxId,
283
+ checked: value,
284
+ onCheckedChange: handleCheckedChange,
285
+ onBlur: handleBlur,
286
+ disabled,
287
+ "aria-invalid": error || props["aria-invalid"],
288
+ "aria-describedby": description ? `${checkboxId}-description` : props["aria-describedby"],
289
+ "aria-required": required || props["aria-required"],
290
+ ...props
291
+ }
292
+ ));
293
+ if (!label) {
294
+ return /* @__PURE__ */ React17.createElement("div", { className }, checkbox);
295
+ }
296
+ return /* @__PURE__ */ React17.createElement(
297
+ "label",
298
+ {
299
+ htmlFor: checkboxId,
300
+ className: cn(
301
+ "flex gap-3 p-3 duration-200",
302
+ showChoiceCard && "border rounded-lg hover:ring-2 hover:ring-ring/50",
303
+ showChoiceCard && value && "ring-2 ring-ring",
304
+ showChoiceCard && error && "border-destructive",
305
+ disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer",
306
+ className
307
+ )
308
+ },
309
+ /* @__PURE__ */ React17.createElement(
310
+ "div",
311
+ {
312
+ className: cn(
313
+ "flex w-full gap-3",
314
+ showChoiceCard ? "items-start" : "items-center"
315
+ )
316
+ },
317
+ checkbox,
318
+ /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React17.createElement(
319
+ Label,
320
+ {
321
+ htmlFor: checkboxId,
322
+ className: "cursor-pointer font-medium leading-none"
323
+ },
324
+ label
325
+ ), description && /* @__PURE__ */ React17.createElement(
326
+ "p",
327
+ {
328
+ id: `${checkboxId}-description`,
329
+ className: "text-sm opacity-70 leading-snug"
330
+ },
331
+ description
332
+ ))
333
+ )
334
+ );
335
+ }
336
+ Checkbox2.displayName = "Checkbox";
121
337
  var LabelGroup = ({
122
338
  labelHtmlFor,
123
339
  required = false,
@@ -133,11 +349,11 @@ var LabelGroup = ({
133
349
  variant === "legend" ? "mb-1.5" : "mb-1 block",
134
350
  primaryClassName
135
351
  );
136
- const requiredIndicator = required ? /* @__PURE__ */ React9.createElement("span", { className: "text-destructive pl-0.5", "aria-label": "required" }, "*") : null;
352
+ const requiredIndicator = required ? /* @__PURE__ */ React17.createElement("span", { className: "text-destructive pl-0.5", "aria-label": "required" }, "*") : null;
137
353
  let primaryElement = null;
138
354
  if (primary) {
139
355
  if (variant === "label") {
140
- primaryElement = /* @__PURE__ */ React9.createElement(
356
+ primaryElement = /* @__PURE__ */ React17.createElement(
141
357
  "label",
142
358
  {
143
359
  htmlFor: labelHtmlFor,
@@ -148,12 +364,12 @@ var LabelGroup = ({
148
364
  requiredIndicator
149
365
  );
150
366
  } else if (variant === "legend") {
151
- primaryElement = /* @__PURE__ */ React9.createElement("legend", { "data-slot": "field-legend", className: primaryClasses }, primary, requiredIndicator);
367
+ primaryElement = /* @__PURE__ */ React17.createElement("legend", { "data-slot": "field-legend", className: primaryClasses }, primary, requiredIndicator);
152
368
  } else {
153
- primaryElement = /* @__PURE__ */ React9.createElement("div", { "data-slot": "field-label", className: primaryClasses }, primary, requiredIndicator);
369
+ primaryElement = /* @__PURE__ */ React17.createElement("div", { "data-slot": "field-label", className: primaryClasses }, primary, requiredIndicator);
154
370
  }
155
371
  }
156
- const secondaryElement = secondary ? /* @__PURE__ */ React9.createElement(
372
+ const secondaryElement = secondary ? /* @__PURE__ */ React17.createElement(
157
373
  "p",
158
374
  {
159
375
  "data-slot": "field-description",
@@ -164,148 +380,12 @@ var LabelGroup = ({
164
380
  ) : null;
165
381
  if (!primaryElement && !secondaryElement) return null;
166
382
  if (variant === "legend") {
167
- return /* @__PURE__ */ React9.createElement(React9.Fragment, null, primaryElement, secondaryElement);
383
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, primaryElement, secondaryElement);
168
384
  }
169
- return /* @__PURE__ */ React9.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, primaryElement, secondaryElement);
385
+ return /* @__PURE__ */ React17.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, primaryElement, secondaryElement);
170
386
  };
171
387
 
172
- // src/inputs/Checkbox.tsx
173
- function Checkbox({
174
- name,
175
- value,
176
- onChange,
177
- onBlur,
178
- disabled = false,
179
- required = false,
180
- error = false,
181
- className = "",
182
- indeterminate = false,
183
- label,
184
- description,
185
- useChoiceCard = false,
186
- ...props
187
- }) {
188
- const inputRef = React9.useRef(null);
189
- const checkboxId = props.id || `checkbox-${name}`;
190
- React9.useEffect(() => {
191
- if (inputRef.current) {
192
- inputRef.current.indeterminate = indeterminate;
193
- }
194
- }, [indeterminate]);
195
- const handleChange = (e) => {
196
- onChange(e.target.checked);
197
- };
198
- const handleBlur = () => {
199
- onBlur?.();
200
- };
201
- const isActive = value || indeterminate && !value;
202
- const checkbox = /* @__PURE__ */ React9.createElement(
203
- "div",
204
- {
205
- className: cn(
206
- "relative inline-flex items-center justify-center",
207
- !label && className
208
- )
209
- },
210
- /* @__PURE__ */ React9.createElement(
211
- "input",
212
- {
213
- ref: inputRef,
214
- type: "checkbox",
215
- id: checkboxId,
216
- name,
217
- checked: value,
218
- onChange: handleChange,
219
- onBlur: handleBlur,
220
- disabled,
221
- required,
222
- className: "peer sr-only",
223
- "aria-invalid": error || props["aria-invalid"],
224
- "aria-describedby": description ? `${checkboxId}-description` : props["aria-describedby"],
225
- "aria-required": required || props["aria-required"],
226
- ...props
227
- }
228
- ),
229
- /* @__PURE__ */ React9.createElement(
230
- "div",
231
- {
232
- className: cn(
233
- "flex shrink-0 items-center justify-center rounded-full border-2 transition-colors size-6",
234
- !error && isActive && "border-primary bg-primary text-primary-foreground",
235
- !error && !isActive && "border-input bg-transparent",
236
- error && isActive && "border-destructive bg-destructive text-destructive-foreground",
237
- error && !isActive && "border-destructive bg-transparent",
238
- disabled && "opacity-50",
239
- "peer-focus-visible:ring-2 peer-focus-visible:ring-ring/50 peer-focus-visible:ring-offset-1"
240
- )
241
- },
242
- value && /* @__PURE__ */ React9.createElement(
243
- "svg",
244
- {
245
- className: "size-3.5",
246
- viewBox: "0 0 24 24",
247
- fill: "none",
248
- stroke: "currentColor",
249
- strokeWidth: "3",
250
- strokeLinecap: "round",
251
- strokeLinejoin: "round"
252
- },
253
- /* @__PURE__ */ React9.createElement("polyline", { points: "20 6 9 17 4 12" })
254
- ),
255
- indeterminate && !value && /* @__PURE__ */ React9.createElement(
256
- "svg",
257
- {
258
- className: "size-3.5",
259
- viewBox: "0 0 24 24",
260
- fill: "none",
261
- stroke: "currentColor",
262
- strokeWidth: "3",
263
- strokeLinecap: "round",
264
- strokeLinejoin: "round"
265
- },
266
- /* @__PURE__ */ React9.createElement("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
267
- )
268
- )
269
- );
270
- if (label) {
271
- return /* @__PURE__ */ React9.createElement(
272
- "label",
273
- {
274
- className: cn(
275
- "w-full h-full flex gap-3 p-3 duration-200",
276
- useChoiceCard && "border rounded-lg hover:ring-2",
277
- useChoiceCard && value && "ring-2",
278
- disabled ? "opacity-50 cursor-not-allowed hover:ring-0" : "cursor-pointer",
279
- className
280
- ),
281
- htmlFor: checkboxId
282
- },
283
- /* @__PURE__ */ React9.createElement(
284
- "div",
285
- {
286
- className: cn(
287
- "flex w-full flex-row gap-2",
288
- useChoiceCard ? "items-start" : "items-center"
289
- )
290
- },
291
- checkbox,
292
- /* @__PURE__ */ React9.createElement(
293
- LabelGroup,
294
- {
295
- variant: "text",
296
- primary: label,
297
- secondary: description,
298
- secondaryId: description ? `${checkboxId}-description` : void 0,
299
- primaryClassName: "mb-0",
300
- secondaryClassName: "text-xs opacity-75"
301
- }
302
- )
303
- )
304
- );
305
- }
306
- return checkbox;
307
- }
308
- Checkbox.displayName = "Checkbox";
388
+ // src/inputs/CheckboxGroup.tsx
309
389
  function CheckboxGroup({
310
390
  name,
311
391
  value = [],
@@ -334,11 +414,11 @@ function CheckboxGroup({
334
414
  ).length;
335
415
  const allSelected = selectedEnabledCount === enabledOptions.length;
336
416
  const someSelected = selectedEnabledCount > 0 && !allSelected;
337
- const useChoiceCard = React9.useMemo(() => {
417
+ const useChoiceCard = React17.useMemo(() => {
338
418
  if (!options) return false;
339
419
  return options?.some((opt) => opt.description);
340
420
  }, [options]);
341
- const countableValue = React9.useMemo(() => {
421
+ const countableValue = React17.useMemo(() => {
342
422
  if (value?.length > 0) {
343
423
  return value.length;
344
424
  }
@@ -363,7 +443,7 @@ function CheckboxGroup({
363
443
  onBlur?.();
364
444
  };
365
445
  const maxReached = Boolean(maxSelections && countableValue >= maxSelections);
366
- const containerClass = React9.useMemo(() => {
446
+ const containerClass = React17.useMemo(() => {
367
447
  return cn(
368
448
  "w-full gap-3 grid grid-cols-1 border-0 m-0 p-0 min-w-0",
369
449
  (layout === "grid" || layout === "inline") && "md:grid-cols-2",
@@ -372,7 +452,7 @@ function CheckboxGroup({
372
452
  }, [layout, className]);
373
453
  const groupDescriptionId = description ? `${name}-description` : void 0;
374
454
  const groupAriaDescribedBy = [props["aria-describedby"], groupDescriptionId].filter(Boolean).join(" ") || void 0;
375
- return /* @__PURE__ */ React9.createElement(
455
+ return /* @__PURE__ */ React17.createElement(
376
456
  "fieldset",
377
457
  {
378
458
  className: containerClass,
@@ -382,7 +462,7 @@ function CheckboxGroup({
382
462
  "aria-required": required || props["aria-required"],
383
463
  "aria-label": typeof label === "string" ? label : props["aria-label"]
384
464
  },
385
- /* @__PURE__ */ React9.createElement(
465
+ /* @__PURE__ */ React17.createElement(
386
466
  LabelGroup,
387
467
  {
388
468
  labelHtmlFor: name,
@@ -393,8 +473,8 @@ function CheckboxGroup({
393
473
  primary: label
394
474
  }
395
475
  ),
396
- showSelectAll && enabledOptions.length > 0 && /* @__PURE__ */ React9.createElement(
397
- Checkbox,
476
+ showSelectAll && enabledOptions.length > 0 && /* @__PURE__ */ React17.createElement(
477
+ Checkbox2,
398
478
  {
399
479
  name: `${name}-select-all`,
400
480
  id: `${name}-select-all`,
@@ -411,8 +491,8 @@ function CheckboxGroup({
411
491
  options.map((option) => {
412
492
  const isChecked = value.includes(option.value);
413
493
  const isDisabled = disabled || option.disabled || maxReached && !isChecked;
414
- return /* @__PURE__ */ React9.createElement(
415
- Checkbox,
494
+ return /* @__PURE__ */ React17.createElement(
495
+ Checkbox2,
416
496
  {
417
497
  key: option.value,
418
498
  name,
@@ -429,7 +509,7 @@ function CheckboxGroup({
429
509
  }
430
510
  );
431
511
  }),
432
- (minSelections || maxSelections) && /* @__PURE__ */ React9.createElement(
512
+ (minSelections || maxSelections) && /* @__PURE__ */ React17.createElement(
433
513
  "div",
434
514
  {
435
515
  className: cn(
@@ -438,12 +518,66 @@ function CheckboxGroup({
438
518
  ),
439
519
  "aria-live": "polite"
440
520
  },
441
- minSelections && countableValue < minSelections && /* @__PURE__ */ React9.createElement("span", null, "Select at least ", minSelections, " option", minSelections !== 1 ? "s" : ""),
442
- maxSelections && /* @__PURE__ */ React9.createElement("span", null, countableValue, "/", maxSelections, " selected")
521
+ minSelections && countableValue < minSelections && /* @__PURE__ */ React17.createElement("span", null, "Select at least ", minSelections, " option", minSelections !== 1 ? "s" : ""),
522
+ maxSelections && /* @__PURE__ */ React17.createElement("span", null, countableValue, "/", maxSelections, " selected")
443
523
  )
444
524
  );
445
525
  }
446
526
  CheckboxGroup.displayName = "CheckboxGroup";
527
+ function RadioGroup({
528
+ className,
529
+ ...props
530
+ }) {
531
+ return /* @__PURE__ */ React17.createElement(
532
+ RadioGroup$1.Root,
533
+ {
534
+ "data-slot": "radio-group",
535
+ className: cn("grid gap-3", className),
536
+ ...props
537
+ }
538
+ );
539
+ }
540
+ function RadioGroupItem({
541
+ className,
542
+ ...props
543
+ }) {
544
+ return /* @__PURE__ */ React17.createElement(
545
+ RadioGroup$1.Item,
546
+ {
547
+ "data-slot": "radio-group-item",
548
+ className: cn(
549
+ // Core structure - uses CSS variables
550
+ "aspect-square size-4 shrink-0 rounded-full border border-input bg-transparent shadow-xs",
551
+ "text-primary transition-[color,box-shadow] outline-none",
552
+ // Focus state - uses ring-ring CSS variable
553
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
554
+ // Error state - uses destructive CSS variables
555
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20",
556
+ // Disabled state
557
+ "disabled:cursor-not-allowed disabled:opacity-50",
558
+ className
559
+ ),
560
+ ...props
561
+ },
562
+ /* @__PURE__ */ React17.createElement(
563
+ RadioGroup$1.Indicator,
564
+ {
565
+ "data-slot": "radio-group-indicator",
566
+ className: "relative flex items-center justify-center"
567
+ },
568
+ /* @__PURE__ */ React17.createElement(
569
+ "svg",
570
+ {
571
+ className: "fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2",
572
+ viewBox: "0 0 24 24"
573
+ },
574
+ /* @__PURE__ */ React17.createElement("circle", { cx: "12", cy: "12", r: "12" })
575
+ )
576
+ )
577
+ );
578
+ }
579
+
580
+ // src/inputs/Radio.tsx
447
581
  function Radio({
448
582
  name,
449
583
  value,
@@ -459,146 +593,433 @@ function Radio({
459
593
  options,
460
594
  ...props
461
595
  }) {
462
- const handleChange = (optionValue) => {
463
- onChange(optionValue);
464
- };
465
- const handleKeyDown = (e, currentIndex) => {
466
- if (e.key === "ArrowDown" || e.key === "ArrowRight") {
467
- e.preventDefault();
468
- let nextIndex = (currentIndex + 1) % options.length;
469
- let attempts = 0;
470
- while (options[nextIndex].disabled && attempts < options.length && !disabled) {
471
- nextIndex = (nextIndex + 1) % options.length;
472
- attempts++;
473
- }
474
- if (!options[nextIndex].disabled) {
475
- handleChange(options[nextIndex].value);
476
- }
477
- } else if (e.key === "ArrowUp" || e.key === "ArrowLeft") {
478
- e.preventDefault();
479
- let prevIndex = (currentIndex - 1 + options.length) % options.length;
480
- let attempts = 0;
481
- while (options[prevIndex].disabled && attempts < options.length && !disabled) {
482
- prevIndex = (prevIndex - 1 + options.length) % options.length;
483
- attempts++;
484
- }
485
- if (!options[prevIndex].disabled) {
486
- handleChange(options[prevIndex].value);
487
- }
488
- }
596
+ const handleValueChange = (selectedValue) => {
597
+ onChange(selectedValue);
489
598
  };
490
599
  const handleBlur = () => {
491
600
  onBlur?.();
492
601
  };
493
- const useChoiceCard = React9.useMemo(() => {
602
+ const useChoiceCard = React17.useMemo(() => {
494
603
  return options.some((option) => option.description);
495
604
  }, [options]);
496
- const containerClass = React9.useMemo(() => {
497
- return cn(
498
- "w-full gap-3 grid grid-cols-1 border-0 m-0 p-0 min-w-0",
499
- (layout === "grid" || layout === "inline") && "md:grid-cols-2",
500
- className
501
- );
502
- }, [layout, className]);
503
605
  const groupDescriptionId = description ? `${name}-description` : void 0;
504
- const groupAriaDescribedBy = [props["aria-describedby"], groupDescriptionId].filter(Boolean).join(" ") || void 0;
505
- return /* @__PURE__ */ React9.createElement(
506
- "fieldset",
606
+ return /* @__PURE__ */ React17.createElement("div", { className: cn("w-full", className) }, (label || description) && /* @__PURE__ */ React17.createElement("div", { className: "mb-3" }, label && /* @__PURE__ */ React17.createElement(Label, { className: "text-base font-medium block mb-1" }, label), description && /* @__PURE__ */ React17.createElement(
607
+ "p",
507
608
  {
508
- className: containerClass,
509
- role: "radiogroup",
609
+ id: groupDescriptionId,
610
+ className: "text-sm opacity-70"
611
+ },
612
+ description
613
+ )), /* @__PURE__ */ React17.createElement(
614
+ RadioGroup,
615
+ {
616
+ name,
617
+ value,
618
+ onValueChange: handleValueChange,
619
+ onBlur: handleBlur,
620
+ disabled,
621
+ required,
622
+ className: cn(
623
+ "gap-3",
624
+ layout === "grid" && "grid grid-cols-1 md:grid-cols-2",
625
+ layout === "inline" && "flex flex-wrap"
626
+ ),
510
627
  "aria-invalid": error || props["aria-invalid"],
511
- "aria-describedby": groupAriaDescribedBy,
512
- "aria-required": required || props["aria-required"],
513
- "aria-label": typeof label === "string" ? label : props["aria-label"]
628
+ "aria-describedby": groupDescriptionId || props["aria-describedby"],
629
+ "aria-required": required || props["aria-required"]
514
630
  },
515
- /* @__PURE__ */ React9.createElement(
516
- LabelGroup,
517
- {
518
- variant: "legend",
519
- primary: label,
520
- secondary: description,
521
- secondaryId: groupDescriptionId
522
- }
523
- ),
524
- options.map((option, index) => {
525
- const isChecked = value === option.value;
631
+ options.map((option) => {
632
+ const isSelected = value === option.value;
526
633
  const isDisabled = disabled || option.disabled;
527
634
  const radioId = `${name}-${option.value}`;
528
- const hasDescription = option.description != null && option.description !== "";
529
- const radioIndicator = /* @__PURE__ */ React9.createElement("div", { className: "relative inline-flex items-center justify-center" }, /* @__PURE__ */ React9.createElement(
530
- "input",
531
- {
532
- type: "radio",
533
- id: radioId,
534
- name,
535
- value: option.value,
536
- checked: isChecked,
537
- onChange: (e) => handleChange(e.target.value),
538
- onBlur: handleBlur,
539
- disabled: isDisabled,
540
- required,
541
- className: "peer sr-only",
542
- "aria-describedby": hasDescription ? `${radioId}-description` : props["aria-describedby"]
543
- }
544
- ), /* @__PURE__ */ React9.createElement(
545
- "div",
546
- {
547
- className: cn(
548
- "flex shrink-0 items-center justify-center rounded-full border-2 transition-colors size-6",
549
- !error && isChecked && "border-primary bg-transparent",
550
- !error && !isChecked && "border-input bg-transparent",
551
- error && isChecked && "border-destructive bg-transparent",
552
- error && !isChecked && "border-destructive bg-transparent",
553
- isDisabled && "opacity-50",
554
- "peer-focus-visible:ring-2 peer-focus-visible:ring-ring/50 peer-focus-visible:ring-offset-1"
555
- )
556
- },
557
- isChecked && /* @__PURE__ */ React9.createElement("div", { className: "size-3 rounded-full bg-primary" })
558
- ));
559
- const labelContent = /* @__PURE__ */ React9.createElement(
560
- LabelGroup,
561
- {
562
- variant: "text",
563
- primary: option.label,
564
- secondary: hasDescription ? option.description : void 0,
565
- secondaryId: hasDescription ? `${radioId}-description` : void 0,
566
- primaryClassName: "mb-0",
567
- secondaryClassName: "text-xs opacity-75"
568
- }
569
- );
570
- return /* @__PURE__ */ React9.createElement(
635
+ const hasDescription = !!option.description;
636
+ return /* @__PURE__ */ React17.createElement(
571
637
  "label",
572
638
  {
573
639
  key: option.value,
574
- className: cn(
575
- "w-full h-full flex gap-3 p-3 duration-200",
576
- useChoiceCard && "border rounded-lg hover:ring-2",
577
- useChoiceCard && isChecked && "ring-2",
578
- isDisabled ? "opacity-50 cursor-not-allowed hover:ring-0" : "cursor-pointer"
579
- ),
580
640
  htmlFor: radioId,
581
- onKeyDown: (e) => handleKeyDown(e, index),
582
- tabIndex: isDisabled ? -1 : 0
641
+ className: cn(
642
+ "flex gap-3 p-3 duration-200",
643
+ useChoiceCard && "border rounded-lg hover:ring-2 hover:ring-ring/50",
644
+ useChoiceCard && isSelected && "ring-2 ring-ring",
645
+ useChoiceCard && error && "border-destructive",
646
+ isDisabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"
647
+ )
583
648
  },
584
- /* @__PURE__ */ React9.createElement(
649
+ /* @__PURE__ */ React17.createElement(
585
650
  "div",
586
651
  {
587
652
  className: cn(
588
- "flex w-full flex-row gap-2",
653
+ "flex w-full gap-3",
589
654
  useChoiceCard ? "items-start" : "items-center"
590
655
  )
591
656
  },
592
- !useChoiceCard && radioIndicator,
593
- labelContent,
594
- useChoiceCard && radioIndicator
657
+ /* @__PURE__ */ React17.createElement(
658
+ RadioGroupItem,
659
+ {
660
+ value: option.value,
661
+ id: radioId,
662
+ disabled: isDisabled,
663
+ className: "mt-0.5",
664
+ "aria-describedby": hasDescription ? `${radioId}-description` : void 0
665
+ }
666
+ ),
667
+ /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-1 flex-1" }, /* @__PURE__ */ React17.createElement(
668
+ Label,
669
+ {
670
+ htmlFor: radioId,
671
+ className: "cursor-pointer font-medium leading-none"
672
+ },
673
+ option.label
674
+ ), option.description && /* @__PURE__ */ React17.createElement(
675
+ "p",
676
+ {
677
+ id: `${radioId}-description`,
678
+ className: "text-sm opacity-70 leading-snug"
679
+ },
680
+ option.description
681
+ ))
595
682
  )
596
683
  );
597
684
  })
685
+ ));
686
+ }
687
+ Radio.displayName = "Radio";
688
+ function Switch({
689
+ className,
690
+ size = "default",
691
+ ...props
692
+ }) {
693
+ return /* @__PURE__ */ React17.createElement(
694
+ Switch$1.Root,
695
+ {
696
+ "data-slot": "switch",
697
+ "data-size": size,
698
+ className: cn(
699
+ // Core structure - uses CSS variables
700
+ "peer group/switch inline-flex shrink-0 items-center rounded-full",
701
+ "border border-transparent shadow-xs transition-all outline-none",
702
+ // State-based backgrounds - use CSS variables
703
+ "data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
704
+ // Focus state
705
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
706
+ // Disabled state
707
+ "disabled:cursor-not-allowed disabled:opacity-50",
708
+ // Size variants
709
+ "data-[size=default]:h-[1.15rem] data-[size=default]:w-8",
710
+ "data-[size=sm]:h-3.5 data-[size=sm]:w-6",
711
+ className
712
+ ),
713
+ ...props
714
+ },
715
+ /* @__PURE__ */ React17.createElement(
716
+ Switch$1.Thumb,
717
+ {
718
+ "data-slot": "switch-thumb",
719
+ className: cn(
720
+ // Thumb appearance - inherits from parent theme
721
+ "bg-background pointer-events-none block rounded-full ring-0 transition-transform",
722
+ // Size variants
723
+ "group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3",
724
+ // Position based on state
725
+ "data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
726
+ )
727
+ }
728
+ )
729
+ );
730
+ }
731
+
732
+ // src/inputs/Switch.tsx
733
+ function Switch2({
734
+ name,
735
+ value,
736
+ onChange,
737
+ onBlur,
738
+ disabled = false,
739
+ required = false,
740
+ error = false,
741
+ className = "",
742
+ label,
743
+ description,
744
+ size = "default",
745
+ ...props
746
+ }) {
747
+ const switchId = props.id || `switch-${name}`;
748
+ const handleCheckedChange = (checked) => {
749
+ onChange(checked);
750
+ };
751
+ const handleBlur = () => {
752
+ onBlur?.();
753
+ };
754
+ const switchElement = /* @__PURE__ */ React17.createElement(
755
+ Switch,
756
+ {
757
+ id: switchId,
758
+ checked: value,
759
+ onCheckedChange: handleCheckedChange,
760
+ onBlur: handleBlur,
761
+ disabled,
762
+ size,
763
+ "aria-invalid": error || props["aria-invalid"],
764
+ "aria-describedby": description ? `${switchId}-description` : props["aria-describedby"],
765
+ "aria-required": required || props["aria-required"],
766
+ ...props
767
+ }
768
+ );
769
+ if (!label) {
770
+ return /* @__PURE__ */ React17.createElement("div", { className }, switchElement);
771
+ }
772
+ return /* @__PURE__ */ React17.createElement(
773
+ "label",
774
+ {
775
+ htmlFor: switchId,
776
+ className: cn(
777
+ "flex items-center gap-3 cursor-pointer",
778
+ disabled && "opacity-50 cursor-not-allowed",
779
+ className
780
+ )
781
+ },
782
+ switchElement,
783
+ /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React17.createElement(
784
+ Label,
785
+ {
786
+ htmlFor: switchId,
787
+ className: "cursor-pointer font-medium leading-none"
788
+ },
789
+ label
790
+ ), description && /* @__PURE__ */ React17.createElement(
791
+ "p",
792
+ {
793
+ id: `${switchId}-description`,
794
+ className: "text-sm opacity-70 leading-snug"
795
+ },
796
+ description
797
+ ))
798
+ );
799
+ }
800
+ Switch2.displayName = "Switch";
801
+ function Select({
802
+ ...props
803
+ }) {
804
+ return /* @__PURE__ */ React17.createElement(Select$1.Root, { "data-slot": "select", ...props });
805
+ }
806
+ function SelectGroup({
807
+ ...props
808
+ }) {
809
+ return /* @__PURE__ */ React17.createElement(Select$1.Group, { "data-slot": "select-group", ...props });
810
+ }
811
+ function SelectValue({
812
+ ...props
813
+ }) {
814
+ return /* @__PURE__ */ React17.createElement(Select$1.Value, { "data-slot": "select-value", ...props });
815
+ }
816
+ function SelectTrigger({
817
+ className,
818
+ size = "default",
819
+ children,
820
+ ...props
821
+ }) {
822
+ return /* @__PURE__ */ React17.createElement(
823
+ Select$1.Trigger,
824
+ {
825
+ "data-slot": "select-trigger",
826
+ "data-size": size,
827
+ className: cn(
828
+ // Core structure - uses CSS variables
829
+ "flex w-fit items-center justify-between gap-2 rounded-md border border-input",
830
+ "bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs",
831
+ "transition-[color,box-shadow] outline-none",
832
+ // Focus state
833
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
834
+ // Error state
835
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20",
836
+ // Disabled state
837
+ "disabled:cursor-not-allowed disabled:opacity-50",
838
+ // Size variants
839
+ "data-[size=default]:h-9 data-[size=sm]:h-8",
840
+ // Value styling
841
+ "*:data-[slot=select-value]:line-clamp-1",
842
+ "*:data-[slot=select-value]:flex",
843
+ "*:data-[slot=select-value]:items-center",
844
+ "*:data-[slot=select-value]:gap-2",
845
+ // SVG styling
846
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
847
+ className
848
+ ),
849
+ ...props
850
+ },
851
+ children,
852
+ /* @__PURE__ */ React17.createElement(Select$1.Icon, { asChild: true }, /* @__PURE__ */ React17.createElement(
853
+ "svg",
854
+ {
855
+ className: "size-4 opacity-50",
856
+ viewBox: "0 0 24 24",
857
+ fill: "none",
858
+ stroke: "currentColor",
859
+ strokeWidth: "2",
860
+ strokeLinecap: "round",
861
+ strokeLinejoin: "round"
862
+ },
863
+ /* @__PURE__ */ React17.createElement("polyline", { points: "6 9 12 15 18 9" })
864
+ ))
865
+ );
866
+ }
867
+ function SelectContent({
868
+ className,
869
+ children,
870
+ position = "item-aligned",
871
+ align = "center",
872
+ ...props
873
+ }) {
874
+ return /* @__PURE__ */ React17.createElement(Select$1.Portal, null, /* @__PURE__ */ React17.createElement(
875
+ Select$1.Content,
876
+ {
877
+ "data-slot": "select-content",
878
+ className: cn(
879
+ "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",
880
+ 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",
881
+ className
882
+ ),
883
+ position,
884
+ align,
885
+ ...props
886
+ },
887
+ /* @__PURE__ */ React17.createElement(SelectScrollUpButton, null),
888
+ /* @__PURE__ */ React17.createElement(
889
+ Select$1.Viewport,
890
+ {
891
+ className: cn(
892
+ "p-1",
893
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
894
+ )
895
+ },
896
+ children
897
+ ),
898
+ /* @__PURE__ */ React17.createElement(SelectScrollDownButton, null)
899
+ ));
900
+ }
901
+ function SelectLabel({
902
+ className,
903
+ ...props
904
+ }) {
905
+ return /* @__PURE__ */ React17.createElement(
906
+ Select$1.Label,
907
+ {
908
+ "data-slot": "select-label",
909
+ className: cn("px-2 py-1.5 text-xs opacity-70", className),
910
+ ...props
911
+ }
912
+ );
913
+ }
914
+ function SelectItem({
915
+ className,
916
+ children,
917
+ ...props
918
+ }) {
919
+ return /* @__PURE__ */ React17.createElement(
920
+ Select$1.Item,
921
+ {
922
+ "data-slot": "select-item",
923
+ className: cn(
924
+ // Core structure - inherits text color
925
+ "relative flex w-full cursor-default items-center gap-2 rounded-sm",
926
+ "py-1.5 pr-8 pl-2 text-sm outline-hidden select-none",
927
+ // Focus state - uses accent CSS variable
928
+ "focus:bg-accent focus:text-accent-foreground",
929
+ // Disabled state
930
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
931
+ // SVG styling
932
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
933
+ // Span styling
934
+ "*:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
935
+ className
936
+ ),
937
+ ...props
938
+ },
939
+ /* @__PURE__ */ React17.createElement(
940
+ "span",
941
+ {
942
+ "data-slot": "select-item-indicator",
943
+ className: "absolute right-2 flex size-3.5 items-center justify-center"
944
+ },
945
+ /* @__PURE__ */ React17.createElement(Select$1.ItemIndicator, null, /* @__PURE__ */ React17.createElement(
946
+ "svg",
947
+ {
948
+ className: "size-4",
949
+ viewBox: "0 0 24 24",
950
+ fill: "none",
951
+ stroke: "currentColor",
952
+ strokeWidth: "3",
953
+ strokeLinecap: "round",
954
+ strokeLinejoin: "round"
955
+ },
956
+ /* @__PURE__ */ React17.createElement("polyline", { points: "20 6 9 17 4 12" })
957
+ ))
958
+ ),
959
+ /* @__PURE__ */ React17.createElement(Select$1.ItemText, null, children)
598
960
  );
599
961
  }
600
- Radio.displayName = "Radio";
601
- function Select({
962
+ function SelectScrollUpButton({
963
+ className,
964
+ ...props
965
+ }) {
966
+ return /* @__PURE__ */ React17.createElement(
967
+ Select$1.ScrollUpButton,
968
+ {
969
+ "data-slot": "select-scroll-up-button",
970
+ className: cn(
971
+ "flex cursor-default items-center justify-center py-1",
972
+ className
973
+ ),
974
+ ...props
975
+ },
976
+ /* @__PURE__ */ React17.createElement(
977
+ "svg",
978
+ {
979
+ className: "size-4",
980
+ viewBox: "0 0 24 24",
981
+ fill: "none",
982
+ stroke: "currentColor",
983
+ strokeWidth: "2",
984
+ strokeLinecap: "round",
985
+ strokeLinejoin: "round"
986
+ },
987
+ /* @__PURE__ */ React17.createElement("polyline", { points: "18 15 12 9 6 15" })
988
+ )
989
+ );
990
+ }
991
+ function SelectScrollDownButton({
992
+ className,
993
+ ...props
994
+ }) {
995
+ return /* @__PURE__ */ React17.createElement(
996
+ Select$1.ScrollDownButton,
997
+ {
998
+ "data-slot": "select-scroll-down-button",
999
+ className: cn(
1000
+ "flex cursor-default items-center justify-center py-1",
1001
+ className
1002
+ ),
1003
+ ...props
1004
+ },
1005
+ /* @__PURE__ */ React17.createElement(
1006
+ "svg",
1007
+ {
1008
+ className: "size-4",
1009
+ viewBox: "0 0 24 24",
1010
+ fill: "none",
1011
+ stroke: "currentColor",
1012
+ strokeWidth: "2",
1013
+ strokeLinecap: "round",
1014
+ strokeLinejoin: "round"
1015
+ },
1016
+ /* @__PURE__ */ React17.createElement("polyline", { points: "6 9 12 15 18 9" })
1017
+ )
1018
+ );
1019
+ }
1020
+
1021
+ // src/inputs/Select.tsx
1022
+ function Select2({
602
1023
  name,
603
1024
  value,
604
1025
  onChange,
@@ -609,283 +1030,83 @@ function Select({
609
1030
  error = false,
610
1031
  className = "",
611
1032
  placeholder = "Select...",
612
- searchable = true,
613
- clearable = true,
614
- loading = false,
615
1033
  options = [],
616
1034
  optionGroups = [],
617
1035
  renderOption,
618
1036
  ...props
619
1037
  }) {
620
- const [isOpen, setIsOpen] = React9.useState(false);
621
- const [searchQuery, setSearchQuery] = React9.useState("");
622
- const [focusedIndex, setFocusedIndex] = React9.useState(-1);
623
- const triggerRef = React9.useRef(null);
624
- const dropdownRef = React9.useRef(null);
625
- const searchInputRef = React9.useRef(null);
626
- const dropdownId = `${name}-dropdown`;
627
- const allOptions = React9.useMemo(() => {
1038
+ const [hasInteracted, setHasInteracted] = React17.useState(false);
1039
+ const allOptions = React17.useMemo(() => {
628
1040
  if (optionGroups.length > 0) {
629
1041
  return optionGroups.flatMap((group) => group.options);
630
1042
  }
631
1043
  return options;
632
1044
  }, [options, optionGroups]);
633
- const filteredOptions = React9.useMemo(() => {
634
- if (!searchQuery.trim()) {
635
- return allOptions;
636
- }
637
- const query = searchQuery.toLowerCase();
638
- return allOptions.filter((option) => {
639
- const label = typeof option.label === "string" ? option.label : String(option.label);
640
- return label.toLowerCase().includes(query);
641
- });
642
- }, [allOptions, searchQuery]);
643
- const selectedOption = React9.useMemo(() => {
644
- return allOptions.find((opt) => opt.value === value);
645
- }, [allOptions, value]);
646
1045
  const hasValue = Boolean(value);
647
- const handleSelect = (optionValue) => {
648
- onChange(optionValue);
649
- setIsOpen(false);
650
- setSearchQuery("");
651
- setFocusedIndex(-1);
652
- };
653
- const handleClear = (e) => {
654
- e.stopPropagation();
655
- onChange("");
656
- setSearchQuery("");
657
- setFocusedIndex(-1);
1046
+ const handleValueChange = (newValue) => {
1047
+ onChange(newValue);
658
1048
  };
659
- const handleToggle = () => {
660
- if (disabled) return;
661
- const newIsOpen = !isOpen;
662
- setIsOpen(newIsOpen);
663
- if (newIsOpen && searchable && searchInputRef.current) {
664
- setTimeout(() => searchInputRef.current?.focus(), 0);
665
- }
666
- if (newIsOpen) {
1049
+ const handleOpenChange = (open) => {
1050
+ if (open) {
1051
+ if (!hasInteracted) {
1052
+ setHasInteracted(true);
1053
+ }
667
1054
  onFocus?.();
668
- }
669
- };
670
- const handleSearchChange = (e) => {
671
- setSearchQuery(e.target.value);
672
- setFocusedIndex(0);
673
- };
674
- const handleKeyDown = (e) => {
675
- if (disabled) return;
676
- switch (e.key) {
677
- case "ArrowDown":
678
- e.preventDefault();
679
- if (!isOpen) {
680
- setIsOpen(true);
681
- setFocusedIndex(0);
682
- } else {
683
- const enabledOptions = filteredOptions.filter((opt) => !opt.disabled);
684
- if (enabledOptions.length > 0) {
685
- const currentIndexInFiltered = focusedIndex;
686
- const nextIndex = (currentIndexInFiltered + 1) % enabledOptions.length;
687
- setFocusedIndex(filteredOptions.indexOf(enabledOptions[nextIndex]));
688
- }
689
- }
690
- break;
691
- case "ArrowUp":
692
- e.preventDefault();
693
- if (isOpen) {
694
- const enabledOptions = filteredOptions.filter((opt) => !opt.disabled);
695
- if (enabledOptions.length > 0) {
696
- const currentIndexInFiltered = focusedIndex;
697
- const prevIndex = (currentIndexInFiltered - 1 + enabledOptions.length) % enabledOptions.length;
698
- setFocusedIndex(filteredOptions.indexOf(enabledOptions[prevIndex]));
699
- }
700
- }
701
- break;
702
- case "Enter":
703
- e.preventDefault();
704
- if (isOpen && focusedIndex >= 0 && focusedIndex < filteredOptions.length) {
705
- const focusedOption = filteredOptions[focusedIndex];
706
- if (!focusedOption.disabled) {
707
- handleSelect(focusedOption.value);
708
- }
709
- } else if (!isOpen) {
710
- setIsOpen(true);
711
- }
712
- break;
713
- case "Escape":
714
- e.preventDefault();
715
- if (isOpen) {
716
- setIsOpen(false);
717
- setSearchQuery("");
718
- setFocusedIndex(-1);
719
- }
720
- break;
721
- case " ":
722
- if (!isOpen && !searchable) {
723
- e.preventDefault();
724
- setIsOpen(true);
725
- }
726
- break;
727
- default:
728
- if (!searchable && e.key.length === 1 && !e.ctrlKey && !e.metaKey) {
729
- const char = e.key.toLowerCase();
730
- const matchingOption = filteredOptions.find((opt) => {
731
- const label = typeof opt.label === "string" ? opt.label : String(opt.label);
732
- return label.toLowerCase().startsWith(char) && !opt.disabled;
733
- });
734
- if (matchingOption) {
735
- handleSelect(matchingOption.value);
736
- }
737
- }
738
- break;
739
- }
740
- };
741
- const handleBlur = (event) => {
742
- const nextTarget = event?.relatedTarget;
743
- const focusStayedInside = !!triggerRef.current && triggerRef.current.contains(nextTarget) || !!dropdownRef.current && dropdownRef.current.contains(nextTarget);
744
- if (!nextTarget || !focusStayedInside) {
1055
+ } else if (hasInteracted) {
745
1056
  onBlur?.();
746
1057
  }
747
1058
  };
748
- const closeDropdown = React9.useCallback(() => {
749
- setIsOpen(false);
750
- setSearchQuery("");
751
- setFocusedIndex(-1);
752
- onBlur?.();
753
- }, [onBlur]);
754
- useOnClickOutside([triggerRef, dropdownRef], closeDropdown, void 0, {
755
- capture: true
756
- });
757
- const combinedClassName = cn("relative w-full", className);
758
- return /* @__PURE__ */ React9.createElement(
759
- "div",
1059
+ return /* @__PURE__ */ React17.createElement(
1060
+ Select,
760
1061
  {
761
- className: combinedClassName,
762
- onKeyDown: handleKeyDown,
763
- onBlur: handleBlur
1062
+ name,
1063
+ value,
1064
+ onValueChange: handleValueChange,
1065
+ onOpenChange: handleOpenChange,
1066
+ disabled,
1067
+ required
764
1068
  },
765
- /* @__PURE__ */ React9.createElement(
766
- "select",
767
- {
768
- name,
769
- value,
770
- onChange: () => {
771
- },
772
- disabled,
773
- required,
774
- "aria-hidden": "true",
775
- tabIndex: -1,
776
- style: { display: "none" }
777
- },
778
- /* @__PURE__ */ React9.createElement("option", { value: "" }, "Select..."),
779
- allOptions.map((option) => /* @__PURE__ */ React9.createElement("option", { key: option.value, value: option.value }, typeof option.label === "string" ? option.label : option.value))
780
- ),
781
- /* @__PURE__ */ React9.createElement(
782
- "div",
1069
+ /* @__PURE__ */ React17.createElement(
1070
+ SelectTrigger,
783
1071
  {
784
- ref: triggerRef,
785
1072
  className: cn(
786
- "flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm",
787
- "cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
1073
+ // Valid value indicator - ring-2 when has value and no error
788
1074
  !error && hasValue && "ring-2 ring-ring",
789
- disabled && "cursor-not-allowed opacity-50 pointer-events-none",
790
- error && "border-destructive ring-1 ring-destructive"
1075
+ // Error state - handled by SelectTrigger via aria-invalid
1076
+ className
791
1077
  ),
792
- onClick: handleToggle,
793
- role: "combobox",
794
- "aria-expanded": isOpen,
795
- "aria-controls": dropdownId,
796
1078
  "aria-invalid": error || props["aria-invalid"],
797
1079
  "aria-describedby": props["aria-describedby"],
798
- "aria-required": required || props["aria-required"],
799
- "aria-disabled": disabled,
800
- tabIndex: disabled ? -1 : 0
1080
+ "aria-required": required || props["aria-required"]
801
1081
  },
802
- /* @__PURE__ */ React9.createElement("span", { className: "flex items-center flex-1 overflow-hidden text-ellipsis" }, selectedOption ? renderOption ? renderOption(selectedOption) : selectedOption.label : /* @__PURE__ */ React9.createElement("span", { className: "relative" }, placeholder)),
803
- /* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-1 ml-2" }, loading && /* @__PURE__ */ React9.createElement("span", { className: "text-xs" }, "\u23F3"), clearable && value && !disabled && !loading && /* @__PURE__ */ React9.createElement(
804
- "button",
1082
+ /* @__PURE__ */ React17.createElement(SelectValue, { placeholder })
1083
+ ),
1084
+ /* @__PURE__ */ React17.createElement(SelectContent, null, optionGroups.length > 0 ? (
1085
+ // Render grouped options
1086
+ optionGroups.map((group, groupIndex) => /* @__PURE__ */ React17.createElement(SelectGroup, { key: groupIndex }, /* @__PURE__ */ React17.createElement(SelectLabel, null, group.label), group.options.map((option) => /* @__PURE__ */ React17.createElement(
1087
+ SelectItem,
805
1088
  {
806
- type: "button",
807
- className: "flex items-center justify-center h-4 w-4 rounded-sm border-none bg-transparent cursor-pointer text-xs p-0 transition-opacity hover:opacity-70",
808
- onClick: handleClear,
809
- "aria-label": "Clear selection",
810
- tabIndex: -1
1089
+ key: option.value,
1090
+ value: option.value,
1091
+ disabled: option.disabled
811
1092
  },
812
- "\u2715"
813
- ), /* @__PURE__ */ React9.createElement("span", { className: "text-xs leading-none", "aria-hidden": "true" }, isOpen ? "\u25B2" : "\u25BC"))
814
- ),
815
- isOpen && /* @__PURE__ */ React9.createElement(
816
- "div",
817
- {
818
- ref: dropdownRef,
819
- id: dropdownId,
820
- className: "absolute z-50 top-full mt-1 min-w-full overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md",
821
- role: "listbox"
822
- },
823
- searchable && /* @__PURE__ */ React9.createElement("div", { className: "p-2 border-b border-border" }, /* @__PURE__ */ React9.createElement(
824
- "input",
1093
+ renderOption ? renderOption(option) : option.label
1094
+ ))))
1095
+ ) : (
1096
+ // Render flat options
1097
+ allOptions.map((option) => /* @__PURE__ */ React17.createElement(
1098
+ SelectItem,
825
1099
  {
826
- ref: searchInputRef,
827
- type: "text",
828
- className: cn(
829
- "w-full border border-input rounded px-2 py-1 text-sm bg-transparent outline-none focus:ring-1 focus:ring-ring",
830
- INPUT_AUTOFILL_RESET_CLASSES
831
- ),
832
- placeholder: "Search...",
833
- value: searchQuery,
834
- onChange: handleSearchChange,
835
- onClick: (e) => e.stopPropagation(),
836
- "aria-label": "Search options"
837
- }
838
- )),
839
- /* @__PURE__ */ React9.createElement("div", { className: "max-h-64 overflow-y-auto p-1" }, filteredOptions.length === 0 ? /* @__PURE__ */ React9.createElement("div", { className: "py-2 px-3 text-center text-sm " }, "No options found") : optionGroups.length > 0 ? (
840
- // Render grouped options
841
- optionGroups.map((group, groupIndex) => {
842
- const groupOptions = group.options.filter(
843
- (opt) => filteredOptions.includes(opt)
844
- );
845
- if (groupOptions.length === 0) return null;
846
- return /* @__PURE__ */ React9.createElement("div", { key: groupIndex, className: "py-1" }, /* @__PURE__ */ React9.createElement("div", { className: "py-1.5 px-2 text-xs font-semibold " }, group.label), groupOptions.map((option) => {
847
- const globalIndex = filteredOptions.indexOf(option);
848
- const isSelected = value === option.value;
849
- const isFocused = globalIndex === focusedIndex;
850
- const isDisabled = option.disabled;
851
- return /* @__PURE__ */ React9.createElement(
852
- "div",
853
- {
854
- key: option.value,
855
- className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-muted ${isFocused ? "bg-muted" : ""} ${isSelected ? "font-medium bg-muted" : ""} ${isDisabled ? "pointer-events-none opacity-50" : ""}`,
856
- onClick: () => !isDisabled && handleSelect(option.value),
857
- role: "option",
858
- "aria-selected": isSelected,
859
- "aria-disabled": isDisabled
860
- },
861
- renderOption ? renderOption(option) : option.label
862
- );
863
- }));
864
- })
865
- ) : (
866
- // Render flat options
867
- filteredOptions.map((option, index) => {
868
- const isSelected = value === option.value;
869
- const isFocused = index === focusedIndex;
870
- const isDisabled = option.disabled;
871
- return /* @__PURE__ */ React9.createElement(
872
- "div",
873
- {
874
- key: option.value,
875
- className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-muted ${isFocused ? "bg-muted" : ""} ${isSelected ? "font-medium bg-muted" : ""} ${isDisabled ? "pointer-events-none opacity-50" : ""}`,
876
- onClick: () => !isDisabled && handleSelect(option.value),
877
- role: "option",
878
- "aria-selected": isSelected,
879
- "aria-disabled": isDisabled
880
- },
881
- renderOption ? renderOption(option) : option.label
882
- );
883
- })
1100
+ key: option.value,
1101
+ value: option.value,
1102
+ disabled: option.disabled
1103
+ },
1104
+ renderOption ? renderOption(option) : option.label
884
1105
  ))
885
- )
1106
+ ))
886
1107
  );
887
1108
  }
888
- Select.displayName = "Select";
1109
+ Select2.displayName = "Select";
889
1110
  function MultiSelect({
890
1111
  name,
891
1112
  value = [],
@@ -908,20 +1129,21 @@ function MultiSelect({
908
1129
  renderValue,
909
1130
  ...props
910
1131
  }) {
911
- const [isOpen, setIsOpen] = React9.useState(false);
912
- const [searchQuery, setSearchQuery] = React9.useState("");
913
- const [focusedIndex, setFocusedIndex] = React9.useState(-1);
914
- const triggerRef = React9.useRef(null);
915
- const dropdownRef = React9.useRef(null);
916
- const searchInputRef = React9.useRef(null);
1132
+ const [isOpen, setIsOpen] = React17.useState(false);
1133
+ const [searchQuery, setSearchQuery] = React17.useState("");
1134
+ const [focusedIndex, setFocusedIndex] = React17.useState(-1);
1135
+ const [hasInteracted, setHasInteracted] = React17.useState(false);
1136
+ const triggerRef = React17.useRef(null);
1137
+ const dropdownRef = React17.useRef(null);
1138
+ const searchInputRef = React17.useRef(null);
917
1139
  const dropdownId = `${name}-dropdown`;
918
- const allOptions = React9.useMemo(() => {
1140
+ const allOptions = React17.useMemo(() => {
919
1141
  if (optionGroups.length > 0) {
920
1142
  return optionGroups.flatMap((group) => group.options);
921
1143
  }
922
1144
  return options;
923
1145
  }, [options, optionGroups]);
924
- const filteredOptions = React9.useMemo(() => {
1146
+ const filteredOptions = React17.useMemo(() => {
925
1147
  if (!searchQuery.trim()) {
926
1148
  return allOptions;
927
1149
  }
@@ -931,11 +1153,11 @@ function MultiSelect({
931
1153
  return label.toLowerCase().includes(query);
932
1154
  });
933
1155
  }, [allOptions, searchQuery]);
934
- const selectedOptions = React9.useMemo(() => {
1156
+ const selectedOptions = React17.useMemo(() => {
935
1157
  return allOptions.filter((opt) => value.includes(opt.value));
936
1158
  }, [allOptions, value]);
937
1159
  const hasValue = value.length > 0;
938
- const isMaxReached = React9.useMemo(() => {
1160
+ const isMaxReached = React17.useMemo(() => {
939
1161
  return maxSelections !== void 0 && value.length >= maxSelections;
940
1162
  }, [maxSelections, value.length]);
941
1163
  const handleToggleOption = (optionValue) => {
@@ -969,6 +1191,9 @@ function MultiSelect({
969
1191
  if (disabled) return;
970
1192
  const newIsOpen = !isOpen;
971
1193
  setIsOpen(newIsOpen);
1194
+ if (newIsOpen && !hasInteracted) {
1195
+ setHasInteracted(true);
1196
+ }
972
1197
  if (newIsOpen && searchable && searchInputRef.current) {
973
1198
  setTimeout(() => searchInputRef.current?.focus(), 0);
974
1199
  }
@@ -1048,24 +1273,27 @@ function MultiSelect({
1048
1273
  onBlur?.();
1049
1274
  }
1050
1275
  };
1051
- const closeDropdown = React9.useCallback(() => {
1276
+ const closeDropdown = React17.useCallback(() => {
1277
+ if (!isOpen) return;
1052
1278
  setIsOpen(false);
1053
1279
  setSearchQuery("");
1054
1280
  setFocusedIndex(-1);
1055
- onBlur?.();
1056
- }, [onBlur]);
1281
+ if (hasInteracted) {
1282
+ onBlur?.();
1283
+ }
1284
+ }, [isOpen, hasInteracted, onBlur]);
1057
1285
  useOnClickOutside([triggerRef, dropdownRef], closeDropdown, void 0, {
1058
1286
  capture: true
1059
1287
  });
1060
1288
  const combinedClassName = cn("relative w-full", className);
1061
- return /* @__PURE__ */ React9.createElement(
1289
+ return /* @__PURE__ */ React17.createElement(
1062
1290
  "div",
1063
1291
  {
1064
1292
  className: combinedClassName,
1065
1293
  onKeyDown: handleKeyDown,
1066
1294
  onBlur: handleBlur
1067
1295
  },
1068
- /* @__PURE__ */ React9.createElement(
1296
+ /* @__PURE__ */ React17.createElement(
1069
1297
  "select",
1070
1298
  {
1071
1299
  name,
@@ -1079,10 +1307,10 @@ function MultiSelect({
1079
1307
  style: { display: "none" },
1080
1308
  multiple: true
1081
1309
  },
1082
- /* @__PURE__ */ React9.createElement("option", { value: "" }, "Select..."),
1083
- allOptions.map((option) => /* @__PURE__ */ React9.createElement("option", { key: option.value, value: option.value }, typeof option.label === "string" ? option.label : option.value))
1310
+ /* @__PURE__ */ React17.createElement("option", { value: "" }, "Select..."),
1311
+ allOptions.map((option) => /* @__PURE__ */ React17.createElement("option", { key: option.value, value: option.value }, typeof option.label === "string" ? option.label : option.value))
1084
1312
  ),
1085
- /* @__PURE__ */ React9.createElement(
1313
+ /* @__PURE__ */ React17.createElement(
1086
1314
  "div",
1087
1315
  {
1088
1316
  ref: triggerRef,
@@ -1103,13 +1331,13 @@ function MultiSelect({
1103
1331
  "aria-disabled": disabled,
1104
1332
  tabIndex: disabled ? -1 : 0
1105
1333
  },
1106
- /* @__PURE__ */ React9.createElement("div", { className: "flex items-center flex-1 overflow-hidden" }, selectedOptions.length > 0 ? /* @__PURE__ */ React9.createElement("div", { className: "flex flex-wrap gap-1" }, selectedOptions.map((option) => /* @__PURE__ */ React9.createElement(
1334
+ /* @__PURE__ */ React17.createElement("div", { className: "flex items-center flex-1 overflow-hidden" }, selectedOptions.length > 0 ? /* @__PURE__ */ React17.createElement("div", { className: "flex flex-wrap gap-1" }, selectedOptions.map((option) => /* @__PURE__ */ React17.createElement(
1107
1335
  "span",
1108
1336
  {
1109
1337
  key: option.value,
1110
1338
  className: "inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium"
1111
1339
  },
1112
- renderValue ? renderValue(option) : /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement("span", { className: "max-w-40 overflow-hidden text-ellipsis whitespace-nowrap" }, option.label), !disabled && /* @__PURE__ */ React9.createElement(
1340
+ renderValue ? renderValue(option) : /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("span", { className: "max-w-40 overflow-hidden text-ellipsis whitespace-nowrap" }, option.label), !disabled && /* @__PURE__ */ React17.createElement(
1113
1341
  "button",
1114
1342
  {
1115
1343
  type: "button",
@@ -1120,8 +1348,8 @@ function MultiSelect({
1120
1348
  },
1121
1349
  "\u2715"
1122
1350
  ))
1123
- ))) : /* @__PURE__ */ React9.createElement("span", { className: "relative" }, placeholder)),
1124
- /* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-1 ml-2" }, loading && /* @__PURE__ */ React9.createElement("span", { className: "text-xs" }, "\u23F3"), clearable && value.length > 0 && !disabled && !loading && /* @__PURE__ */ React9.createElement(
1351
+ ))) : /* @__PURE__ */ React17.createElement("span", { className: "relative" }, placeholder)),
1352
+ /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-1 ml-2" }, loading && /* @__PURE__ */ React17.createElement("span", { className: "text-xs" }, "\u23F3"), clearable && value.length > 0 && !disabled && !loading && /* @__PURE__ */ React17.createElement(
1125
1353
  "button",
1126
1354
  {
1127
1355
  type: "button",
@@ -1131,9 +1359,9 @@ function MultiSelect({
1131
1359
  tabIndex: -1
1132
1360
  },
1133
1361
  "\u2715"
1134
- ), /* @__PURE__ */ React9.createElement("span", { className: "text-xs leading-none", "aria-hidden": "true" }, isOpen ? "\u25B2" : "\u25BC"))
1362
+ ), /* @__PURE__ */ React17.createElement("span", { className: "text-xs leading-none", "aria-hidden": "true" }, isOpen ? "\u25B2" : "\u25BC"))
1135
1363
  ),
1136
- isOpen && /* @__PURE__ */ React9.createElement(
1364
+ isOpen && /* @__PURE__ */ React17.createElement(
1137
1365
  "div",
1138
1366
  {
1139
1367
  ref: dropdownRef,
@@ -1142,7 +1370,7 @@ function MultiSelect({
1142
1370
  role: "listbox",
1143
1371
  "aria-multiselectable": "true"
1144
1372
  },
1145
- searchable && /* @__PURE__ */ React9.createElement("div", { className: "p-2 border-b border-border" }, /* @__PURE__ */ React9.createElement(
1373
+ searchable && /* @__PURE__ */ React17.createElement("div", { className: "p-2 border-b border-border" }, /* @__PURE__ */ React17.createElement(
1146
1374
  "input",
1147
1375
  {
1148
1376
  ref: searchInputRef,
@@ -1158,7 +1386,7 @@ function MultiSelect({
1158
1386
  "aria-label": "Search options"
1159
1387
  }
1160
1388
  )),
1161
- showSelectAll && filteredOptions.length > 0 && /* @__PURE__ */ React9.createElement("div", { className: "flex gap-2 p-2 border-b border-border" }, /* @__PURE__ */ React9.createElement(
1389
+ showSelectAll && filteredOptions.length > 0 && /* @__PURE__ */ React17.createElement("div", { className: "flex gap-2 p-2 border-b border-border" }, /* @__PURE__ */ React17.createElement(
1162
1390
  "button",
1163
1391
  {
1164
1392
  type: "button",
@@ -1167,7 +1395,7 @@ function MultiSelect({
1167
1395
  disabled
1168
1396
  },
1169
1397
  "Select All"
1170
- ), value.length > 0 && /* @__PURE__ */ React9.createElement(
1398
+ ), value.length > 0 && /* @__PURE__ */ React17.createElement(
1171
1399
  "button",
1172
1400
  {
1173
1401
  type: "button",
@@ -1177,20 +1405,20 @@ function MultiSelect({
1177
1405
  },
1178
1406
  "Clear All"
1179
1407
  )),
1180
- isMaxReached && /* @__PURE__ */ React9.createElement("div", { className: "px-2 py-1 text-xs font-medium text-amber-600 bg-destructive/80 text-destructive-foreground border-b border-destructive" }, "Maximum ", maxSelections, " selection", maxSelections !== 1 ? "s" : "", " ", "reached"),
1181
- /* @__PURE__ */ React9.createElement("div", { className: "max-h-64 overflow-y-auto p-1" }, filteredOptions.length === 0 ? /* @__PURE__ */ React9.createElement("div", { className: "px-2 py-1 text-center text-sm" }, "No options found") : optionGroups.length > 0 ? (
1408
+ isMaxReached && /* @__PURE__ */ React17.createElement("div", { className: "px-2 py-1 text-xs font-medium text-amber-600 bg-destructive/80 text-destructive-foreground border-b border-destructive" }, "Maximum ", maxSelections, " selection", maxSelections !== 1 ? "s" : "", " ", "reached"),
1409
+ /* @__PURE__ */ React17.createElement("div", { className: "max-h-64 overflow-y-auto p-1" }, filteredOptions.length === 0 ? /* @__PURE__ */ React17.createElement("div", { className: "px-2 py-1 text-center text-sm" }, "No options found") : optionGroups.length > 0 ? (
1182
1410
  // Render grouped options
1183
1411
  optionGroups.map((group, groupIndex) => {
1184
1412
  const groupOptions = group.options.filter(
1185
1413
  (opt) => filteredOptions.includes(opt)
1186
1414
  );
1187
1415
  if (groupOptions.length === 0) return null;
1188
- return /* @__PURE__ */ React9.createElement("div", { key: groupIndex, className: "py-1" }, /* @__PURE__ */ React9.createElement("div", { className: "py-1.5 px-2 text-xs font-semibold " }, group.label), groupOptions.map((option) => {
1416
+ return /* @__PURE__ */ React17.createElement("div", { key: groupIndex, className: "py-1" }, /* @__PURE__ */ React17.createElement("div", { className: "py-1.5 px-2 text-xs font-semibold " }, group.label), groupOptions.map((option) => {
1189
1417
  const globalIndex = filteredOptions.indexOf(option);
1190
1418
  const isSelected = value.includes(option.value);
1191
1419
  const isFocused = globalIndex === focusedIndex;
1192
1420
  const isDisabled = option.disabled || isMaxReached && !isSelected;
1193
- return /* @__PURE__ */ React9.createElement(
1421
+ return /* @__PURE__ */ React17.createElement(
1194
1422
  "div",
1195
1423
  {
1196
1424
  key: option.value,
@@ -1205,8 +1433,8 @@ function MultiSelect({
1205
1433
  "aria-selected": isSelected,
1206
1434
  "aria-disabled": isDisabled
1207
1435
  },
1208
- /* @__PURE__ */ React9.createElement("span", { className: "text-base leading-none" }, isSelected ? "\u2611" : "\u2610"),
1209
- /* @__PURE__ */ React9.createElement("span", { className: "flex-1" }, renderOption ? renderOption(option) : option.label)
1436
+ /* @__PURE__ */ React17.createElement("span", { className: "text-base leading-none" }, isSelected ? "\u2611" : "\u2610"),
1437
+ /* @__PURE__ */ React17.createElement("span", { className: "flex-1" }, renderOption ? renderOption(option) : option.label)
1210
1438
  );
1211
1439
  }));
1212
1440
  })
@@ -1216,7 +1444,7 @@ function MultiSelect({
1216
1444
  const isSelected = value.includes(option.value);
1217
1445
  const isFocused = index === focusedIndex;
1218
1446
  const isDisabled = option.disabled || isMaxReached && !isSelected;
1219
- return /* @__PURE__ */ React9.createElement(
1447
+ return /* @__PURE__ */ React17.createElement(
1220
1448
  "div",
1221
1449
  {
1222
1450
  key: option.value,
@@ -1231,8 +1459,8 @@ function MultiSelect({
1231
1459
  "aria-selected": isSelected,
1232
1460
  "aria-disabled": isDisabled
1233
1461
  },
1234
- /* @__PURE__ */ React9.createElement("span", { className: "text-base leading-none" }, isSelected ? "\u2611" : "\u2610"),
1235
- /* @__PURE__ */ React9.createElement("span", { className: "flex-1" }, renderOption ? renderOption(option) : option.label)
1462
+ /* @__PURE__ */ React17.createElement("span", { className: "text-base leading-none" }, isSelected ? "\u2611" : "\u2610"),
1463
+ /* @__PURE__ */ React17.createElement("span", { className: "flex-1" }, renderOption ? renderOption(option) : option.label)
1236
1464
  );
1237
1465
  })
1238
1466
  ))
@@ -1265,14 +1493,14 @@ function FileInput({
1265
1493
  onFileRemove,
1266
1494
  ...props
1267
1495
  }) {
1268
- const inputRef = React9.useRef(null);
1269
- const [dragActive, setDragActive] = React9.useState(false);
1270
- const [cropperOpen, setCropperOpen] = React9.useState(false);
1271
- const [imageToCrop, setImageToCrop] = React9.useState(null);
1272
- const [crop, setCrop] = React9.useState({ x: 0, y: 0 });
1273
- const [zoom, setZoom] = React9.useState(1);
1274
- const [croppedAreaPixels, setCroppedAreaPixels] = React9.useState(null);
1275
- const validateFile = React9.useCallback(
1496
+ const inputRef = React17.useRef(null);
1497
+ const [dragActive, setDragActive] = React17.useState(false);
1498
+ const [cropperOpen, setCropperOpen] = React17.useState(false);
1499
+ const [imageToCrop, setImageToCrop] = React17.useState(null);
1500
+ const [crop, setCrop] = React17.useState({ x: 0, y: 0 });
1501
+ const [zoom, setZoom] = React17.useState(1);
1502
+ const [croppedAreaPixels, setCroppedAreaPixels] = React17.useState(null);
1503
+ const validateFile = React17.useCallback(
1276
1504
  (file) => {
1277
1505
  if (accept) {
1278
1506
  const acceptedTypes = accept.split(",").map((t) => t.trim());
@@ -1307,7 +1535,7 @@ function FileInput({
1307
1535
  },
1308
1536
  [accept, maxSize]
1309
1537
  );
1310
- const handleFiles = React9.useCallback(
1538
+ const handleFiles = React17.useCallback(
1311
1539
  (fileList) => {
1312
1540
  if (!fileList || fileList.length === 0) return;
1313
1541
  const newFiles = Array.from(fileList);
@@ -1358,7 +1586,7 @@ function FileInput({
1358
1586
  onValidationError
1359
1587
  ]
1360
1588
  );
1361
- const createCroppedImage = React9.useCallback(
1589
+ const createCroppedImage = React17.useCallback(
1362
1590
  async (imageUrl, cropArea) => {
1363
1591
  return new Promise((resolve, reject) => {
1364
1592
  const image = new Image();
@@ -1402,7 +1630,7 @@ function FileInput({
1402
1630
  },
1403
1631
  []
1404
1632
  );
1405
- const handleCropSave = React9.useCallback(async () => {
1633
+ const handleCropSave = React17.useCallback(async () => {
1406
1634
  if (!imageToCrop || !croppedAreaPixels) return;
1407
1635
  try {
1408
1636
  const croppedBlob = await createCroppedImage(
@@ -1435,7 +1663,7 @@ function FileInput({
1435
1663
  onChange,
1436
1664
  multiple
1437
1665
  ]);
1438
- const handleCropCancel = React9.useCallback(() => {
1666
+ const handleCropCancel = React17.useCallback(() => {
1439
1667
  if (imageToCrop) {
1440
1668
  URL.revokeObjectURL(imageToCrop.url);
1441
1669
  }
@@ -1445,13 +1673,13 @@ function FileInput({
1445
1673
  setZoom(1);
1446
1674
  setCroppedAreaPixels(null);
1447
1675
  }, [imageToCrop]);
1448
- const onCropChange = React9.useCallback((crop2) => {
1676
+ const onCropChange = React17.useCallback((crop2) => {
1449
1677
  setCrop(crop2);
1450
1678
  }, []);
1451
- const onZoomChange = React9.useCallback((zoom2) => {
1679
+ const onZoomChange = React17.useCallback((zoom2) => {
1452
1680
  setZoom(zoom2);
1453
1681
  }, []);
1454
- const onCropCompleteInternal = React9.useCallback(
1682
+ const onCropCompleteInternal = React17.useCallback(
1455
1683
  (_, croppedAreaPixels2) => {
1456
1684
  setCroppedAreaPixels(croppedAreaPixels2);
1457
1685
  },
@@ -1512,7 +1740,7 @@ function FileInput({
1512
1740
  }
1513
1741
  return null;
1514
1742
  };
1515
- React9.useEffect(() => {
1743
+ React17.useEffect(() => {
1516
1744
  return () => {
1517
1745
  value.forEach((file) => {
1518
1746
  const previewUrl = getPreviewUrl(file);
@@ -1526,7 +1754,7 @@ function FileInput({
1526
1754
  };
1527
1755
  }, [value, imageToCrop]);
1528
1756
  const combinedClassName = `${className}`.trim();
1529
- return /* @__PURE__ */ React9.createElement("div", { className: combinedClassName }, /* @__PURE__ */ React9.createElement(
1757
+ return /* @__PURE__ */ React17.createElement("div", { className: combinedClassName }, /* @__PURE__ */ React17.createElement(
1530
1758
  "input",
1531
1759
  {
1532
1760
  ref: inputRef,
@@ -1543,7 +1771,7 @@ function FileInput({
1543
1771
  "aria-required": required || props["aria-required"],
1544
1772
  style: { display: "none" }
1545
1773
  }
1546
- ), /* @__PURE__ */ React9.createElement(
1774
+ ), /* @__PURE__ */ React17.createElement(
1547
1775
  "div",
1548
1776
  {
1549
1777
  className: `flex min-h-32 w-full cursor-pointer items-center justify-center rounded-md border-2 border-dashed border-input bg-transparent p-6 transition-colors hover:bg-primary/50 hover:border-ring ${dragActive ? "bg-primary text-primary-foreground border-ring" : ""} ${disabled ? "cursor-not-allowed opacity-50" : ""} ${error ? "border-destructive" : ""}`,
@@ -1558,7 +1786,7 @@ function FileInput({
1558
1786
  "aria-label": placeholder,
1559
1787
  "aria-disabled": disabled
1560
1788
  },
1561
- /* @__PURE__ */ React9.createElement("div", { className: "flex flex-col items-center gap-2 text-center" }, /* @__PURE__ */ React9.createElement(
1789
+ /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col items-center gap-2 text-center" }, /* @__PURE__ */ React17.createElement(
1562
1790
  "svg",
1563
1791
  {
1564
1792
  width: "48",
@@ -1571,19 +1799,19 @@ function FileInput({
1571
1799
  strokeLinejoin: "round",
1572
1800
  "aria-hidden": "true"
1573
1801
  },
1574
- /* @__PURE__ */ React9.createElement("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1575
- /* @__PURE__ */ React9.createElement("polyline", { points: "17 8 12 3 7 8" }),
1576
- /* @__PURE__ */ React9.createElement("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
1577
- ), /* @__PURE__ */ React9.createElement("p", { className: "text-sm font-medium" }, value.length > 0 ? `${value.length} file(s) selected` : placeholder), accept && /* @__PURE__ */ React9.createElement("p", { className: "text-xs" }, "Accepted: ", accept), maxSize && /* @__PURE__ */ React9.createElement("p", { className: "text-xs " }, "Max size: ", formatFileSize(maxSize)))
1578
- ), value.length > 0 && /* @__PURE__ */ React9.createElement("ul", { className: "flex flex-col gap-2 mt-4", role: "list" }, value.map((file, index) => {
1802
+ /* @__PURE__ */ React17.createElement("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1803
+ /* @__PURE__ */ React17.createElement("polyline", { points: "17 8 12 3 7 8" }),
1804
+ /* @__PURE__ */ React17.createElement("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
1805
+ ), /* @__PURE__ */ React17.createElement("p", { className: "text-sm font-medium" }, value.length > 0 ? `${value.length} file(s) selected` : placeholder), accept && /* @__PURE__ */ React17.createElement("p", { className: "text-xs" }, "Accepted: ", accept), maxSize && /* @__PURE__ */ React17.createElement("p", { className: "text-xs " }, "Max size: ", formatFileSize(maxSize)))
1806
+ ), value.length > 0 && /* @__PURE__ */ React17.createElement("ul", { className: "flex flex-col gap-2 mt-4", role: "list" }, value.map((file, index) => {
1579
1807
  const previewUrl = showPreview ? getPreviewUrl(file) : null;
1580
- return /* @__PURE__ */ React9.createElement(
1808
+ return /* @__PURE__ */ React17.createElement(
1581
1809
  "li",
1582
1810
  {
1583
1811
  key: `${file.name}-${index}`,
1584
1812
  className: "flex items-center gap-3 p-3 rounded-md border border-border bg-card text-card-foreground hover:bg-primary/50 transition-colors"
1585
1813
  },
1586
- previewUrl && /* @__PURE__ */ React9.createElement(
1814
+ previewUrl && /* @__PURE__ */ React17.createElement(
1587
1815
  "img",
1588
1816
  {
1589
1817
  src: previewUrl,
@@ -1593,7 +1821,7 @@ function FileInput({
1593
1821
  height: "48"
1594
1822
  }
1595
1823
  ),
1596
- /* @__PURE__ */ React9.createElement("div", { className: "flex flex-col flex-1 min-w-0" }, /* @__PURE__ */ React9.createElement("span", { className: "text-sm font-medium truncate" }, file.name), /* @__PURE__ */ React9.createElement("span", { className: "text-xs" }, formatFileSize(file.size)), showProgress && uploadProgress[file.name] !== void 0 && /* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ React9.createElement(
1824
+ /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col flex-1 min-w-0" }, /* @__PURE__ */ React17.createElement("span", { className: "text-sm font-medium truncate" }, file.name), /* @__PURE__ */ React17.createElement("span", { className: "text-xs" }, formatFileSize(file.size)), showProgress && uploadProgress[file.name] !== void 0 && /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ React17.createElement(
1597
1825
  "div",
1598
1826
  {
1599
1827
  className: "h-1.5 bg-muted rounded-full overflow-hidden flex-1",
@@ -1603,15 +1831,15 @@ function FileInput({
1603
1831
  "aria-valuemax": 100,
1604
1832
  "aria-label": `Upload progress: ${uploadProgress[file.name]}%`
1605
1833
  },
1606
- /* @__PURE__ */ React9.createElement(
1834
+ /* @__PURE__ */ React17.createElement(
1607
1835
  "div",
1608
1836
  {
1609
1837
  className: "h-full bg-primary transition-all",
1610
1838
  style: { width: `${uploadProgress[file.name]}%` }
1611
1839
  }
1612
1840
  )
1613
- ), /* @__PURE__ */ React9.createElement("span", { className: "text-xs " }, uploadProgress[file.name], "%"))),
1614
- enableCropping && file.type.startsWith("image/") && /* @__PURE__ */ React9.createElement(
1841
+ ), /* @__PURE__ */ React17.createElement("span", { className: "text-xs " }, uploadProgress[file.name], "%"))),
1842
+ enableCropping && file.type.startsWith("image/") && /* @__PURE__ */ React17.createElement(
1615
1843
  "button",
1616
1844
  {
1617
1845
  type: "button",
@@ -1623,7 +1851,7 @@ function FileInput({
1623
1851
  className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
1624
1852
  "aria-label": `Crop ${file.name}`
1625
1853
  },
1626
- /* @__PURE__ */ React9.createElement(
1854
+ /* @__PURE__ */ React17.createElement(
1627
1855
  "svg",
1628
1856
  {
1629
1857
  width: "20",
@@ -1636,11 +1864,11 @@ function FileInput({
1636
1864
  strokeLinejoin: "round",
1637
1865
  "aria-hidden": "true"
1638
1866
  },
1639
- /* @__PURE__ */ React9.createElement("path", { d: "M6.13 1L6 16a2 2 0 0 0 2 2h15" }),
1640
- /* @__PURE__ */ React9.createElement("path", { d: "M1 6.13L16 6a2 2 0 0 1 2 2v15" })
1867
+ /* @__PURE__ */ React17.createElement("path", { d: "M6.13 1L6 16a2 2 0 0 0 2 2h15" }),
1868
+ /* @__PURE__ */ React17.createElement("path", { d: "M1 6.13L16 6a2 2 0 0 1 2 2v15" })
1641
1869
  )
1642
1870
  ),
1643
- /* @__PURE__ */ React9.createElement(
1871
+ /* @__PURE__ */ React17.createElement(
1644
1872
  "button",
1645
1873
  {
1646
1874
  type: "button",
@@ -1652,7 +1880,7 @@ function FileInput({
1652
1880
  className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
1653
1881
  "aria-label": `Remove ${file.name}`
1654
1882
  },
1655
- /* @__PURE__ */ React9.createElement(
1883
+ /* @__PURE__ */ React17.createElement(
1656
1884
  "svg",
1657
1885
  {
1658
1886
  width: "20",
@@ -1665,19 +1893,19 @@ function FileInput({
1665
1893
  strokeLinejoin: "round",
1666
1894
  "aria-hidden": "true"
1667
1895
  },
1668
- /* @__PURE__ */ React9.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1669
- /* @__PURE__ */ React9.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1896
+ /* @__PURE__ */ React17.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1897
+ /* @__PURE__ */ React17.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1670
1898
  )
1671
1899
  )
1672
1900
  );
1673
- })), cropperOpen && imageToCrop && /* @__PURE__ */ React9.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center" }, /* @__PURE__ */ React9.createElement(
1901
+ })), cropperOpen && imageToCrop && /* @__PURE__ */ React17.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center" }, /* @__PURE__ */ React17.createElement(
1674
1902
  "div",
1675
1903
  {
1676
1904
  className: "absolute inset-0 bg-black/50",
1677
1905
  onClick: handleCropCancel,
1678
1906
  "aria-label": "Close cropper"
1679
1907
  }
1680
- ), /* @__PURE__ */ React9.createElement("div", { className: "relative bg-popover border border-border rounded-lg shadow-lg max-w-3xl w-full mx-4" }, /* @__PURE__ */ React9.createElement("div", { className: "flex items-center justify-between p-4 border-b border-border" }, /* @__PURE__ */ React9.createElement("h3", { className: "text-lg font-semibold" }, "Crop Image"), /* @__PURE__ */ React9.createElement(
1908
+ ), /* @__PURE__ */ React17.createElement("div", { className: "relative bg-popover border border-border rounded-lg shadow-lg max-w-3xl w-full mx-4" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between p-4 border-b border-border" }, /* @__PURE__ */ React17.createElement("h3", { className: "text-lg font-semibold" }, "Crop Image"), /* @__PURE__ */ React17.createElement(
1681
1909
  "button",
1682
1910
  {
1683
1911
  type: "button",
@@ -1686,7 +1914,7 @@ function FileInput({
1686
1914
  "aria-label": "Close"
1687
1915
  },
1688
1916
  "\u2715"
1689
- )), /* @__PURE__ */ React9.createElement("div", { className: "p-4" }, /* @__PURE__ */ React9.createElement(
1917
+ )), /* @__PURE__ */ React17.createElement("div", { className: "p-4" }, /* @__PURE__ */ React17.createElement(
1690
1918
  "div",
1691
1919
  {
1692
1920
  className: "relative w-full h-96 bg-muted rounded-md overflow-hidden",
@@ -1708,7 +1936,7 @@ function FileInput({
1708
1936
  document.addEventListener("mouseup", handleMouseUp);
1709
1937
  }
1710
1938
  },
1711
- /* @__PURE__ */ React9.createElement(
1939
+ /* @__PURE__ */ React17.createElement(
1712
1940
  "img",
1713
1941
  {
1714
1942
  src: imageToCrop.url,
@@ -1743,7 +1971,7 @@ function FileInput({
1743
1971
  }
1744
1972
  }
1745
1973
  ),
1746
- /* @__PURE__ */ React9.createElement(
1974
+ /* @__PURE__ */ React17.createElement(
1747
1975
  "div",
1748
1976
  {
1749
1977
  className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 border-2 border-primary rounded pointer-events-none",
@@ -1752,9 +1980,9 @@ function FileInput({
1752
1980
  aspectRatio: cropAspectRatio ? String(cropAspectRatio) : void 0
1753
1981
  }
1754
1982
  },
1755
- /* @__PURE__ */ React9.createElement("div", { className: "absolute inset-0 grid grid-cols-3 grid-rows-3" }, /* @__PURE__ */ React9.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React9.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React9.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React9.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React9.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React9.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React9.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React9.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React9.createElement("div", null))
1983
+ /* @__PURE__ */ React17.createElement("div", { className: "absolute inset-0 grid grid-cols-3 grid-rows-3" }, /* @__PURE__ */ React17.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React17.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React17.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React17.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React17.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React17.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React17.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React17.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React17.createElement("div", null))
1756
1984
  )
1757
- ), /* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-3 mt-4" }, /* @__PURE__ */ React9.createElement(
1985
+ ), /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-3 mt-4" }, /* @__PURE__ */ React17.createElement(
1758
1986
  "label",
1759
1987
  {
1760
1988
  htmlFor: "zoom-slider",
@@ -1763,7 +1991,7 @@ function FileInput({
1763
1991
  "Zoom: ",
1764
1992
  zoom.toFixed(1),
1765
1993
  "x"
1766
- ), /* @__PURE__ */ React9.createElement(
1994
+ ), /* @__PURE__ */ React17.createElement(
1767
1995
  "input",
1768
1996
  {
1769
1997
  id: "zoom-slider",
@@ -1776,7 +2004,7 @@ function FileInput({
1776
2004
  className: "flex-1 h-2 bg-muted rounded-lg appearance-none cursor-pointer",
1777
2005
  "aria-label": "Zoom level"
1778
2006
  }
1779
- ))), /* @__PURE__ */ React9.createElement("div", { className: "flex items-center justify-end gap-2 p-4 border-t border-border" }, /* @__PURE__ */ React9.createElement(
2007
+ ))), /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-end gap-2 p-4 border-t border-border" }, /* @__PURE__ */ React17.createElement(
1780
2008
  "button",
1781
2009
  {
1782
2010
  type: "button",
@@ -1784,7 +2012,7 @@ function FileInput({
1784
2012
  onClick: handleCropCancel
1785
2013
  },
1786
2014
  "Cancel"
1787
- ), /* @__PURE__ */ React9.createElement(
2015
+ ), /* @__PURE__ */ React17.createElement(
1788
2016
  "button",
1789
2017
  {
1790
2018
  type: "button",
@@ -1826,13 +2054,14 @@ function DatePicker({
1826
2054
  showIcon = true,
1827
2055
  ...props
1828
2056
  }) {
1829
- const [isOpen, setIsOpen] = React9.useState(false);
1830
- const [selectedMonth, setSelectedMonth] = React9.useState(
2057
+ const [isOpen, setIsOpen] = React17.useState(false);
2058
+ const [hasInteracted, setHasInteracted] = React17.useState(false);
2059
+ const [selectedMonth, setSelectedMonth] = React17.useState(
1831
2060
  value || /* @__PURE__ */ new Date()
1832
2061
  );
1833
- const inputRef = React9.useRef(null);
1834
- const dropdownRef = React9.useRef(null);
1835
- React9.useEffect(() => {
2062
+ const inputRef = React17.useRef(null);
2063
+ const dropdownRef = React17.useRef(null);
2064
+ React17.useEffect(() => {
1836
2065
  if (value) {
1837
2066
  setSelectedMonth(value);
1838
2067
  }
@@ -1849,7 +2078,13 @@ function DatePicker({
1849
2078
  };
1850
2079
  const handleToggle = () => {
1851
2080
  if (disabled) return;
1852
- setIsOpen((prev) => !prev);
2081
+ setIsOpen((prev) => {
2082
+ const newIsOpen = !prev;
2083
+ if (newIsOpen && !hasInteracted) {
2084
+ setHasInteracted(true);
2085
+ }
2086
+ return newIsOpen;
2087
+ });
1853
2088
  };
1854
2089
  const isDisabled = (date) => {
1855
2090
  if (minDate && date < minDate) return true;
@@ -1858,10 +2093,13 @@ function DatePicker({
1858
2093
  if (isDateDisabled && isDateDisabled(date)) return true;
1859
2094
  return false;
1860
2095
  };
1861
- const closeCalendar = React9.useCallback(() => {
2096
+ const closeCalendar = React17.useCallback(() => {
2097
+ if (!isOpen) return;
1862
2098
  setIsOpen(false);
1863
- onBlur?.();
1864
- }, [onBlur]);
2099
+ if (hasInteracted) {
2100
+ onBlur?.();
2101
+ }
2102
+ }, [isOpen, hasInteracted, onBlur]);
1865
2103
  useOnClickOutside([inputRef, dropdownRef], closeCalendar, void 0, {
1866
2104
  capture: true
1867
2105
  });
@@ -1909,7 +2147,7 @@ function DatePicker({
1909
2147
  const handleNextMonth = () => {
1910
2148
  setSelectedMonth(new Date(year, month + 1, 1));
1911
2149
  };
1912
- return /* @__PURE__ */ React9.createElement("div", { role: "grid", "aria-label": "Calendar", className: "w-[248px] max-w-full" }, /* @__PURE__ */ React9.createElement("div", { className: "flex items-center justify-between pb-3" }, /* @__PURE__ */ React9.createElement(
2150
+ return /* @__PURE__ */ React17.createElement("div", { role: "grid", "aria-label": "Calendar", className: "w-[248px] max-w-full" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between pb-3" }, /* @__PURE__ */ React17.createElement(
1913
2151
  "button",
1914
2152
  {
1915
2153
  type: "button",
@@ -1918,7 +2156,7 @@ function DatePicker({
1918
2156
  "aria-label": "Previous month"
1919
2157
  },
1920
2158
  "\u2039"
1921
- ), /* @__PURE__ */ React9.createElement("div", { className: "font-medium text-sm" }, `${monthNames[month]} ${year}`), /* @__PURE__ */ React9.createElement(
2159
+ ), /* @__PURE__ */ React17.createElement("div", { className: "font-medium text-sm" }, `${monthNames[month]} ${year}`), /* @__PURE__ */ React17.createElement(
1922
2160
  "button",
1923
2161
  {
1924
2162
  type: "button",
@@ -1927,13 +2165,13 @@ function DatePicker({
1927
2165
  "aria-label": "Next month"
1928
2166
  },
1929
2167
  "\u203A"
1930
- )), /* @__PURE__ */ React9.createElement(
2168
+ )), /* @__PURE__ */ React17.createElement(
1931
2169
  "div",
1932
2170
  {
1933
2171
  className: "grid gap-1 text-xs text-muted-foreground",
1934
2172
  style: dayGridStyle
1935
2173
  },
1936
- ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React9.createElement(
2174
+ ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React17.createElement(
1937
2175
  "div",
1938
2176
  {
1939
2177
  key: day,
@@ -1941,14 +2179,14 @@ function DatePicker({
1941
2179
  },
1942
2180
  day
1943
2181
  ))
1944
- ), /* @__PURE__ */ React9.createElement("div", { className: "grid gap-1", style: dayGridStyle }, days.map((date, index) => {
2182
+ ), /* @__PURE__ */ React17.createElement("div", { className: "grid gap-1", style: dayGridStyle }, days.map((date, index) => {
1945
2183
  if (!date) {
1946
- return /* @__PURE__ */ React9.createElement("div", { key: `empty-${index}`, className: "h-8 w-8" });
2184
+ return /* @__PURE__ */ React17.createElement("div", { key: `empty-${index}`, className: "h-8 w-8" });
1947
2185
  }
1948
2186
  const isSelected = value && date.toDateString() === value.toDateString();
1949
2187
  const isToday = date.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
1950
2188
  const disabled2 = isDisabled(date);
1951
- return /* @__PURE__ */ React9.createElement(
2189
+ return /* @__PURE__ */ React17.createElement(
1952
2190
  "button",
1953
2191
  {
1954
2192
  key: date.toISOString(),
@@ -1969,20 +2207,20 @@ function DatePicker({
1969
2207
  })));
1970
2208
  };
1971
2209
  const combinedClassName = cn("relative", className);
1972
- return /* @__PURE__ */ React9.createElement("div", { className: combinedClassName, onBlur: handleBlur }, /* @__PURE__ */ React9.createElement(
2210
+ return /* @__PURE__ */ React17.createElement("div", { className: combinedClassName, onBlur: handleBlur }, /* @__PURE__ */ React17.createElement(
1973
2211
  "input",
1974
2212
  {
1975
2213
  type: "hidden",
1976
2214
  name,
1977
2215
  value: value ? value.toISOString() : ""
1978
2216
  }
1979
- ), /* @__PURE__ */ React9.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React9.createElement(
2217
+ ), /* @__PURE__ */ React17.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React17.createElement(
1980
2218
  "span",
1981
2219
  {
1982
2220
  className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
1983
2221
  "aria-hidden": "true"
1984
2222
  },
1985
- /* @__PURE__ */ React9.createElement(
2223
+ /* @__PURE__ */ React17.createElement(
1986
2224
  "svg",
1987
2225
  {
1988
2226
  xmlns: "http://www.w3.org/2000/svg",
@@ -1995,9 +2233,9 @@ function DatePicker({
1995
2233
  strokeLinejoin: "round",
1996
2234
  strokeWidth: "2"
1997
2235
  },
1998
- /* @__PURE__ */ React9.createElement("path", { d: "M8 2v4m8-4v4m5 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8M3 10h18m-5 10l2 2l4-4" })
2236
+ /* @__PURE__ */ React17.createElement("path", { d: "M8 2v4m8-4v4m5 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8M3 10h18m-5 10l2 2l4-4" })
1999
2237
  )
2000
- ), /* @__PURE__ */ React9.createElement(
2238
+ ), /* @__PURE__ */ React17.createElement(
2001
2239
  "input",
2002
2240
  {
2003
2241
  ref: inputRef,
@@ -2022,7 +2260,7 @@ function DatePicker({
2022
2260
  "aria-required": required || props["aria-required"],
2023
2261
  readOnly: true
2024
2262
  }
2025
- ), clearable && value && !disabled && /* @__PURE__ */ React9.createElement(
2263
+ ), clearable && value && !disabled && /* @__PURE__ */ React17.createElement(
2026
2264
  "button",
2027
2265
  {
2028
2266
  type: "button",
@@ -2032,7 +2270,7 @@ function DatePicker({
2032
2270
  tabIndex: -1
2033
2271
  },
2034
2272
  "\u2715"
2035
- )), isOpen && !disabled && /* @__PURE__ */ React9.createElement(
2273
+ )), isOpen && !disabled && /* @__PURE__ */ React17.createElement(
2036
2274
  "div",
2037
2275
  {
2038
2276
  ref: dropdownRef,
@@ -2099,11 +2337,11 @@ function TimePicker({
2099
2337
  showIcon = true,
2100
2338
  ...props
2101
2339
  }) {
2102
- const inputRef = React9.useRef(null);
2103
- const [nativeValue, setNativeValue] = React9.useState(
2340
+ const inputRef = React17.useRef(null);
2341
+ const [nativeValue, setNativeValue] = React17.useState(
2104
2342
  normalizeToNativeTime(value)
2105
2343
  );
2106
- React9.useEffect(() => {
2344
+ React17.useEffect(() => {
2107
2345
  setNativeValue(normalizeToNativeTime(value));
2108
2346
  }, [value]);
2109
2347
  const handleChange = (e) => {
@@ -2119,13 +2357,13 @@ function TimePicker({
2119
2357
  };
2120
2358
  const hasValue = Boolean(value);
2121
2359
  const stepInSeconds = Math.max(1, minuteStep * 60);
2122
- return /* @__PURE__ */ React9.createElement("div", { className: cn("relative", className) }, /* @__PURE__ */ React9.createElement("input", { type: "hidden", name, value }), /* @__PURE__ */ React9.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React9.createElement(
2360
+ return /* @__PURE__ */ React17.createElement("div", { className: cn("relative", className) }, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name, value }), /* @__PURE__ */ React17.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React17.createElement(
2123
2361
  "span",
2124
2362
  {
2125
2363
  className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
2126
2364
  "aria-hidden": "true"
2127
2365
  },
2128
- /* @__PURE__ */ React9.createElement(
2366
+ /* @__PURE__ */ React17.createElement(
2129
2367
  "svg",
2130
2368
  {
2131
2369
  xmlns: "http://www.w3.org/2000/svg",
@@ -2138,10 +2376,10 @@ function TimePicker({
2138
2376
  strokeLinejoin: "round",
2139
2377
  strokeWidth: "2"
2140
2378
  },
2141
- /* @__PURE__ */ React9.createElement("circle", { cx: "12", cy: "12", r: "10" }),
2142
- /* @__PURE__ */ React9.createElement("path", { d: "M12 6v6l4 2" })
2379
+ /* @__PURE__ */ React17.createElement("circle", { cx: "12", cy: "12", r: "10" }),
2380
+ /* @__PURE__ */ React17.createElement("path", { d: "M12 6v6l4 2" })
2143
2381
  )
2144
- ), /* @__PURE__ */ React9.createElement(
2382
+ ), /* @__PURE__ */ React17.createElement(
2145
2383
  "input",
2146
2384
  {
2147
2385
  ref: inputRef,
@@ -2169,7 +2407,7 @@ function TimePicker({
2169
2407
  "aria-required": required || props["aria-required"],
2170
2408
  ...props
2171
2409
  }
2172
- ), clearable && value && !disabled && /* @__PURE__ */ React9.createElement(
2410
+ ), clearable && value && !disabled && /* @__PURE__ */ React17.createElement(
2173
2411
  "button",
2174
2412
  {
2175
2413
  type: "button",
@@ -2222,16 +2460,17 @@ function DateRangePicker({
2222
2460
  separator = " - ",
2223
2461
  ...props
2224
2462
  }) {
2225
- const [isOpen, setIsOpen] = React9.useState(false);
2226
- const [selectedMonth, setSelectedMonth] = React9.useState(
2463
+ const [isOpen, setIsOpen] = React17.useState(false);
2464
+ const [hasInteracted, setHasInteracted] = React17.useState(false);
2465
+ const [selectedMonth, setSelectedMonth] = React17.useState(
2227
2466
  value.start || /* @__PURE__ */ new Date()
2228
2467
  );
2229
- const [rangeStart, setRangeStart] = React9.useState(value.start);
2230
- const [rangeEnd, setRangeEnd] = React9.useState(value.end);
2231
- const [hoverDate, setHoverDate] = React9.useState(null);
2232
- const triggerRef = React9.useRef(null);
2233
- const dropdownRef = React9.useRef(null);
2234
- React9.useEffect(() => {
2468
+ const [rangeStart, setRangeStart] = React17.useState(value.start);
2469
+ const [rangeEnd, setRangeEnd] = React17.useState(value.end);
2470
+ const [hoverDate, setHoverDate] = React17.useState(null);
2471
+ const triggerRef = React17.useRef(null);
2472
+ const dropdownRef = React17.useRef(null);
2473
+ React17.useEffect(() => {
2235
2474
  setRangeStart(value.start);
2236
2475
  setRangeEnd(value.end);
2237
2476
  if (value.start) {
@@ -2265,7 +2504,13 @@ function DateRangePicker({
2265
2504
  };
2266
2505
  const handleToggle = () => {
2267
2506
  if (disabled) return;
2268
- setIsOpen((prev) => !prev);
2507
+ setIsOpen((prev) => {
2508
+ const newIsOpen = !prev;
2509
+ if (newIsOpen && !hasInteracted) {
2510
+ setHasInteracted(true);
2511
+ }
2512
+ return newIsOpen;
2513
+ });
2269
2514
  };
2270
2515
  const isDisabled = (date) => {
2271
2516
  if (minDate && date < minDate) return true;
@@ -2274,10 +2519,13 @@ function DateRangePicker({
2274
2519
  if (isDateDisabled && isDateDisabled(date)) return true;
2275
2520
  return false;
2276
2521
  };
2277
- const closeCalendar = React9.useCallback(() => {
2522
+ const closeCalendar = React17.useCallback(() => {
2523
+ if (!isOpen) return;
2278
2524
  setIsOpen(false);
2279
- onBlur?.();
2280
- }, [onBlur]);
2525
+ if (hasInteracted) {
2526
+ onBlur?.();
2527
+ }
2528
+ }, [isOpen, hasInteracted, onBlur]);
2281
2529
  useOnClickOutside([triggerRef, dropdownRef], closeCalendar, void 0, {
2282
2530
  capture: true
2283
2531
  });
@@ -2321,7 +2569,7 @@ function DateRangePicker({
2321
2569
  for (let day = 1; day <= daysInMonth; day++) {
2322
2570
  days.push(new Date(year, month, day));
2323
2571
  }
2324
- return /* @__PURE__ */ React9.createElement("div", { className: "w-[240px] max-w-full" }, /* @__PURE__ */ React9.createElement("div", { className: "flex items-center justify-between pb-3" }, controls?.prev ? /* @__PURE__ */ React9.createElement(
2572
+ return /* @__PURE__ */ React17.createElement("div", { className: "w-[240px] max-w-full" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between pb-3" }, controls?.prev ? /* @__PURE__ */ React17.createElement(
2325
2573
  "button",
2326
2574
  {
2327
2575
  type: "button",
@@ -2330,7 +2578,7 @@ function DateRangePicker({
2330
2578
  "aria-label": "Previous month"
2331
2579
  },
2332
2580
  "\u2039"
2333
- ) : /* @__PURE__ */ React9.createElement("div", { className: "h-8 w-8", "aria-hidden": "true" }), /* @__PURE__ */ React9.createElement("div", { className: "font-medium text-sm" }, `${monthNames[month]} ${year}`), controls?.next ? /* @__PURE__ */ React9.createElement(
2581
+ ) : /* @__PURE__ */ React17.createElement("div", { className: "h-8 w-8", "aria-hidden": "true" }), /* @__PURE__ */ React17.createElement("div", { className: "font-medium text-sm" }, `${monthNames[month]} ${year}`), controls?.next ? /* @__PURE__ */ React17.createElement(
2334
2582
  "button",
2335
2583
  {
2336
2584
  type: "button",
@@ -2339,13 +2587,13 @@ function DateRangePicker({
2339
2587
  "aria-label": "Next month"
2340
2588
  },
2341
2589
  "\u203A"
2342
- ) : /* @__PURE__ */ React9.createElement("div", { className: "h-8 w-8", "aria-hidden": "true" })), /* @__PURE__ */ React9.createElement(
2590
+ ) : /* @__PURE__ */ React17.createElement("div", { className: "h-8 w-8", "aria-hidden": "true" })), /* @__PURE__ */ React17.createElement(
2343
2591
  "div",
2344
2592
  {
2345
2593
  className: "grid gap-1 text-xs text-muted-foreground",
2346
2594
  style: dayGridStyle
2347
2595
  },
2348
- ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React9.createElement(
2596
+ ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React17.createElement(
2349
2597
  "div",
2350
2598
  {
2351
2599
  key: `${month}-${day}`,
@@ -2353,9 +2601,9 @@ function DateRangePicker({
2353
2601
  },
2354
2602
  day
2355
2603
  ))
2356
- ), /* @__PURE__ */ React9.createElement("div", { className: "grid gap-1", style: dayGridStyle }, days.map((date, index) => {
2604
+ ), /* @__PURE__ */ React17.createElement("div", { className: "grid gap-1", style: dayGridStyle }, days.map((date, index) => {
2357
2605
  if (!date) {
2358
- return /* @__PURE__ */ React9.createElement("div", { key: `empty-${month}-${index}`, className: "h-8 w-8" });
2606
+ return /* @__PURE__ */ React17.createElement("div", { key: `empty-${month}-${index}`, className: "h-8 w-8" });
2359
2607
  }
2360
2608
  const isStart = rangeStart && date.toDateString() === rangeStart.toDateString();
2361
2609
  const isEnd = rangeEnd && date.toDateString() === rangeEnd.toDateString();
@@ -2367,7 +2615,7 @@ function DateRangePicker({
2367
2615
  );
2368
2616
  const isToday = date.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
2369
2617
  const disabled2 = isDisabled(date);
2370
- return /* @__PURE__ */ React9.createElement(
2618
+ return /* @__PURE__ */ React17.createElement(
2371
2619
  "button",
2372
2620
  {
2373
2621
  key: date.toISOString(),
@@ -2392,27 +2640,27 @@ function DateRangePicker({
2392
2640
  };
2393
2641
  const combinedClassName = cn("relative", className);
2394
2642
  const displayValue = rangeStart && rangeEnd ? `${formatDate2(rangeStart, format)}${separator}${formatDate2(rangeEnd, format)}` : rangeStart ? formatDate2(rangeStart, format) : "";
2395
- return /* @__PURE__ */ React9.createElement("div", { className: combinedClassName, onBlur: handleBlur }, /* @__PURE__ */ React9.createElement(
2643
+ return /* @__PURE__ */ React17.createElement("div", { className: combinedClassName, onBlur: handleBlur }, /* @__PURE__ */ React17.createElement(
2396
2644
  "input",
2397
2645
  {
2398
2646
  type: "hidden",
2399
2647
  name: `${name}[start]`,
2400
2648
  value: rangeStart ? rangeStart.toISOString() : ""
2401
2649
  }
2402
- ), /* @__PURE__ */ React9.createElement(
2650
+ ), /* @__PURE__ */ React17.createElement(
2403
2651
  "input",
2404
2652
  {
2405
2653
  type: "hidden",
2406
2654
  name: `${name}[end]`,
2407
2655
  value: rangeEnd ? rangeEnd.toISOString() : ""
2408
2656
  }
2409
- ), /* @__PURE__ */ React9.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React9.createElement(
2657
+ ), /* @__PURE__ */ React17.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React17.createElement(
2410
2658
  "span",
2411
2659
  {
2412
2660
  className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
2413
2661
  "aria-hidden": "true"
2414
2662
  },
2415
- /* @__PURE__ */ React9.createElement(
2663
+ /* @__PURE__ */ React17.createElement(
2416
2664
  "svg",
2417
2665
  {
2418
2666
  xmlns: "http://www.w3.org/2000/svg",
@@ -2425,9 +2673,9 @@ function DateRangePicker({
2425
2673
  strokeLinejoin: "round",
2426
2674
  strokeWidth: "2"
2427
2675
  },
2428
- /* @__PURE__ */ React9.createElement("path", { d: "M8 2v4m8-4v4m5 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8M3 10h18m-5 10l2 2l4-4" })
2676
+ /* @__PURE__ */ React17.createElement("path", { d: "M8 2v4m8-4v4m5 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8M3 10h18m-5 10l2 2l4-4" })
2429
2677
  )
2430
- ), /* @__PURE__ */ React9.createElement(
2678
+ ), /* @__PURE__ */ React17.createElement(
2431
2679
  "input",
2432
2680
  {
2433
2681
  ref: triggerRef,
@@ -2452,7 +2700,7 @@ function DateRangePicker({
2452
2700
  "aria-required": required || props["aria-required"],
2453
2701
  readOnly: true
2454
2702
  }
2455
- ), clearable && (rangeStart || rangeEnd) && !disabled && /* @__PURE__ */ React9.createElement(
2703
+ ), clearable && (rangeStart || rangeEnd) && !disabled && /* @__PURE__ */ React17.createElement(
2456
2704
  "button",
2457
2705
  {
2458
2706
  type: "button",
@@ -2462,14 +2710,14 @@ function DateRangePicker({
2462
2710
  tabIndex: -1
2463
2711
  },
2464
2712
  "\u2715"
2465
- )), isOpen && !disabled && /* @__PURE__ */ React9.createElement(
2713
+ )), isOpen && !disabled && /* @__PURE__ */ React17.createElement(
2466
2714
  "div",
2467
2715
  {
2468
2716
  ref: dropdownRef,
2469
2717
  className: "absolute z-50 top-full mt-1 w-fit rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3"
2470
2718
  },
2471
- /* @__PURE__ */ React9.createElement("div", { role: "grid", "aria-label": "Calendar" }, /* @__PURE__ */ React9.createElement("div", { className: "grid gap-4", style: monthsGridStyle }, renderMonth(selectedMonth, { prev: true }), renderMonth(addMonths(selectedMonth, 1), { next: true }))),
2472
- rangeStart && !rangeEnd && /* @__PURE__ */ React9.createElement("div", { className: "text-xs text-center pt-2 border-t border-border mt-2" }, "Select end date")
2719
+ /* @__PURE__ */ React17.createElement("div", { role: "grid", "aria-label": "Calendar" }, /* @__PURE__ */ React17.createElement("div", { className: "grid gap-4", style: monthsGridStyle }, renderMonth(selectedMonth, { prev: true }), renderMonth(addMonths(selectedMonth, 1), { next: true }))),
2720
+ rangeStart && !rangeEnd && /* @__PURE__ */ React17.createElement("div", { className: "text-xs text-center pt-2 border-t border-border mt-2" }, "Select end date")
2473
2721
  ));
2474
2722
  }
2475
2723
  DateRangePicker.displayName = "DateRangePicker";
@@ -2541,11 +2789,11 @@ function RichTextEditor({
2541
2789
  ],
2542
2790
  ...props
2543
2791
  }) {
2544
- const [currentMode, setCurrentMode] = React9.useState(mode);
2545
- const [content, setContent] = React9.useState(value);
2546
- const editorRef = React9.useRef(null);
2547
- const textareaRef = React9.useRef(null);
2548
- React9.useEffect(() => {
2792
+ const [currentMode, setCurrentMode] = React17.useState(mode);
2793
+ const [content, setContent] = React17.useState(value);
2794
+ const editorRef = React17.useRef(null);
2795
+ const textareaRef = React17.useRef(null);
2796
+ React17.useEffect(() => {
2549
2797
  setContent(value);
2550
2798
  if (currentMode === "wysiwyg" && editorRef.current) {
2551
2799
  editorRef.current.innerHTML = value;
@@ -2633,7 +2881,7 @@ function RichTextEditor({
2633
2881
  }
2634
2882
  }
2635
2883
  };
2636
- const hasValue = React9.useMemo(() => {
2884
+ const hasValue = React17.useMemo(() => {
2637
2885
  if (!content) return false;
2638
2886
  const stripped = content.replace(/<[^>]+>/g, "").trim();
2639
2887
  return stripped.length > 0;
@@ -2650,10 +2898,10 @@ function RichTextEditor({
2650
2898
  maxHeight,
2651
2899
  overflowY: maxHeight ? "auto" : void 0
2652
2900
  };
2653
- return /* @__PURE__ */ React9.createElement("div", { className: combinedClassName }, /* @__PURE__ */ React9.createElement("input", { type: "hidden", name, value: content }), showToolbar && /* @__PURE__ */ React9.createElement("div", { className: "flex items-center justify-between p-2 border-b border-border bg-muted/50" }, /* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-1" }, toolbarButtons.map((buttonName) => {
2901
+ return /* @__PURE__ */ React17.createElement("div", { className: combinedClassName }, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name, value: content }), showToolbar && /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between p-2 border-b border-border bg-muted/50" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-1" }, toolbarButtons.map((buttonName) => {
2654
2902
  const button = toolbarConfig[buttonName];
2655
2903
  if (!button) return null;
2656
- return /* @__PURE__ */ React9.createElement(
2904
+ return /* @__PURE__ */ React17.createElement(
2657
2905
  "button",
2658
2906
  {
2659
2907
  key: buttonName,
@@ -2666,7 +2914,7 @@ function RichTextEditor({
2666
2914
  },
2667
2915
  button.icon
2668
2916
  );
2669
- })), allowModeSwitch && /* @__PURE__ */ React9.createElement(
2917
+ })), allowModeSwitch && /* @__PURE__ */ React17.createElement(
2670
2918
  "button",
2671
2919
  {
2672
2920
  type: "button",
@@ -2677,7 +2925,7 @@ function RichTextEditor({
2677
2925
  "aria-label": `Switch to ${currentMode === "wysiwyg" ? "Markdown" : "WYSIWYG"}`
2678
2926
  },
2679
2927
  currentMode === "wysiwyg" ? "MD" : "WYSIWYG"
2680
- )), /* @__PURE__ */ React9.createElement("div", { style: editorStyle }, currentMode === "wysiwyg" ? /* @__PURE__ */ React9.createElement(
2928
+ )), /* @__PURE__ */ React17.createElement("div", { style: editorStyle }, currentMode === "wysiwyg" ? /* @__PURE__ */ React17.createElement(
2681
2929
  "div",
2682
2930
  {
2683
2931
  ref: editorRef,
@@ -2692,7 +2940,7 @@ function RichTextEditor({
2692
2940
  "aria-required": required || props["aria-required"],
2693
2941
  suppressContentEditableWarning: true
2694
2942
  }
2695
- ) : /* @__PURE__ */ React9.createElement(
2943
+ ) : /* @__PURE__ */ React17.createElement(
2696
2944
  "textarea",
2697
2945
  {
2698
2946
  ref: textareaRef,
@@ -2715,6 +2963,6 @@ function RichTextEditor({
2715
2963
  }
2716
2964
  RichTextEditor.displayName = "RichTextEditor";
2717
2965
 
2718
- export { Checkbox, CheckboxGroup, DatePicker, DateRangePicker, FileInput, MultiSelect, Radio, RichTextEditor, Select, TextArea, TextInput, TimePicker };
2966
+ export { Checkbox2 as Checkbox, CheckboxGroup, DatePicker, DateRangePicker, FileInput, MultiSelect, Radio, RichTextEditor, Select2 as Select, Switch2 as Switch, TextArea, TextInput, TimePicker };
2719
2967
  //# sourceMappingURL=inputs.js.map
2720
2968
  //# sourceMappingURL=inputs.js.map