@pos-360/horizon 0.30.1 → 0.30.2

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.
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk23BJPJOK_js = require('./chunk-23BJPJOK.js');
3
+ var chunkNTUQQDCL_js = require('./chunk-NTUQQDCL.js');
4
4
  var React10 = require('react');
5
5
  var reactSlot = require('@radix-ui/react-slot');
6
6
  var classVarianceAuthority = require('class-variance-authority');
@@ -88,7 +88,7 @@ var Button = React10__namespace.forwardRef(
88
88
  return /* @__PURE__ */ jsxRuntime.jsx(
89
89
  Comp,
90
90
  {
91
- className: chunk23BJPJOK_js.cn(buttonVariants({ variant, size, className })),
91
+ className: chunkNTUQQDCL_js.cn(buttonVariants({ variant, size, className })),
92
92
  ref,
93
93
  ...props,
94
94
  children
@@ -99,7 +99,7 @@ var Button = React10__namespace.forwardRef(
99
99
  return /* @__PURE__ */ jsxRuntime.jsxs(
100
100
  Comp,
101
101
  {
102
- className: chunk23BJPJOK_js.cn(buttonVariants({ variant, size, className })),
102
+ className: chunkNTUQQDCL_js.cn(buttonVariants({ variant, size, className })),
103
103
  ref,
104
104
  ...props,
105
105
  children: [
@@ -116,7 +116,7 @@ var Card = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @_
116
116
  "div",
117
117
  {
118
118
  ref,
119
- className: chunk23BJPJOK_js.cn(
119
+ className: chunkNTUQQDCL_js.cn(
120
120
  "rounded-hz-lg border border-gray-200 bg-white text-gray-900 shadow dark:border-neutral-700 dark:bg-neutral-800 dark:text-gray-100",
121
121
  className
122
122
  ),
@@ -128,7 +128,7 @@ var CardHeader = React10__namespace.forwardRef(({ className, ...props }, ref) =>
128
128
  "div",
129
129
  {
130
130
  ref,
131
- className: chunk23BJPJOK_js.cn("flex flex-col space-y-1.5 p-4", className),
131
+ className: chunkNTUQQDCL_js.cn("flex flex-col space-y-1.5 p-4", className),
132
132
  ...props
133
133
  }
134
134
  ));
@@ -137,7 +137,7 @@ var CardTitle = React10__namespace.forwardRef(({ className, ...props }, ref) =>
137
137
  "div",
138
138
  {
139
139
  ref,
140
- className: chunk23BJPJOK_js.cn("font-semibold leading-none tracking-tight", className),
140
+ className: chunkNTUQQDCL_js.cn("font-semibold leading-none tracking-tight", className),
141
141
  ...props
142
142
  }
143
143
  ));
@@ -146,7 +146,7 @@ var CardDescription = React10__namespace.forwardRef(({ className, ...props }, re
146
146
  "div",
147
147
  {
148
148
  ref,
149
- className: chunk23BJPJOK_js.cn("text-sm text-gray-500 dark:text-gray-400", className),
149
+ className: chunkNTUQQDCL_js.cn("text-sm text-gray-500 dark:text-gray-400", className),
150
150
  ...props
151
151
  }
152
152
  ));
@@ -155,7 +155,7 @@ var CardContent = React10__namespace.forwardRef(({ className, ...props }, ref) =
155
155
  "div",
156
156
  {
157
157
  ref,
158
- className: chunk23BJPJOK_js.cn("p-4 pt-0", className),
158
+ className: chunkNTUQQDCL_js.cn("p-4 pt-0", className),
159
159
  ...props
160
160
  }
161
161
  ));
@@ -164,7 +164,7 @@ var CardFooter = React10__namespace.forwardRef(({ className, ...props }, ref) =>
164
164
  "div",
165
165
  {
166
166
  ref,
167
- className: chunk23BJPJOK_js.cn("flex items-center p-4 pt-0", className),
167
+ className: chunkNTUQQDCL_js.cn("flex items-center p-4 pt-0", className),
168
168
  ...props
169
169
  }
170
170
  ));
@@ -173,7 +173,7 @@ var Checkbox = React10__namespace.forwardRef(({ className, indicatorIcon, ...pro
173
173
  CheckboxPrimitive__namespace.Root,
174
174
  {
175
175
  ref,
176
- className: chunk23BJPJOK_js.cn(
176
+ className: chunkNTUQQDCL_js.cn(
177
177
  "peer h-4 w-4 shrink-0 rounded-hz-sm border border-gray-300 bg-transparent shadow focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-blue-600 data-[state=checked]:border-blue-600 data-[state=checked]:text-white dark:border-neutral-600 dark:data-[state=checked]:bg-blue-600",
178
178
  className
179
179
  ),
@@ -181,7 +181,7 @@ var Checkbox = React10__namespace.forwardRef(({ className, indicatorIcon, ...pro
181
181
  children: /* @__PURE__ */ jsxRuntime.jsx(
182
182
  CheckboxPrimitive__namespace.Indicator,
183
183
  {
184
- className: chunk23BJPJOK_js.cn("flex items-center justify-center text-current"),
184
+ className: chunkNTUQQDCL_js.cn("flex items-center justify-center text-current"),
185
185
  children: indicatorIcon ?? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5", strokeWidth: 3 })
186
186
  }
187
187
  )
@@ -196,7 +196,7 @@ var DialogOverlay = React10__namespace.forwardRef(({ className, ...props }, ref)
196
196
  DialogPrimitive__namespace.Overlay,
197
197
  {
198
198
  ref,
199
- className: chunk23BJPJOK_js.cn(
199
+ className: chunkNTUQQDCL_js.cn(
200
200
  "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
201
201
  className
202
202
  ),
@@ -210,7 +210,7 @@ var DialogContent = React10__namespace.forwardRef(({ className, children, ...pro
210
210
  DialogPrimitive__namespace.Content,
211
211
  {
212
212
  ref,
213
- className: chunk23BJPJOK_js.cn(
213
+ className: chunkNTUQQDCL_js.cn(
214
214
  "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-gray-200 bg-white p-6 shadow-lg duration-hz-normal 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-hz-lg dark:border-neutral-700 dark:bg-neutral-800",
215
215
  className
216
216
  ),
@@ -232,7 +232,7 @@ var DialogHeader = ({
232
232
  }) => /* @__PURE__ */ jsxRuntime.jsx(
233
233
  "div",
234
234
  {
235
- className: chunk23BJPJOK_js.cn(
235
+ className: chunkNTUQQDCL_js.cn(
236
236
  "flex flex-col space-y-1.5 text-center sm:text-left",
237
237
  className
238
238
  ),
@@ -246,7 +246,7 @@ var DialogFooter = ({
246
246
  }) => /* @__PURE__ */ jsxRuntime.jsx(
247
247
  "div",
248
248
  {
249
- className: chunk23BJPJOK_js.cn(
249
+ className: chunkNTUQQDCL_js.cn(
250
250
  "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
251
251
  className
252
252
  ),
@@ -258,7 +258,7 @@ var DialogTitle = React10__namespace.forwardRef(({ className, ...props }, ref) =
258
258
  DialogPrimitive__namespace.Title,
259
259
  {
260
260
  ref,
261
- className: chunk23BJPJOK_js.cn(
261
+ className: chunkNTUQQDCL_js.cn(
262
262
  "text-lg font-semibold leading-none tracking-tight text-gray-900 dark:text-gray-100",
263
263
  className
264
264
  ),
@@ -270,7 +270,7 @@ var DialogDescription = React10__namespace.forwardRef(({ className, ...props },
270
270
  DialogPrimitive__namespace.Description,
271
271
  {
272
272
  ref,
273
- className: chunk23BJPJOK_js.cn("text-sm text-gray-500 dark:text-gray-400", className),
273
+ className: chunkNTUQQDCL_js.cn("text-sm text-gray-500 dark:text-gray-400", className),
274
274
  ...props
275
275
  }
276
276
  ));
@@ -285,7 +285,7 @@ var DropdownMenuSubTrigger = React10__namespace.forwardRef(({ className, inset,
285
285
  DropdownMenuPrimitive__namespace.SubTrigger,
286
286
  {
287
287
  ref,
288
- className: chunk23BJPJOK_js.cn(
288
+ className: chunkNTUQQDCL_js.cn(
289
289
  "flex cursor-default select-none items-center gap-2 rounded-hz-sm px-2 py-1.5 text-sm outline-none focus:bg-gray-100 data-[state=open]:bg-gray-100 dark:focus:bg-gray-700 dark:data-[state=open]:bg-gray-700 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
290
290
  inset && "pl-8",
291
291
  className
@@ -302,7 +302,7 @@ var DropdownMenuSubContent = React10__namespace.forwardRef(({ className, ...prop
302
302
  DropdownMenuPrimitive__namespace.SubContent,
303
303
  {
304
304
  ref,
305
- className: chunk23BJPJOK_js.cn(
305
+ className: chunkNTUQQDCL_js.cn(
306
306
  "z-50 min-w-[8rem] overflow-hidden rounded-hz-md border border-gray-200 bg-white p-1 text-gray-900 shadow-lg 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 origin-[--radix-dropdown-menu-content-transform-origin] dark:border-neutral-700 dark:bg-neutral-800 dark:text-gray-100",
307
307
  className
308
308
  ),
@@ -315,7 +315,7 @@ var DropdownMenuContent = React10__namespace.forwardRef(({ className, sideOffset
315
315
  {
316
316
  ref,
317
317
  sideOffset,
318
- className: chunk23BJPJOK_js.cn(
318
+ className: chunkNTUQQDCL_js.cn(
319
319
  "z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-hz-md border border-gray-200 bg-white p-1 text-gray-900 shadow-md dark:border-neutral-700 dark:bg-neutral-800 dark:text-gray-100",
320
320
  "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 origin-[--radix-dropdown-menu-content-transform-origin]",
321
321
  className
@@ -328,7 +328,7 @@ var DropdownMenuItem = React10__namespace.forwardRef(({ className, inset, ...pro
328
328
  DropdownMenuPrimitive__namespace.Item,
329
329
  {
330
330
  ref,
331
- className: chunk23BJPJOK_js.cn(
331
+ className: chunkNTUQQDCL_js.cn(
332
332
  "relative flex cursor-default select-none items-center gap-2 rounded-hz-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-gray-100 focus:text-gray-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-gray-700 dark:focus:text-gray-100 [&>svg]:size-4 [&>svg]:shrink-0",
333
333
  inset && "pl-8",
334
334
  className
@@ -341,7 +341,7 @@ var DropdownMenuCheckboxItem = React10__namespace.forwardRef(({ className, child
341
341
  DropdownMenuPrimitive__namespace.CheckboxItem,
342
342
  {
343
343
  ref,
344
- className: chunk23BJPJOK_js.cn(
344
+ className: chunkNTUQQDCL_js.cn(
345
345
  "relative flex cursor-default select-none items-center rounded-hz-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-gray-100 focus:text-gray-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-gray-700 dark:focus:text-gray-100",
346
346
  className
347
347
  ),
@@ -358,7 +358,7 @@ var DropdownMenuRadioItem = React10__namespace.forwardRef(({ className, children
358
358
  DropdownMenuPrimitive__namespace.RadioItem,
359
359
  {
360
360
  ref,
361
- className: chunk23BJPJOK_js.cn(
361
+ className: chunkNTUQQDCL_js.cn(
362
362
  "relative flex cursor-default select-none items-center rounded-hz-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-gray-100 focus:text-gray-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-gray-700 dark:focus:text-gray-100",
363
363
  className
364
364
  ),
@@ -374,7 +374,7 @@ var DropdownMenuLabel = React10__namespace.forwardRef(({ className, inset, ...pr
374
374
  DropdownMenuPrimitive__namespace.Label,
375
375
  {
376
376
  ref,
377
- className: chunk23BJPJOK_js.cn(
377
+ className: chunkNTUQQDCL_js.cn(
378
378
  "px-2 py-1.5 text-sm font-semibold",
379
379
  inset && "pl-8",
380
380
  className
@@ -387,7 +387,7 @@ var DropdownMenuSeparator = React10__namespace.forwardRef(({ className, ...props
387
387
  DropdownMenuPrimitive__namespace.Separator,
388
388
  {
389
389
  ref,
390
- className: chunk23BJPJOK_js.cn("-mx-1 my-1 h-px bg-gray-100 dark:bg-neutral-700", className),
390
+ className: chunkNTUQQDCL_js.cn("-mx-1 my-1 h-px bg-gray-100 dark:bg-neutral-700", className),
391
391
  ...props
392
392
  }
393
393
  ));
@@ -399,7 +399,7 @@ var DropdownMenuShortcut = ({
399
399
  return /* @__PURE__ */ jsxRuntime.jsx(
400
400
  "span",
401
401
  {
402
- className: chunk23BJPJOK_js.cn("ml-auto text-xs tracking-widest opacity-60", className),
402
+ className: chunkNTUQQDCL_js.cn("ml-auto text-xs tracking-widest opacity-60", className),
403
403
  ...props
404
404
  }
405
405
  );
@@ -476,7 +476,7 @@ var Form = React10__namespace.forwardRef(
476
476
  "form",
477
477
  {
478
478
  ref,
479
- className: chunk23BJPJOK_js.cn("space-y-6", className),
479
+ className: chunkNTUQQDCL_js.cn("space-y-6", className),
480
480
  onSubmit: handleSubmit,
481
481
  ...props,
482
482
  children
@@ -494,18 +494,18 @@ var FormField = React10__namespace.forwardRef(
494
494
  () => ({ name, error, id }),
495
495
  [name, error, id]
496
496
  );
497
- return /* @__PURE__ */ jsxRuntime.jsx(FormFieldContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: chunk23BJPJOK_js.cn("space-y-2", className), ...props, children }) });
497
+ return /* @__PURE__ */ jsxRuntime.jsx(FormFieldContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: chunkNTUQQDCL_js.cn("space-y-2", className), ...props, children }) });
498
498
  }
499
499
  );
500
500
  FormField.displayName = "FormField";
501
501
  var FormLabel = React10__namespace.forwardRef(({ className, ...props }, ref) => {
502
502
  const { id, error } = useFormFieldContext();
503
503
  return /* @__PURE__ */ jsxRuntime.jsx(
504
- chunk23BJPJOK_js.Label,
504
+ chunkNTUQQDCL_js.Label,
505
505
  {
506
506
  ref,
507
507
  htmlFor: id,
508
- className: chunk23BJPJOK_js.cn(error && "text-rose-500 dark:text-rose-400", className),
508
+ className: chunkNTUQQDCL_js.cn(error && "text-rose-500 dark:text-rose-400", className),
509
509
  ...props
510
510
  }
511
511
  );
@@ -531,7 +531,7 @@ var FormDescription = React10__namespace.forwardRef(
531
531
  "span",
532
532
  {
533
533
  ref,
534
- className: chunk23BJPJOK_js.cn(
534
+ className: chunkNTUQQDCL_js.cn(
535
535
  "block text-sm text-neutral-500 dark:text-neutral-400",
536
536
  className
537
537
  ),
@@ -554,7 +554,7 @@ var FormMessage = React10__namespace.forwardRef(
554
554
  {
555
555
  ref,
556
556
  id: id ? `${id}-error` : void 0,
557
- className: chunk23BJPJOK_js.cn(
557
+ className: chunkNTUQQDCL_js.cn(
558
558
  "text-sm font-medium",
559
559
  error ? "text-rose-500 dark:text-rose-400" : "text-neutral-600 dark:text-neutral-400",
560
560
  className
@@ -645,7 +645,7 @@ var PopoverContent = React10__namespace.forwardRef(({ className, align = "center
645
645
  damping: 25,
646
646
  mass: 0.8
647
647
  },
648
- className: chunk23BJPJOK_js.cn(
648
+ className: chunkNTUQQDCL_js.cn(
649
649
  "z-50 w-72 rounded-md border border-white/20 bg-white/80 backdrop-blur-xl p-4 text-gray-900 shadow-lg outline-none dark:border-neutral-700/50 dark:bg-neutral-900/80 dark:text-neutral-100 origin-[--radix-popover-content-transform-origin]",
650
650
  className
651
651
  ),
@@ -690,7 +690,7 @@ var SelectTrigger = React10__namespace.forwardRef(({ className, children, ...pro
690
690
  SelectPrimitive__namespace.Trigger,
691
691
  {
692
692
  ref,
693
- className: chunk23BJPJOK_js.cn(
693
+ className: chunkNTUQQDCL_js.cn(
694
694
  "flex h-[52px] w-full items-center justify-between rounded-hz-md border border-gray-300 bg-white px-4 py-2 text-sm text-gray-900 placeholder:text-gray-400 focus:outline-none focus:ring-0 disabled:cursor-not-allowed disabled:opacity-50 dark:border-neutral-600 dark:bg-neutral-800 dark:text-gray-100 dark:placeholder:text-gray-500 [&>span]:line-clamp-1",
695
695
  className
696
696
  ),
@@ -706,7 +706,7 @@ var SelectScrollUpButton = React10__namespace.forwardRef(({ className, ...props
706
706
  SelectPrimitive__namespace.ScrollUpButton,
707
707
  {
708
708
  ref,
709
- className: chunk23BJPJOK_js.cn(
709
+ className: chunkNTUQQDCL_js.cn(
710
710
  "flex cursor-default items-center justify-center py-1",
711
711
  className
712
712
  ),
@@ -719,7 +719,7 @@ var SelectScrollDownButton = React10__namespace.forwardRef(({ className, ...prop
719
719
  SelectPrimitive__namespace.ScrollDownButton,
720
720
  {
721
721
  ref,
722
- className: chunk23BJPJOK_js.cn(
722
+ className: chunkNTUQQDCL_js.cn(
723
723
  "flex cursor-default items-center justify-center py-1",
724
724
  className
725
725
  ),
@@ -790,7 +790,7 @@ var SelectContent = React10__namespace.forwardRef(({ className, children, positi
790
790
  damping: 25,
791
791
  mass: 0.8
792
792
  },
793
- className: chunk23BJPJOK_js.cn(
793
+ className: chunkNTUQQDCL_js.cn(
794
794
  "relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-hidden rounded-hz-lg border border-white/20 bg-white/80 backdrop-blur-xl text-gray-900 shadow-lg dark:border-neutral-700/50 dark:bg-neutral-900/80 dark:text-gray-100 origin-[--radix-select-content-transform-origin]",
795
795
  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",
796
796
  className
@@ -815,7 +815,7 @@ var SelectContent = React10__namespace.forwardRef(({ className, children, positi
815
815
  /* @__PURE__ */ jsxRuntime.jsx(
816
816
  SelectPrimitive__namespace.Viewport,
817
817
  {
818
- className: chunk23BJPJOK_js.cn(
818
+ className: chunkNTUQQDCL_js.cn(
819
819
  "p-1",
820
820
  position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
821
821
  ),
@@ -835,7 +835,7 @@ var SelectLabel = React10__namespace.forwardRef(({ className, ...props }, ref) =
835
835
  SelectPrimitive__namespace.Label,
836
836
  {
837
837
  ref,
838
- className: chunk23BJPJOK_js.cn("px-2 py-1.5 text-sm font-semibold", className),
838
+ className: chunkNTUQQDCL_js.cn("px-2 py-1.5 text-sm font-semibold", className),
839
839
  ...props
840
840
  }
841
841
  ));
@@ -851,7 +851,7 @@ var SelectItem = React10__namespace.forwardRef(({ className, children, textValue
851
851
  {
852
852
  ref,
853
853
  textValue,
854
- className: chunk23BJPJOK_js.cn(
854
+ className: chunkNTUQQDCL_js.cn(
855
855
  "relative flex w-full cursor-default select-none items-center rounded-hz-md py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-black/5 focus:text-gray-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-white/10 dark:focus:text-gray-100 transition-colors",
856
856
  className
857
857
  ),
@@ -868,7 +868,7 @@ var SelectSeparator = React10__namespace.forwardRef(({ className, ...props }, re
868
868
  SelectPrimitive__namespace.Separator,
869
869
  {
870
870
  ref,
871
- className: chunk23BJPJOK_js.cn("-mx-1 my-1 h-px bg-gray-200/50 dark:bg-neutral-700/50", className),
871
+ className: chunkNTUQQDCL_js.cn("-mx-1 my-1 h-px bg-gray-200/50 dark:bg-neutral-700/50", className),
872
872
  ...props
873
873
  }
874
874
  ));
@@ -895,7 +895,7 @@ function Separator3({
895
895
  {
896
896
  role: decorative ? "none" : "separator",
897
897
  "aria-orientation": decorative ? void 0 : orientation ?? void 0,
898
- className: chunk23BJPJOK_js.cn(separatorVariants({ orientation }), className),
898
+ className: chunkNTUQQDCL_js.cn(separatorVariants({ orientation }), className),
899
899
  ...props
900
900
  }
901
901
  );
@@ -904,7 +904,7 @@ function Skeleton({ className }) {
904
904
  return /* @__PURE__ */ jsxRuntime.jsx(
905
905
  "div",
906
906
  {
907
- className: chunk23BJPJOK_js.cn(
907
+ className: chunkNTUQQDCL_js.cn(
908
908
  "animate-pulse rounded-hz-md bg-neutral-200 dark:bg-neutral-800",
909
909
  className
910
910
  )
@@ -912,28 +912,28 @@ function Skeleton({ className }) {
912
912
  );
913
913
  }
914
914
  function SkeletonText({ className }) {
915
- return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunk23BJPJOK_js.cn("h-4", className) });
915
+ return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunkNTUQQDCL_js.cn("h-4", className) });
916
916
  }
917
917
  function SkeletonTitle({ className }) {
918
- return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunk23BJPJOK_js.cn("h-6 w-48", className) });
918
+ return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunkNTUQQDCL_js.cn("h-6 w-48", className) });
919
919
  }
920
920
  function SkeletonSubtitle({ className }) {
921
- return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunk23BJPJOK_js.cn("h-3 w-64", className) });
921
+ return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunkNTUQQDCL_js.cn("h-3 w-64", className) });
922
922
  }
923
923
  function SkeletonAvatar({ className }) {
924
- return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunk23BJPJOK_js.cn("w-10 h-10 rounded", className) });
924
+ return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunkNTUQQDCL_js.cn("w-10 h-10 rounded", className) });
925
925
  }
926
926
  function SkeletonBadge({ className }) {
927
- return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunk23BJPJOK_js.cn("h-6 w-24", className) });
927
+ return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunkNTUQQDCL_js.cn("h-6 w-24", className) });
928
928
  }
929
929
  function SkeletonIcon({ className }) {
930
- return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunk23BJPJOK_js.cn("w-6 h-6 rounded", className) });
930
+ return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunkNTUQQDCL_js.cn("w-6 h-6 rounded", className) });
931
931
  }
932
932
  function SkeletonButton({ className }) {
933
- return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunk23BJPJOK_js.cn("h-10 w-24 rounded-hz-md", className) });
933
+ return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunkNTUQQDCL_js.cn("h-10 w-24 rounded-hz-md", className) });
934
934
  }
935
935
  function SkeletonInput({ className }) {
936
- return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunk23BJPJOK_js.cn("h-10 w-full rounded-hz-md", className) });
936
+ return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: chunkNTUQQDCL_js.cn("h-10 w-full rounded-hz-md", className) });
937
937
  }
938
938
  function SkeletonTableRow({
939
939
  columns = 4,
@@ -951,7 +951,7 @@ function SkeletonCard({ className }) {
951
951
  return /* @__PURE__ */ jsxRuntime.jsxs(
952
952
  "div",
953
953
  {
954
- className: chunk23BJPJOK_js.cn(
954
+ className: chunkNTUQQDCL_js.cn(
955
955
  "rounded-hz-lg border bg-card p-6 space-y-4",
956
956
  className
957
957
  ),
@@ -1025,7 +1025,7 @@ function SegmentedControl({
1025
1025
  {
1026
1026
  ...props,
1027
1027
  ...value !== void 0 ? { value, onValueChange: onChange } : {},
1028
- className: chunk23BJPJOK_js.cn(
1028
+ className: chunkNTUQQDCL_js.cn(
1029
1029
  segmentedControlVariants({ size }),
1030
1030
  containerRadiusClass[radius],
1031
1031
  className
@@ -1035,7 +1035,7 @@ function SegmentedControl({
1035
1035
  {
1036
1036
  value: option.value,
1037
1037
  disabled: option.disabled,
1038
- className: chunk23BJPJOK_js.cn(
1038
+ className: chunkNTUQQDCL_js.cn(
1039
1039
  segmentedControlItemVariants({ size }),
1040
1040
  itemRadiusClass[radius],
1041
1041
  "border border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200",
@@ -1072,7 +1072,7 @@ function BulkEditPopover({ column, onApply }) {
1072
1072
  }
1073
1073
  if (!next) setValue("");
1074
1074
  };
1075
- return /* @__PURE__ */ jsxRuntime.jsx(chunk23BJPJOK_js.Tooltip, { content: `Apply to all ${headingLabel}`, side: "top", disabled: open, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex", children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
1075
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkNTUQQDCL_js.Tooltip, { content: `Apply to all ${headingLabel}`, side: "top", disabled: open, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex", children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
1076
1076
  /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1077
1077
  "button",
1078
1078
  {
@@ -1083,7 +1083,7 @@ function BulkEditPopover({ column, onApply }) {
1083
1083
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PenLine, { className: "h-3.5 w-3.5" })
1084
1084
  }
1085
1085
  ) }),
1086
- /* @__PURE__ */ jsxRuntime.jsxs(PopoverContent, { align: "start", className: chunk23BJPJOK_js.cn("p-3 space-y-3", bulkEdit.kind === "segmented-control" ? "w-auto" : "w-64"), children: [
1086
+ /* @__PURE__ */ jsxRuntime.jsxs(PopoverContent, { align: "start", className: chunkNTUQQDCL_js.cn("p-3 space-y-3", bulkEdit.kind === "segmented-control" ? "w-auto" : "w-64"), children: [
1087
1087
  /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide", children: [
1088
1088
  "Apply to all \u2014 ",
1089
1089
  headingLabel
@@ -1104,7 +1104,7 @@ function BulkEditPopover({ column, onApply }) {
1104
1104
  }
1105
1105
  },
1106
1106
  autoFocus: true,
1107
- className: chunk23BJPJOK_js.cn(
1107
+ className: chunkNTUQQDCL_js.cn(
1108
1108
  "w-full rounded-hz-md border border-gray-300 bg-white py-2 text-sm text-gray-900 placeholder:text-gray-400 focus:outline-none focus:ring-1 focus:ring-blue-500/50 dark:border-neutral-600 dark:bg-neutral-800 dark:text-gray-100 dark:placeholder:text-gray-500",
1109
1109
  bulkEdit.leadingDecorator ? "pl-7 pr-3" : "px-3"
1110
1110
  )
@@ -1335,12 +1335,12 @@ var TableInner = React10__namespace.forwardRef(
1335
1335
  "div",
1336
1336
  {
1337
1337
  ref: wrapperRef,
1338
- className: chunk23BJPJOK_js.cn("relative w-full overflow-auto scrollbar-thin scrollbar-thumb-gray-300 dark:scrollbar-thumb-neutral-600 scrollbar-track-transparent", rounded && "rounded-lg", containerClassName),
1338
+ className: chunkNTUQQDCL_js.cn("relative w-full overflow-auto scrollbar-thin scrollbar-thumb-gray-300 dark:scrollbar-thumb-neutral-600 scrollbar-track-transparent", rounded && "rounded-lg", containerClassName),
1339
1339
  children: /* @__PURE__ */ jsxRuntime.jsx(
1340
1340
  "table",
1341
1341
  {
1342
1342
  ref,
1343
- className: chunk23BJPJOK_js.cn("w-full caption-bottom text-sm", className),
1343
+ className: chunkNTUQQDCL_js.cn("w-full caption-bottom text-sm", className),
1344
1344
  ...props,
1345
1345
  children: columns && data ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: (() => {
1346
1346
  const filteredCols = columns.filter(
@@ -1393,7 +1393,7 @@ var TableInner = React10__namespace.forwardRef(
1393
1393
  ...col.stickyXHeader ? { left: stickyOffsets[col.key] } : {},
1394
1394
  ...col.stickyXHeader && stickyYHeader ? { boxShadow: xyShadow } : col.stickyXHeader ? { boxShadow: xShadow } : stickyYHeader ? { boxShadow: yShadow } : {}
1395
1395
  },
1396
- className: chunk23BJPJOK_js.cn(
1396
+ className: chunkNTUQQDCL_js.cn(
1397
1397
  "h-12 px-4 text-left align-middle font-medium text-gray-500 dark:text-gray-400",
1398
1398
  stickyYHeader && "sticky top-0 z-20 bg-gray-50 dark:bg-neutral-800",
1399
1399
  col.stickyXHeader && "sticky z-20 bg-gray-50 dark:bg-neutral-800",
@@ -1420,7 +1420,7 @@ var TableInner = React10__namespace.forwardRef(
1420
1420
  "tr",
1421
1421
  {
1422
1422
  "data-state": isSelected ? "selected" : void 0,
1423
- className: chunk23BJPJOK_js.cn(
1423
+ className: chunkNTUQQDCL_js.cn(
1424
1424
  "border-b border-gray-200 transition-colors dark:border-neutral-700",
1425
1425
  isSelected ? "bg-blue-50 dark:bg-blue-900/20" : (highlightMode === "row" || highlightMode === "cross") && "hover:bg-gray-50 dark:hover:bg-neutral-800/50",
1426
1426
  onRowClick && "cursor-pointer"
@@ -1442,9 +1442,9 @@ var TableInner = React10__namespace.forwardRef(
1442
1442
  }
1443
1443
  contextValue.toggleRow(rowId);
1444
1444
  } : col.key === "__delete__" ? (e) => e.stopPropagation() : void 0,
1445
- className: chunk23BJPJOK_js.cn(
1445
+ className: chunkNTUQQDCL_js.cn(
1446
1446
  "p-4 align-middle",
1447
- col.stickyXHeader && chunk23BJPJOK_js.cn("sticky z-20", isSelected ? "bg-blue-50 dark:bg-[#242a3a]" : "bg-gray-50 dark:bg-neutral-800"),
1447
+ col.stickyXHeader && chunkNTUQQDCL_js.cn("sticky z-20", isSelected ? "bg-blue-50 dark:bg-[#242a3a]" : "bg-gray-50 dark:bg-neutral-800"),
1448
1448
  showDividers && "border-r border-gray-200 dark:border-neutral-700",
1449
1449
  typeof col.cellClassName === "function" ? col.cellClassName(row) : col.cellClassName
1450
1450
  ),
@@ -1470,7 +1470,7 @@ var TableHeader = React10__namespace.forwardRef(({ className, ...props }, ref) =
1470
1470
  "thead",
1471
1471
  {
1472
1472
  ref,
1473
- className: chunk23BJPJOK_js.cn("[&_tr]:border-b [&_tr]:border-gray-200 dark:[&_tr]:border-gray-700", className),
1473
+ className: chunkNTUQQDCL_js.cn("[&_tr]:border-b [&_tr]:border-gray-200 dark:[&_tr]:border-gray-700", className),
1474
1474
  ...props
1475
1475
  }
1476
1476
  ));
@@ -1479,7 +1479,7 @@ var TableBody = React10__namespace.forwardRef(({ className, ...props }, ref) =>
1479
1479
  "tbody",
1480
1480
  {
1481
1481
  ref,
1482
- className: chunk23BJPJOK_js.cn("[&_tr:last-child]:border-0", className),
1482
+ className: chunkNTUQQDCL_js.cn("[&_tr:last-child]:border-0", className),
1483
1483
  ...props
1484
1484
  }
1485
1485
  ));
@@ -1488,7 +1488,7 @@ var TableFooter = React10__namespace.forwardRef(({ className, ...props }, ref) =
1488
1488
  "tfoot",
1489
1489
  {
1490
1490
  ref,
1491
- className: chunk23BJPJOK_js.cn(
1491
+ className: chunkNTUQQDCL_js.cn(
1492
1492
  "border-t border-gray-200 bg-gray-50 font-medium dark:border-neutral-700 dark:bg-neutral-800/50 [&>tr]:last:border-b-0",
1493
1493
  className
1494
1494
  ),
@@ -1529,7 +1529,7 @@ var TableRow = React10__namespace.forwardRef(
1529
1529
  ref,
1530
1530
  "data-state": isSelected ? "selected" : void 0,
1531
1531
  "data-row-id": finalRowId,
1532
- className: chunk23BJPJOK_js.cn(
1532
+ className: chunkNTUQQDCL_js.cn(
1533
1533
  "border-b border-gray-200 transition-colors hover:bg-gray-50 data-[state=selected]:bg-blue-50 dark:border-neutral-700 dark:hover:bg-neutral-800/50 dark:data-[state=selected]:bg-blue-900/20",
1534
1534
  className
1535
1535
  ),
@@ -1549,7 +1549,7 @@ var TableHead = React10__namespace.forwardRef(({ className, style, ...props }, r
1549
1549
  {
1550
1550
  ref,
1551
1551
  style: context?.stickyHeader ? { boxShadow: yShadow, ...style } : style,
1552
- className: chunk23BJPJOK_js.cn(
1552
+ className: chunkNTUQQDCL_js.cn(
1553
1553
  "h-12 px-4 text-left align-middle font-medium text-gray-500 dark:text-gray-400 [&:has([role=checkbox])]:pr-0",
1554
1554
  context?.stickyHeader && "sticky top-0 z-20 bg-gray-50 dark:bg-neutral-800",
1555
1555
  className
@@ -1564,7 +1564,7 @@ var TableCell = React10__namespace.forwardRef(
1564
1564
  "td",
1565
1565
  {
1566
1566
  ref,
1567
- className: chunk23BJPJOK_js.cn(
1567
+ className: chunkNTUQQDCL_js.cn(
1568
1568
  "align-middle [&:has([role=checkbox])]:pr-0",
1569
1569
  variant === "embed" ? "p-1.5" : "p-4",
1570
1570
  className
@@ -1578,7 +1578,7 @@ var TableCaption = React10__namespace.forwardRef(({ className, ...props }, ref)
1578
1578
  "caption",
1579
1579
  {
1580
1580
  ref,
1581
- className: chunk23BJPJOK_js.cn("mt-4 text-sm text-gray-500 dark:text-gray-400", className),
1581
+ className: chunkNTUQQDCL_js.cn("mt-4 text-sm text-gray-500 dark:text-gray-400", className),
1582
1582
  ...props
1583
1583
  }
1584
1584
  ));
@@ -1720,7 +1720,7 @@ function ColumnSelection({
1720
1720
  return /* @__PURE__ */ jsxRuntime.jsxs(
1721
1721
  "label",
1722
1722
  {
1723
- className: chunk23BJPJOK_js.cn(
1723
+ className: chunkNTUQQDCL_js.cn(
1724
1724
  "flex items-center gap-2.5 rounded-hz-md px-2 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-neutral-800",
1725
1725
  isSticky && "opacity-50 cursor-not-allowed"
1726
1726
  ),
@@ -1824,7 +1824,7 @@ var TabsList = React10__namespace.forwardRef(({ className, children, variant = "
1824
1824
  else if (ref) ref.current = node;
1825
1825
  listRef.current = node;
1826
1826
  },
1827
- className: chunk23BJPJOK_js.cn(
1827
+ className: chunkNTUQQDCL_js.cn(
1828
1828
  variant === "pill" ? "relative inline-flex h-10 items-center justify-center rounded-hz-lg p-1 bg-gray-100 text-gray-500 dark:bg-neutral-700 dark:text-gray-400" : "flex gap-4 border-b border-gray-200 dark:border-neutral-800",
1829
1829
  className
1830
1830
  ),
@@ -1870,12 +1870,12 @@ var TabsTrigger = React10__namespace.forwardRef(({ className, value, icon, child
1870
1870
  else if (ref) ref.current = node;
1871
1871
  },
1872
1872
  value,
1873
- className: chunk23BJPJOK_js.cn(
1873
+ className: chunkNTUQQDCL_js.cn(
1874
1874
  "inline-flex items-center gap-1.5 whitespace-nowrap text-sm font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
1875
- variant === "pill" ? chunk23BJPJOK_js.cn(
1875
+ variant === "pill" ? chunkNTUQQDCL_js.cn(
1876
1876
  "relative z-10 justify-center rounded-hz-md px-3 py-1.5 transition-colors",
1877
1877
  isActive ? "text-gray-900 dark:text-gray-100" : "text-gray-500 dark:text-gray-400"
1878
- ) : chunk23BJPJOK_js.cn(
1878
+ ) : chunkNTUQQDCL_js.cn(
1879
1879
  "pb-3 border-b-2 transition-colors",
1880
1880
  isActive ? "border-blue-600 text-blue-600 dark:border-blue-400 dark:text-blue-400" : "border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-600"
1881
1881
  ),
@@ -1894,7 +1894,7 @@ var TabsContent = React10__namespace.forwardRef(({ className, ...props }, ref) =
1894
1894
  TabsPrimitive__namespace.Content,
1895
1895
  {
1896
1896
  ref,
1897
- className: chunk23BJPJOK_js.cn(
1897
+ className: chunkNTUQQDCL_js.cn(
1898
1898
  "mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2",
1899
1899
  className
1900
1900
  ),
@@ -1907,7 +1907,7 @@ var Textarea = React10__namespace.forwardRef(
1907
1907
  return /* @__PURE__ */ jsxRuntime.jsx(
1908
1908
  "textarea",
1909
1909
  {
1910
- className: chunk23BJPJOK_js.cn(
1910
+ className: chunkNTUQQDCL_js.cn(
1911
1911
  "flex min-h-[80px] w-full rounded-hz-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 placeholder:text-gray-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-neutral-600 dark:bg-neutral-800 dark:text-gray-100 dark:placeholder:text-gray-500",
1912
1912
  className
1913
1913
  ),
@@ -1986,7 +1986,7 @@ function Toggle({
1986
1986
  ...props,
1987
1987
  type: "multiple",
1988
1988
  ...value !== void 0 ? { value, onValueChange: onChange } : {},
1989
- className: chunk23BJPJOK_js.cn(
1989
+ className: chunkNTUQQDCL_js.cn(
1990
1990
  toggleGroupVariants({ size }),
1991
1991
  containerRadiusClass2[radius],
1992
1992
  className
@@ -1999,7 +1999,7 @@ function Toggle({
1999
1999
  value: option.value,
2000
2000
  disabled: option.disabled,
2001
2001
  "aria-label": iconOnly ? option.ariaLabel ?? option.value : void 0,
2002
- className: chunk23BJPJOK_js.cn(
2002
+ className: chunkNTUQQDCL_js.cn(
2003
2003
  toggleItemVariants({ size, iconOnly }),
2004
2004
  itemRadiusClass2[radius],
2005
2005
  "border border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200",
@@ -2068,7 +2068,7 @@ var Switch = React10__namespace.forwardRef(({ className, size, label, labelPosit
2068
2068
  ...props,
2069
2069
  id: switchId,
2070
2070
  ref,
2071
- className: chunk23BJPJOK_js.cn(switchTrackVariants({ size }), className),
2071
+ className: chunkNTUQQDCL_js.cn(switchTrackVariants({ size }), className),
2072
2072
  children: /* @__PURE__ */ jsxRuntime.jsx(SwitchPrimitive__namespace.Thumb, { className: switchThumbVariants({ size }) })
2073
2073
  }
2074
2074
  );
@@ -2076,7 +2076,7 @@ var Switch = React10__namespace.forwardRef(({ className, size, label, labelPosit
2076
2076
  return /* @__PURE__ */ jsxRuntime.jsxs(
2077
2077
  "div",
2078
2078
  {
2079
- className: chunk23BJPJOK_js.cn(
2079
+ className: chunkNTUQQDCL_js.cn(
2080
2080
  "inline-flex items-center gap-2",
2081
2081
  props.disabled ? "cursor-not-allowed" : "cursor-pointer"
2082
2082
  ),
@@ -2085,7 +2085,7 @@ var Switch = React10__namespace.forwardRef(({ className, size, label, labelPosit
2085
2085
  "label",
2086
2086
  {
2087
2087
  htmlFor: switchId,
2088
- className: chunk23BJPJOK_js.cn(
2088
+ className: chunkNTUQQDCL_js.cn(
2089
2089
  switchLabelVariants({ size }),
2090
2090
  props.disabled ? "cursor-not-allowed" : "cursor-pointer"
2091
2091
  ),
@@ -2097,7 +2097,7 @@ var Switch = React10__namespace.forwardRef(({ className, size, label, labelPosit
2097
2097
  "label",
2098
2098
  {
2099
2099
  htmlFor: switchId,
2100
- className: chunk23BJPJOK_js.cn(
2100
+ className: chunkNTUQQDCL_js.cn(
2101
2101
  switchLabelVariants({ size }),
2102
2102
  props.disabled ? "cursor-not-allowed" : "cursor-pointer"
2103
2103
  ),
@@ -2138,6 +2138,7 @@ function TimeInput({
2138
2138
  max,
2139
2139
  onChange,
2140
2140
  onComplete,
2141
+ onDirty,
2141
2142
  inputRef,
2142
2143
  disabled = false,
2143
2144
  "aria-label": ariaLabel
@@ -2145,32 +2146,51 @@ function TimeInput({
2145
2146
  const [editValue, setEditValue] = React10__namespace.useState(null);
2146
2147
  const internalRef = React10__namespace.useRef(null);
2147
2148
  const committedRef = React10__namespace.useRef(false);
2148
- const setRefs = React10__namespace.useCallback(chunk23BJPJOK_js.mergeRefs(internalRef, inputRef), [inputRef]);
2149
- const handleChange = (e) => {
2150
- const raw = e.target.value.replace(/\D/g, "").slice(0, 2);
2151
- if (raw === "") {
2152
- setEditValue(raw);
2153
- return;
2154
- }
2155
- if (raw.length === 1) {
2156
- setEditValue(raw);
2157
- return;
2158
- }
2149
+ const pendingDigitRef = React10__namespace.useRef(null);
2150
+ const setRefs = React10__namespace.useCallback(chunkNTUQQDCL_js.mergeRefs(internalRef, inputRef), [inputRef]);
2151
+ const commitTwoDigits = (raw) => {
2159
2152
  const parsed = parseInt(raw, 10);
2160
2153
  const clamped = clamp(parsed, min2, max);
2154
+ pendingDigitRef.current = null;
2161
2155
  committedRef.current = true;
2162
2156
  onChange(clamped);
2163
2157
  setEditValue(null);
2164
2158
  onComplete?.();
2165
2159
  };
2160
+ const handleChange = (e) => {
2161
+ const allDigits = e.target.value.replace(/\D/g, "");
2162
+ if (allDigits === "") {
2163
+ setEditValue("");
2164
+ pendingDigitRef.current = null;
2165
+ return;
2166
+ }
2167
+ if (pendingDigitRef.current !== null) {
2168
+ if (allDigits.length > 2) {
2169
+ commitTwoDigits(pendingDigitRef.current + allDigits[allDigits.length - 1]);
2170
+ return;
2171
+ }
2172
+ pendingDigitRef.current = null;
2173
+ setEditValue("");
2174
+ return;
2175
+ }
2176
+ if (allDigits.length === 1) {
2177
+ pendingDigitRef.current = allDigits;
2178
+ setEditValue("0" + allDigits);
2179
+ onDirty?.();
2180
+ return;
2181
+ }
2182
+ commitTwoDigits(allDigits.slice(0, 2));
2183
+ };
2166
2184
  const commit = () => {
2167
2185
  if (committedRef.current) {
2168
2186
  committedRef.current = false;
2187
+ pendingDigitRef.current = null;
2169
2188
  setEditValue(null);
2170
2189
  return;
2171
2190
  }
2172
2191
  if (editValue === null) return;
2173
2192
  if (editValue === "") {
2193
+ pendingDigitRef.current = null;
2174
2194
  setEditValue(null);
2175
2195
  return;
2176
2196
  }
@@ -2178,6 +2198,7 @@ function TimeInput({
2178
2198
  if (!isNaN(parsed)) {
2179
2199
  onChange(clamp(parsed, min2, max));
2180
2200
  }
2201
+ pendingDigitRef.current = null;
2181
2202
  setEditValue(null);
2182
2203
  };
2183
2204
  const handleKeyDown = (e) => {
@@ -2185,16 +2206,19 @@ function TimeInput({
2185
2206
  commit();
2186
2207
  internalRef.current?.blur();
2187
2208
  } else if (e.key === "Escape") {
2209
+ pendingDigitRef.current = null;
2188
2210
  setEditValue(null);
2189
2211
  internalRef.current?.blur();
2190
2212
  } else if (e.key === "ArrowUp") {
2191
2213
  e.preventDefault();
2214
+ pendingDigitRef.current = null;
2192
2215
  const curr = value ?? min2;
2193
2216
  const next = curr >= max ? min2 : curr + 1;
2194
2217
  onChange(next);
2195
2218
  setEditValue(pad(next));
2196
2219
  } else if (e.key === "ArrowDown") {
2197
2220
  e.preventDefault();
2221
+ pendingDigitRef.current = null;
2198
2222
  const curr = value ?? max;
2199
2223
  const next = curr <= min2 ? max : curr - 1;
2200
2224
  onChange(next);
@@ -2212,12 +2236,13 @@ function TimeInput({
2212
2236
  value: editValue ?? (value === null ? "--" : pad(value)),
2213
2237
  onChange: handleChange,
2214
2238
  onFocus: (e) => {
2239
+ pendingDigitRef.current = null;
2215
2240
  setEditValue("");
2216
2241
  requestAnimationFrame(() => e.target.select());
2217
2242
  },
2218
2243
  onBlur: () => commit(),
2219
2244
  onKeyDown: handleKeyDown,
2220
- className: chunk23BJPJOK_js.cn(
2245
+ className: chunkNTUQQDCL_js.cn(
2221
2246
  "w-9 h-8 rounded-md border text-center text-sm tabular-nums font-medium outline-none transition-colors",
2222
2247
  "bg-white border-gray-200 text-gray-600",
2223
2248
  "focus:border-blue-500 focus:ring-1 focus:ring-blue-500/30 focus:text-gray-700",
@@ -2232,7 +2257,7 @@ function PeriodToggle({ value, onChange, disabled = false }) {
2232
2257
  return /* @__PURE__ */ jsxRuntime.jsx(
2233
2258
  "div",
2234
2259
  {
2235
- className: chunk23BJPJOK_js.cn(
2260
+ className: chunkNTUQQDCL_js.cn(
2236
2261
  "inline-flex rounded-md border overflow-hidden",
2237
2262
  disabled && "opacity-40 cursor-not-allowed",
2238
2263
  "border-gray-200 dark:border-neutral-600"
@@ -2243,7 +2268,7 @@ function PeriodToggle({ value, onChange, disabled = false }) {
2243
2268
  type: "button",
2244
2269
  disabled,
2245
2270
  onClick: () => onChange(p),
2246
- className: chunk23BJPJOK_js.cn(
2271
+ className: chunkNTUQQDCL_js.cn(
2247
2272
  "px-2 h-8 text-xs font-semibold tracking-wide transition-colors",
2248
2273
  "disabled:pointer-events-none",
2249
2274
  value === p ? "!bg-blue-600 !text-white dark:!bg-blue-500" : "bg-white text-gray-500 hover:bg-gray-50 hover:text-gray-600 dark:bg-neutral-800 dark:text-gray-400 dark:hover:bg-neutral-700"
@@ -2262,11 +2287,12 @@ function TimeField({
2262
2287
  hourRef,
2263
2288
  minuteRef,
2264
2289
  onMinuteComplete,
2290
+ onDirty,
2265
2291
  disabled = false
2266
2292
  }) {
2267
2293
  const { hour12, period } = to12Hour(value.hour);
2268
2294
  const minuteInputRef = React10__namespace.useRef(null);
2269
- const mergedMinuteRef = React10__namespace.useCallback(chunk23BJPJOK_js.mergeRefs(minuteInputRef, minuteRef), [minuteRef]);
2295
+ const mergedMinuteRef = React10__namespace.useCallback(chunkNTUQQDCL_js.mergeRefs(minuteInputRef, minuteRef), [minuteRef]);
2270
2296
  const handleHourChange = (newHour12) => {
2271
2297
  onChange({ ...value, hour: to24Hour(newHour12, period) });
2272
2298
  };
@@ -2284,7 +2310,7 @@ function TimeField({
2284
2310
  /* @__PURE__ */ jsxRuntime.jsx(
2285
2311
  "span",
2286
2312
  {
2287
- className: chunk23BJPJOK_js.cn(
2313
+ className: chunkNTUQQDCL_js.cn(
2288
2314
  "text-xs font-semibold uppercase tracking-wider",
2289
2315
  disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
2290
2316
  ),
@@ -2300,6 +2326,7 @@ function TimeField({
2300
2326
  max: 12,
2301
2327
  onChange: handleHourChange,
2302
2328
  onComplete: focusMinute,
2329
+ onDirty,
2303
2330
  inputRef: hourRef,
2304
2331
  disabled,
2305
2332
  "aria-label": `${label} hour`
@@ -2308,7 +2335,7 @@ function TimeField({
2308
2335
  /* @__PURE__ */ jsxRuntime.jsx(
2309
2336
  "span",
2310
2337
  {
2311
- className: chunk23BJPJOK_js.cn(
2338
+ className: chunkNTUQQDCL_js.cn(
2312
2339
  "text-sm font-bold select-none",
2313
2340
  disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
2314
2341
  ),
@@ -2323,6 +2350,7 @@ function TimeField({
2323
2350
  max: 59,
2324
2351
  onChange: handleMinuteChange,
2325
2352
  onComplete: onMinuteComplete,
2353
+ onDirty,
2326
2354
  inputRef: mergedMinuteRef,
2327
2355
  disabled,
2328
2356
  "aria-label": `${label} minute`
@@ -2339,11 +2367,14 @@ function TimeField({
2339
2367
  ] })
2340
2368
  ] });
2341
2369
  }
2342
- function TimePickerColumn({ value, onChange, disabled = false }) {
2343
- const toHourRef = React10__namespace.useRef(null);
2370
+ function useTimeFieldState(value) {
2344
2371
  const fromSet = isTimeSet(value.from);
2345
2372
  const toSet = isTimeSet(value.to);
2346
2373
  const bothSet = fromSet && toSet;
2374
+ const orphanMinutes = value.from.hour === null && value.from.minute !== null || value.to.hour === null && value.to.minute !== null;
2375
+ const fromPartial = !fromSet && (value.from.hour !== null || value.from.minute !== null);
2376
+ const toPartial = !toSet && (value.to.hour !== null || value.to.minute !== null);
2377
+ const oneSideMissing = fromSet && !toSet && !toPartial || toSet && !fromSet && !fromPartial;
2347
2378
  const fromMinutes = (value.from.hour ?? 0) * 60 + (value.from.minute ?? 0);
2348
2379
  const toMinutes = (value.to.hour ?? 0) * 60 + (value.to.minute ?? 0);
2349
2380
  const bothEqual = fromMinutes === toMinutes;
@@ -2353,140 +2384,142 @@ function TimePickerColumn({ value, onChange, disabled = false }) {
2353
2384
  const durationRemaining = durationMinutes % 60;
2354
2385
  const showDuration = bothSet && !bothEqual;
2355
2386
  const durationLabel = durationRemaining > 0 ? `${durationHours}h ${durationRemaining}m window${isOvernight ? " (overnight)" : ""}` : `${durationHours}h window${isOvernight ? " (overnight)" : ""}`;
2356
- return /* @__PURE__ */ jsxRuntime.jsxs(
2357
- "div",
2358
- {
2359
- className: chunk23BJPJOK_js.cn(
2360
- "flex flex-col px-2 pt-2 pb-2 gap-1",
2361
- "border-t border-gray-100 dark:border-neutral-700"
2387
+ const incompleteHint = orphanMinutes ? "Please set hours for the time to take effect" : fromPartial || toPartial ? "Please complete both hour and minute fields" : oneSideMissing ? `Please set the ${fromSet ? "to" : "from"} time` : null;
2388
+ return { showDuration, durationLabel, isOvernight, incompleteHint };
2389
+ }
2390
+ function TimePickerColumn({ value, onChange, disabled = false, onRemove, showRemove = false, onDirty }) {
2391
+ const toHourRef = React10__namespace.useRef(null);
2392
+ const { showDuration, durationLabel, isOvernight, incompleteHint } = useTimeFieldState(value);
2393
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col px-2 pt-2 pb-2 gap-1", children: [
2394
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2395
+ /* @__PURE__ */ jsxRuntime.jsx(
2396
+ lucideReact.Clock,
2397
+ {
2398
+ className: chunkNTUQQDCL_js.cn(
2399
+ "w-4 h-4 shrink-0",
2400
+ disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
2401
+ )
2402
+ }
2362
2403
  ),
2363
- children: [
2364
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2365
- /* @__PURE__ */ jsxRuntime.jsx(
2366
- lucideReact.Clock,
2367
- {
2368
- className: chunk23BJPJOK_js.cn(
2369
- "w-4 h-4 shrink-0",
2370
- disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
2371
- )
2372
- }
2373
- ),
2374
- /* @__PURE__ */ jsxRuntime.jsx(
2375
- "span",
2376
- {
2377
- className: chunk23BJPJOK_js.cn(
2378
- "text-xs font-semibold uppercase tracking-wider",
2379
- disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
2380
- ),
2381
- children: "Time"
2382
- }
2383
- ),
2384
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] font-medium text-gray-400 dark:text-gray-600 tracking-wide", children: "(Optional)" })
2385
- ] }),
2386
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 pl-6", children: [
2387
- /* @__PURE__ */ jsxRuntime.jsx(
2388
- TimeField,
2389
- {
2390
- label: "From",
2391
- value: value.from,
2392
- onChange: (from) => onChange({ ...value, from }),
2393
- onMinuteComplete: () => toHourRef.current?.focus(),
2394
- disabled
2395
- }
2396
- ),
2397
- /* @__PURE__ */ jsxRuntime.jsx(
2398
- TimeField,
2399
- {
2400
- label: "To",
2401
- value: value.to,
2402
- onChange: (to) => onChange({ ...value, to }),
2403
- hourRef: toHourRef,
2404
- disabled
2405
- }
2404
+ /* @__PURE__ */ jsxRuntime.jsx(
2405
+ "span",
2406
+ {
2407
+ className: chunkNTUQQDCL_js.cn(
2408
+ "text-xs font-semibold uppercase tracking-wider",
2409
+ disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
2406
2410
  ),
2407
- showDuration && /* @__PURE__ */ jsxRuntime.jsx("span", { className: chunk23BJPJOK_js.cn(
2408
- "text-[10px] font-medium",
2409
- isOvernight ? "text-amber-500 dark:text-amber-400" : "text-gray-400 dark:text-gray-500"
2410
- ), children: durationLabel })
2411
- ] })
2412
- ]
2413
- }
2414
- );
2411
+ children: "Time"
2412
+ }
2413
+ ),
2414
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] font-medium text-gray-400 dark:text-gray-600 tracking-wide", children: "(Optional)" }),
2415
+ showRemove && onRemove && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
2416
+ chunkNTUQQDCL_js.TextButton,
2417
+ {
2418
+ variant: "danger",
2419
+ onClick: onRemove,
2420
+ size: "sm",
2421
+ className: "!text-[0.625rem]",
2422
+ children: "Remove"
2423
+ }
2424
+ ) })
2425
+ ] }),
2426
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 pl-6", children: [
2427
+ /* @__PURE__ */ jsxRuntime.jsx(
2428
+ TimeField,
2429
+ {
2430
+ label: "From",
2431
+ value: value.from,
2432
+ onChange: (from) => onChange({ ...value, from }),
2433
+ onMinuteComplete: () => toHourRef.current?.focus(),
2434
+ onDirty,
2435
+ disabled
2436
+ }
2437
+ ),
2438
+ /* @__PURE__ */ jsxRuntime.jsx(
2439
+ TimeField,
2440
+ {
2441
+ label: "To",
2442
+ value: value.to,
2443
+ onChange: (to) => onChange({ ...value, to }),
2444
+ hourRef: toHourRef,
2445
+ onDirty,
2446
+ disabled
2447
+ }
2448
+ ),
2449
+ showDuration && /* @__PURE__ */ jsxRuntime.jsx("span", { className: chunkNTUQQDCL_js.cn(
2450
+ "text-[10px] font-medium",
2451
+ isOvernight ? "text-amber-500 dark:text-amber-400" : "text-gray-400 dark:text-gray-500"
2452
+ ), children: durationLabel }),
2453
+ incompleteHint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-amber-500 dark:text-amber-400", children: incompleteHint })
2454
+ ] })
2455
+ ] });
2415
2456
  }
2416
- function TimePickerRow({ value, onChange, disabled = false }) {
2457
+ function TimePickerRow({ value, onChange, disabled = false, onRemove, showRemove = false, onDirty }) {
2417
2458
  const toHourRef = React10__namespace.useRef(null);
2418
- const fromSet = isTimeSet(value.from);
2419
- const toSet = isTimeSet(value.to);
2420
- const bothSet = fromSet && toSet;
2421
- const fromMinutes = (value.from.hour ?? 0) * 60 + (value.from.minute ?? 0);
2422
- const toMinutes = (value.to.hour ?? 0) * 60 + (value.to.minute ?? 0);
2423
- const bothEqual = fromMinutes === toMinutes;
2424
- const isOvernight = bothSet && toMinutes < fromMinutes;
2425
- const durationMinutes = bothSet && !bothEqual ? isOvernight ? 24 * 60 - fromMinutes + toMinutes : toMinutes - fromMinutes : 0;
2426
- const durationHours = Math.floor(durationMinutes / 60);
2427
- const durationRemaining = durationMinutes % 60;
2428
- const showDuration = bothSet && !bothEqual;
2429
- const durationLabel = durationRemaining > 0 ? `${durationHours}h ${durationRemaining}m window${isOvernight ? " (overnight)" : ""}` : `${durationHours}h window${isOvernight ? " (overnight)" : ""}`;
2430
- return /* @__PURE__ */ jsxRuntime.jsx(
2431
- "div",
2432
- {
2433
- className: chunk23BJPJOK_js.cn(
2434
- "flex flex-col px-4 pt-2 pb-3 gap-1",
2435
- "border-t border-gray-100 dark:border-neutral-700"
2459
+ const { showDuration, durationLabel, isOvernight, incompleteHint } = useTimeFieldState(value);
2460
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col px-4 pt-2 pb-3 gap-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
2461
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-1", children: [
2462
+ /* @__PURE__ */ jsxRuntime.jsx(
2463
+ lucideReact.Clock,
2464
+ {
2465
+ className: chunkNTUQQDCL_js.cn(
2466
+ "w-4 h-4 shrink-0",
2467
+ disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
2468
+ )
2469
+ }
2436
2470
  ),
2437
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
2438
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-1", children: [
2439
- /* @__PURE__ */ jsxRuntime.jsx(
2440
- lucideReact.Clock,
2441
- {
2442
- className: chunk23BJPJOK_js.cn(
2443
- "w-4 h-4 shrink-0",
2444
- disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
2445
- )
2446
- }
2447
- ),
2448
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] font-medium text-gray-300 dark:text-gray-600 tracking-wide", children: "OPT" })
2449
- ] }),
2450
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 flex-1", children: [
2451
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-5", children: [
2452
- /* @__PURE__ */ jsxRuntime.jsx(
2453
- TimeField,
2454
- {
2455
- label: "From",
2456
- value: value.from,
2457
- onChange: (from) => onChange({ ...value, from }),
2458
- onMinuteComplete: () => toHourRef.current?.focus(),
2459
- disabled
2460
- }
2461
- ),
2462
- /* @__PURE__ */ jsxRuntime.jsx(
2463
- "div",
2464
- {
2465
- className: chunk23BJPJOK_js.cn(
2466
- "w-4 h-px",
2467
- disabled ? "bg-gray-200 dark:bg-neutral-700" : "bg-gray-300 dark:bg-neutral-600"
2468
- )
2469
- }
2470
- ),
2471
- /* @__PURE__ */ jsxRuntime.jsx(
2472
- TimeField,
2473
- {
2474
- label: "To",
2475
- value: value.to,
2476
- onChange: (to) => onChange({ ...value, to }),
2477
- hourRef: toHourRef,
2478
- disabled
2479
- }
2471
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] font-medium text-gray-300 dark:text-gray-600 tracking-wide", children: "OPT" })
2472
+ ] }),
2473
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 flex-1", children: [
2474
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
2475
+ /* @__PURE__ */ jsxRuntime.jsx(
2476
+ TimeField,
2477
+ {
2478
+ label: "From",
2479
+ value: value.from,
2480
+ onChange: (from) => onChange({ ...value, from }),
2481
+ onMinuteComplete: () => toHourRef.current?.focus(),
2482
+ onDirty,
2483
+ disabled
2484
+ }
2485
+ ),
2486
+ /* @__PURE__ */ jsxRuntime.jsx(
2487
+ "div",
2488
+ {
2489
+ className: chunkNTUQQDCL_js.cn(
2490
+ "w-4 h-px",
2491
+ disabled ? "bg-gray-200 dark:bg-neutral-700" : "bg-gray-300 dark:bg-neutral-600"
2480
2492
  )
2481
- ] }),
2482
- showDuration && /* @__PURE__ */ jsxRuntime.jsx("span", { className: chunk23BJPJOK_js.cn(
2483
- "text-[10px] font-medium pl-0.5",
2484
- isOvernight ? "text-amber-500 dark:text-amber-400" : "text-gray-400 dark:text-gray-500"
2485
- ), children: durationLabel })
2486
- ] })
2487
- ] })
2488
- }
2489
- );
2493
+ }
2494
+ ),
2495
+ /* @__PURE__ */ jsxRuntime.jsx(
2496
+ TimeField,
2497
+ {
2498
+ label: "To",
2499
+ value: value.to,
2500
+ onChange: (to) => onChange({ ...value, to }),
2501
+ hourRef: toHourRef,
2502
+ onDirty,
2503
+ disabled
2504
+ }
2505
+ ),
2506
+ showRemove && onRemove && /* @__PURE__ */ jsxRuntime.jsx(
2507
+ Button,
2508
+ {
2509
+ variant: "outline",
2510
+ onClick: onRemove,
2511
+ className: "text-[0.625rem] border border-red-100 dark:border-red-700 rounded-md px-2 py-1 h-8 text-red-500 hover:text-red-600 dark:text-red-400 dark:hover:text-red-300 transition-colors",
2512
+ children: "Remove"
2513
+ }
2514
+ )
2515
+ ] }),
2516
+ showDuration && /* @__PURE__ */ jsxRuntime.jsx("span", { className: chunkNTUQQDCL_js.cn(
2517
+ "text-[10px] font-medium pl-0.5",
2518
+ isOvernight ? "text-amber-500 dark:text-amber-400" : "text-gray-400 dark:text-gray-500"
2519
+ ), children: durationLabel }),
2520
+ incompleteHint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium pl-0.5 text-amber-500 dark:text-amber-400", children: incompleteHint })
2521
+ ] })
2522
+ ] }) });
2490
2523
  }
2491
2524
  var WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
2492
2525
  function getCalendarDays(month) {
@@ -2534,7 +2567,7 @@ function CalendarMonth({
2534
2567
  "button",
2535
2568
  {
2536
2569
  onClick: onPrevMonth,
2537
- className: chunk23BJPJOK_js.cn(
2570
+ className: chunkNTUQQDCL_js.cn(
2538
2571
  "p-1 rounded-md transition-colors",
2539
2572
  showPrevNav ? "hover:bg-gray-100 dark:hover:bg-neutral-700 text-gray-500 dark:text-gray-400" : "invisible pointer-events-none"
2540
2573
  ),
@@ -2546,7 +2579,7 @@ function CalendarMonth({
2546
2579
  "button",
2547
2580
  {
2548
2581
  onClick: onNextMonth,
2549
- className: chunk23BJPJOK_js.cn(
2582
+ className: chunkNTUQQDCL_js.cn(
2550
2583
  "p-1 rounded-md transition-colors",
2551
2584
  showNextNav ? "hover:bg-gray-100 dark:hover:bg-neutral-700 text-gray-500 dark:text-gray-400" : "invisible pointer-events-none"
2552
2585
  ),
@@ -2581,7 +2614,7 @@ function CalendarMonth({
2581
2614
  return /* @__PURE__ */ jsxRuntime.jsx(
2582
2615
  "div",
2583
2616
  {
2584
- className: chunk23BJPJOK_js.cn(
2617
+ className: chunkNTUQQDCL_js.cn(
2585
2618
  "h-9 flex items-center justify-center",
2586
2619
  (inRange || rangeStart || rangeEnd) && "bg-blue-50 dark:bg-blue-950/40",
2587
2620
  rangeStart && !rangeEnd && "rounded-l-full",
@@ -2595,7 +2628,7 @@ function CalendarMonth({
2595
2628
  onMouseEnter: () => !disabled && onDayHover(day),
2596
2629
  tabIndex: disabled ? -1 : 0,
2597
2630
  disabled,
2598
- className: chunk23BJPJOK_js.cn(
2631
+ className: chunkNTUQQDCL_js.cn(
2599
2632
  "w-8 h-8 rounded-full text-sm flex items-center justify-center transition-colors",
2600
2633
  isFuture && "text-gray-300 dark:text-gray-600 pointer-events-none cursor-not-allowed",
2601
2634
  !disabled && !rangeStart && !rangeEnd && "text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-neutral-700",
@@ -2614,6 +2647,167 @@ function CalendarMonth({
2614
2647
  )
2615
2648
  ] });
2616
2649
  }
2650
+ function useDateRangePicker({
2651
+ value,
2652
+ onChange,
2653
+ showTimePicker = false,
2654
+ timeValue,
2655
+ onTimeChange
2656
+ }) {
2657
+ const [open, setOpen] = React10__namespace.useState(false);
2658
+ const [internalRange, setInternalRange] = React10__namespace.useState({
2659
+ from: void 0,
2660
+ to: void 0
2661
+ });
2662
+ const [draft, setDraft] = React10__namespace.useState({
2663
+ from: void 0,
2664
+ to: void 0
2665
+ });
2666
+ const [hoverDate, setHoverDate] = React10__namespace.useState();
2667
+ const [viewMonth, setViewMonth] = React10__namespace.useState(
2668
+ () => dateFns.startOfMonth(value?.from ?? /* @__PURE__ */ new Date())
2669
+ );
2670
+ const [activePreset, setActivePreset] = React10__namespace.useState();
2671
+ const [committedInternalTime, setCommittedInternalTime] = React10__namespace.useState(DEFAULT_TIME_RANGE);
2672
+ const [draftTime, setDraftTime] = React10__namespace.useState(DEFAULT_TIME_RANGE);
2673
+ const [timeExpanded, setTimeExpanded] = React10__namespace.useState(false);
2674
+ const [timeDirty, setTimeDirty] = React10__namespace.useState(false);
2675
+ const committedRange = value ?? internalRange;
2676
+ const committedTime = timeValue ?? committedInternalTime;
2677
+ const timeVisible = !!(draft.from && draft.to);
2678
+ const hasAnyTimeInput = timeDirty || draftTime.from.hour !== null || draftTime.from.minute !== null || draftTime.to.hour !== null || draftTime.to.minute !== null;
2679
+ const isTimeComplete2 = draftTime.from.hour !== null && draftTime.from.minute !== null && draftTime.to.hour !== null && draftTime.to.minute !== null;
2680
+ const hasPartialTime = showTimePicker && timeExpanded && !isTimeComplete2;
2681
+ const canClear = !!(draft.from || committedRange.from);
2682
+ const canApply = !(draft.from && !draft.to) && !!(draft.from || committedRange.from) && !hasPartialTime;
2683
+ const resetTime = React10__namespace.useCallback(() => {
2684
+ setDraftTime(DEFAULT_TIME_RANGE);
2685
+ setTimeExpanded(false);
2686
+ setTimeDirty(false);
2687
+ }, []);
2688
+ const handleTimeChange = React10__namespace.useCallback((newTime) => {
2689
+ setDraftTime(newTime);
2690
+ }, []);
2691
+ const handleOpenChange = React10__namespace.useCallback(
2692
+ (newOpen) => {
2693
+ if (newOpen) {
2694
+ setDraft(committedRange);
2695
+ if (committedRange.from)
2696
+ setViewMonth(dateFns.startOfMonth(committedRange.from));
2697
+ setDraftTime(committedTime);
2698
+ const hasExistingTime = committedTime.from.hour !== null || committedTime.from.minute !== null || committedTime.to.hour !== null || committedTime.to.minute !== null;
2699
+ setTimeExpanded(hasExistingTime);
2700
+ setTimeDirty(false);
2701
+ }
2702
+ setOpen(newOpen);
2703
+ },
2704
+ [committedRange, committedTime]
2705
+ );
2706
+ const handleDayClick = React10__namespace.useCallback(
2707
+ (date) => {
2708
+ const { from, to } = draft;
2709
+ if (!from || from && to) {
2710
+ setDraft({ from: date, to: void 0 });
2711
+ setActivePreset(void 0);
2712
+ if (showTimePicker && timeExpanded) {
2713
+ resetTime();
2714
+ }
2715
+ return;
2716
+ }
2717
+ const [start, end] = dateFns.isBefore(from, date) ? [from, date] : [date, from];
2718
+ setDraft({ from: start, to: end });
2719
+ setHoverDate(void 0);
2720
+ },
2721
+ [draft, showTimePicker, timeExpanded, resetTime]
2722
+ );
2723
+ const handlePreset = React10__namespace.useCallback(
2724
+ (preset) => {
2725
+ const newRange = preset.getRange();
2726
+ setDraft(newRange);
2727
+ setActivePreset(preset.label);
2728
+ if (newRange.from) setViewMonth(dateFns.startOfMonth(newRange.from));
2729
+ if (showTimePicker) resetTime();
2730
+ },
2731
+ [showTimePicker, resetTime]
2732
+ );
2733
+ const handleApply = React10__namespace.useCallback(() => {
2734
+ if (draft.from && !draft.to) return;
2735
+ const newRange = draft.from && draft.to ? draft : void 0;
2736
+ const rangeChanged = newRange?.from?.getTime() !== committedRange.from?.getTime() || newRange?.to?.getTime() !== committedRange.to?.getTime();
2737
+ const timeChanged = draftTime.from.hour !== committedTime.from.hour || draftTime.from.minute !== committedTime.from.minute || draftTime.to.hour !== committedTime.to.hour || draftTime.to.minute !== committedTime.to.minute;
2738
+ if (rangeChanged) {
2739
+ if (onChange) onChange(newRange);
2740
+ else setInternalRange(newRange ?? { from: void 0, to: void 0 });
2741
+ }
2742
+ if (timeChanged) {
2743
+ if (onTimeChange) onTimeChange(draftTime);
2744
+ else setCommittedInternalTime(draftTime);
2745
+ }
2746
+ setOpen(false);
2747
+ }, [draft, onChange, committedRange, draftTime, committedTime, onTimeChange]);
2748
+ const handleClear = React10__namespace.useCallback(() => {
2749
+ setDraft({ from: void 0, to: void 0 });
2750
+ setActivePreset(void 0);
2751
+ if (showTimePicker) resetTime();
2752
+ }, [showTimePicker, resetTime]);
2753
+ const expandTime = React10__namespace.useCallback(() => {
2754
+ setTimeExpanded(true);
2755
+ }, []);
2756
+ const markTimeDirty = React10__namespace.useCallback(() => {
2757
+ setTimeDirty(true);
2758
+ }, []);
2759
+ return {
2760
+ open,
2761
+ draft,
2762
+ hoverDate,
2763
+ viewMonth,
2764
+ activePreset,
2765
+ committedRange,
2766
+ committedTime,
2767
+ draftTime,
2768
+ timeExpanded,
2769
+ timeVisible,
2770
+ hasAnyTimeInput,
2771
+ canClear,
2772
+ canApply,
2773
+ showTimePicker,
2774
+ setHoverDate,
2775
+ setViewMonth,
2776
+ handleTimeChange,
2777
+ handleOpenChange,
2778
+ handleDayClick,
2779
+ handlePreset,
2780
+ handleApply,
2781
+ handleClear,
2782
+ resetTime,
2783
+ expandTime,
2784
+ markTimeDirty
2785
+ };
2786
+ }
2787
+ function formatTime(hour, minute) {
2788
+ const period = hour >= 12 ? "PM" : "AM";
2789
+ const h = hour % 12 || 12;
2790
+ const m = minute.toString().padStart(2, "0");
2791
+ return `${h}:${m} ${period}`;
2792
+ }
2793
+ function isTimeComplete(time) {
2794
+ return time.from.hour !== null && time.from.minute !== null && time.to.hour !== null && time.to.minute !== null;
2795
+ }
2796
+ function formatDateRange(range, placeholder, time) {
2797
+ if (!range?.from) return placeholder;
2798
+ const hasTime = time && isTimeComplete(time);
2799
+ if (!range.to || dateFns.isSameDay(range.from, range.to)) {
2800
+ const dateStr = dateFns.format(range.from, "MMM d, yyyy");
2801
+ return hasTime ? `${dateStr} ${formatTime(time.from.hour, time.from.minute)} \u2013 ${formatTime(time.to.hour, time.to.minute)}` : dateStr;
2802
+ }
2803
+ const sameYear = range.from.getFullYear() === range.to.getFullYear();
2804
+ const fromDate = dateFns.format(range.from, sameYear ? "MMM d" : "MMM d, yyyy");
2805
+ const toDate = dateFns.format(range.to, "MMM d, yyyy");
2806
+ if (hasTime) {
2807
+ return `${fromDate} ${formatTime(time.from.hour, time.from.minute)} \u2013 ${toDate} ${formatTime(time.to.hour, time.to.minute)}`;
2808
+ }
2809
+ return `${fromDate} \u2013 ${toDate}`;
2810
+ }
2617
2811
  var DEFAULT_PRESETS = [
2618
2812
  {
2619
2813
  label: "Today",
@@ -2661,26 +2855,6 @@ var DEFAULT_PRESETS = [
2661
2855
  }
2662
2856
  }
2663
2857
  ];
2664
- function formatTime(tv) {
2665
- if (tv.hour === null || tv.minute === null) return "--:--";
2666
- const period = tv.hour >= 12 ? "PM" : "AM";
2667
- const h = tv.hour % 12 || 12;
2668
- const m = tv.minute.toString().padStart(2, "0");
2669
- return `${h}:${m} ${period}`;
2670
- }
2671
- function formatDateRange(range, placeholder, time) {
2672
- if (!range?.from) return placeholder;
2673
- const timeActive = time && time.from.hour !== null && time.to.hour !== null;
2674
- const timeSuffix = timeActive ? ` ${formatTime(time.from)} \u2013 ${formatTime(time.to)}` : "";
2675
- if (!range.to || dateFns.isSameDay(range.from, range.to)) {
2676
- return dateFns.format(range.from, "MMM d, yyyy") + timeSuffix;
2677
- }
2678
- const sameYear = range.from.getFullYear() === range.to.getFullYear();
2679
- if (sameYear) {
2680
- return `${dateFns.format(range.from, "MMM d")} \u2013 ${dateFns.format(range.to, "MMM d, yyyy")}${timeSuffix}`;
2681
- }
2682
- return `${dateFns.format(range.from, "MMM d, yyyy")} \u2013 ${dateFns.format(range.to, "MMM d, yyyy")}${timeSuffix}`;
2683
- }
2684
2858
  function DateRangePicker({
2685
2859
  value,
2686
2860
  onChange,
@@ -2694,87 +2868,33 @@ function DateRangePicker({
2694
2868
  timeValue,
2695
2869
  onTimeChange
2696
2870
  }) {
2697
- const [open, setOpen] = React10__namespace.useState(false);
2698
- const [internalRange, setInternalRange] = React10__namespace.useState({
2699
- from: void 0,
2700
- to: void 0
2871
+ const picker = useDateRangePicker({
2872
+ value,
2873
+ onChange,
2874
+ showTimePicker,
2875
+ timeValue,
2876
+ onTimeChange
2701
2877
  });
2702
- const [draft, setDraft] = React10__namespace.useState({
2703
- from: void 0,
2704
- to: void 0
2705
- });
2706
- const [hoverDate, setHoverDate] = React10__namespace.useState();
2707
- const [leftMonth, setLeftMonth] = React10__namespace.useState(
2708
- () => dateFns.startOfMonth(value?.from ?? /* @__PURE__ */ new Date())
2709
- );
2710
- const [activePreset, setActivePreset] = React10__namespace.useState();
2711
- const [internalTime, setInternalTime] = React10__namespace.useState(DEFAULT_TIME_RANGE);
2712
- const committedRange = value ?? internalRange;
2713
- const currentTime = timeValue ?? internalTime;
2714
- const handleTimeChange = (newTime) => {
2715
- if (onTimeChange) onTimeChange(newTime);
2716
- else setInternalTime(newTime);
2717
- };
2718
- const timeVisible = !!(draft.from && draft.to);
2719
- const handleOpenChange = (newOpen) => {
2720
- if (newOpen) {
2721
- setDraft(committedRange);
2722
- if (committedRange.from) setLeftMonth(dateFns.startOfMonth(committedRange.from));
2723
- if (!onTimeChange) setInternalTime(currentTime);
2724
- }
2725
- setOpen(newOpen);
2726
- };
2727
- const handleDayClick = (date) => {
2728
- const { from, to } = draft;
2729
- if (!from || from && to) {
2730
- setDraft({ from: date, to: void 0 });
2731
- setActivePreset(void 0);
2732
- return;
2733
- }
2734
- const [start, end] = dateFns.isBefore(from, date) ? [from, date] : [date, from];
2735
- setDraft({ from: start, to: end });
2736
- setHoverDate(void 0);
2737
- };
2738
- const handlePreset = (preset) => {
2739
- const newRange = preset.getRange();
2740
- setDraft(newRange);
2741
- setActivePreset(preset.label);
2742
- if (newRange.from) setLeftMonth(dateFns.startOfMonth(newRange.from));
2743
- };
2744
- const handleApply = () => {
2745
- if (draft.from && !draft.to) return;
2746
- const newRange = draft.from && draft.to ? draft : void 0;
2747
- if (onChange) onChange(newRange);
2748
- else setInternalRange(newRange ?? { from: void 0, to: void 0 });
2749
- setOpen(false);
2750
- };
2751
- const handleClear = () => {
2752
- setDraft({ from: void 0, to: void 0 });
2753
- setActivePreset(void 0);
2754
- if (showTimePicker) handleTimeChange(DEFAULT_TIME_RANGE);
2755
- };
2756
- const canClear = !!(draft.from || committedRange.from);
2757
- const canApply = !(draft.from && !draft.to) && !!(draft.from || committedRange.from);
2758
- const rightMonth = dateFns.addMonths(leftMonth, 1);
2759
- return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
2878
+ const rightMonth = dateFns.addMonths(picker.viewMonth, 1);
2879
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: picker.open, onOpenChange: picker.handleOpenChange, children: [
2760
2880
  /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
2761
2881
  "button",
2762
2882
  {
2763
2883
  disabled,
2764
- className: chunk23BJPJOK_js.cn(
2884
+ className: chunkNTUQQDCL_js.cn(
2765
2885
  "inline-flex items-center gap-2 rounded-md border border-gray-300 bg-white px-3 py-2 text-sm shadow-sm transition-colors",
2766
2886
  "hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2",
2767
2887
  "dark:border-neutral-600 dark:bg-neutral-800 dark:hover:bg-neutral-700",
2768
2888
  "disabled:pointer-events-none disabled:opacity-50",
2769
- committedRange.from ? "text-gray-900 dark:text-gray-100" : "text-gray-400 dark:text-gray-500",
2889
+ picker.committedRange.from ? "text-gray-900 dark:text-gray-100" : "text-gray-400 dark:text-gray-500",
2770
2890
  className
2771
2891
  ),
2772
2892
  children: [
2773
2893
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CalendarIcon, { className: "w-4 h-4 shrink-0 text-gray-400 dark:text-gray-500" }),
2774
2894
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDateRange(
2775
- committedRange,
2895
+ picker.committedRange,
2776
2896
  placeholder,
2777
- showTimePicker ? currentTime : void 0
2897
+ showTimePicker ? picker.committedTime : void 0
2778
2898
  ) })
2779
2899
  ]
2780
2900
  }
@@ -2786,10 +2906,10 @@ function DateRangePicker({
2786
2906
  section.options.map((preset) => /* @__PURE__ */ jsxRuntime.jsx(
2787
2907
  "button",
2788
2908
  {
2789
- onClick: () => handlePreset(preset),
2790
- className: chunk23BJPJOK_js.cn(
2909
+ onClick: () => picker.handlePreset(preset),
2910
+ className: chunkNTUQQDCL_js.cn(
2791
2911
  "w-full text-left px-2 py-1.5 rounded-md text-sm transition-colors",
2792
- activePreset === preset.label ? "bg-blue-50 text-blue-600 font-medium dark:bg-blue-950/50 dark:text-blue-400" : "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700"
2912
+ picker.activePreset === preset.label ? "bg-blue-50 text-blue-600 font-medium dark:bg-blue-950/50 dark:text-blue-400" : "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700"
2793
2913
  ),
2794
2914
  children: preset.label
2795
2915
  },
@@ -2801,12 +2921,12 @@ function DateRangePicker({
2801
2921
  /* @__PURE__ */ jsxRuntime.jsx(
2802
2922
  CalendarMonth,
2803
2923
  {
2804
- month: leftMonth,
2805
- range: draft,
2806
- hoverDate,
2807
- onDayClick: handleDayClick,
2808
- onDayHover: setHoverDate,
2809
- onPrevMonth: () => setLeftMonth(dateFns.subMonths(leftMonth, 1)),
2924
+ month: picker.viewMonth,
2925
+ range: picker.draft,
2926
+ hoverDate: picker.hoverDate,
2927
+ onDayClick: picker.handleDayClick,
2928
+ onDayHover: picker.setHoverDate,
2929
+ onPrevMonth: () => picker.setViewMonth(dateFns.subMonths(picker.viewMonth, 1)),
2810
2930
  showPrevNav: true,
2811
2931
  showNextNav: false
2812
2932
  }
@@ -2816,46 +2936,72 @@ function DateRangePicker({
2816
2936
  CalendarMonth,
2817
2937
  {
2818
2938
  month: rightMonth,
2819
- range: draft,
2820
- hoverDate,
2821
- onDayClick: handleDayClick,
2822
- onDayHover: setHoverDate,
2823
- onNextMonth: () => setLeftMonth(dateFns.addMonths(leftMonth, 1)),
2939
+ range: picker.draft,
2940
+ hoverDate: picker.hoverDate,
2941
+ onDayClick: picker.handleDayClick,
2942
+ onDayHover: picker.setHoverDate,
2943
+ onNextMonth: () => picker.setViewMonth(dateFns.addMonths(picker.viewMonth, 1)),
2824
2944
  showPrevNav: false,
2825
2945
  showNextNav: true
2826
2946
  }
2827
2947
  )
2828
2948
  ] }),
2829
- showTimePicker && /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: timeVisible && /* @__PURE__ */ jsxRuntime.jsx(
2949
+ showTimePicker && /* @__PURE__ */ jsxRuntime.jsx(
2830
2950
  framerMotion.motion.div,
2831
2951
  {
2832
- initial: { height: 0, opacity: 0 },
2833
- animate: { height: "auto", opacity: 1 },
2834
- exit: { height: 0, opacity: 0 },
2835
- transition: {
2836
- height: { type: "spring", stiffness: 400, damping: 30, mass: 0.8 },
2837
- opacity: { duration: 0.2 }
2838
- },
2839
- className: "overflow-hidden",
2840
- children: /* @__PURE__ */ jsxRuntime.jsx(
2841
- TimePickerRow,
2952
+ layout: true,
2953
+ transition: { layout: { duration: 0.2, ease: "easeInOut" } },
2954
+ className: "border-t border-gray-100 dark:border-neutral-700",
2955
+ children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", initial: false, children: picker.timeVisible && !picker.timeExpanded ? /* @__PURE__ */ jsxRuntime.jsx(
2956
+ framerMotion.motion.div,
2842
2957
  {
2843
- value: currentTime,
2844
- onChange: handleTimeChange
2845
- }
2846
- )
2847
- },
2848
- "time-picker"
2849
- ) }),
2958
+ initial: { opacity: 0 },
2959
+ animate: { opacity: 1 },
2960
+ exit: { opacity: 0 },
2961
+ transition: { duration: 0.12 },
2962
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2 ", children: /* @__PURE__ */ jsxRuntime.jsx(
2963
+ Button,
2964
+ {
2965
+ variant: "outline",
2966
+ onClick: picker.expandTime,
2967
+ leadingDecorator: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "w-3.5 h-3.5" }),
2968
+ className: "w-full rounded-md h-9",
2969
+ children: "Add time range"
2970
+ }
2971
+ ) })
2972
+ },
2973
+ "add-time-btn"
2974
+ ) : picker.timeVisible && picker.timeExpanded ? /* @__PURE__ */ jsxRuntime.jsx(
2975
+ framerMotion.motion.div,
2976
+ {
2977
+ initial: { opacity: 0 },
2978
+ animate: { opacity: 1 },
2979
+ exit: { opacity: 0 },
2980
+ transition: { duration: 0.12 },
2981
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2982
+ TimePickerRow,
2983
+ {
2984
+ value: picker.draftTime,
2985
+ onChange: picker.handleTimeChange,
2986
+ onRemove: picker.resetTime,
2987
+ showRemove: picker.timeExpanded,
2988
+ onDirty: picker.markTimeDirty
2989
+ }
2990
+ )
2991
+ },
2992
+ "time-picker"
2993
+ ) : null })
2994
+ }
2995
+ ),
2850
2996
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-2 px-4 py-3 border-t border-gray-100 dark:border-neutral-700", children: [
2851
2997
  /* @__PURE__ */ jsxRuntime.jsx(
2852
2998
  "button",
2853
2999
  {
2854
- onClick: handleClear,
2855
- disabled: !canClear,
2856
- className: chunk23BJPJOK_js.cn(
3000
+ onClick: picker.handleClear,
3001
+ disabled: !picker.canClear,
3002
+ className: chunkNTUQQDCL_js.cn(
2857
3003
  "px-3 py-1.5 rounded-md text-sm transition-colors",
2858
- canClear ? "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700" : "text-gray-300 dark:text-gray-600 cursor-not-allowed"
3004
+ picker.canClear ? "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700" : "text-gray-300 dark:text-gray-600 cursor-not-allowed"
2859
3005
  ),
2860
3006
  children: "Clear"
2861
3007
  }
@@ -2863,11 +3009,11 @@ function DateRangePicker({
2863
3009
  /* @__PURE__ */ jsxRuntime.jsx(
2864
3010
  "button",
2865
3011
  {
2866
- onClick: handleApply,
2867
- disabled: !canApply,
2868
- className: chunk23BJPJOK_js.cn(
3012
+ onClick: picker.handleApply,
3013
+ disabled: !picker.canApply,
3014
+ className: chunkNTUQQDCL_js.cn(
2869
3015
  "px-3 py-1.5 rounded-md text-sm font-medium transition-colors",
2870
- canApply ? "bg-blue-600 text-white hover:bg-blue-700 dark:hover:bg-blue-500" : "bg-blue-100 text-blue-300 cursor-not-allowed dark:bg-blue-950/30 dark:text-blue-800"
3016
+ picker.canApply ? "bg-blue-600 text-white hover:bg-blue-700 dark:hover:bg-blue-500" : "bg-blue-100 text-blue-300 cursor-not-allowed dark:bg-blue-950/30 dark:text-blue-800"
2871
3017
  ),
2872
3018
  children: "Apply"
2873
3019
  }
@@ -2877,30 +3023,6 @@ function DateRangePicker({
2877
3023
  ] }) })
2878
3024
  ] });
2879
3025
  }
2880
- function formatTime2(tv) {
2881
- if (tv.hour === null || tv.minute === null) return "";
2882
- const period = tv.hour >= 12 ? "PM" : "AM";
2883
- const h = tv.hour % 12 || 12;
2884
- const m = tv.minute.toString().padStart(2, "0");
2885
- return `${h}:${m} ${period}`;
2886
- }
2887
- function formatDateWithTime(date, dateFmt, time) {
2888
- const dateStr = dateFns.format(date, dateFmt);
2889
- const timeStr = time ? formatTime2(time) : "";
2890
- return timeStr ? `${dateStr}, ${timeStr}` : dateStr;
2891
- }
2892
- function formatDateRange2(range, placeholder, time) {
2893
- if (!range?.from) return placeholder;
2894
- const hasTime = time && time.from.hour !== null && time.to.hour !== null;
2895
- if (!range.to || dateFns.isSameDay(range.from, range.to)) {
2896
- return formatDateWithTime(range.from, "MMMM d, yyyy", hasTime ? time.from : void 0);
2897
- }
2898
- const sameYear = range.from.getFullYear() === range.to.getFullYear();
2899
- const fromFmt = sameYear ? "MMMM d" : "MMMM d, yyyy";
2900
- const fromStr = formatDateWithTime(range.from, fromFmt, hasTime ? time.from : void 0);
2901
- const toStr = formatDateWithTime(range.to, "MMMM d, yyyy", hasTime ? time.to : void 0);
2902
- return `${fromStr} \u2013 ${toStr}`;
2903
- }
2904
3026
  function DateRangePickerMobile({
2905
3027
  label,
2906
3028
  value,
@@ -2914,87 +3036,33 @@ function DateRangePickerMobile({
2914
3036
  timeValue,
2915
3037
  onTimeChange
2916
3038
  }) {
2917
- const [open, setOpen] = React10__namespace.useState(false);
2918
- const [internalRange, setInternalRange] = React10__namespace.useState({
2919
- from: void 0,
2920
- to: void 0
3039
+ const picker = useDateRangePicker({
3040
+ value,
3041
+ onChange,
3042
+ showTimePicker,
3043
+ timeValue,
3044
+ onTimeChange
2921
3045
  });
2922
- const [draft, setDraft] = React10__namespace.useState({
2923
- from: void 0,
2924
- to: void 0
2925
- });
2926
- const [hoverDate, setHoverDate] = React10__namespace.useState();
2927
- const [viewMonth, setViewMonth] = React10__namespace.useState(
2928
- () => dateFns.startOfMonth(value?.from ?? /* @__PURE__ */ new Date())
2929
- );
2930
- const [activePreset, setActivePreset] = React10__namespace.useState();
2931
- const [internalTime, setInternalTime] = React10__namespace.useState(DEFAULT_TIME_RANGE);
2932
- const committedRange = value ?? internalRange;
2933
- const currentTime = timeValue ?? internalTime;
2934
- const handleTimeChange = (newTime) => {
2935
- if (onTimeChange) onTimeChange(newTime);
2936
- else setInternalTime(newTime);
2937
- };
2938
- const timeVisible = !!(draft.from && draft.to);
2939
- const handleOpenChange = (newOpen) => {
2940
- if (newOpen) {
2941
- setDraft(committedRange);
2942
- if (committedRange.from) setViewMonth(dateFns.startOfMonth(committedRange.from));
2943
- if (!onTimeChange) setInternalTime(currentTime);
2944
- }
2945
- setOpen(newOpen);
2946
- };
2947
- const handleDayClick = (date) => {
2948
- const { from, to } = draft;
2949
- if (!from || from && to) {
2950
- setDraft({ from: date, to: void 0 });
2951
- setActivePreset(void 0);
2952
- return;
2953
- }
2954
- const [start, end] = dateFns.isBefore(from, date) ? [from, date] : [date, from];
2955
- setDraft({ from: start, to: end });
2956
- setHoverDate(void 0);
2957
- };
2958
- const handlePreset = (preset) => {
2959
- const newRange = preset.getRange();
2960
- setDraft(newRange);
2961
- setActivePreset(preset.label);
2962
- if (newRange.from) setViewMonth(dateFns.startOfMonth(newRange.from));
2963
- };
2964
- const handleApply = () => {
2965
- if (draft.from && !draft.to) return;
2966
- const newRange = draft.from && draft.to ? draft : void 0;
2967
- if (onChange) onChange(newRange);
2968
- else setInternalRange(newRange ?? { from: void 0, to: void 0 });
2969
- setOpen(false);
2970
- };
2971
- const handleClear = () => {
2972
- setDraft({ from: void 0, to: void 0 });
2973
- setActivePreset(void 0);
2974
- if (showTimePicker) handleTimeChange(DEFAULT_TIME_RANGE);
2975
- };
2976
- const canClear = !!(draft.from || committedRange.from);
2977
- const canApply = !(draft.from && !draft.to) && !!(draft.from || committedRange.from);
2978
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunk23BJPJOK_js.cn("space-y-1.5", className), children: [
2979
- label && /* @__PURE__ */ jsxRuntime.jsx(chunk23BJPJOK_js.Label, { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: label }),
2980
- /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
3046
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkNTUQQDCL_js.cn("space-y-1.5", className), children: [
3047
+ label && /* @__PURE__ */ jsxRuntime.jsx(chunkNTUQQDCL_js.Label, { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: label }),
3048
+ /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: picker.open, onOpenChange: picker.handleOpenChange, children: [
2981
3049
  /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
2982
3050
  "button",
2983
3051
  {
2984
3052
  disabled,
2985
- className: chunk23BJPJOK_js.cn(
3053
+ className: chunkNTUQQDCL_js.cn(
2986
3054
  "inline-flex w-full items-center gap-2 rounded-md border border-gray-300 bg-white px-3 py-2 text-sm shadow-sm transition-colors",
2987
3055
  "hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2",
2988
3056
  "dark:border-neutral-600 dark:bg-neutral-800 dark:hover:bg-neutral-700",
2989
3057
  "disabled:pointer-events-none disabled:opacity-50",
2990
- committedRange.from ? "text-gray-900 dark:text-gray-100" : "text-gray-400 dark:text-gray-500"
3058
+ picker.committedRange.from ? "text-gray-900 dark:text-gray-100" : "text-gray-400 dark:text-gray-500"
2991
3059
  ),
2992
3060
  children: [
2993
3061
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CalendarIcon, { className: "w-4 h-4 shrink-0 text-gray-400 dark:text-gray-500" }),
2994
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatDateRange2(
2995
- committedRange,
3062
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatDateRange(
3063
+ picker.committedRange,
2996
3064
  placeholder,
2997
- showTimePicker ? currentTime : void 0
3065
+ showTimePicker ? picker.committedTime : void 0
2998
3066
  ) })
2999
3067
  ]
3000
3068
  }
@@ -3007,10 +3075,10 @@ function DateRangePickerMobile({
3007
3075
  section.options.map((preset) => /* @__PURE__ */ jsxRuntime.jsx(
3008
3076
  "button",
3009
3077
  {
3010
- onClick: () => handlePreset(preset),
3011
- className: chunk23BJPJOK_js.cn(
3078
+ onClick: () => picker.handlePreset(preset),
3079
+ className: chunkNTUQQDCL_js.cn(
3012
3080
  "w-full text-left px-2 py-1.5 rounded-md text-sm transition-colors",
3013
- activePreset === preset.label ? "bg-blue-50 text-blue-600 font-medium dark:bg-blue-950/50 dark:text-blue-400" : "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700"
3081
+ picker.activePreset === preset.label ? "bg-blue-50 text-blue-600 font-medium dark:bg-blue-950/50 dark:text-blue-400" : "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700"
3014
3082
  ),
3015
3083
  children: preset.label
3016
3084
  },
@@ -3022,52 +3090,73 @@ function DateRangePickerMobile({
3022
3090
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
3023
3091
  CalendarMonth,
3024
3092
  {
3025
- month: viewMonth,
3026
- range: draft,
3027
- hoverDate,
3028
- onDayClick: handleDayClick,
3029
- onDayHover: setHoverDate,
3030
- onPrevMonth: () => setViewMonth(dateFns.subMonths(viewMonth, 1)),
3031
- onNextMonth: () => setViewMonth(dateFns.addMonths(viewMonth, 1)),
3093
+ month: picker.viewMonth,
3094
+ range: picker.draft,
3095
+ hoverDate: picker.hoverDate,
3096
+ onDayClick: picker.handleDayClick,
3097
+ onDayHover: picker.setHoverDate,
3098
+ onPrevMonth: () => picker.setViewMonth(dateFns.subMonths(picker.viewMonth, 1)),
3099
+ onNextMonth: () => picker.setViewMonth(dateFns.addMonths(picker.viewMonth, 1)),
3032
3100
  showPrevNav: true,
3033
3101
  showNextNav: true
3034
3102
  }
3035
3103
  ) }),
3036
- showTimePicker && /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: timeVisible && /* @__PURE__ */ jsxRuntime.jsx(
3104
+ showTimePicker && /* @__PURE__ */ jsxRuntime.jsx(
3037
3105
  framerMotion.motion.div,
3038
3106
  {
3039
- initial: { height: 0, opacity: 0 },
3040
- animate: { height: "auto", opacity: 1 },
3041
- exit: { height: 0, opacity: 0 },
3042
- transition: {
3043
- height: {
3044
- type: "spring",
3045
- stiffness: 400,
3046
- damping: 30,
3047
- mass: 0.8
3107
+ layout: true,
3108
+ transition: { layout: { duration: 0.2, ease: "easeInOut" } },
3109
+ className: "border-t border-gray-100 dark:border-neutral-700",
3110
+ children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", initial: false, children: picker.timeVisible && !picker.timeExpanded ? /* @__PURE__ */ jsxRuntime.jsx(
3111
+ framerMotion.motion.div,
3112
+ {
3113
+ initial: { opacity: 0 },
3114
+ animate: { opacity: 1 },
3115
+ exit: { opacity: 0 },
3116
+ transition: { duration: 0.12 },
3117
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(
3118
+ Button,
3119
+ {
3120
+ variant: "outline",
3121
+ onClick: picker.expandTime,
3122
+ leadingDecorator: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "w-3.5 h-3.5" }),
3123
+ className: "w-full rounded-md h-9",
3124
+ children: "Add time range"
3125
+ }
3126
+ ) })
3048
3127
  },
3049
- opacity: { duration: 0.2 }
3050
- },
3051
- className: "overflow-hidden",
3052
- children: /* @__PURE__ */ jsxRuntime.jsx(
3053
- TimePickerColumn,
3128
+ "add-time-btn"
3129
+ ) : picker.timeVisible && picker.timeExpanded ? /* @__PURE__ */ jsxRuntime.jsx(
3130
+ framerMotion.motion.div,
3054
3131
  {
3055
- value: currentTime,
3056
- onChange: handleTimeChange
3057
- }
3058
- )
3059
- },
3060
- "time-picker"
3061
- ) }),
3132
+ initial: { opacity: 0 },
3133
+ animate: { opacity: 1 },
3134
+ exit: { opacity: 0 },
3135
+ transition: { duration: 0.12 },
3136
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3137
+ TimePickerColumn,
3138
+ {
3139
+ value: picker.draftTime,
3140
+ onChange: picker.handleTimeChange,
3141
+ onRemove: picker.resetTime,
3142
+ showRemove: picker.timeExpanded,
3143
+ onDirty: picker.markTimeDirty
3144
+ }
3145
+ )
3146
+ },
3147
+ "time-picker"
3148
+ ) : null })
3149
+ }
3150
+ ),
3062
3151
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-2 px-2 py-3 border-t border-gray-100 dark:border-neutral-700", children: [
3063
3152
  /* @__PURE__ */ jsxRuntime.jsx(
3064
3153
  "button",
3065
3154
  {
3066
- onClick: handleClear,
3067
- disabled: !canClear,
3068
- className: chunk23BJPJOK_js.cn(
3155
+ onClick: picker.handleClear,
3156
+ disabled: !picker.canClear,
3157
+ className: chunkNTUQQDCL_js.cn(
3069
3158
  "px-3 py-1.5 rounded-md text-sm transition-colors",
3070
- canClear ? "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700" : "text-gray-300 dark:text-gray-600 cursor-not-allowed"
3159
+ picker.canClear ? "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700" : "text-gray-300 dark:text-gray-600 cursor-not-allowed"
3071
3160
  ),
3072
3161
  children: "Clear"
3073
3162
  }
@@ -3075,11 +3164,11 @@ function DateRangePickerMobile({
3075
3164
  /* @__PURE__ */ jsxRuntime.jsx(
3076
3165
  "button",
3077
3166
  {
3078
- onClick: handleApply,
3079
- disabled: !canApply,
3080
- className: chunk23BJPJOK_js.cn(
3167
+ onClick: picker.handleApply,
3168
+ disabled: !picker.canApply,
3169
+ className: chunkNTUQQDCL_js.cn(
3081
3170
  "px-3 py-1.5 rounded-md text-sm font-medium transition-colors",
3082
- canApply ? "bg-blue-600 text-white hover:bg-blue-700 dark:hover:bg-blue-500" : "bg-blue-100 text-blue-300 cursor-not-allowed dark:bg-blue-950/30 dark:text-blue-800"
3171
+ picker.canApply ? "bg-blue-600 text-white hover:bg-blue-700 dark:hover:bg-blue-500" : "bg-blue-100 text-blue-300 cursor-not-allowed dark:bg-blue-950/30 dark:text-blue-800"
3083
3172
  ),
3084
3173
  children: "Apply"
3085
3174
  }
@@ -3117,7 +3206,7 @@ function MobileDataCard({
3117
3206
  image && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: image }),
3118
3207
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-2", children: [
3119
3208
  /* @__PURE__ */ jsxRuntime.jsx(
3120
- chunk23BJPJOK_js.Text,
3209
+ chunkNTUQQDCL_js.Text,
3121
3210
  {
3122
3211
  size: "sm",
3123
3212
  weight: "semibold",
@@ -3125,7 +3214,7 @@ function MobileDataCard({
3125
3214
  children: title
3126
3215
  }
3127
3216
  ),
3128
- subtitle && /* @__PURE__ */ jsxRuntime.jsx(chunk23BJPJOK_js.Text, { size: "xs", className: "text-neutral-400 dark:text-neutral-500", children: subtitle }),
3217
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx(chunkNTUQQDCL_js.Text, { size: "xs", className: "text-neutral-400 dark:text-neutral-500", children: subtitle }),
3129
3218
  contentRows && contentRows.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-x-4 gap-y-1 text-xs", children: contentRows.map((row) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "truncate", children: [
3130
3219
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-neutral-400 dark:text-neutral-500", children: [
3131
3220
  row.label,
@@ -3142,7 +3231,7 @@ function MobileDataCard({
3142
3231
  return /* @__PURE__ */ jsxRuntime.jsxs(
3143
3232
  "div",
3144
3233
  {
3145
- className: chunk23BJPJOK_js.cn(
3234
+ className: chunkNTUQQDCL_js.cn(
3146
3235
  "overflow-hidden rounded-lg border transition-colors",
3147
3236
  isSelected ? "border-blue-500 bg-blue-50/50 dark:border-blue-400 dark:bg-blue-900/10" : "border-neutral-200 bg-white dark:border-neutral-700 dark:bg-neutral-800/30",
3148
3237
  className
@@ -3172,11 +3261,11 @@ function MobileDataCard({
3172
3261
  }
3173
3262
  ),
3174
3263
  /* @__PURE__ */ jsxRuntime.jsx(
3175
- chunk23BJPJOK_js.Text,
3264
+ chunkNTUQQDCL_js.Text,
3176
3265
  {
3177
3266
  size: "xs",
3178
3267
  as: "span",
3179
- className: chunk23BJPJOK_js.cn(
3268
+ className: chunkNTUQQDCL_js.cn(
3180
3269
  isSelected ? "font-medium text-blue-600 dark:text-blue-400" : "text-neutral-400 dark:text-neutral-500"
3181
3270
  ),
3182
3271
  children: isSelected ? "Selected" : "Select"
@@ -3195,13 +3284,13 @@ function MobileDataCard({
3195
3284
  children: contentBody
3196
3285
  }
3197
3286
  ) : contentBody,
3198
- statsRenderer ?? (stats && stats.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunk23BJPJOK_js.cn("grid gap-1.5 px-3 pb-3", colsClass[cols]), children: stats.map((stat) => /* @__PURE__ */ jsxRuntime.jsxs(
3287
+ statsRenderer ?? (stats && stats.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkNTUQQDCL_js.cn("grid gap-1.5 px-3 pb-3", colsClass[cols]), children: stats.map((stat) => /* @__PURE__ */ jsxRuntime.jsxs(
3199
3288
  "div",
3200
3289
  {
3201
3290
  className: "flex flex-col items-center rounded-md bg-neutral-100 py-1.5 dark:bg-neutral-800",
3202
3291
  children: [
3203
3292
  /* @__PURE__ */ jsxRuntime.jsx(
3204
- chunk23BJPJOK_js.Text,
3293
+ chunkNTUQQDCL_js.Text,
3205
3294
  {
3206
3295
  size: "xs",
3207
3296
  as: "span",
@@ -3210,12 +3299,12 @@ function MobileDataCard({
3210
3299
  }
3211
3300
  ),
3212
3301
  /* @__PURE__ */ jsxRuntime.jsx(
3213
- chunk23BJPJOK_js.Text,
3302
+ chunkNTUQQDCL_js.Text,
3214
3303
  {
3215
3304
  size: "sm",
3216
3305
  weight: "semibold",
3217
3306
  as: "span",
3218
- className: chunk23BJPJOK_js.cn(
3307
+ className: chunkNTUQQDCL_js.cn(
3219
3308
  "mt-0.5 tabular-nums",
3220
3309
  stat.className ?? "text-neutral-800 dark:text-neutral-200"
3221
3310
  ),
@@ -3234,7 +3323,7 @@ function MobileDataCard({
3234
3323
  className: "flex items-center justify-between",
3235
3324
  children: [
3236
3325
  /* @__PURE__ */ jsxRuntime.jsx(
3237
- chunk23BJPJOK_js.Text,
3326
+ chunkNTUQQDCL_js.Text,
3238
3327
  {
3239
3328
  size: "xs",
3240
3329
  as: "span",
@@ -3243,7 +3332,7 @@ function MobileDataCard({
3243
3332
  }
3244
3333
  ),
3245
3334
  detail.pill ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center rounded-full bg-blue-50 px-2 py-0.5 dark:bg-blue-900/30", children: /* @__PURE__ */ jsxRuntime.jsx(
3246
- chunk23BJPJOK_js.Text,
3335
+ chunkNTUQQDCL_js.Text,
3247
3336
  {
3248
3337
  size: "xs",
3249
3338
  weight: "medium",
@@ -3443,5 +3532,5 @@ exports.useColumnVisibility = useColumnVisibility;
3443
3532
  exports.useFormContext = useFormContext;
3444
3533
  exports.useFormFieldContext = useFormFieldContext;
3445
3534
  exports.useTableSelection = useTableSelection;
3446
- //# sourceMappingURL=chunk-H7KYKSHC.js.map
3447
- //# sourceMappingURL=chunk-H7KYKSHC.js.map
3535
+ //# sourceMappingURL=chunk-ZYPPWLV6.js.map
3536
+ //# sourceMappingURL=chunk-ZYPPWLV6.js.map