@datum-cloud/datum-ui 0.1.0 → 0.2.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/chunk-CtajNgzt.mjs +36 -0
  2. package/dist/close.icon-DgjsP0sw.mjs +23 -0
  3. package/dist/close.icon-DgjsP0sw.mjs.map +1 -0
  4. package/dist/components/index.d.mts +27 -0
  5. package/dist/components/index.d.mts.map +1 -0
  6. package/dist/components/index.mjs +252 -0
  7. package/dist/components/index.mjs.map +1 -0
  8. package/dist/datum.provider-CsG2KNNc.d.mts +30 -0
  9. package/dist/datum.provider-CsG2KNNc.d.mts.map +1 -0
  10. package/dist/datum.provider-D6VMjSV0.mjs +38 -0
  11. package/dist/datum.provider-D6VMjSV0.mjs.map +1 -0
  12. package/dist/fonts/AllianceNo1-Medium.ttf +0 -0
  13. package/dist/fonts/AllianceNo1-Regular.ttf +0 -0
  14. package/dist/fonts/AllianceNo1-SemiBold.ttf +0 -0
  15. package/dist/fonts/FTRegolaNeue-Medium.woff2 +0 -0
  16. package/dist/fonts/FTRegolaNeue-Regular.woff2 +0 -0
  17. package/dist/fonts/FTRegolaNeue-Semibold.woff2 +0 -0
  18. package/dist/hooks/index.d.mts +3 -0
  19. package/dist/hooks/index.mjs +5 -0
  20. package/dist/icon-wrapper-BTllM5Re.mjs +62 -0
  21. package/dist/icon-wrapper-BTllM5Re.mjs.map +1 -0
  22. package/dist/icons/index.d.mts +3 -0
  23. package/dist/icons/index.mjs +5 -0
  24. package/dist/index-DH2XEEjO.d.mts +3995 -0
  25. package/dist/index-DH2XEEjO.d.mts.map +1 -0
  26. package/dist/index.d.mts +29 -50
  27. package/dist/index.d.mts.map +1 -0
  28. package/dist/index.mjs +251 -3479
  29. package/dist/index.mjs.map +1 -0
  30. package/dist/providers/index.d.mts +3 -0
  31. package/dist/providers/index.mjs +4 -0
  32. package/dist/spinner.icon-q9zisVlw.d.mts +46 -0
  33. package/dist/spinner.icon-q9zisVlw.d.mts.map +1 -0
  34. package/dist/style.css +7096 -0
  35. package/dist/style.css.map +1 -0
  36. package/dist/theme-script-B_TkiYs4.mjs +8841 -0
  37. package/dist/theme-script-B_TkiYs4.mjs.map +1 -0
  38. package/dist/theme.provider-DpFLwtHe.mjs +135 -0
  39. package/dist/theme.provider-DpFLwtHe.mjs.map +1 -0
  40. package/dist/types-BoL47uxV.d.mts +34 -0
  41. package/dist/types-BoL47uxV.d.mts.map +1 -0
  42. package/dist/use-copy-to-clipboard-D5U8bWsn.mjs +117 -0
  43. package/dist/use-copy-to-clipboard-D5U8bWsn.mjs.map +1 -0
  44. package/dist/use-debounce-BYB-jPeX.mjs +25 -0
  45. package/dist/use-debounce-BYB-jPeX.mjs.map +1 -0
  46. package/dist/use-debounce-Dg9zNz9U.d.mts +19 -0
  47. package/dist/use-debounce-Dg9zNz9U.d.mts.map +1 -0
  48. package/dist/utils/index.d.mts +3 -0
  49. package/dist/utils/index.mjs +4 -0
  50. package/package.json +129 -50
  51. package/LICENSE +0 -21
  52. package/README.md +0 -42
  53. package/dist/index.d.ts +0 -52
  54. package/dist/index.js +0 -3529
  55. package/src/styles/custom.css +0 -27
  56. package/src/styles/fonts.css +0 -51
  57. package/src/styles/root.css +0 -28
  58. package/src/styles/themes/alpha.css +0 -421
  59. package/src/styles/tokens/brand-tokens.css +0 -57
  60. package/src/styles/tokens/figma-tokens.css +0 -624
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-script-B_TkiYs4.mjs","names":["React","buttonVariants","Button","buttonVariants","Calendar","React","Checkbox","ShadcnCheckbox","Dialog","ShadcnDialog","DialogOverlay","ShadcnDialogOverlay","Trigger","ShadcnDialogFooter","Input","ShadcnInput","Label","ShadcnLabel","RadioGroup","ShadcnRadioGroup","RadioGroupItem","ShadcnRadioGroupItem","Select","ShadcnSelect","SelectValue","ShadcnSelectValue","SelectGroup","ShadcnSelectGroup","SelectTrigger","ShadcnSelectTrigger","SelectContent","ShadcnSelectContent","SelectLabel","ShadcnSelectLabel","SelectItem","ShadcnSelectItem","SelectSeparator","ShadcnSelectSeparator","SelectScrollUpButton","ShadcnSelectScrollUpButton","SelectScrollDownButton","ShadcnSelectScrollDownButton","SheetPrimitive","SheetContent","Sheet","ShadcnSheet","SheetHeader","SheetTitle","SheetDescription","Switch","ShadcnSwitch","Textarea","ShadcnTextarea","TooltipContent","Tooltip","TooltipPrimitive","React","Tooltip","React","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Calendar","Button","scene5","scene6","scene7","miloStamp","Button","React","useFieldContext","useFieldContext","React","FormProvider","useFormContext","useFormContext","Button","useFieldContext","Checkbox","Label","Toaster","SonnerToaster","useFieldContext","React","Button","useFormContext","React","Dialog","React","Label","Tooltip","useFormContext","useFormContext","React","useFieldContext","Input","useFieldContext","RadioGroup","RadioGroupItem","Label","React","FormProvider","ConformFormProvider","useFieldContext","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","useFormContext","Button","useFieldContext","Switch","Label","useFieldContext","Textarea","useFormContext","React","React","React","FormProvider","ConformFormProvider","useFormContext","Button","React","useFieldContext","useFormContext","React","useFieldContextInternal","useFormContextInternal","Input","Button","Tooltip","React","Tooltip","Input","RemoveIcon","Input","Button","Tooltip","Button","Dialog","Button","Button","Calendar","Input","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Button","CalendarIcon","Calendar","React","React"],"sources":["../src/components/base/alert/alert.tsx","../src/components/base/badge/badge.tsx","../src/components/base/button/button.tsx","../src/components/base/button/link-button.tsx","../src/components/base/calendar/calendar.tsx","../src/components/base/card/card.tsx","../src/components/base/checkbox/checkbox.tsx","../src/components/base/dialog/dialog.tsx","../src/components/base/input/input.tsx","../src/components/base/label/label.tsx","../src/components/base/radio-group/radio-group.tsx","../src/components/base/select/select.tsx","../src/components/base/sheet/sheet.tsx","../src/components/base/switch/switch.tsx","../src/components/base/tabs/tabs.tsx","../src/components/base/textarea/textarea.tsx","../src/components/base/tooltip/tooltip.tsx","../src/components/features/loader-overlay/loader-overlay.tsx","../src/components/features/autocomplete/autocomplete.tsx","../src/components/features/avatar-stack/avatar-stack.tsx","../src/components/features/calendar-date-picker/calendar-date-picker.tsx","../src/components/features/dropdown/dropdown.tsx","../src/components/features/dropzone/dropzone.tsx","../src/components/features/empty-content/assets/milo-stamp.svg","../src/components/features/empty-content/assets/scene-5.png","../src/components/features/empty-content/assets/scene-6.png","../src/components/features/empty-content/assets/scene-7.png","../src/components/features/empty-content/empty-content.tsx","../src/components/features/file-input-button/file-input-button.tsx","../src/components/features/form/context/field-context.tsx","../src/components/features/form/components/form-autocomplete.tsx","../src/components/features/form/context/form-context.tsx","../src/components/features/form/components/form-button.tsx","../src/components/features/form/components/form-checkbox.tsx","../src/components/features/toast/toaster.tsx","../src/components/features/toast/use-toast.ts","../src/components/features/form/components/form-copy-box.tsx","../src/components/features/form/components/form-custom.tsx","../src/components/features/form/components/form-description.tsx","../src/components/features/form/components/form-dialog.tsx","../src/components/features/form/components/form-error.tsx","../src/components/features/form/components/form-field.tsx","../src/components/features/form/components/form-field-array.tsx","../src/components/features/form/components/form-input.tsx","../src/components/features/form/components/form-radio-group.tsx","../src/components/features/form/components/form-root.tsx","../src/components/features/form/components/form-select.tsx","../src/components/features/form/components/form-submit.tsx","../src/components/features/form/components/form-switch.tsx","../src/components/features/form/components/form-textarea.tsx","../src/components/features/form/hooks/use-watch.ts","../src/components/features/form/components/form-when.tsx","../src/components/features/stepper/stepper.tsx","../src/components/features/form/components/stepper/form-stepper.tsx","../src/components/features/form/components/stepper/form-step.tsx","../src/components/features/form/components/stepper/stepper-controls.tsx","../src/components/features/form/components/stepper/stepper-navigation.tsx","../src/components/features/input-with-addons/input-with-addons.tsx","../src/components/features/form/components/form-input-group.tsx","../src/components/features/form/hooks/use-field.ts","../src/components/features/form/hooks/use-field-context.ts","../src/components/features/form/hooks/use-form-context.ts","../src/components/features/form/hooks/use-stepper.ts","../src/components/features/form/index.ts","../src/components/features/grid/constants/grid.constants.ts","../src/components/features/grid/utils/responsive.ts","../src/components/features/grid/components/row.tsx","../src/components/features/grid/components/col.tsx","../src/components/features/input-number/input-number.tsx","../src/components/features/more-actions/more-actions.tsx","../src/components/features/nprogress/index.ts","../src/components/features/page-title/page-title.tsx","../src/components/features/sidebar/nav-main.tsx","../src/components/features/sidebar/app-sidebar.tsx","../src/components/features/sidebar/sidebar.tsx","../src/components/features/tag-input/tag-input.tsx","../src/components/features/task-queue/engine/executor.ts","../src/components/features/task-queue/constants.ts","../src/components/features/task-queue/utils/index.ts","../src/components/features/task-queue/engine/storage/local-storage.ts","../src/components/features/task-queue/engine/storage/memory-storage.ts","../src/components/features/task-queue/engine/storage/redis-storage.ts","../src/components/features/task-queue/engine/storage/detect-storage.ts","../src/components/features/task-queue/engine/queue.ts","../src/components/features/task-queue/provider/task-queue-provider.tsx","../src/components/features/task-queue/hooks/use-task-queue.ts","../src/components/features/task-queue/hooks/use-task-scope.ts","../src/components/features/task-queue/core/task-panel-header.tsx","../src/components/features/task-queue/core/task-panel-actions.tsx","../src/components/features/task-queue/core/task-panel-counter.tsx","../src/components/features/task-queue/core/task-panel-item.tsx","../src/components/features/task-queue/core/task-panel.tsx","../src/components/features/task-queue/core/task-queue-trigger.tsx","../src/components/features/task-queue/core/task-summary-dialog.tsx","../src/components/features/task-queue/core/task-queue-dropdown.tsx","../src/components/features/time-range-picker/utils/timezone.ts","../src/components/features/time-range-picker/components/absolute-range-panel.tsx","../src/components/features/time-range-picker/components/quick-ranges-panel.tsx","../src/components/features/time-range-picker/components/timezone-selector.tsx","../src/components/features/time-range-picker/presets.ts","../src/components/features/time-range-picker/utils/format-display.ts","../src/components/features/time-range-picker/time-range-picker.tsx","../src/components/features/time-range-picker/utils/to-api-format.ts","../src/components/themes/client-only.tsx","../src/components/themes/script.ts","../src/components/themes/theme-script.tsx"],"sourcesContent":["import type { VariantProps } from 'class-variance-authority'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { cva } from 'class-variance-authority'\nimport { CircleXIcon } from 'lucide-react'\nimport * as React from 'react'\n\n/**\n * Datum Alert Component\n * Extends shadcn Alert with Datum-specific variants: success, info, warning\n */\n\n// Variant definitions - both classes and close button color in one place\nconst variantDefinitions = {\n default: {\n classes: 'bg-background text-foreground',\n closeButtonColor: 'text-foreground',\n },\n secondary: {\n classes: 'bg-muted text-primary [&>svg]:text-primary',\n closeButtonColor: 'text-primary',\n },\n outline: {\n classes: 'border-muted text-muted-foreground',\n closeButtonColor: 'text-muted-foreground',\n },\n destructive: {\n classes:\n 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',\n closeButtonColor: 'text-destructive',\n },\n success: {\n classes: 'border-success-300 bg-success-100 text-success-500',\n closeButtonColor: 'text-success-500',\n },\n info: {\n classes: 'border-info-300 bg-info-100 text-info-500! [&>svg]:text-info-500',\n closeButtonColor: 'text-info-500',\n },\n warning: {\n classes: 'border-yellow-500 bg-yellow-50 text-yellow-700! [&>svg]:text-yellow-700',\n closeButtonColor: 'text-yellow-700',\n },\n} as const\n\nconst alertVariants = cva(\n 'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',\n {\n variants: {\n variant: {\n default: variantDefinitions.default.classes,\n secondary: variantDefinitions.secondary.classes,\n outline: variantDefinitions.outline.classes,\n destructive: variantDefinitions.destructive.classes,\n success: variantDefinitions.success.classes,\n info: variantDefinitions.info.classes,\n warning: variantDefinitions.warning.classes,\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n\nexport interface AlertProps\n extends React.ComponentProps<'div'>, VariantProps<typeof alertVariants> {\n /**\n * Whether the alert can be closed. When true, a close button is displayed.\n * @default false\n */\n closable?: boolean\n /**\n * Callback function called when the close button is clicked.\n */\n onClose?: () => void\n}\n\nfunction Alert({ className, variant, closable = false, onClose, ...props }: AlertProps) {\n const [isVisible, setIsVisible] = React.useState(true)\n\n const handleClose = () => {\n if (onClose) {\n onClose()\n }\n else {\n setIsVisible(false)\n }\n }\n\n if (!isVisible) {\n return null\n }\n\n return (\n <div\n role=\"alert\"\n className={cn(alertVariants({ variant }), closable && 'pr-10', className)}\n {...props}\n >\n {props.children}\n {closable && (\n <span\n onClick={handleClose}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n handleClose()\n }\n }}\n className=\"absolute top-4 right-4 z-10 cursor-pointer opacity-70 transition-opacity hover:opacity-100\"\n aria-label=\"Close alert\"\n >\n <CircleXIcon\n className={cn('size-4', variant && variantDefinitions[variant]?.closeButtonColor)}\n />\n </span>\n )}\n </div>\n )\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n className={cn('col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight', className)}\n {...props}\n />\n )\n}\n\nfunction AlertDescription({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n className={cn(\n 'text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed',\n className,\n )}\n {...props}\n />\n )\n}\n\nexport { Alert, AlertDescription, AlertTitle }\n","import type { VariantProps } from 'class-variance-authority'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\n\n/**\n * Datum Badge Component\n * Similar to Button component but with badge-specific styling\n * Supports types: primary, secondary, tertiary, quaternary, warning, danger, success\n * Supports themes: solid, outline, light\n */\n\nconst badgeVariants = cva(\n 'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-all focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2',\n {\n variants: {\n type: {\n primary: '',\n secondary: '',\n tertiary: '',\n quaternary: '',\n info: '',\n warning: '',\n danger: '',\n success: '',\n muted: '',\n },\n theme: {\n solid: '',\n outline: 'border',\n light: 'border',\n },\n },\n compoundVariants: [\n // Primary badge variants\n {\n type: 'primary',\n theme: 'solid',\n className:\n 'border-transparent bg-[var(--color-badge-primary)] text-[var(--color-badge-primary-foreground)]',\n },\n {\n type: 'primary',\n theme: 'outline',\n className:\n 'border-[var(--color-badge-primary)] text-[var(--color-badge-primary)] dark:border-[var(--color-badge-primary)] dark:text-[var(--color-badge-primary)]',\n },\n {\n type: 'primary',\n theme: 'light',\n className:\n 'border-[var(--color-badge-primary)]/30 text-[var(--color-badge-primary)] bg-[var(--color-badge-primary)]/10 dark:border-[var(--color-badge-primary)] dark:text-[var(--color-badge-primary)] dark:bg-[var(--color-badge-primary)]/20',\n },\n\n // Secondary badge variants\n {\n type: 'secondary',\n theme: 'solid',\n className:\n 'border-transparent bg-[var(--color-badge-secondary)] text-[var(--color-badge-secondary-foreground)]',\n },\n {\n type: 'secondary',\n theme: 'outline',\n className:\n 'border-[var(--color-badge-secondary)] text-[var(--color-badge-secondary)] dark:border-[var(--color-badge-secondary)] dark:text-[var(--color-badge-secondary)]',\n },\n {\n type: 'secondary',\n theme: 'light',\n className:\n 'border-[var(--color-badge-secondary)] text-[var(--color-badge-secondary)] bg-[var(--color-badge-secondary)]/20 dark:border-[var(--color-badge-secondary)] dark:text-[var(--color-badge-secondary)] dark:bg-[var(--color-badge-secondary)]/20',\n },\n\n // Tertiary badge variants\n {\n type: 'tertiary',\n theme: 'solid',\n className:\n 'border-transparent bg-[var(--color-badge-tertiary)] text-[var(--color-badge-tertiary-foreground)]',\n },\n {\n type: 'tertiary',\n theme: 'outline',\n className:\n 'border-[var(--color-badge-tertiary)] text-[var(--color-badge-tertiary)] dark:border-[var(--color-badge-tertiary)] dark:text-[var(--color-badge-tertiary)]',\n },\n {\n type: 'tertiary',\n theme: 'light',\n className:\n 'border-[var(--color-badge-tertiary)] text-[var(--color-badge-tertiary)] bg-[var(--color-badge-tertiary)]/20 dark:border-[var(--color-badge-tertiary)] dark:text-[var(--color-badge-tertiary)] dark:bg-[var(--color-badge-tertiary)]/20',\n },\n\n // Quaternary badge variants\n {\n type: 'quaternary',\n theme: 'solid',\n className:\n 'border-transparent bg-[var(--color-badge-quaternary)] text-[var(--color-badge-quaternary-foreground)]',\n },\n {\n type: 'quaternary',\n theme: 'outline',\n className:\n 'border-[var(--color-badge-quaternary)] text-[var(--color-badge-quaternary-foreground)] dark:border-[var(--color-badge-quaternary)] dark:text-[var(--color-badge-quaternary-foreground)]',\n },\n {\n type: 'quaternary',\n theme: 'light',\n className:\n 'border-[var(--color-badge-quaternary)] text-[var(--color-badge-quaternary-foreground)] bg-[var(--color-badge-quaternary)]/20 dark:border-[var(--color-badge-quaternary)] dark:text-[var(--color-badge-quaternary-foreground)] dark:bg-[var(--color-badge-quaternary)]/20',\n },\n\n // Info badge variants\n {\n type: 'info',\n theme: 'solid',\n className:\n 'border-transparent bg-[var(--color-badge-info)] text-[var(--color-badge-info-foreground)]',\n },\n {\n type: 'info',\n theme: 'outline',\n className:\n 'border-[var(--color-badge-info)] text-[var(--color-badge-info)] dark:border-[var(--color-badge-info)] dark:text-[var(--color-badge-info)]',\n },\n {\n type: 'info',\n theme: 'light',\n className:\n 'border-[var(--color-badge-info)] text-[var(--color-badge-info)] bg-[var(--color-badge-info)]/20 dark:border-[var(--color-badge-info)] dark:text-[var(--color-badge-info)] dark:bg-[var(--color-badge-info)]/20',\n },\n\n // Warning badge variants\n {\n type: 'warning',\n theme: 'solid',\n className:\n 'border-transparent bg-[var(--color-badge-warning)] text-[var(--color-badge-warning-foreground)]',\n },\n {\n type: 'warning',\n theme: 'outline',\n className:\n 'border-[var(--color-badge-warning)] text-[var(--color-badge-warning)] dark:border-[var(--color-badge-warning)] dark:text-[var(--color-badge-warning)]',\n },\n {\n type: 'warning',\n theme: 'light',\n className:\n 'border-[var(--color-badge-warning)] text-[var(--color-badge-warning)] bg-[var(--color-badge-warning)]/20 dark:border-[var(--color-badge-warning)] dark:text-[var(--color-badge-warning)] dark:bg-[var(--color-badge-warning)]/20',\n },\n\n // Danger badge variants\n {\n type: 'danger',\n theme: 'solid',\n className:\n 'border-transparent bg-[var(--color-badge-danger)] text-[var(--color-badge-danger-foreground)]',\n },\n {\n type: 'danger',\n theme: 'outline',\n className:\n 'border-[var(--color-badge-danger)] text-[var(--color-badge-danger)] dark:border-[var(--color-badge-danger)] dark:text-[var(--color-badge-danger)]',\n },\n {\n type: 'danger',\n theme: 'light',\n className:\n 'border-[var(--color-badge-danger)] text-[var(--color-badge-danger)] bg-[var(--color-badge-danger)]/20 dark:border-[var(--color-badge-danger)] dark:text-[var(--color-badge-danger)] dark:bg-[var(--color-badge-danger)]/20',\n },\n\n // Success badge variants\n {\n type: 'success',\n theme: 'solid',\n className:\n 'border-transparent bg-[var(--color-badge-success)] text-[var(--color-badge-success-foreground)]',\n },\n {\n type: 'success',\n theme: 'outline',\n className:\n 'border-[var(--color-badge-success)] text-[var(--color-badge-success)] dark:border-[var(--color-badge-success)] dark:text-[var(--color-badge-success)]',\n },\n {\n type: 'success',\n theme: 'light',\n className:\n 'border-[var(--color-badge-success)] text-[var(--color-badge-success)] bg-[var(--color-badge-success)]/20 dark:border-[var(--color-badge-success)] dark:text-[var(--color-badge-success)] dark:bg-[var(--color-badge-success)]/20',\n },\n\n // Muted badge variants\n {\n type: 'muted',\n theme: 'solid',\n className:\n 'border-transparent text-[var(--color-badge-muted-foreground)] bg-[var(--color-badge-muted)] dark:border-[var(--color-badge-muted)]/20 dark:text-[var(--color-badge-muted)] dark:bg-[var(--color-badge-muted)]/20',\n },\n {\n type: 'muted',\n theme: 'outline',\n className:\n 'border-[var(--color-badge-muted)] text-[var(--color-badge-muted)] dark:border-[var(--color-badge-muted)] dark:text-[var(--color-badge-muted)]',\n },\n {\n type: 'muted',\n theme: 'light',\n className:\n 'border-[var(--color-badge-muted)] text-[var(--color-badge-muted)] bg-[var(--color-badge-muted)]/20 dark:border-[var(--color-badge-muted)] dark:text-[var(--color-badge-muted)] dark:bg-[var(--color-badge-muted)]/20',\n },\n ],\n defaultVariants: {\n type: 'muted',\n theme: 'solid',\n },\n },\n)\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {}\n\nfunction Badge({ className, type, theme, ...props }: BadgeProps) {\n return <div className={cn(badgeVariants({ type, theme }), className)} {...props} />\n}\n\nexport { Badge, badgeVariants }\n","import type { VariantProps } from 'class-variance-authority'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { SpinnerIcon } from '../../icons/spinner.icon'\n\nconst buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50',\n {\n variants: {\n type: {\n primary: '',\n secondary: '',\n tertiary: '',\n quaternary: '',\n warning: '',\n danger: '',\n success: '',\n },\n theme: {\n solid: '',\n light: '',\n outline: 'border',\n borderless: 'border-0 bg-transparent',\n link: 'text-primary underline-offset-2 underline hover:opacity-80',\n },\n size: {\n xs: 'h-7 px-2.5 text-xs',\n small: 'h-9 px-3 text-xs',\n default: 'h-9 px-4 py-2',\n large: 'h-11 px-8 text-base',\n icon: 'h-9 w-9',\n link: 'px-0 py-0',\n },\n block: {\n true: 'w-full',\n false: '',\n },\n },\n compoundVariants: [\n // Primary button variants\n {\n type: 'primary',\n theme: 'solid',\n className:\n 'bg-btn-primary border border-btn-primary-border text-btn-primary-foreground hover:bg-btn-primary-hover active:bg-btn-primary-active disabled:bg-btn-primary/60',\n },\n {\n type: 'primary',\n theme: 'light',\n className: cn(\n 'bg-btn-neutral-bg text-primary hover:bg-btn-neutral-bg-hover active:bg-btn-neutral-bg-active disabled:bg-btn-neutral-bg disabled:text-primary',\n 'dark:text-foreground',\n ),\n },\n {\n type: 'primary',\n theme: 'outline',\n className: cn(\n 'border border-btn-primary-border/60 text-primary hover:border-btn-primary-border active:border-btn-primary-border disabled:bg-transparent disabled:text-primary disabled:border-btn-primary-border/60',\n 'dark:text-foreground dark:border-foreground/60 dark:hover:border-foreground dark:active:border-foreground/80',\n ),\n },\n {\n type: 'primary',\n theme: 'borderless',\n className: cn(\n 'text-primary hover:bg-btn-neutral-bg active:bg-btn-neutral-bg-active disabled:bg-transparent disabled:text-primary',\n 'dark:text-foreground',\n ),\n },\n\n // Secondary button variants\n {\n type: 'secondary',\n theme: 'solid',\n className:\n 'bg-btn-secondary border border-btn-secondary-border text-btn-secondary-foreground hover:bg-btn-secondary-hover active:bg-btn-secondary-active disabled:bg-btn-secondary/60',\n },\n {\n type: 'secondary',\n theme: 'light',\n className: cn(\n 'bg-btn-neutral-bg text-secondary hover:bg-btn-neutral-bg-hover active:bg-btn-neutral-bg-active disabled:bg-btn-neutral-bg disabled:text-secondary',\n 'dark:text-foreground',\n ),\n },\n {\n type: 'secondary',\n theme: 'outline',\n className: cn(\n 'border border-btn-secondary-border/60 text-secondary hover:border-btn-secondary-border active:border-btn-secondary-border disabled:bg-transparent disabled:text-secondary disabled:border-btn-secondary-border/60',\n 'dark:text-foreground dark:border-foreground/60 dark:hover:border-foreground dark:active:border-foreground/80',\n ),\n },\n {\n type: 'secondary',\n theme: 'borderless',\n className: cn(\n 'text-secondary hover:bg-btn-neutral-bg active:bg-btn-neutral-bg-active disabled:bg-transparent disabled:text-secondary',\n 'dark:text-foreground',\n ),\n },\n\n // Tertiary button variants\n {\n type: 'tertiary',\n theme: 'solid',\n className:\n 'bg-btn-tertiary border border-btn-tertiary-border text-btn-tertiary-foreground hover:bg-btn-tertiary-hover active:bg-btn-tertiary-active disabled:bg-btn-tertiary/60',\n },\n {\n type: 'tertiary',\n theme: 'light',\n className: cn(\n 'bg-btn-neutral-bg text-tertiary hover:bg-btn-neutral-bg-hover active:bg-btn-neutral-bg-active disabled:bg-btn-neutral-bg disabled:text-tertiary',\n 'dark:text-foreground',\n ),\n },\n {\n type: 'tertiary',\n theme: 'outline',\n className: cn(\n 'border border-btn-tertiary-border/60 text-tertiary hover:border-btn-tertiary-border active:border-btn-tertiary-border disabled:bg-transparent disabled:text-tertiary disabled:border-btn-tertiary-border/60',\n 'dark:text-foreground dark:border-foreground/60 dark:hover:border-foreground dark:active:border-foreground/80',\n ),\n },\n {\n type: 'tertiary',\n theme: 'borderless',\n className: cn(\n 'text-tertiary hover:bg-btn-neutral-bg active:bg-btn-neutral-bg-active disabled:bg-transparent disabled:text-tertiary',\n 'dark:text-foreground',\n ),\n },\n\n // Quaternary button variants\n {\n type: 'quaternary',\n theme: 'solid',\n className:\n 'bg-btn-quaternary border border-btn-quaternary text-btn-quaternary-foreground hover:bg-btn-quaternary-hover active:bg-btn-quaternary-active disabled:bg-btn-quaternary/60',\n },\n {\n type: 'quaternary',\n theme: 'light',\n className: cn(\n 'bg-btn-neutral-bg text-btn-quaternary-foreground hover:bg-btn-neutral-bg-hover active:bg-btn-neutral-bg-active disabled:bg-btn-neutral-bg disabled:text-btn-quaternary-foreground',\n 'dark:text-foreground',\n ),\n },\n {\n type: 'quaternary',\n theme: 'outline',\n className: cn(\n 'border border-btn-quaternary-border/60 text-btn-quaternary-foreground hover:border-btn-quaternary-border active:border-btn-quaternary-border disabled:bg-transparent disabled:text-btn-quaternary-foreground disabled:border-btn-quaternary-border/60',\n 'dark:text-foreground dark:border-foreground/60 dark:hover:border-foreground dark:active:border-foreground/80',\n ),\n },\n {\n type: 'quaternary',\n theme: 'borderless',\n className: cn(\n 'text-btn-quaternary-foreground hover:bg-btn-neutral-bg active:bg-btn-neutral-bg-active disabled:bg-transparent disabled:text-btn-quaternary-foreground',\n 'dark:text-foreground',\n ),\n },\n\n // Warning button variants\n {\n type: 'warning',\n theme: 'solid',\n className:\n 'bg-btn-warning text-btn-warning-foreground border border-btn-warning-border hover:bg-btn-warning-hover active:bg-btn-warning-active disabled:bg-btn-warning/60',\n },\n {\n type: 'warning',\n theme: 'light',\n className:\n 'bg-btn-neutral-bg text-btn-warning hover:bg-btn-neutral-bg-hover active:bg-btn-neutral-bg-active disabled:bg-btn-neutral-bg disabled:text-btn-warning',\n },\n {\n type: 'warning',\n theme: 'outline',\n className:\n 'border-yellow-600 text-yellow-600 hover:bg-yellow-600 hover:text-white active:bg-yellow-700 active:text-white dark:border-yellow-500 dark:text-yellow-500 dark:hover:bg-yellow-500 dark:hover:text-white dark:active:bg-yellow-600 dark:active:text-white disabled:bg-transparent disabled:text-yellow-600 disabled:border-yellow-600 disabled:hover:bg-transparent disabled:hover:text-yellow-600',\n },\n {\n type: 'warning',\n theme: 'borderless',\n className:\n 'text-btn-warning hover:bg-btn-neutral-bg active:bg-btn-neutral-bg-active disabled:bg-transparent disabled:text-btn-warning',\n },\n\n // Danger button variants\n {\n type: 'danger',\n theme: 'solid',\n className:\n 'bg-btn-danger text-btn-danger-foreground border border-btn-danger-border hover:bg-btn-danger-hover active:bg-btn-danger-active disabled:bg-btn-danger/60',\n },\n {\n type: 'danger',\n theme: 'light',\n className:\n 'bg-btn-neutral-bg text-btn-danger hover:bg-btn-neutral-bg-hover active:bg-btn-neutral-bg-active disabled:bg-btn-neutral-bg disabled:text-btn-danger',\n },\n {\n type: 'danger',\n theme: 'outline',\n className:\n 'border-destructive text-destructive hover:bg-destructive hover:text-destructive-foreground active:bg-destructive/90 active:text-destructive-foreground disabled:bg-transparent disabled:text-destructive disabled:border-destructive disabled:hover:bg-transparent disabled:hover:text-destructive',\n },\n {\n type: 'danger',\n theme: 'borderless',\n className:\n 'text-btn-danger hover:bg-btn-neutral-bg active:bg-btn-neutral-bg-active disabled:bg-transparent disabled:text-btn-danger',\n },\n\n // Success button variants\n {\n type: 'success',\n theme: 'solid',\n className:\n 'bg-btn-success text-btn-success-foreground border border-btn-success-border hover:bg-btn-success-hover active:bg-btn-success-active disabled:bg-btn-success/60',\n },\n {\n type: 'success',\n theme: 'light',\n className:\n 'bg-btn-neutral-bg text-btn-success hover:bg-btn-neutral-bg-hover active:bg-btn-neutral-bg-active disabled:bg-btn-neutral-bg disabled:text-btn-success',\n },\n {\n type: 'success',\n theme: 'outline',\n className:\n 'border-green-600 text-green-600 hover:bg-green-600 hover:text-white active:bg-green-700 active:text-white dark:border-green-500 dark:text-green-500 dark:hover:bg-green-500 dark:hover:text-white dark:active:bg-green-600 dark:active:text-white disabled:bg-transparent disabled:text-green-600 disabled:border-green-600 disabled:hover:bg-transparent disabled:hover:text-green-600',\n },\n {\n type: 'success',\n theme: 'borderless',\n className:\n 'text-btn-success hover:bg-btn-neutral-bg active:bg-btn-neutral-bg-active disabled:bg-transparent disabled:text-btn-success',\n },\n ],\n defaultVariants: {\n type: 'primary',\n theme: 'solid',\n size: 'default',\n block: false,\n },\n },\n)\n\nexport interface ButtonProps\n extends\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean\n loading?: boolean\n icon?: React.ReactNode\n iconPosition?: 'left' | 'right'\n loadingIcon?: React.ReactNode\n htmlType?: 'button' | 'submit' | 'reset'\n}\n\nfunction Button({ ref, className, type, theme, size, block, loading = false, disabled, icon, iconPosition = 'left', loadingIcon, htmlType = 'button', children, ...props }: ButtonProps & { ref?: React.RefObject<HTMLButtonElement | null> }) {\n const isDisabled = disabled || loading\n\n // Auto-detect icon-only buttons and adjust to square\n const isIconOnly = (icon || loading) && !children\n\n // For icon-only buttons, replace icon with loading spinner when loading\n const showIcon = !loading && icon\n const getLoadingIcon = () => {\n return (\n loadingIcon || (\n <SpinnerIcon\n size={size === 'small' ? 'xs' : size === 'large' ? 'sm' : 'md'}\n aria-hidden=\"true\"\n />\n )\n )\n }\n const showLoadingIcon\n = loading && (isIconOnly ? getLoadingIcon() : <SpinnerIcon size=\"sm\" aria-hidden=\"true\" />)\n\n const getIconOnlyClass = () => {\n if (!isIconOnly || size === 'icon')\n return ''\n if (size === 'small')\n return 'w-8 px-0'\n if (size === 'large')\n return 'w-11 px-0'\n return 'w-9 px-0' // default\n }\n\n return (\n <button\n className={cn(buttonVariants({ type, theme, size, block }), getIconOnlyClass(), className)}\n ref={ref}\n disabled={isDisabled}\n type={htmlType}\n {...props}\n >\n {/* For icon-only buttons: show loading OR icon, not both */}\n {isIconOnly\n ? (\n loading\n ? (\n showLoadingIcon\n )\n : (\n showIcon && icon\n )\n )\n : (\n <>\n {showLoadingIcon && showLoadingIcon}\n {showIcon && iconPosition === 'left' && icon}\n {children}\n {showIcon && iconPosition === 'right' && icon}\n </>\n )}\n </button>\n )\n}\n\nButton.displayName = 'Button'\n\nexport { Button, buttonVariants }\n","import type { VariantProps } from 'class-variance-authority'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { buttonVariants } from './button'\n\nexport interface LinkButtonProps\n extends\n Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'type'>,\n VariantProps<typeof buttonVariants> {\n /** Polymorphic component to render (defaults to native `<a>`) */\n as?: React.ElementType\n /** Destination URL — mapped to `href` for native `<a>`, `to` for router Links */\n href?: string\n icon?: React.ReactNode\n iconPosition?: 'left' | 'right'\n}\n\nfunction LinkButton({ ref, className, type, theme, size, block, icon, iconPosition = 'left', children, as: Component = 'a', href, ...props }: LinkButtonProps & { ref?: React.RefObject<HTMLAnchorElement | null> }) {\n const isIconOnly = icon && !children\n\n const getIconOnlyClass = () => {\n if (!isIconOnly || size === 'icon')\n return ''\n if (size === 'small')\n return 'w-8 px-0'\n if (size === 'large')\n return 'w-11 px-0'\n return 'w-9 px-0'\n }\n\n // Map href to the appropriate prop for the component:\n // - Native <a>: uses `href`\n // - Router Links (e.g. react-router Link): use `to`\n const linkProps = Component === 'a' ? { href } : { to: href }\n\n return (\n <Component\n className={cn(buttonVariants({ type, theme, size, block }), getIconOnlyClass(), className)}\n ref={ref}\n {...linkProps}\n {...props}\n >\n {isIconOnly\n ? (\n icon\n )\n : (\n <>\n {icon && iconPosition === 'left' && icon}\n {children}\n {icon && iconPosition === 'right' && icon}\n </>\n )}\n </Component>\n )\n}\n\nLinkButton.displayName = 'LinkButton'\n\nexport { LinkButton }\n","import type { DayButton } from 'react-day-picker'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Button, buttonVariants } from '@repo/shadcn/ui/button'\nimport { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\nimport * as React from 'react'\nimport { DayPicker, getDefaultClassNames } from 'react-day-picker'\nimport { Icon } from '../../icons/icon-wrapper'\n\nfunction CalendarRoot({ className, rootRef, ...props }: any) {\n return <div data-slot=\"calendar\" ref={rootRef} className={cn(className)} {...props} />\n}\n\nfunction CalendarChevron({ className, orientation, ...props }: any) {\n if (orientation === 'left') {\n return <Icon icon={ChevronLeftIcon} className={cn('size-4', className)} {...props} />\n }\n\n if (orientation === 'right') {\n return <Icon icon={ChevronRightIcon} className={cn('size-4', className)} {...props} />\n }\n\n return <Icon icon={ChevronDownIcon} className={cn('size-4', className)} {...props} />\n}\n\nfunction CalendarWeekNumber({ children, ...props }: any) {\n return (\n <td {...props}>\n <div className=\"flex size-(--cell-size) items-center justify-center text-center\">\n {children}\n </div>\n </td>\n )\n}\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n captionLayout = 'label',\n buttonVariant = 'ghost',\n formatters,\n components,\n ...props\n}: React.ComponentProps<typeof DayPicker> & {\n buttonVariant?: React.ComponentProps<typeof Button>['variant']\n}) {\n const defaultClassNames = getDefaultClassNames()\n\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\n 'bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent',\n String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\n String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n className,\n )}\n captionLayout={captionLayout}\n formatters={{\n formatMonthDropdown: date => date.toLocaleString('default', { month: 'short' }),\n ...formatters,\n }}\n classNames={{\n root: cn('w-fit', defaultClassNames.root),\n months: cn('flex gap-4 flex-col md:flex-row relative', defaultClassNames.months),\n month: cn('flex flex-col w-full gap-4', defaultClassNames.month),\n nav: cn(\n 'flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between',\n defaultClassNames.nav,\n ),\n button_previous: cn(\n buttonVariants({ variant: buttonVariant }),\n 'size-(--cell-size) aria-disabled:opacity-50 p-0 select-none',\n defaultClassNames.button_previous,\n ),\n button_next: cn(\n buttonVariants({ variant: buttonVariant }),\n 'size-(--cell-size) aria-disabled:opacity-50 p-0 select-none',\n defaultClassNames.button_next,\n ),\n month_caption: cn(\n 'flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)',\n defaultClassNames.month_caption,\n ),\n dropdowns: cn(\n 'w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5',\n defaultClassNames.dropdowns,\n ),\n dropdown_root: cn(\n 'relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md',\n defaultClassNames.dropdown_root,\n ),\n dropdown: cn('absolute bg-popover inset-0 opacity-0', defaultClassNames.dropdown),\n caption_label: cn(\n 'select-none font-medium',\n captionLayout === 'label'\n ? 'text-sm'\n : 'rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5',\n defaultClassNames.caption_label,\n ),\n table: 'w-full border-collapse',\n weekdays: cn('flex', defaultClassNames.weekdays),\n weekday: cn(\n 'text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none',\n defaultClassNames.weekday,\n ),\n week: cn('flex w-full mt-2', defaultClassNames.week),\n week_number_header: cn('select-none w-(--cell-size)', defaultClassNames.week_number_header),\n week_number: cn(\n 'text-[0.8rem] select-none text-muted-foreground',\n defaultClassNames.week_number,\n ),\n day: cn(\n 'relative w-full h-full p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none',\n defaultClassNames.day,\n ),\n range_start: cn('rounded-l-md bg-accent', defaultClassNames.range_start),\n range_middle: cn('rounded-none', defaultClassNames.range_middle),\n range_end: cn('rounded-r-md bg-accent', defaultClassNames.range_end),\n today: cn(\n 'bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none',\n defaultClassNames.today,\n ),\n outside: cn(\n 'text-muted-foreground aria-selected:text-muted-foreground',\n defaultClassNames.outside,\n ),\n disabled: cn('text-muted-foreground opacity-50', defaultClassNames.disabled),\n hidden: cn('invisible', defaultClassNames.hidden),\n ...classNames,\n }}\n components={{\n Root: CalendarRoot,\n Chevron: CalendarChevron,\n DayButton: CalendarDayButton,\n WeekNumber: CalendarWeekNumber,\n ...components,\n }}\n {...props}\n />\n )\n}\n\nfunction CalendarDayButton({\n className,\n day,\n modifiers,\n ...props\n}: React.ComponentProps<typeof DayButton>) {\n const defaultClassNames = getDefaultClassNames()\n\n const ref = React.useRef<HTMLButtonElement>(null)\n React.useEffect(() => {\n if (modifiers.focused)\n ref.current?.focus()\n }, [modifiers.focused])\n\n return (\n <Button\n ref={ref}\n variant=\"ghost\"\n size=\"icon\"\n data-day={day.date.toLocaleDateString()}\n data-selected-single={\n modifiers.selected\n && !modifiers.range_start\n && !modifiers.range_end\n && !modifiers.range_middle\n }\n data-range-start={modifiers.range_start}\n data-range-end={modifiers.range_end}\n data-range-middle={modifiers.range_middle}\n className={cn(\n 'data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70',\n defaultClassNames.day,\n className,\n )}\n {...props}\n />\n )\n}\n\nexport { Calendar, CalendarDayButton }\n","import { cn } from '@repo/shadcn/lib/utils'\nimport { CardContent, CardDescription, CardTitle } from '@repo/shadcn/ui/card'\nimport * as React from 'react'\n\n/**\n * Datum Card Component\n * Extends shadcn Card with custom default className\n *\n * This component replaces the default className of shadcn Card without modifying\n * the original shadcn component. All sub-components (CardHeader, CardTitle, etc.)\n * are re-exported from shadcn as-is.\n */\n\nconst DEFAULT_CARD_CLASSNAME\n = 'bg-card text-card-foreground flex flex-col gap-4 rounded-xl border border-card-border py-6 shadow'\n\nfunction Card({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"card\" className={cn(DEFAULT_CARD_CLASSNAME, className)} {...props} />\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn('border-card-border flex flex-col gap-3 px-6', className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div data-slot=\"card-footer\" className={cn('border-card-border px-6', className)} {...props} />\n )\n}\n\nexport { CardContent, CardDescription, CardFooter, CardTitle }\nexport { Card, CardHeader }\n","import { cn } from '@repo/shadcn/lib/utils'\nimport { Checkbox as ShadcnCheckbox } from '@repo/shadcn/ui/checkbox'\nimport * as React from 'react'\n\nfunction Checkbox({ ref, className, ...props }: React.ComponentProps<typeof ShadcnCheckbox> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnCheckbox> | null> }) {\n return <ShadcnCheckbox ref={ref} className={cn(className)} {...props} />\n}\n\nCheckbox.displayName = 'Checkbox'\n\nexport { Checkbox }\n","import * as DialogPrimitive from '@radix-ui/react-dialog'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport {\n DialogClose,\n DialogDescription,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n Dialog as ShadcnDialog,\n DialogFooter as ShadcnDialogFooter,\n DialogOverlay as ShadcnDialogOverlay,\n} from '@repo/shadcn/ui/dialog'\nimport * as React from 'react'\nimport { CloseIcon } from '../../icons/close.icon'\n\n/* -----------------------------------------------------------------------------\n * Dialog Root\n * -------------------------------------------------------------------------- */\n\ninterface DialogProps {\n open?: boolean\n onOpenChange?: (open: boolean) => void\n defaultOpen?: boolean\n children: React.ReactNode\n}\n\nfunction Dialog({ children, ...props }: DialogProps) {\n return <ShadcnDialog {...props}>{children}</ShadcnDialog>\n}\n\n/* -----------------------------------------------------------------------------\n * Dialog Overlay\n * -------------------------------------------------------------------------- */\n\ninterface DialogOverlayProps {\n className?: string\n}\n\nfunction DialogOverlay({ className, ...props }: DialogOverlayProps) {\n return (\n <ShadcnDialogOverlay\n className={cn('bg-dialog-overlay/50 backdrop-blur-[2px]', className)}\n {...props}\n />\n )\n}\n\n/* -----------------------------------------------------------------------------\n * Dialog Trigger\n * -------------------------------------------------------------------------- */\n\ninterface DialogTriggerProps {\n children: React.ReactNode\n asChild?: boolean\n}\n\nfunction Trigger({ children, asChild = true }: DialogTriggerProps) {\n return <DialogTrigger asChild={asChild}>{children}</DialogTrigger>\n}\n\n/* -----------------------------------------------------------------------------\n * Dialog Content\n * -------------------------------------------------------------------------- */\n\ninterface DialogContentProps {\n children: React.ReactNode\n className?: string\n}\n\nfunction Content({ children, className }: DialogContentProps) {\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n className={cn(\n 'dark:bg-muted dark:border-dialog-border 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 fixed top-[50%] left-[50%] z-50 flex max-h-[80vh] w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] flex-col gap-0 overflow-y-auto rounded-lg bg-white p-0 shadow-xl duration-200 sm:max-w-lg dark:border [&>button:last-child]:hidden',\n className,\n )}\n >\n {children}\n </DialogPrimitive.Content>\n </DialogPortal>\n )\n}\n\n/* -----------------------------------------------------------------------------\n * Dialog Header\n * -------------------------------------------------------------------------- */\n\ninterface DialogHeaderProps {\n title: React.ReactNode\n description?: React.ReactNode\n onClose?: () => void\n className?: string\n descriptionClassName?: string\n}\n\nfunction Header({\n title,\n description,\n onClose,\n className,\n descriptionClassName,\n}: DialogHeaderProps) {\n return (\n <div\n className={cn(\n 'dark:bg-muted dark:border-dialog-border sticky top-0 z-50 flex shrink-0 flex-col gap-2 bg-white p-5',\n className,\n )}\n >\n <DialogTitle className=\"text-base font-semibold\">{title}</DialogTitle>\n {description && (\n <DialogDescription className={cn('text-sm font-normal', descriptionClassName)}>\n {description}\n </DialogDescription>\n )}\n\n {onClose && (\n <DialogClose className=\"absolute top-4 right-4 cursor-pointer\" onClick={onClose}>\n <CloseIcon />\n </DialogClose>\n )}\n </div>\n )\n}\n\n/* -----------------------------------------------------------------------------\n * Dialog Body\n * -------------------------------------------------------------------------- */\n\ninterface DialogBodyProps {\n children: React.ReactNode\n className?: string\n}\n\nfunction Body({ children, className }: DialogBodyProps) {\n return <div className={cn('py-5', className)}>{children}</div>\n}\n\n/* -----------------------------------------------------------------------------\n * Dialog Footer\n * -------------------------------------------------------------------------- */\n\ninterface DialogFooterProps {\n children: React.ReactNode\n className?: string\n}\n\nfunction Footer({ children, className }: DialogFooterProps) {\n return (\n <ShadcnDialogFooter\n className={cn(\n 'dark:bg-muted dark:border-dialog-border sticky bottom-0 z-50 shrink-0 gap-3 bg-white p-5',\n className,\n )}\n >\n {children}\n </ShadcnDialogFooter>\n )\n}\n\n/* -----------------------------------------------------------------------------\n * Compound Component Export\n * -------------------------------------------------------------------------- */\n\nDialog.Trigger = Trigger\nDialog.Content = Content\nDialog.Header = Header\nDialog.Body = Body\nDialog.Footer = Footer\nDialog.Overlay = DialogOverlay\n\nexport { Dialog }\nexport type {\n DialogBodyProps,\n DialogContentProps,\n DialogFooterProps,\n DialogHeaderProps,\n DialogProps,\n DialogTriggerProps,\n}\n","import { cn } from '@repo/shadcn/lib/utils'\nimport { Input as ShadcnInput } from '@repo/shadcn/ui/input'\nimport * as React from 'react'\n\nfunction Input({ ref, className, ...props }: React.ComponentProps<'input'> & { ref?: React.RefObject<HTMLInputElement | null> }) {\n return (\n <ShadcnInput\n ref={ref}\n className={cn(\n 'rounded-lg',\n 'bg-input-background/50',\n 'text-input-foreground',\n 'border-input-border',\n 'placeholder:text-input-placeholder',\n 'focus-visible:ring-0 focus-visible:ring-offset-0',\n 'focus-visible:border-input-focus-border',\n 'focus-visible:shadow-(--input-focus-shadow)',\n 'aria-invalid:border-destructive',\n className,\n )}\n {...props}\n />\n )\n}\n\nInput.displayName = 'Input'\n\nexport { Input }\n","import { cn } from '@repo/shadcn/lib/utils'\nimport { Label as ShadcnLabel } from '@repo/shadcn/ui/label'\nimport * as React from 'react'\n\n/**\n * Datum Label component - extends shadcn Label with Datum-specific styling\n *\n * This component wraps the shadcn Label and allows for Datum-specific\n * class customizations without modifying the core shadcn component.\n *\n * @example\n * ```tsx\n * <Label\n * htmlFor=\"input-id\"\n * className=\"custom-class\"\n * >\n * Field Label\n * </Label>\n * ```\n */\nfunction Label({ ref, className, ...props }: React.ComponentProps<typeof ShadcnLabel> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnLabel> | null> }) {\n return (\n <ShadcnLabel\n ref={ref}\n className={cn(\n // Datum-specific customizations can be added here\n // These classes will merge with shadcn defaults\n className,\n )}\n {...props}\n />\n )\n}\n\nLabel.displayName = 'Label'\n\nexport { Label }\n","import { cn } from '@repo/shadcn/lib/utils'\nimport {\n RadioGroup as ShadcnRadioGroup,\n RadioGroupItem as ShadcnRadioGroupItem,\n} from '@repo/shadcn/ui/radio-group'\nimport * as React from 'react'\n\nfunction RadioGroup({ ref, className, ...props }: React.ComponentProps<typeof ShadcnRadioGroup> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnRadioGroup> | null> }) {\n return <ShadcnRadioGroup ref={ref} className={cn(className)} {...props} />\n}\n\nRadioGroup.displayName = 'RadioGroup'\n\nfunction RadioGroupItem({ ref, className, ...props }: React.ComponentProps<typeof ShadcnRadioGroupItem> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnRadioGroupItem> | null> }) {\n return <ShadcnRadioGroupItem ref={ref} className={cn(className)} {...props} />\n}\n\nRadioGroupItem.displayName = 'RadioGroupItem'\n\nexport { RadioGroup, RadioGroupItem }\n","import { cn } from '@repo/shadcn/lib/utils'\nimport {\n Select as ShadcnSelect,\n SelectContent as ShadcnSelectContent,\n SelectGroup as ShadcnSelectGroup,\n SelectItem as ShadcnSelectItem,\n SelectLabel as ShadcnSelectLabel,\n SelectScrollDownButton as ShadcnSelectScrollDownButton,\n SelectScrollUpButton as ShadcnSelectScrollUpButton,\n SelectSeparator as ShadcnSelectSeparator,\n SelectTrigger as ShadcnSelectTrigger,\n SelectValue as ShadcnSelectValue,\n} from '@repo/shadcn/ui/select'\nimport * as React from 'react'\n\nconst Select = ShadcnSelect\n\nconst SelectValue = ShadcnSelectValue\n\nfunction SelectGroup({ ref, className, ...props }: React.ComponentProps<typeof ShadcnSelectGroup> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnSelectGroup> | null> }) {\n return <ShadcnSelectGroup ref={ref} className={cn(className)} {...props} />\n}\n\nSelectGroup.displayName = 'SelectGroup'\n\nfunction SelectTrigger({ ref, className, ...props }: React.ComponentProps<typeof ShadcnSelectTrigger> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnSelectTrigger> | null> }) {\n return (\n <ShadcnSelectTrigger\n ref={ref}\n className={cn(\n 'rounded-lg',\n 'bg-input-background/50',\n 'text-input-foreground',\n 'border-input-border',\n 'placeholder:text-input-placeholder',\n 'focus-visible:ring-0 focus-visible:ring-offset-0',\n 'focus-visible:border-input-focus-border',\n 'focus-visible:shadow-(--input-focus-shadow)',\n 'aria-invalid:border-destructive',\n className,\n )}\n {...props}\n />\n )\n}\n\nSelectTrigger.displayName = 'SelectTrigger'\n\nfunction SelectContent({ ref, className, ...props }: React.ComponentProps<typeof ShadcnSelectContent> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnSelectContent> | null> }) {\n return <ShadcnSelectContent ref={ref} className={cn(className)} {...props} />\n}\n\nSelectContent.displayName = 'SelectContent'\n\nfunction SelectLabel({ ref, className, ...props }: React.ComponentProps<typeof ShadcnSelectLabel> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnSelectLabel> | null> }) {\n return <ShadcnSelectLabel ref={ref} className={cn(className)} {...props} />\n}\n\nSelectLabel.displayName = 'SelectLabel'\n\nfunction SelectItem({ ref, className, ...props }: React.ComponentProps<typeof ShadcnSelectItem> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnSelectItem> | null> }) {\n return <ShadcnSelectItem ref={ref} className={cn(className)} {...props} />\n}\n\nSelectItem.displayName = 'SelectItem'\n\nfunction SelectSeparator({ ref, className, ...props }: React.ComponentProps<typeof ShadcnSelectSeparator> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnSelectSeparator> | null> }) {\n return <ShadcnSelectSeparator ref={ref} className={cn(className)} {...props} />\n}\n\nSelectSeparator.displayName = 'SelectSeparator'\n\nfunction SelectScrollUpButton({ ref, className, ...props }: React.ComponentProps<typeof ShadcnSelectScrollUpButton> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnSelectScrollUpButton> | null> }) {\n return <ShadcnSelectScrollUpButton ref={ref} className={cn(className)} {...props} />\n}\n\nSelectScrollUpButton.displayName = 'SelectScrollUpButton'\n\nfunction SelectScrollDownButton({ ref, className, ...props }: React.ComponentProps<typeof ShadcnSelectScrollDownButton> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnSelectScrollDownButton> | null> }) {\n return <ShadcnSelectScrollDownButton ref={ref} className={cn(className)} {...props} />\n}\n\nSelectScrollDownButton.displayName = 'SelectScrollDownButton'\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n}\n","import * as SheetPrimitive from '@radix-ui/react-dialog'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport {\n Sheet as ShadcnSheet,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from '@repo/shadcn/ui/sheet'\nimport * as React from 'react'\nimport { CloseIcon } from '../../icons/close.icon'\n\n/* -----------------------------------------------------------------------------\n * Re-exports from shadcn (unchanged)\n * -------------------------------------------------------------------------- */\n\nexport const SheetClose = SheetPrimitive.Close\n\n/* -----------------------------------------------------------------------------\n * Sheet Overlay – matches dialog overlay (datum-ui Dialog)\n * -------------------------------------------------------------------------- */\n\ninterface SheetOverlayProps extends React.ComponentProps<typeof SheetPrimitive.Overlay> { }\n\nfunction SheetOverlay({ className, ...props }: SheetOverlayProps) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn(\n 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 bg-dialog-overlay/50 fixed inset-0 z-50 backdrop-blur-[2px]',\n className,\n )}\n {...props}\n />\n )\n}\n\n/* -----------------------------------------------------------------------------\n * Sheet Content – same layout as shadcn, with dialog-style close button\n * -------------------------------------------------------------------------- */\n\ninterface SheetContentProps extends React.ComponentProps<typeof SheetPrimitive.Content> {\n side?: 'top' | 'right' | 'bottom' | 'left'\n}\n\nfunction SheetContent({ className, children, side = 'right', ...props }: SheetContentProps) {\n return (\n <SheetPrimitive.Portal data-slot=\"sheet-portal\">\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n className={cn(\n 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',\n side === 'right'\n && 'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',\n side === 'left'\n && 'data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',\n side === 'top'\n && 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b',\n side === 'bottom'\n && 'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t',\n className,\n )}\n {...props}\n >\n {children}\n <SheetPrimitive.Close className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 cursor-pointer rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0\">\n <CloseIcon className=\"size-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </SheetPrimitive.Content>\n </SheetPrimitive.Portal>\n )\n}\n\n/* -----------------------------------------------------------------------------\n * Compound export – typed so Sheet.Trigger, Sheet.Content, etc. are valid\n * -------------------------------------------------------------------------- */\n\ninterface SheetComponent extends React.FC<React.ComponentProps<typeof ShadcnSheet>> {\n Trigger: typeof SheetTrigger\n Content: typeof SheetContent\n Close: typeof SheetClose\n Header: typeof SheetHeader\n Footer: typeof SheetFooter\n Title: typeof SheetTitle\n Description: typeof SheetDescription\n}\n\nexport const Sheet: SheetComponent = Object.assign(ShadcnSheet, {\n Trigger: SheetTrigger,\n Content: SheetContent,\n Close: SheetClose,\n Header: SheetHeader,\n Footer: SheetFooter,\n Title: SheetTitle,\n Description: SheetDescription,\n})\n\nexport {\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetOverlay,\n SheetTitle,\n SheetTrigger,\n}\n","import { cn } from '@repo/shadcn/lib/utils'\nimport { Switch as ShadcnSwitch } from '@repo/shadcn/ui/switch'\nimport * as React from 'react'\n\nfunction Switch({ ref, className, ...props }: React.ComponentProps<typeof ShadcnSwitch> & { ref?: React.RefObject<React.ElementRef<typeof ShadcnSwitch> | null> }) {\n return <ShadcnSwitch ref={ref} className={cn(className)} {...props} />\n}\n\nSwitch.displayName = 'Switch'\n\nexport { Switch }\n","import * as TabsPrimitive from '@radix-ui/react-tabs'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\n\n/**\n * Datum Tabs Component\n * Extends shadcn Tabs with:\n * - TabsLinkTrigger for router-agnostic link integration\n * - Dark mode customizations\n */\n\nfunction Tabs({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Root>) {\n return <TabsPrimitive.Root className={cn('flex flex-col gap-2', className)} {...props} />\n}\n\nfunction TabsList({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.List>) {\n return (\n <TabsPrimitive.List\n className={cn(\n 'bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-1',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction TabsTrigger({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {\n return (\n <TabsPrimitive.Trigger\n className={cn(\n 'data-[state=active]:bg-background dark:data-[state=active]:text-foreground data-[state=active]:text-foreground dark:hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring inline-flex flex-1 items-center justify-center gap-1.5 rounded-md px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\\'size-\\'])]:size-4',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction TabsContent({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Content>) {\n return <TabsPrimitive.Content className={cn('flex-1 outline-none', className)} {...props} />\n}\n\ninterface TabsLinkTriggerProps extends React.ComponentProps<typeof TabsPrimitive.Trigger> {\n /** Destination URL — mapped to `href` for native `<a>`, `to` for router Links */\n href: string\n /** Link component to use (defaults to native `<a>`) */\n linkComponent?: React.ElementType\n}\n\nfunction TabsLinkTrigger({\n value,\n href,\n linkComponent: LinkComp = 'a',\n children,\n className,\n ...props\n}: TabsLinkTriggerProps) {\n // Map href to the appropriate prop for the component\n const linkProps = LinkComp === 'a' ? { href } : { to: href }\n\n return (\n <TabsTrigger value={value} asChild className={className} {...props}>\n <LinkComp {...linkProps}>{children}</LinkComp>\n </TabsTrigger>\n )\n}\n\nexport { Tabs, TabsContent, TabsLinkTrigger, TabsList, TabsTrigger }\nexport type { TabsLinkTriggerProps }\n","import { cn } from '@repo/shadcn/lib/utils'\nimport { Textarea as ShadcnTextarea } from '@repo/shadcn/ui/textarea'\nimport * as React from 'react'\n\nfunction Textarea({ ref, className, ...props }: React.ComponentProps<'textarea'> & { ref?: React.RefObject<HTMLTextAreaElement | null> }) {\n return (\n <ShadcnTextarea\n ref={ref}\n className={cn(\n 'rounded-lg',\n 'bg-input-background/50',\n 'text-input-foreground',\n 'border-input-border',\n 'placeholder:text-input-placeholder',\n 'focus-visible:ring-0 focus-visible:ring-offset-0',\n 'focus-visible:border-input-focus-border',\n 'focus-visible:shadow-(--input-focus-shadow)',\n 'aria-invalid:border-destructive',\n className,\n )}\n {...props}\n />\n )\n}\n\nTextarea.displayName = 'Textarea'\n\nexport { Textarea }\n","import type { ReactNode } from 'react'\nimport * as TooltipPrimitiveRadix from '@radix-ui/react-tooltip'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Tooltip as TooltipPrimitive, TooltipTrigger } from '@repo/shadcn/ui/tooltip'\n\ninterface TooltipProps {\n message: string | ReactNode\n children: ReactNode\n delayDuration?: number\n // Advanced props passed to TooltipContent\n side?: 'top' | 'right' | 'bottom' | 'left'\n align?: 'start' | 'center' | 'end'\n sideOffset?: number\n hidden?: boolean\n // Controlled state props\n open?: boolean\n onOpenChange?: (open: boolean) => void\n contentClassName?: string\n arrowClassName?: string\n}\n\nfunction TooltipContent({\n className,\n arrowClassName,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitiveRadix.Content> & {\n arrowClassName?: string\n}) {\n return (\n <TooltipPrimitiveRadix.Portal>\n <TooltipPrimitiveRadix.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n 'tooltip-content',\n 'bg-secondary text-secondary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit rounded-md px-3 py-1.5 text-xs text-balance',\n className,\n )}\n {...props}\n >\n {children}\n <TooltipPrimitiveRadix.Arrow\n className={cn(\n 'fill-secondary -my-px border-none drop-shadow-[0_1px_0_secondary]',\n arrowClassName,\n )}\n width={12}\n height={7}\n aria-hidden=\"true\"\n />\n </TooltipPrimitiveRadix.Content>\n </TooltipPrimitiveRadix.Portal>\n )\n}\n\nexport function Tooltip({\n message,\n children,\n delayDuration = 200,\n side,\n align,\n sideOffset,\n hidden,\n open,\n onOpenChange,\n contentClassName,\n arrowClassName,\n}: TooltipProps) {\n return (\n <TooltipPrimitive delayDuration={delayDuration} open={open} onOpenChange={onOpenChange}>\n <TooltipTrigger asChild>{children}</TooltipTrigger>\n <TooltipContent\n side={side}\n align={align}\n sideOffset={sideOffset}\n hidden={hidden}\n className={contentClassName}\n arrowClassName={arrowClassName}\n >\n <span>{message}</span>\n </TooltipContent>\n </TooltipPrimitive>\n )\n}\n","import { cn } from '@repo/shadcn/lib/utils'\nimport { SpinnerIcon } from '../../icons/spinner.icon'\n\nexport function LoaderOverlay({\n message,\n className,\n}: {\n message?: string | React.ReactNode\n className?: string\n}) {\n return (\n <div\n className={cn(\n 'bg-background/80 absolute inset-0 z-10 flex items-center justify-center gap-2 backdrop-blur-[1px]',\n className,\n )}\n >\n <SpinnerIcon size=\"sm\" />\n {typeof message === 'string'\n ? (\n <span className=\"text-sm font-medium\">{message}</span>\n )\n : (\n message\n )}\n </div>\n )\n}\n","import type {\n AutocompleteGroup,\n AutocompleteOption,\n AutocompleteProps,\n} from './autocomplete.types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@repo/shadcn/ui/command'\nimport { Popover, PopoverContent, PopoverTrigger } from '@repo/shadcn/ui/popover'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport { CheckIcon, ChevronDown } from 'lucide-react'\nimport * as React from 'react'\nimport { LoaderOverlay } from '../loader-overlay'\n\n// ============================================================================\n// Helper: detect grouped options\n// ============================================================================\n\nfunction isGroupedOptions<T extends AutocompleteOption>(\n options: T[] | AutocompleteGroup<T>[],\n): options is AutocompleteGroup<T>[] {\n return options.length > 0 && 'options' in options[0]!\n}\n\nfunction flattenOptions<T extends AutocompleteOption>(options: T[] | AutocompleteGroup<T>[]): T[] {\n if (isGroupedOptions(options)) {\n return options.flatMap(g => g.options)\n }\n return options\n}\n\n// ============================================================================\n// Trigger\n// ============================================================================\n\ninterface TriggerProps {\n selectedOption: AutocompleteOption | undefined\n renderValue?: (option: any) => React.ReactNode\n placeholder: string\n loading: boolean\n disabled: boolean\n open: boolean\n id?: string\n className?: string\n}\n\nfunction Trigger({ ref, selectedOption, renderValue, placeholder, loading, disabled, open, id, className, ...rest }: TriggerProps & { ref?: React.RefObject<HTMLButtonElement | null> }) {\n let displayContent: React.ReactNode\n if (!selectedOption) {\n displayContent = <span className=\"text-muted-foreground\">{placeholder}</span>\n }\n else if (renderValue) {\n displayContent = renderValue(selectedOption)\n }\n else {\n displayContent = <span className=\"truncate\">{selectedOption.label}</span>\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n id={id}\n role=\"combobox\"\n aria-expanded={open}\n disabled={disabled || loading}\n className={cn(\n 'text-input-foreground placeholder:text-input-placeholder',\n 'border-input-border bg-input-background/50 relative flex h-10 w-full items-center justify-between rounded-lg border px-3 py-2 text-left text-sm transition-all',\n 'focus-visible:border-input-focus-border focus-visible:shadow-(--input-focus-shadow)',\n 'focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:outline-hidden',\n 'aria-invalid:border-destructive',\n (disabled || loading) && 'cursor-not-allowed opacity-50',\n className,\n )}\n {...rest}\n >\n {loading && <LoaderOverlay />}\n <div className=\"min-w-0 flex-1\">{displayContent}</div>\n <ChevronDown className=\"text-muted-foreground ml-2 size-4 shrink-0\" />\n </button>\n )\n}\n\nTrigger.displayName = 'AutocompleteTrigger'\n\n// ============================================================================\n// Default Option Renderer\n// ============================================================================\n\nfunction DefaultOptionContent<T extends AutocompleteOption>({\n option,\n isSelected,\n}: {\n option: T\n isSelected: boolean\n}) {\n return (\n <div className=\"flex w-full items-center justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <span className=\"truncate text-sm\">{option.label}</span>\n {option.description && (\n <p className=\"text-muted-foreground mt-0.5 line-clamp-2 text-xs\">{option.description}</p>\n )}\n </div>\n {isSelected && <CheckIcon className=\"text-primary size-4 shrink-0\" />}\n </div>\n )\n}\n\n// ============================================================================\n// StaticOptions\n// ============================================================================\n\ninterface OptionsRendererProps<T extends AutocompleteOption> {\n options: T[] | AutocompleteGroup<T>[]\n selectedValue: string | undefined\n onSelect: (value: string) => void\n renderOption?: (option: T, isSelected: boolean) => React.ReactNode\n}\n\nfunction StaticOptions<T extends AutocompleteOption>({\n options,\n selectedValue,\n onSelect,\n renderOption,\n}: OptionsRendererProps<T>) {\n const renderItem = (option: T) => {\n const isSelected = option.value === selectedValue\n return (\n <CommandItem\n key={option.value}\n value={option.value}\n keywords={[option.label, option.description ?? '']}\n disabled={option.disabled}\n onSelect={() => onSelect(option.value)}\n className=\"cursor-pointer justify-between px-3 py-2 text-xs\"\n >\n {renderOption\n ? (\n renderOption(option, isSelected)\n )\n : (\n <DefaultOptionContent option={option} isSelected={isSelected} />\n )}\n </CommandItem>\n )\n }\n\n if (isGroupedOptions(options)) {\n return (\n <>\n {options.map((group, index) => (\n <CommandGroup\n key={group.label}\n heading={group.label}\n className={index > 0 ? 'border-t pt-1' : ''}\n >\n {group.options.map(renderItem)}\n </CommandGroup>\n ))}\n </>\n )\n }\n\n return <CommandGroup className=\"p-0\">{(options as T[]).map(renderItem)}</CommandGroup>\n}\n\n// ============================================================================\n// VirtualizedOptions\n// ============================================================================\n\nfunction VirtualizedOptions<T extends AutocompleteOption>({\n options,\n selectedValue,\n onSelect,\n renderOption,\n itemSize = 36,\n listClassName,\n}: OptionsRendererProps<T> & { itemSize?: number, listClassName?: string }) {\n const flatOptions = flattenOptions(options)\n const parentRef = React.useRef<HTMLDivElement>(null)\n\n const virtualizer = useVirtualizer({\n count: flatOptions.length,\n getScrollElement: () => parentRef.current,\n estimateSize: () => itemSize,\n })\n\n // Scroll to selected item on open\n React.useEffect(() => {\n if (selectedValue) {\n const index = flatOptions.findIndex(o => o.value === selectedValue)\n if (index >= 0) {\n virtualizer.scrollToIndex(index, { align: 'center' })\n }\n }\n }, [selectedValue, flatOptions, virtualizer])\n\n return (\n <div ref={parentRef} className={cn('max-h-[200px] overflow-auto', listClassName)}>\n <CommandGroup>\n <div style={{ height: `${virtualizer.getTotalSize()}px` }} className=\"relative w-full\">\n {virtualizer.getVirtualItems().map((virtualItem) => {\n const option = flatOptions[virtualItem.index]!\n const isSelected = option.value === selectedValue\n\n return (\n <CommandItem\n key={option.value}\n value={option.value}\n keywords={[option.label, option.description ?? '']}\n disabled={option.disabled}\n onSelect={() => onSelect(option.value)}\n className=\"absolute top-0 left-0 w-full cursor-pointer justify-between px-3 py-2 text-xs\"\n style={{\n height: `${virtualItem.size}px`,\n transform: `translateY(${virtualItem.start}px)`,\n }}\n >\n {renderOption\n ? (\n renderOption(option, isSelected)\n )\n : (\n <DefaultOptionContent option={option} isSelected={isSelected} />\n )}\n </CommandItem>\n )\n })}\n </div>\n </CommandGroup>\n </div>\n )\n}\n\n// ============================================================================\n// Autocomplete (Main Component)\n// ============================================================================\n\n/**\n * Autocomplete - A searchable select component\n *\n * Standalone, form-agnostic combobox built on Popover + Command (cmdk).\n * Supports flat/grouped options, virtualization, custom rendering, and async search.\n *\n * @example Basic usage\n * ```tsx\n * <Autocomplete\n * value={country}\n * onValueChange={setCountry}\n * options={countries}\n * placeholder=\"Select country...\"\n * />\n * ```\n *\n * @example Async search\n * ```tsx\n * <Autocomplete\n * value={userId}\n * onValueChange={setUserId}\n * options={users ?? []}\n * onSearchChange={setSearch}\n * loading={isLoading}\n * placeholder=\"Search users...\"\n * />\n * ```\n */\nexport function Autocomplete<T extends AutocompleteOption = AutocompleteOption>({\n options,\n value,\n onValueChange,\n onSearchChange,\n searchPlaceholder = 'Search...',\n disableSearch = false,\n renderOption,\n renderValue,\n placeholder = 'Select...',\n emptyContent = 'No results found',\n footer,\n creatable = false,\n creatableLabel,\n virtualize = false,\n itemSize = 36,\n loading = false,\n disabled = false,\n name,\n id,\n className,\n triggerClassName,\n contentClassName,\n listClassName,\n}: AutocompleteProps<T>) {\n const [open, setOpen] = React.useState(false)\n const [search, setSearch] = React.useState('')\n\n const flatOptions = React.useMemo(() => flattenOptions(options), [options])\n const selectedOption = React.useMemo(\n () => flatOptions.find(o => o.value === value),\n [flatOptions, value],\n )\n\n // When creatable and value doesn't match any option, show raw value in trigger\n const displayOption = React.useMemo(() => {\n if (selectedOption)\n return selectedOption\n if (creatable && value)\n return { value, label: value } as T\n return undefined\n }, [selectedOption, creatable, value])\n\n // External search mode when onSearchChange is provided\n const isExternalSearch = !!onSearchChange\n\n // Creatable item visibility\n const trimmedSearch = React.useMemo(() => search.trim(), [search])\n const showCreatableItem = React.useMemo(() => {\n if (!creatable || trimmedSearch.length === 0)\n return false\n const needle = trimmedSearch.toLowerCase()\n return !flatOptions.some(\n o => o.value.toLowerCase() === needle || o.label.toLowerCase() === needle,\n )\n }, [creatable, trimmedSearch, flatOptions])\n\n const handleSelect = React.useCallback(\n (optionValue: string) => {\n onValueChange?.(optionValue)\n setSearch('')\n setOpen(false)\n },\n [onValueChange],\n )\n\n const handleCreatableSelect = React.useCallback(() => {\n onValueChange?.(trimmedSearch)\n setSearch('')\n setOpen(false)\n }, [onValueChange, trimmedSearch])\n\n const handleOpenChange = React.useCallback(\n (nextOpen: boolean) => {\n setOpen(nextOpen)\n if (!nextOpen) {\n setSearch('')\n if (isExternalSearch)\n onSearchChange?.('')\n }\n },\n [isExternalSearch, onSearchChange],\n )\n\n const handleSearchChange = React.useCallback(\n (val: string) => {\n setSearch(val)\n if (isExternalSearch)\n onSearchChange?.(val)\n },\n [isExternalSearch, onSearchChange],\n )\n\n return (\n <div className={cn('relative', className)}>\n <Popover open={open} onOpenChange={handleOpenChange} modal>\n <PopoverTrigger asChild>\n <Trigger\n selectedOption={displayOption}\n renderValue={renderValue}\n placeholder={placeholder}\n loading={loading}\n disabled={disabled}\n open={open}\n id={id}\n className={triggerClassName}\n />\n </PopoverTrigger>\n <PopoverContent\n className={cn('popover-content-width-full p-0', contentClassName)}\n align=\"start\"\n >\n <Command shouldFilter={!isExternalSearch && !creatable} defaultValue={value}>\n {!disableSearch && (\n <CommandInput\n className=\"placeholder:text-secondary/60 h-7 border-none text-xs placeholder:text-xs focus-visible:ring-0\"\n iconClassName=\"text-secondary size-3.5\"\n wrapperClassName=\"px-3 py-2\"\n placeholder={searchPlaceholder}\n value={search}\n onValueChange={handleSearchChange}\n />\n )}\n <CommandList className={cn(!virtualize && 'max-h-[300px]', listClassName)}>\n {!showCreatableItem && (\n <CommandEmpty>\n {typeof emptyContent === 'string'\n ? (\n <span className=\"text-muted-foreground text-xs\">{emptyContent}</span>\n )\n : (\n emptyContent\n )}\n </CommandEmpty>\n )}\n\n {virtualize\n ? (\n <VirtualizedOptions\n options={options}\n selectedValue={value}\n onSelect={handleSelect}\n renderOption={renderOption}\n itemSize={itemSize}\n listClassName={listClassName}\n />\n )\n : (\n <StaticOptions\n options={options}\n selectedValue={value}\n onSelect={handleSelect}\n renderOption={renderOption}\n />\n )}\n\n {showCreatableItem && (\n <CommandGroup forceMount className=\"p-0\">\n <CommandItem\n forceMount\n // \\0 prefix prevents collision with real option values;\n // handleCreatableSelect passes trimmedSearch to onValueChange\n value={`\\0creatable:${trimmedSearch}`}\n keywords={[trimmedSearch]}\n onSelect={handleCreatableSelect}\n className=\"cursor-pointer px-3 py-2 text-xs\"\n >\n {creatableLabel ? creatableLabel(trimmedSearch) : `Use \"${trimmedSearch}\"`}\n </CommandItem>\n </CommandGroup>\n )}\n </CommandList>\n\n {footer && <div className=\"border-t\">{footer}</div>}\n </Command>\n </PopoverContent>\n </Popover>\n\n {/* Hidden input for non-Conform usage (plain HTML forms) */}\n {name && <input type=\"hidden\" name={name} value={value ?? ''} />}\n </div>\n )\n}\n\nAutocomplete.displayName = 'Autocomplete'\n","import type { VariantProps } from 'class-variance-authority'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Avatar, AvatarFallback, AvatarImage } from '@repo/shadcn/ui/avatar'\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { Tooltip } from '../../base/tooltip/tooltip'\n\nconst avatarStackVariants = cva('flex', {\n variants: {\n orientation: {\n vertical: 'flex-row',\n horizontal: 'flex-col',\n },\n spacing: {\n sm: '-space-x-5 -space-y-5',\n md: '-space-x-4 -space-y-4',\n lg: '-space-x-3 -space-y-3',\n xl: '-space-x-2 -space-y-2',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n spacing: 'md',\n },\n})\n\nexport interface AvatarStackProps\n extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof avatarStackVariants> {\n avatars: { name: string, image: string }[]\n maxAvatarsAmount?: number\n avatarClassName?: string\n}\n\nfunction AvatarStack({\n className,\n orientation,\n avatars,\n spacing,\n maxAvatarsAmount = 3,\n avatarClassName,\n ...props\n}: AvatarStackProps) {\n const shownAvatars = avatars.slice(0, maxAvatarsAmount)\n const hiddenAvatars = avatars.slice(maxAvatarsAmount)\n\n return (\n <div\n className={cn(\n avatarStackVariants({ orientation, spacing }),\n className,\n orientation === 'horizontal' ? '-space-x-0' : '-space-y-0',\n )}\n {...props}\n >\n {shownAvatars.map(({ name, image }, index) => (\n <Tooltip key={`${image}-${index + 1}`} message={name} delayDuration={300}>\n <Avatar className={cn(avatarStackVariants(), 'hover:z-10', avatarClassName)}>\n <AvatarImage src={image} />\n <AvatarFallback>\n {name\n ?.split(' ')\n ?.map(word => word[0])\n ?.join('')\n ?.toUpperCase()}\n </AvatarFallback>\n </Avatar>\n </Tooltip>\n ))}\n\n {hiddenAvatars.length\n ? (\n <Tooltip\n message={(\n <>\n {hiddenAvatars.map(({ name }, index) => (\n <p key={`${name}-${index + 1}`}>{name}</p>\n ))}\n </>\n )}\n delayDuration={300}\n >\n <Avatar key=\"Excesive avatars\" className={cn(avatarClassName)}>\n <AvatarFallback>\n +\n {avatars.length - shownAvatars.length}\n </AvatarFallback>\n </Avatar>\n </Tooltip>\n )\n : null}\n </div>\n )\n}\n\nexport { AvatarStack, avatarStackVariants }\n","import type { VariantProps } from 'class-variance-authority'\nimport type { DateRange } from 'react-day-picker'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Button } from '@repo/shadcn/ui/button'\nimport { Popover, PopoverContent, PopoverTrigger } from '@repo/shadcn/ui/popover'\nimport { cva } from 'class-variance-authority'\nimport {\n endOfDay,\n endOfMonth,\n endOfWeek,\n endOfYear,\n startOfDay,\n startOfMonth,\n startOfWeek,\n startOfYear,\n subDays,\n} from 'date-fns'\nimport { formatInTimeZone, toDate } from 'date-fns-tz'\nimport { CalendarIcon, X } from 'lucide-react'\nimport * as React from 'react'\nimport { Calendar } from '../../base/calendar/calendar'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../base/select/select'\n\n// src/components/calendar-date-picker.tsx\n\nconst months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n]\n\nconst multiSelectVariants = cva(\n 'flex font-normal shadow-none items-center justify-center whitespace-nowrap rounded-md text-sm text-foreground ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground text-background',\n link: 'text-primary underline-offset-4 hover:underline text-background',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n\nexport interface DateRangePreset {\n key: string\n label: string\n start: Date\n end: Date\n}\n\ninterface CalendarDatePickerProps\n extends React.HTMLAttributes<HTMLButtonElement>, VariantProps<typeof multiSelectVariants> {\n id?: string\n className?: string\n triggerClassName?: string\n date: DateRange\n closeOnSelect?: boolean\n numberOfMonths?: 1 | 2\n yearsRange?: number\n onDateSelect: (range: { from: Date, to: Date } | undefined) => void\n placeholder?: string\n excludePresets?: string[]\n customPresets?: DateRangePreset[] // Custom presets to use instead of default ones\n // Date range constraints\n minDate?: Date\n maxDate?: Date\n disableFuture?: boolean\n disablePast?: boolean\n maxRange?: number // Maximum number of days between start and end date\n}\n\nexport function CalendarDatePicker({ ref, id = 'calendar-date-picker', className, triggerClassName, date, closeOnSelect = false, numberOfMonths = 2, yearsRange = 10, onDateSelect, variant, placeholder, excludePresets, customPresets, minDate, maxDate, disableFuture = false, disablePast = false, maxRange, ...props }: CalendarDatePickerProps & { ref?: React.RefObject<HTMLButtonElement | null> }) {\n const [isPopoverOpen, setIsPopoverOpen] = React.useState(false)\n const [selectedRange, setSelectedRange] = React.useState<string | null>(\n numberOfMonths === 2 ? 'This Year' : 'Today',\n )\n const [monthFrom, setMonthFrom] = React.useState<Date | undefined>(date?.from)\n const [yearFrom, setYearFrom] = React.useState<number | undefined>(date?.from?.getFullYear())\n const [monthTo, setMonthTo] = React.useState<Date | undefined>(\n numberOfMonths === 2 ? date?.to : date?.from,\n )\n const [yearTo, setYearTo] = React.useState<number | undefined>(\n numberOfMonths === 2 ? date?.to?.getFullYear() : date?.from?.getFullYear(),\n )\n const [highlightedPart, setHighlightedPart] = React.useState<string | null>(null)\n\n // Temporary state for pending changes (until Apply is clicked)\n const [pendingDate, setPendingDate] = React.useState<DateRange>(date)\n\n const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone\n const today = new Date()\n\n // Calculate date constraints\n const effectiveMinDate = React.useMemo(() => {\n let min = minDate\n if (disablePast) {\n const todayStart = startOfDay(today)\n min = min ? (min > todayStart ? min : todayStart) : todayStart\n }\n return min\n }, [minDate, disablePast, today])\n\n const effectiveMaxDate = React.useMemo(() => {\n let max = maxDate\n if (disableFuture) {\n const todayEnd = endOfDay(today)\n max = max ? (max < todayEnd ? max : todayEnd) : todayEnd\n }\n return max\n }, [maxDate, disableFuture, today])\n\n // Validate if a date is selectable\n const isDateDisabled = React.useCallback(\n (date: Date) => {\n if (effectiveMinDate && date < effectiveMinDate)\n return true\n if (effectiveMaxDate && date > effectiveMaxDate)\n return true\n return false\n },\n [effectiveMinDate, effectiveMaxDate],\n )\n\n // Calculate the number of days between two dates\n const getDaysDifference = React.useCallback((from: Date, to: Date): number => {\n const timeDiff = Math.abs(to.getTime() - from.getTime())\n return Math.ceil(timeDiff / (1000 * 60 * 60 * 24))\n }, [])\n\n // Validate if a date range exceeds the maximum allowed range\n const isRangeValid = React.useCallback(\n (from: Date, to: Date): boolean => {\n if (!maxRange)\n return true\n if (numberOfMonths === 1)\n return true // Single date picker always valid\n return getDaysDifference(from, to) <= maxRange\n },\n [maxRange, numberOfMonths, getDaysDifference],\n )\n\n // Auto-adjust date range to fit within maxRange\n const adjustRangeToMaxRange = React.useCallback(\n (from: Date, to: Date): { from: Date, to: Date } => {\n if (!maxRange || numberOfMonths === 1)\n return { from, to }\n\n const daysDiff = getDaysDifference(from, to)\n if (daysDiff <= maxRange)\n return { from, to }\n\n // Adjust the 'to' date to be within maxRange from 'from' date\n const adjustedTo = new Date(from.getTime() + maxRange * 24 * 60 * 60 * 1000)\n\n // Make sure the adjusted date doesn't exceed effectiveMaxDate\n if (effectiveMaxDate && adjustedTo > effectiveMaxDate) {\n // If adjusting 'to' would exceed maxDate, try adjusting 'from' instead\n const adjustedFrom = new Date(to.getTime() - maxRange * 24 * 60 * 60 * 1000)\n\n // Make sure the adjusted 'from' doesn't go below effectiveMinDate\n if (effectiveMinDate && adjustedFrom < effectiveMinDate) {\n // If both adjustments fail, keep original dates (validation will catch this)\n return { from, to }\n }\n\n return { from: adjustedFrom, to }\n }\n\n return { from, to: adjustedTo }\n },\n [maxRange, numberOfMonths, getDaysDifference, effectiveMinDate, effectiveMaxDate],\n )\n\n // Sync pendingDate with date prop changes\n React.useEffect(() => {\n setPendingDate(date)\n }, [date])\n\n const handleClose = () => setIsPopoverOpen(false)\n\n const handleTogglePopover = () => setIsPopoverOpen(prev => !prev)\n\n // Clear the date selection\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation()\n onDateSelect(undefined)\n setPendingDate({ from: undefined, to: undefined })\n setSelectedRange(null)\n }\n\n // Apply the pending changes\n const handleApply = () => {\n if (pendingDate?.from) {\n onDateSelect({\n from: pendingDate.from,\n to: pendingDate.to || pendingDate.from,\n })\n }\n setIsPopoverOpen(false)\n }\n\n // Reset to the original date\n const handleReset = () => {\n setPendingDate(date)\n setMonthFrom(date?.from)\n setYearFrom(date?.from?.getFullYear())\n setMonthTo(numberOfMonths === 2 ? date?.to : date?.from)\n setYearTo(numberOfMonths === 2 ? date?.to?.getFullYear() : date?.from?.getFullYear())\n setSelectedRange(null)\n }\n\n const selectDateRange = (from: Date, to: Date, range: string) => {\n const startDate = startOfDay(toDate(from, { timeZone }))\n const endDate = numberOfMonths === 2 ? endOfDay(toDate(to, { timeZone })) : startDate\n\n // Validate date constraints\n if (isDateDisabled(startDate) || isDateDisabled(endDate)) {\n return // Don't select if dates are disabled\n }\n\n // Validate and adjust range if necessary\n let finalDates = { from: startDate, to: endDate }\n if (numberOfMonths === 2 && !isRangeValid(startDate, endDate)) {\n finalDates = adjustRangeToMaxRange(startDate, endDate)\n\n // If adjustment still results in invalid range, don't select\n if (!isRangeValid(finalDates.from, finalDates.to)) {\n return\n }\n }\n\n setPendingDate({ from: finalDates.from, to: finalDates.to })\n setSelectedRange(range)\n setMonthFrom(finalDates.from)\n setYearFrom(finalDates.from.getFullYear())\n setMonthTo(finalDates.to)\n setYearTo(finalDates.to.getFullYear())\n if (closeOnSelect) {\n onDateSelect({ from: finalDates.from, to: finalDates.to })\n setIsPopoverOpen(false)\n }\n }\n\n const handleDateSelect = (range: DateRange | undefined) => {\n if (range) {\n let from = startOfDay(toDate(range.from as Date, { timeZone }))\n let to = range.to ? endOfDay(toDate(range.to, { timeZone })) : from\n if (numberOfMonths === 1) {\n if (range.from !== pendingDate?.from) {\n to = from\n }\n else {\n from = startOfDay(toDate(range.to as Date, { timeZone }))\n }\n }\n\n // Validate date constraints\n if (isDateDisabled(from) || isDateDisabled(to)) {\n return // Don't select if dates are disabled\n }\n\n // Validate and adjust range if necessary\n let finalDates = { from, to }\n if (numberOfMonths === 2 && !isRangeValid(from, to)) {\n finalDates = adjustRangeToMaxRange(from, to)\n\n // If adjustment still results in invalid range, don't select\n if (!isRangeValid(finalDates.from, finalDates.to)) {\n return\n }\n }\n\n setPendingDate({ from: finalDates.from, to: finalDates.to })\n setMonthFrom(finalDates.from)\n setYearFrom(finalDates.from.getFullYear())\n setMonthTo(finalDates.to)\n setYearTo(finalDates.to.getFullYear())\n\n if (closeOnSelect) {\n onDateSelect({ from: finalDates.from, to: finalDates.to })\n setIsPopoverOpen(false)\n }\n }\n setSelectedRange(null)\n }\n\n const handleMonthChange = (newMonthIndex: number, part: string) => {\n setSelectedRange(null)\n if (part === 'from') {\n if (yearFrom !== undefined) {\n if (newMonthIndex < 0 || newMonthIndex > yearsRange + 1)\n return\n const newMonth = new Date(yearFrom, newMonthIndex, 1)\n const from\n = numberOfMonths === 2\n ? startOfMonth(toDate(newMonth, { timeZone }))\n : pendingDate?.from\n ? new Date(\n pendingDate.from.getFullYear(),\n newMonth.getMonth(),\n pendingDate.from.getDate(),\n )\n : newMonth\n const to\n = numberOfMonths === 2\n ? pendingDate?.to\n ? endOfDay(toDate(pendingDate.to, { timeZone }))\n : endOfMonth(toDate(newMonth, { timeZone }))\n : from\n if (from <= to) {\n setPendingDate({ from, to })\n setMonthFrom(newMonth)\n setMonthTo(pendingDate?.to)\n }\n }\n }\n else {\n if (yearTo !== undefined) {\n if (newMonthIndex < 0 || newMonthIndex > yearsRange + 1)\n return\n const newMonth = new Date(yearTo, newMonthIndex, 1)\n const from = pendingDate?.from\n ? startOfDay(toDate(pendingDate.from, { timeZone }))\n : startOfMonth(toDate(newMonth, { timeZone }))\n const to = numberOfMonths === 2 ? endOfMonth(toDate(newMonth, { timeZone })) : from\n if (from <= to) {\n setPendingDate({ from, to })\n setMonthTo(newMonth)\n setMonthFrom(pendingDate?.from)\n }\n }\n }\n }\n\n const years = Array.from(\n { length: yearsRange + 1 },\n (_, i) => today.getFullYear() - yearsRange / 2 + i,\n )\n\n const handleYearChange = (newYear: number, part: string) => {\n setSelectedRange(null)\n if (part === 'from') {\n if (years.includes(newYear)) {\n const newMonth = monthFrom\n ? new Date(newYear, monthFrom ? monthFrom.getMonth() : 0, 1)\n : new Date(newYear, 0, 1)\n const from\n = numberOfMonths === 2\n ? startOfMonth(toDate(newMonth, { timeZone }))\n : pendingDate?.from\n ? new Date(newYear, newMonth.getMonth(), pendingDate.from.getDate())\n : newMonth\n const to\n = numberOfMonths === 2\n ? pendingDate?.to\n ? endOfDay(toDate(pendingDate.to, { timeZone }))\n : endOfMonth(toDate(newMonth, { timeZone }))\n : from\n if (from <= to) {\n setPendingDate({ from, to })\n setYearFrom(newYear)\n setMonthFrom(newMonth)\n setYearTo(pendingDate?.to?.getFullYear())\n setMonthTo(pendingDate?.to)\n }\n }\n }\n else {\n if (years.includes(newYear)) {\n const newMonth = monthTo\n ? new Date(newYear, monthTo.getMonth(), 1)\n : new Date(newYear, 0, 1)\n const from = pendingDate?.from\n ? startOfDay(toDate(pendingDate.from, { timeZone }))\n : startOfMonth(toDate(newMonth, { timeZone }))\n const to = numberOfMonths === 2 ? endOfMonth(toDate(newMonth, { timeZone })) : from\n if (from <= to) {\n setPendingDate({ from, to })\n setYearTo(newYear)\n setMonthTo(newMonth)\n setYearFrom(pendingDate?.from?.getFullYear())\n setMonthFrom(pendingDate?.from)\n }\n }\n }\n }\n\n // Default date range presets\n const defaultDateRangePresets: DateRangePreset[] = [\n { key: 'today', label: 'Today', start: today, end: today },\n { key: 'yesterday', label: 'Yesterday', start: subDays(today, 1), end: subDays(today, 1) },\n {\n key: 'thisWeek',\n label: 'This Week',\n start: startOfWeek(today, { weekStartsOn: 1 }),\n end: endOfWeek(today, { weekStartsOn: 1 }),\n },\n {\n key: 'lastWeek',\n label: 'Last Week',\n start: subDays(startOfWeek(today, { weekStartsOn: 1 }), 7),\n end: subDays(endOfWeek(today, { weekStartsOn: 1 }), 7),\n },\n {\n key: 'last7Days',\n label: 'Last 7 Days',\n start: subDays(today, 6),\n end: today,\n },\n {\n key: 'thisMonth',\n label: 'This Month',\n start: startOfMonth(today),\n end: endOfMonth(today),\n },\n {\n key: 'lastMonth',\n label: 'Last Month',\n start: startOfMonth(subDays(today, today.getDate())),\n end: endOfMonth(subDays(today, today.getDate())),\n },\n {\n key: 'thisYear',\n label: 'This Year',\n start: startOfYear(today),\n end: endOfYear(today),\n },\n {\n key: 'lastYear',\n label: 'Last Year',\n start: startOfYear(subDays(today, 365)),\n end: endOfYear(subDays(today, 365)),\n },\n ]\n\n // Use custom presets if provided, otherwise use default presets\n const allDateRangePresets = customPresets || defaultDateRangePresets\n\n // Filter presets based on date constraints and excludePresets\n const dateRanges = React.useMemo(() => {\n return allDateRangePresets.filter((preset) => {\n // Check if preset is excluded\n if (excludePresets?.includes(preset.key))\n return false\n\n // Check if preset dates are within constraints\n const startValid = !isDateDisabled(preset.start)\n const endValid = !isDateDisabled(preset.end)\n\n // Check if preset range is within maxRange limit\n const rangeValid = numberOfMonths === 1 || isRangeValid(preset.start, preset.end)\n\n return startValid && endValid && rangeValid\n })\n }, [isDateDisabled, excludePresets, numberOfMonths, isRangeValid])\n\n const handleMouseOver = (part: string) => {\n setHighlightedPart(part)\n }\n\n const handleMouseLeave = () => {\n setHighlightedPart(null)\n }\n\n const handleWheel = (event: React.WheelEvent) => {\n event.preventDefault()\n setSelectedRange(null)\n if (highlightedPart === 'firstDay') {\n const newDate = new Date(pendingDate?.from as Date)\n const increment = event.deltaY > 0 ? -1 : 1\n newDate.setDate(newDate.getDate() + increment)\n if (newDate <= (pendingDate?.to as Date)) {\n numberOfMonths === 2\n ? setPendingDate({ from: newDate, to: new Date(pendingDate?.to as Date) })\n : setPendingDate({ from: newDate, to: newDate })\n setMonthFrom(newDate)\n }\n else if (newDate > (pendingDate?.to as Date) && numberOfMonths === 1) {\n setPendingDate({ from: newDate, to: newDate })\n setMonthFrom(newDate)\n }\n }\n else if (highlightedPart === 'firstMonth') {\n const currentMonth = monthFrom ? monthFrom.getMonth() : 0\n const newMonthIndex = currentMonth + (event.deltaY > 0 ? -1 : 1)\n handleMonthChange(newMonthIndex, 'from')\n }\n else if (highlightedPart === 'firstYear' && yearFrom !== undefined) {\n const newYear = yearFrom + (event.deltaY > 0 ? -1 : 1)\n handleYearChange(newYear, 'from')\n }\n else if (highlightedPart === 'secondDay') {\n const newDate = new Date(pendingDate?.to as Date)\n const increment = event.deltaY > 0 ? -1 : 1\n newDate.setDate(newDate.getDate() + increment)\n if (newDate >= (pendingDate?.from as Date)) {\n setPendingDate({ from: new Date(pendingDate?.from as Date), to: newDate })\n setMonthTo(newDate)\n }\n }\n else if (highlightedPart === 'secondMonth') {\n const currentMonth = monthTo ? monthTo.getMonth() : 0\n const newMonthIndex = currentMonth + (event.deltaY > 0 ? -1 : 1)\n handleMonthChange(newMonthIndex, 'to')\n }\n else if (highlightedPart === 'secondYear' && yearTo !== undefined) {\n const newYear = yearTo + (event.deltaY > 0 ? -1 : 1)\n handleYearChange(newYear, 'to')\n }\n }\n\n React.useEffect(() => {\n const firstDayElement = document.getElementById(`firstDay-${id}`)\n const firstMonthElement = document.getElementById(`firstMonth-${id}`)\n const firstYearElement = document.getElementById(`firstYear-${id}`)\n const secondDayElement = document.getElementById(`secondDay-${id}`)\n const secondMonthElement = document.getElementById(`secondMonth-${id}`)\n const secondYearElement = document.getElementById(`secondYear-${id}`)\n\n const elements = [\n firstDayElement,\n firstMonthElement,\n firstYearElement,\n secondDayElement,\n secondMonthElement,\n secondYearElement,\n ]\n\n const addPassiveEventListener = (element: HTMLElement | null) => {\n if (element) {\n element.addEventListener('wheel', handleWheel as unknown as EventListener, {\n passive: false,\n })\n }\n }\n\n elements.forEach(addPassiveEventListener)\n\n return () => {\n elements.forEach((element) => {\n if (element) {\n element.removeEventListener('wheel', handleWheel as unknown as EventListener)\n }\n })\n }\n }, [highlightedPart, pendingDate])\n\n const formatWithTz = (date: Date, fmt: string) => formatInTimeZone(date, timeZone, fmt)\n\n return (\n <>\n <style>\n {`\n .date-part {\n touch-action: none;\n }\n `}\n </style>\n <Popover open={isPopoverOpen} onOpenChange={setIsPopoverOpen}>\n <PopoverTrigger asChild>\n <Button\n id=\"date\"\n ref={ref}\n {...props}\n className={cn(\n 'w-full',\n triggerClassName,\n multiSelectVariants({ variant, className }),\n )}\n onClick={handleTogglePopover}\n suppressHydrationWarning\n >\n <div className=\"flex w-full items-center justify-between gap-2\">\n <div className=\"flex items-center gap-2\">\n <CalendarIcon className=\"text-muted-foreground h-4 w-4\" />\n <span>\n {date?.from\n ? (\n date.to\n ? (\n <>\n <span\n id={`firstDay-${id}`}\n className={cn(\n 'date-part',\n highlightedPart === 'firstDay' && 'font-bold underline',\n )}\n onMouseOver={() => handleMouseOver('firstDay')}\n onMouseLeave={handleMouseLeave}\n >\n {formatWithTz(date.from, 'dd')}\n </span>\n {' '}\n <span\n id={`firstMonth-${id}`}\n className={cn(\n 'date-part',\n highlightedPart === 'firstMonth' && 'font-bold underline',\n )}\n onMouseOver={() => handleMouseOver('firstMonth')}\n onMouseLeave={handleMouseLeave}\n >\n {formatWithTz(date.from, 'LLL')}\n </span>\n ,\n {' '}\n <span\n id={`firstYear-${id}`}\n className={cn(\n 'date-part',\n highlightedPart === 'firstYear' && 'font-bold underline',\n )}\n onMouseOver={() => handleMouseOver('firstYear')}\n onMouseLeave={handleMouseLeave}\n >\n {formatWithTz(date.from, 'y')}\n </span>\n {numberOfMonths === 2 && (\n <>\n {' - '}\n <span\n id={`secondDay-${id}`}\n className={cn(\n 'date-part',\n highlightedPart === 'secondDay' && 'font-bold underline',\n )}\n onMouseOver={() => handleMouseOver('secondDay')}\n onMouseLeave={handleMouseLeave}\n >\n {formatWithTz(date.to, 'dd')}\n </span>\n {' '}\n <span\n id={`secondMonth-${id}`}\n className={cn(\n 'date-part',\n highlightedPart === 'secondMonth' && 'font-bold underline',\n )}\n onMouseOver={() => handleMouseOver('secondMonth')}\n onMouseLeave={handleMouseLeave}\n >\n {formatWithTz(date.to, 'LLL')}\n </span>\n ,\n {' '}\n <span\n id={`secondYear-${id}`}\n className={cn(\n 'date-part',\n highlightedPart === 'secondYear' && 'font-bold underline',\n )}\n onMouseOver={() => handleMouseOver('secondYear')}\n onMouseLeave={handleMouseLeave}\n >\n {formatWithTz(date.to, 'y')}\n </span>\n </>\n )}\n </>\n )\n : (\n <>\n <span\n id=\"day\"\n className={cn(\n 'date-part',\n highlightedPart === 'day' && 'font-bold underline',\n )}\n onMouseOver={() => handleMouseOver('day')}\n onMouseLeave={handleMouseLeave}\n >\n {formatWithTz(date.from, 'dd')}\n </span>\n {' '}\n <span\n id=\"month\"\n className={cn(\n 'date-part',\n highlightedPart === 'month' && 'font-bold underline',\n )}\n onMouseOver={() => handleMouseOver('month')}\n onMouseLeave={handleMouseLeave}\n >\n {formatWithTz(date.from, 'LLL')}\n </span>\n ,\n {' '}\n <span\n id=\"year\"\n className={cn(\n 'date-part',\n highlightedPart === 'year' && 'font-bold underline',\n )}\n onMouseOver={() => handleMouseOver('year')}\n onMouseLeave={handleMouseLeave}\n >\n {formatWithTz(date.from, 'y')}\n </span>\n </>\n )\n )\n : (\n <span className=\"text-muted-foreground\">{placeholder || 'Pick a date'}</span>\n )}\n </span>\n </div>\n {date?.from && (\n <div\n onClick={handleClear}\n className=\"text-muted-foreground hover:text-primary size-4 p-0 hover:bg-transparent\"\n >\n <X size={14} />\n <span className=\"sr-only\">Clear date</span>\n </div>\n )}\n </div>\n </Button>\n </PopoverTrigger>\n {isPopoverOpen && (\n <PopoverContent\n className=\"w-auto\"\n align=\"center\"\n avoidCollisions={false}\n onInteractOutside={handleClose}\n onEscapeKeyDown={handleClose}\n style={{\n maxHeight: 'var(--radix-popover-content-available-height)',\n overflowY: 'auto',\n }}\n >\n <div className=\"flex\">\n {numberOfMonths === 2 && (\n <div className=\"border-foreground/10 hidden flex-col gap-1 border-r pr-4 text-left md:flex\">\n {dateRanges.map(({ key, label, start, end }) => (\n <Button\n key={key}\n variant=\"ghost\"\n size=\"sm\"\n className={cn(\n 'hover:bg-primary/90 hover:text-background justify-start',\n selectedRange === label\n && 'bg-primary text-background hover:bg-primary/90 hover:text-background',\n )}\n onClick={() => {\n selectDateRange(start, end, label)\n setMonthFrom(start)\n setYearFrom(start.getFullYear())\n setMonthTo(end)\n setYearTo(end.getFullYear())\n }}\n >\n {label}\n </Button>\n ))}\n </div>\n )}\n <div className=\"flex flex-col\">\n <div className=\"flex items-center gap-4\">\n <div className=\"ml-3 flex gap-2\">\n <Select\n onValueChange={(value) => {\n handleMonthChange(months.indexOf(value), 'from')\n setSelectedRange(null)\n }}\n value={monthFrom ? months[monthFrom.getMonth()] : undefined}\n >\n <SelectTrigger className=\"hover:bg-accent hover:text-accent-foreground hidden w-[122px] font-medium focus:ring-0 focus:ring-offset-0 sm:flex\">\n <SelectValue placeholder=\"Month\" />\n </SelectTrigger>\n <SelectContent>\n {months.map((month, idx) => (\n <SelectItem key={idx} value={month}>\n {month}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select\n onValueChange={(value) => {\n handleYearChange(Number(value), 'from')\n setSelectedRange(null)\n }}\n value={yearFrom ? yearFrom.toString() : undefined}\n >\n <SelectTrigger className=\"hover:bg-accent hover:text-accent-foreground hidden w-[122px] font-medium focus:ring-0 focus:ring-offset-0 sm:flex\">\n <SelectValue placeholder=\"Year\" />\n </SelectTrigger>\n <SelectContent>\n {years.map((year, idx) => (\n <SelectItem key={idx} value={year.toString()}>\n {year}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {numberOfMonths === 2 && (\n <div className=\"flex gap-2\">\n <Select\n onValueChange={(value) => {\n handleMonthChange(months.indexOf(value), 'to')\n setSelectedRange(null)\n }}\n value={monthTo ? months[monthTo.getMonth()] : undefined}\n >\n <SelectTrigger className=\"hover:bg-accent hover:text-accent-foreground hidden w-[122px] font-medium focus:ring-0 focus:ring-offset-0 sm:flex\">\n <SelectValue placeholder=\"Month\" />\n </SelectTrigger>\n <SelectContent>\n {months.map((month, idx) => (\n <SelectItem key={idx} value={month}>\n {month}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select\n onValueChange={(value) => {\n handleYearChange(Number(value), 'to')\n setSelectedRange(null)\n }}\n value={yearTo ? yearTo.toString() : undefined}\n >\n <SelectTrigger className=\"hover:bg-accent hover:text-accent-foreground hidden w-[122px] font-medium focus:ring-0 focus:ring-offset-0 sm:flex\">\n <SelectValue placeholder=\"Year\" />\n </SelectTrigger>\n <SelectContent>\n {years.map((year, idx) => (\n <SelectItem key={idx} value={year.toString()}>\n {year}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n </div>\n <div className=\"flex\">\n <Calendar\n mode=\"range\"\n defaultMonth={monthFrom}\n month={monthFrom}\n onMonthChange={setMonthFrom}\n selected={pendingDate}\n onSelect={handleDateSelect}\n numberOfMonths={numberOfMonths}\n showOutsideDays={false}\n disabled={isDateDisabled}\n fromDate={effectiveMinDate}\n toDate={effectiveMaxDate}\n className={className}\n />\n </div>\n {!closeOnSelect && (\n <div className=\"flex justify-end gap-2 border-t p-3\">\n <Button variant=\"outline\" size=\"sm\" onClick={handleReset} type=\"button\">\n Reset\n </Button>\n <Button size=\"sm\" onClick={handleApply} type=\"button\">\n Apply\n </Button>\n </div>\n )}\n </div>\n </div>\n </PopoverContent>\n )}\n </Popover>\n </>\n )\n}\n\nCalendarDatePicker.displayName = 'CalendarDatePicker'\n","import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react'\nimport * as React from 'react'\nimport { Icon } from '../../icons/icon-wrapper'\n\n/**\n * Datum Dropdown Menu Component\n * Extends shadcn DropdownMenu with:\n * - Destructive variant for DropdownMenuItem\n */\n\nfunction DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root {...props} />\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return <DropdownMenuPrimitive.Portal {...props} />\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return <DropdownMenuPrimitive.Trigger {...props} />\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n sideOffset={sideOffset}\n className={cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return <DropdownMenuPrimitive.Group {...props} />\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = 'default',\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n variant?: 'default' | 'destructive'\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-inset={inset}\n data-variant={variant}\n className={cn(\n 'focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-foreground data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/40 data-[variant=destructive]:focus:text-destructive-foreground data-[variant=destructive]:*:[svg]:!text-destructive-foreground [&_svg:not([class*=\\'text-\\'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\\'size-\\'])]:size-4',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n className={cn(\n 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\\'size-\\'])]:size-4',\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Icon icon={CheckIcon} className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return <DropdownMenuPrimitive.RadioGroup {...props} />\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n className={cn(\n 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\\'size-\\'])]:size-4',\n className,\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Icon icon={CircleIcon} className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-inset={inset}\n className={cn('px-2 py-1.5 text-sm font-medium data-[inset]:pl-8', className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n className={cn('bg-border -mx-1 my-1 h-px', className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n className={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-inset={inset}\n className={cn(\n 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8',\n className,\n )}\n {...props}\n >\n {children}\n <Icon icon={ChevronRightIcon} className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n className={cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg',\n className,\n )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n}\n","import type { ReactNode } from 'react'\nimport type { DropEvent, DropzoneOptions, FileRejection } from 'react-dropzone'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Button } from '@repo/shadcn/ui/button'\nimport { UploadIcon } from 'lucide-react'\nimport { createContext, use } from 'react'\nimport { useDropzone } from 'react-dropzone'\nimport { Icon } from '../../icons/icon-wrapper'\n\ninterface DropzoneContextType {\n src?: File[]\n accept?: DropzoneOptions['accept']\n maxSize?: DropzoneOptions['maxSize']\n minSize?: DropzoneOptions['minSize']\n maxFiles?: DropzoneOptions['maxFiles']\n}\n\nfunction renderBytes(bytes: number) {\n const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']\n let size = bytes\n let unitIndex = 0\n\n while (size >= 1024 && unitIndex < units.length - 1) {\n size /= 1024\n unitIndex++\n }\n\n return `${size.toFixed(2)}${units[unitIndex]}`\n}\n\nconst DropzoneContext = createContext<DropzoneContextType | undefined>(undefined)\n\nexport type DropzoneProps = Omit<DropzoneOptions, 'onDrop'> & {\n src?: File[]\n className?: string\n onDrop?: (acceptedFiles: File[], fileRejections: FileRejection[], event: DropEvent) => void\n children?: ReactNode\n}\n\nexport function Dropzone({\n accept,\n maxFiles = 1,\n maxSize,\n minSize,\n onDrop,\n onError,\n disabled,\n src,\n className,\n children,\n ...props\n}: DropzoneProps) {\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\n accept,\n maxFiles,\n maxSize,\n minSize,\n onError,\n disabled,\n onDrop: (acceptedFiles, fileRejections, event) => {\n if (fileRejections.length > 0) {\n const message = fileRejections.at(0)?.errors.at(0)?.message\n onError?.(new Error(message))\n return\n }\n\n onDrop?.(acceptedFiles, fileRejections, event)\n },\n ...props,\n })\n\n return (\n <DropzoneContext\n key={JSON.stringify(src)}\n value={{ src, accept, maxSize, minSize, maxFiles }}\n >\n <Button\n className={cn(\n 'relative h-auto w-full flex-col overflow-hidden rounded-lg border border-dashed border-[#90969C99] bg-transparent p-9 text-base',\n isDragActive && 'ring-ring ring-1 outline-none',\n className,\n )}\n disabled={disabled}\n type=\"button\"\n variant=\"outline\"\n {...getRootProps()}\n >\n <input {...getInputProps()} disabled={disabled} />\n {children}\n </Button>\n </DropzoneContext>\n )\n}\n\nfunction useDropzoneContext() {\n const context = use(DropzoneContext)\n\n if (!context) {\n throw new Error('useDropzoneContext must be used within a Dropzone')\n }\n\n return context\n}\n\nexport interface DropzoneContentProps {\n children?: ReactNode\n className?: string\n icon?: ReactNode\n label?: ReactNode | ((files: File[]) => ReactNode)\n description?: ReactNode\n}\n\nconst maxLabelItems = 3\n\nfunction defaultContentLabel(files: File[]) {\n if (files.length > maxLabelItems) {\n return `${new Intl.ListFormat('en').format(\n files.slice(0, maxLabelItems).map(file => file.name),\n )} and ${files.length - maxLabelItems} more`\n }\n return new Intl.ListFormat('en').format(files.map(file => file.name))\n}\n\nexport function DropzoneContent({\n children,\n className,\n icon,\n label,\n description,\n}: DropzoneContentProps) {\n const { src } = useDropzoneContext()\n\n if (!src) {\n return null\n }\n\n if (children) {\n return children\n }\n\n const renderedLabel = typeof label === 'function' ? label(src) : label\n\n return (\n <div className={cn('flex flex-col items-center justify-center', className)}>\n {icon ?? <Icon icon={UploadIcon} size={36} className=\"text-primary\" />}\n <div className=\"my-2 w-full truncate text-sm font-medium text-wrap\">\n {renderedLabel ?? defaultContentLabel(src)}\n </div>\n <div className=\"text-muted-foreground w-full text-xs text-wrap\">\n {description ?? 'Drag and drop or click to replace'}\n </div>\n </div>\n )\n}\n\nexport interface DropzoneEmptyStateProps {\n children?: ReactNode\n className?: string\n icon?: ReactNode\n label?: ReactNode\n description?: ReactNode\n /** Set to false to hide the auto-generated caption (accepts, size limits) */\n showCaption?: boolean\n}\n\nexport function DropzoneEmptyState({\n children,\n className,\n icon,\n label,\n description,\n showCaption = false,\n}: DropzoneEmptyStateProps) {\n const { src, accept, maxSize, minSize } = useDropzoneContext()\n\n if (src) {\n return null\n }\n\n if (children) {\n return children\n }\n\n let caption = ''\n\n if (showCaption) {\n if (accept) {\n caption += 'Accepts '\n caption += new Intl.ListFormat('en').format(Object.keys(accept))\n }\n\n if (minSize && maxSize) {\n caption += ` between ${renderBytes(minSize)} and ${renderBytes(maxSize)}`\n }\n else if (minSize) {\n caption += ` at least ${renderBytes(minSize)}`\n }\n else if (maxSize) {\n caption += ` less than ${renderBytes(maxSize)}`\n }\n }\n\n return (\n <div className={cn('flex flex-col items-center justify-center', className)}>\n {icon ?? <Icon icon={UploadIcon} size={36} className=\"text-primary size-9 text-4xl\" />}\n {label && <p className=\"my-2 w-full truncate text-sm font-medium text-wrap\">{label}</p>}\n {description && (\n <div className=\"text-muted-foreground w-full truncate text-xs text-wrap\">{description}</div>\n )}\n {caption && (\n <p className=\"text-muted-foreground text-xs text-wrap\">\n {caption}\n .\n </p>\n )}\n </div>\n )\n}\n","\"data:image/svg+xml,<svg width=\\\"31\\\" height=\\\"32\\\" viewBox=\\\"0 0 31 32\\\" fill=\\\"none\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\">%0A<path opacity=\\\"0.12\\\" d=\\\"M27.1902 28.0179L16.4448 29.5107L4.37812 27.9436L14.8494 27.3087L27.1902 28.0179Z\\\" fill=\\\"black\\\"/>%0A<path d=\\\"M13.0963 11.6877C14.7043 14.9839 16.8292 17.9935 18.6849 21.1497C18.7736 21.5347 18.7763 21.9348 18.8252 22.3239C18.8674 22.6637 19.028 23.7378 18.989 23.983C18.9161 24.4481 18.0354 24.9642 17.6277 25.1134C16.7257 25.4456 15.5767 25.6807 14.6304 25.8932C13.8306 25.1273 13.039 24.3119 12.1914 23.5977C11.9708 23.4106 11.6233 23.0054 11.355 23.0437C11.2998 23.0516 11.2084 22.9782 11.163 23.0844C10.623 24.4942 10.1288 25.9397 9.85711 27.427C9.52163 27.6826 9.00036 28.1049 8.87664 28.5148C8.41962 28.4523 7.95449 28.4093 7.49864 28.3375C7.60704 27.8435 7.79108 26.8922 8.42294 26.9604L8.20621 26.4674C8.41963 26.4781 8.63473 26.5338 8.84927 26.5502L8.94065 26.5078L8.98842 26.1945C9.0746 25.8732 8.96699 25.5773 9.00294 25.3559C9.3092 23.4547 9.84286 21.1943 9.88087 19.2586C9.89868 18.3364 9.2645 17.0669 9.22819 16.1153C9.22418 16.0158 9.20329 15.9458 9.28997 15.8673C10.5356 14.5334 11.6319 13.0383 12.9025 11.7282C12.9735 11.6551 13.0899 11.6944 13.0963 11.6877ZM13.5824 20.2485L13.4513 18.3639C13.3263 18.3198 13.2992 18.3556 13.213 18.4304C13.1036 18.5265 12.1361 20.2828 12.0251 20.5356C11.7635 21.1314 11.5187 21.8582 11.4718 22.4984C11.7007 22.244 11.9467 22.0011 12.1754 21.7485C12.8195 21.9677 13.9904 22.5647 14.6394 22.5287C15.1512 22.4993 16.1052 21.6602 16.6795 21.5809C16.6841 21.4433 16.562 21.4201 16.4691 21.3727C16.1152 21.1908 13.8021 20.2245 13.5821 20.2504L13.5824 20.2485Z\\\" fill=\\\"%23983223\\\"/>%0A<mask id=\\\"mask0_7903_11345\\\" style=\\\"mask-type:alpha\\\" maskUnits=\\\"userSpaceOnUse\\\" x=\\\"8\\\" y=\\\"22\\\" width=\\\"14\\\" height=\\\"8\\\">%0A<path d=\\\"M8.6951 28.6662C8.81882 28.2563 9.52262 27.6819 9.8581 27.4262C10.7714 26.7294 11.7076 26.4502 12.815 26.2191C13.4138 26.0944 13.9988 26.0334 14.6314 25.8925C15.5795 25.6802 16.7267 25.4449 17.6286 25.1127C18.0363 24.9634 18.9171 24.4473 18.99 23.9823C19.029 23.737 18.8686 22.6611 18.8262 22.3232C21.2601 22.3357 21.9187 24.9979 20.899 26.8839C20.002 28.5428 17.6604 29.6666 15.8131 29.5802C13.6111 29.4781 10.9258 28.9663 8.69533 28.6644L8.6951 28.6662Z\\\" fill=\\\"%23591D14\\\"/>%0A</mask>%0A<g mask=\\\"url(%23mask0_7903_11345)\\\">%0A<path d=\\\"M8.6951 28.6662C8.81882 28.2563 9.52262 27.6819 9.8581 27.4262C10.7714 26.7294 11.7076 26.4502 12.815 26.2191C13.4138 26.0944 13.9988 26.0334 14.6314 25.8925C15.5795 25.6802 16.7267 25.4449 17.6286 25.1127C18.0363 24.9634 18.9171 24.4473 18.99 23.9823C19.029 23.737 18.8686 22.6611 18.8262 22.3232C21.2601 22.3357 21.9187 24.9979 20.899 26.8839C20.002 28.5428 17.6604 29.6666 15.8131 29.5802C13.6111 29.4781 10.9258 28.9663 8.69533 28.6644L8.6951 28.6662Z\\\" fill=\\\"%23591D14\\\"/>%0A<path d=\\\"M21.7949 24.2123C21.7949 24.2123 20.8311 27.6822 17.9009 28.4147C14.9708 29.1473 13.3129 28.7617 11.8093 28.6075C10.3057 28.4533 7.56832 28.7617 7.56832 28.7617L19.019 34.7762L21.7949 24.2123Z\\\" fill=\\\"%2340150F\\\"/>%0A</g>%0A<path d=\\\"M11.3557 23.0432L12.8148 26.2193C11.7073 26.4504 10.7712 26.7296 9.85782 27.4264C10.1295 25.9392 10.6221 24.4915 11.1637 23.0838C11.2109 22.9778 11.3005 23.051 11.3557 23.0432Z\\\" fill=\\\"%23BEA284\\\"/>%0A<path d=\\\"M13.5825 20.2479C13.8025 20.2221 16.1156 21.1883 16.4695 21.3702C16.5624 21.4177 16.6843 21.4427 16.6799 21.5785C16.1056 21.6577 15.1516 22.4969 14.6398 22.5263C13.9905 22.5641 12.8199 21.9652 12.1757 21.746C12.6348 21.241 13.0337 20.6666 13.5828 20.2461L13.5825 20.2479Z\\\" fill=\\\"%23C47C4E\\\"/>%0A<path d=\\\"M14.6297 25.8925C13.9971 26.0334 13.4121 26.0945 12.8133 26.2192L11.3543 23.043C11.6225 23.0047 11.9701 23.4099 12.1907 23.597C13.0383 24.3112 13.828 25.1263 14.6297 25.8925Z\\\" fill=\\\"%23B7443F\\\"/>%0A<path d=\\\"M12.1754 21.7485C11.947 21.9993 11.7007 22.244 11.4719 22.4985C11.5185 21.8601 11.7633 21.1333 12.0251 20.5357C12.1361 20.2829 13.1036 18.5265 13.2131 18.4304C13.2993 18.3556 13.3244 18.3196 13.4513 18.3639L13.5824 20.2486C13.0333 20.6691 12.6344 21.2435 12.1754 21.7485Z\\\" fill=\\\"%23B7443F\\\"/>%0A<path d=\\\"M3.63342 10.4694C5.39176 11.0729 7.17567 10.8972 8.98325 10.9729L9.28932 15.8665C9.20264 15.945 9.22353 16.015 9.22753 16.1145C9.26384 17.0661 9.89803 18.3356 9.88022 19.2578C9.84221 21.1935 9.30671 23.4537 9.00229 25.3551C8.91402 24.7928 8.35266 23.6541 8.37263 23.1505C8.38997 22.7399 8.79753 22.374 8.7713 21.9392C8.75961 21.7397 8.51385 21.2691 8.41953 21.0441C8.36372 20.9118 8.42796 20.7463 8.19352 20.7685C8.23548 20.602 8.4602 20.4087 8.27657 20.1665C7.64523 19.383 7.04866 18.576 6.43391 17.7796C6.34746 17.6677 6.18927 17.6342 6.17326 17.6135C6.00036 17.3895 4.9165 15.8698 4.92048 15.7228L6.45934 12.458L5.97174 11.0654C5.80195 10.9333 4.24487 11.2914 3.85808 11.2491C3.51356 11.2123 3.37522 11.0245 3.11866 10.8701L3.6371 10.4699L3.63342 10.4694Z\\\" fill=\\\"%23BEA284\\\"/>%0A<path d=\\\"M11.1538 8.6355C12.0633 8.99907 12.9006 9.50277 13.7915 9.90878C13.9803 9.9947 14.1082 10.1475 14.3191 10.1634C14.3268 10.1906 14.4199 10.2362 14.3953 10.3115C14.3608 10.5218 13.7234 10.9609 13.5415 11.1411C13.3704 11.3096 13.2224 11.5595 13.0937 11.6886C13.0873 11.6952 12.9712 11.6542 12.8999 11.729C11.6293 13.0392 10.533 14.5343 9.28737 15.8682L8.9813 10.9745C7.17165 10.9005 5.38774 11.0762 3.63148 10.4711C3.66871 10.3414 3.796 10.1505 3.78244 10.0236C3.85546 10.0367 3.93432 9.96094 3.978 9.95535C6.3884 9.61366 8.75796 9.06686 11.1517 8.6371L11.1538 8.6355Z\\\" fill=\\\"%23F7E6CA\\\"/>%0A<path d=\\\"M8.19201 20.7688C8.13839 20.9823 8.08181 21.1898 8.0174 21.4001L5.87814 22.0587C5.8969 21.8258 5.85979 21.4755 5.87492 21.3579L6.08769 19.7043C6.09195 19.6712 6.01729 19.5402 6.02714 19.4201C6.07689 18.8157 6.25388 18.224 6.16992 17.6136C6.18593 17.6344 6.34413 17.6678 6.43058 17.7798C7.04556 18.5743 7.64372 19.3834 8.27323 20.1667C8.4587 20.4091 8.23213 20.6022 8.19017 20.7686L8.19201 20.7688Z\\\" fill=\\\"%23B7443F\\\"/>%0A<path d=\\\"M6.61115 25.7951C6.29036 25.6754 5.79838 25.6233 5.6479 25.2976C5.80136 24.3518 5.79385 23.0602 5.87789 22.0587L8.01716 21.4001C7.56838 22.8701 7.04937 24.32 6.61115 25.7951Z\\\" fill=\\\"%23983223\\\"/>%0A<path d=\\\"M5.64781 25.2972C5.79828 25.6229 6.29027 25.675 6.61106 25.7947C6.38055 26.5701 6.05569 27.3239 6.02812 28.1478L3.54773 27.8286C3.6412 27.5231 4.01677 26.8542 4.2569 26.6573C4.55972 26.4086 5.16901 26.4926 5.27949 26.3742C5.31848 26.3325 5.62971 25.4088 5.64781 25.2972Z\\\" fill=\\\"%23B7443F\\\"/>%0A<path d=\\\"M8.20616 26.4667L8.42289 26.9597C7.79103 26.8914 7.60723 27.8409 7.49859 28.3368C7.19294 28.2881 6.87007 28.3008 6.58169 28.1759C6.39886 28.0291 6.89779 27.1127 7.04157 26.9388C7.40874 26.4949 7.67181 26.4391 8.208 26.467L8.20616 26.4667Z\\\" fill=\\\"%23B7443F\\\"/>%0A<path d=\\\"M8.85011 26.5495C8.78657 26.39 8.98508 26.2119 8.98928 26.1938L8.94149 26.5071L8.85011 26.5495Z\\\" fill=\\\"%23C1A17F\\\"/>%0A<path d=\\\"M6.19939 2.8617C6.42593 3.4381 6.69064 4.0082 6.81757 4.61848C6.99346 4.77559 8.22358 3.91034 8.42513 3.70841L8.517 3.72023L9.14824 3.89484C9.16798 4.40915 8.72163 5.84591 8.98431 6.21404L13.7909 9.90869C12.8999 9.50268 12.0626 8.99898 11.1531 8.63541C10.7251 8.30391 9.05156 6.67842 8.65512 6.63862C8.25867 6.59881 7.65627 7.53549 7.51392 7.88699C7.45282 7.88286 7.39153 7.86564 7.33019 7.86335C7.01086 7.84841 6.35946 7.8449 6.10046 7.98528C5.75373 7.92199 5.38794 7.91975 5.04216 7.84911C4.90738 7.82243 4.76653 7.88648 4.83182 7.68383C5.40291 7.01955 6.42893 6.36151 6.92563 5.68019C7.22975 5.26172 7.0202 5.1339 6.8473 4.7213C6.50873 4.94295 6.15138 5.33963 5.76673 5.46944C5.53046 5.54924 5.60575 5.44312 5.5107 5.29641C5.57464 4.45108 5.32895 3.00745 5.26953 2.09021L6.19732 2.8633L6.19939 2.8617Z\\\" fill=\\\"%23983223\\\"/>%0A<path d=\\\"M10.435 4.06019L9.53404 4.87814L12.3324 6.73241C12.8256 7.79138 13.9992 9.07798 14.319 10.1632C14.1082 10.1473 13.9803 9.99448 13.7915 9.90855L8.98489 6.2139C8.72197 5.84761 9.16856 4.40901 9.14882 3.8947L8.51758 3.72009L10.435 4.06019Z\\\" fill=\\\"%23C47C4E\\\"/>%0A<path d=\\\"M12.8101 5.20601C12.6983 5.69778 12.4415 6.22694 12.3336 6.73228L9.53519 4.87801L10.4361 4.06006C11.4399 3.32818 12.4403 2.57906 13.4312 1.83059C13.6029 1.94794 13.4523 2.16016 13.4183 2.294C13.1839 3.25934 13.0165 4.29869 12.8101 5.20601Z\\\" fill=\\\"%23983223\\\"/>%0A<path d=\\\"M5.51262 5.29453C5.60584 5.441 5.53032 5.54895 5.76866 5.46756C6.1533 5.33775 6.51066 4.94107 6.84922 4.71941C7.02029 5.13179 7.23168 5.25984 6.92756 5.67831C6.43245 6.3617 5.40644 7.01974 4.83375 7.68195C4.76845 7.8846 4.90747 7.82031 5.04408 7.84722C5.38987 7.91786 5.75566 7.92011 6.10239 7.9834C5.61478 8.24564 5.07515 9.04285 4.53095 9.32396L3.98136 9.95178C3.93769 9.95737 3.85883 10.0331 3.78581 10.02C3.76494 9.81934 3.07678 9.43382 2.83438 9.43065C3.06431 8.8775 4.30665 8.38177 4.56135 7.97002C4.83986 7.51837 4.57561 6.75595 4.7373 6.26873C4.87133 5.86573 5.46602 5.91797 5.5147 5.29293L5.51262 5.29453Z\\\" fill=\\\"%23C47C4E\\\"/>%0A<path d=\\\"M8.42566 3.70809C8.22595 3.91026 6.994 4.77527 6.8181 4.61816C6.69117 4.00788 6.4267 3.43594 6.19992 2.86138C5.88731 2.06845 5.64449 1.2266 5.19749 0.491093C5.31647 0.248653 5.6709 0.658472 5.7689 0.753263C6.70812 1.66977 7.53763 2.74213 8.42566 3.70809Z\\\" fill=\\\"%2340150F\\\"/>%0A<path d=\\\"M2.8339 9.43269C3.0763 9.43586 3.76445 9.82138 3.78533 10.022C3.79888 10.1489 3.67159 10.3399 3.63436 10.4696L3.11592 10.8698C2.96873 10.7799 2.78216 10.7783 2.63039 10.6224C2.24602 10.2274 2.03754 9.42361 2.8339 9.43269Z\\\" fill=\\\"black\\\"/>%0A<path d=\\\"M12.8101 5.20649C13.0181 4.30124 13.1836 3.26166 13.4182 2.29447C13.4507 2.15856 13.6028 1.94841 13.4312 1.83107C13.6132 1.69386 13.7903 1.4645 14.0074 1.34488C13.8051 2.64122 13.2656 3.95954 12.8101 5.20649Z\\\" fill=\\\"%23C47C4E\\\"/>%0A<path d=\\\"M6.20082 2.86228L5.27304 2.08919C5.25348 1.77663 5.10185 0.690636 5.19838 0.492001C5.64539 1.22751 5.88821 2.06936 6.20082 2.86228Z\\\" fill=\\\"%23BF3D36\\\"/>%0A<path d=\\\"M11.1545 8.63562C8.76076 9.06538 6.39121 9.61218 3.9808 9.95388L4.53039 9.32606C5.07459 9.04494 5.61422 8.24774 6.10183 7.98549C6.36083 7.84512 7.01222 7.84862 7.33155 7.86356C7.35051 8.02102 6.72874 8.46959 7.11077 8.49074C7.298 8.50175 7.888 8.5179 8.02709 8.49657C8.17767 8.47299 8.61592 8.07178 8.29799 7.98791C8.08657 7.93269 7.74637 7.90573 7.51528 7.8872C7.65764 7.5357 8.27314 6.59885 8.65648 6.63883C9.03983 6.67882 10.7283 8.30436 11.1545 8.63562Z\\\" fill=\\\"%23B7443F\\\"/>%0A<path d=\\\"M7.51478 7.88671C7.74586 7.90524 8.0863 7.93036 8.29748 7.98742C8.61358 8.07105 8.1774 8.47066 8.02658 8.49608C7.88933 8.51764 7.29933 8.5015 7.11027 8.49024C6.72823 8.4691 7.35001 8.02053 7.33105 7.86307C7.39239 7.86536 7.45368 7.88258 7.51478 7.88671Z\\\" fill=\\\"black\\\"/>%0A</svg>%0A\"","\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAcIAAAFiCAYAAABlBNirAAAQAElEQVR4AeydX6xkx53Xz7n/5p/HySSLEmLIgogWZSGamGVgbSWZmQRsRSsFwiaLbEsLWhhLGwsRe3lYnjzhFeHNS152IiAbzVwJ+yE8OtrNjDfBtriwrEEQAXlYCfIGsjO2Z7rndt/e+pzbvzs1557+c7rPvzr1Hc13qk79O1Wf6qlvV/XpezcS/REBERABERCBiAnICCOefA1dBERABEQgSWSEMb0KNFYREAEREIFjBGSEx5AoQQREQAREICYCMsKYZltjjYmAxioCIrAkARnhkqBUTAREQAREoJ8EZIT9nFeNSgREICYCGutaBGSEa+FTZREQAREQgdAJyAhDn0H1XwREQAREYC0CgRnhWmNVZREQAREQARE4RkBGeAyJEkRABERABGIiICOMabYDG6u6KwIiIAJNEJARNkFZ9xABERABEegsARlhZ6dGHROBmAhorCLQHgEZYXvsdWcREAEREIEOEJARdmAS1AUREAERiIlA18YqI+zajKg/IiACIiACjRKQETaKWzcTAREQARHoGgEZYZ0zorZFQAREQAQ6T0BG2PkpUgdFQAREQATqJCAjrJOu2o6JgMYqAiIQKAEZYaATp26LgAiIgAhUQ0BGWA1HtSICIhATAY21VwRkhL2aTg1GBERABESgLAEZYVliKi8CIiACItArAguMsFdj1WBEQAREQARE4BgBGeExJEoQAREQARGIiYCMMKbZXjBWZYuACIhAjARkhDHOusYsAiIgAiJwREBGeIRCERGIiYDGKgIiYARkhEZCoQiIgAiIQJQEZIRRTrsGLQIiEBMBjXU+ARnhfD7KFQEREAER6DkBGWHPJ1jDEwEREAERmE+gX0Y4f6zKFQEREAEREIFjBGSEx5AoQQREQAREICYCMsKYZrtfY9VoREAERKASAjLCSjCqEREQAREQgVAJyAhDnTn1WwRiIqCxikCNBGSENcJV0yIgAiIgAt0nsLF348Zk7/r1q93vqnooAiIgAiIQAYHGh3i4I0zTF2WIjbPXDUVABERABDpA4NAIrSMyRCOhUAREQAREIBICDxqhDRpD3N29aZcK6yGgVkVABERABNonUGyE7fdLPRABERABERCBRgjICBvBrJuIgAiIgAh0lYCMsKszo36JgAiIgAg0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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","import type { VariantProps } from 'class-variance-authority'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { cva } from 'class-variance-authority'\nimport { Button } from '../../base/button/button'\nimport miloStamp from './assets/milo-stamp.svg'\nimport scene5 from './assets/scene-5.png'\nimport scene6 from './assets/scene-6.png'\nimport scene7 from './assets/scene-7.png'\n\nexport interface EmptyContentAction {\n type: 'button' | 'link' | 'external-link'\n label: string\n onClick?: () => void\n to?: string\n variant?: 'default' | 'destructive' | 'outline'\n icon?: React.ReactNode\n iconPosition?: 'start' | 'end'\n}\n\n// Container variants\nconst containerVariants = cva(\n 'flex items-center justify-center relative overflow-hidden bg-[#F4F3F2] dark:bg-transparent',\n {\n variants: {\n variant: {\n default: 'rounded-lg border border-border',\n dashed: 'rounded-lg border border-dashed border-border',\n minimal: '',\n },\n size: {\n xs: 'h-32 p-3',\n sm: 'h-48 p-4',\n md: 'h-[226px] py-7 px-6',\n lg: 'h-80 p-8',\n xl: 'h-96 p-12',\n },\n orientation: {\n vertical: 'flex-col',\n horizontal: 'flex-row',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n orientation: 'vertical',\n },\n },\n)\n\n// Title variants\nconst titleVariants = cva('font-normal text-foreground text-center', {\n variants: {\n size: {\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-sm',\n lg: 'text-base',\n xl: 'text-lg',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n})\n\n// Subtitle variants\nconst subtitleVariants = cva('text-muted-foreground text-center text-xs font-normal', {\n variants: {\n size: {\n xs: 'text-xs',\n sm: 'text-xs',\n md: 'text-xs',\n lg: 'text-sm',\n xl: 'text-base',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n})\n\n// Actions container variants\nconst actionsContainerVariants = cva('flex items-center flex-col', {\n variants: {\n size: {\n xs: 'gap-1',\n sm: 'gap-1',\n md: 'gap-1.5',\n lg: 'gap-2',\n xl: 'gap-3',\n },\n spacing: {\n compact: '',\n normal: '',\n relaxed: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n spacing: 'normal',\n },\n})\n\n// Action button variants\nconst actionButtonVariants = cva('flex items-center gap-1', {\n variants: {\n size: {\n xs: 'text-xs',\n sm: 'text-xs',\n md: 'text-xs',\n lg: 'text-sm',\n xl: 'text-sm',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n})\n\n// Size to button size mapping\nconst BUTTON_SIZE_MAP = {\n xs: 'xs',\n sm: 'xs',\n md: 'xs',\n lg: 'default',\n xl: 'default',\n} as const\n\nexport interface EmptyContentProps extends VariantProps<typeof containerVariants> {\n title?: string\n subtitle?: string\n className?: string\n actions?: EmptyContentAction[]\n spacing?: 'compact' | 'normal' | 'relaxed'\n /** User's display name for greeting (e.g., \"Hey John, ...\"). Defaults to \"there\". */\n userName?: string\n /** Link component for action links (e.g., React Router's Link). Defaults to <a>. */\n linkComponent?: React.ElementType\n}\n\nexport function EmptyContent({\n title = 'No data found',\n subtitle,\n variant = 'default',\n size = 'md',\n className,\n actions = [],\n orientation = 'vertical',\n spacing = 'normal',\n userName,\n linkComponent,\n}: EmptyContentProps) {\n const buttonSize = BUTTON_SIZE_MAP[size ?? 'md']\n const LinkComp = linkComponent || 'a'\n\n const renderAction = (action: EmptyContentAction) => {\n const { icon: actionIcon, iconPosition = 'start' } = action\n\n const buttonContent = (\n <Button\n size={buttonSize}\n type={action.variant === 'destructive' ? 'danger' : 'secondary'}\n theme={action.variant === 'outline' ? 'outline' : 'solid'}\n className={actionButtonVariants({ size })}\n >\n {actionIcon && iconPosition === 'start' && actionIcon}\n <span>{action.label}</span>\n {actionIcon && iconPosition === 'end' && actionIcon}\n </Button>\n )\n\n if (action.type === 'link' || action.type === 'external-link') {\n const linkProps = LinkComp === 'a' ? { href: action.to ?? '' } : { to: action.to ?? '' }\n\n return (\n <LinkComp\n key={action.label}\n {...linkProps}\n target={action.type === 'external-link' ? '_blank' : '_self'}\n rel={action.type === 'external-link' ? 'noopener noreferrer' : undefined}\n >\n {buttonContent}\n </LinkComp>\n )\n }\n\n return (\n <Button\n key={action.label}\n size={buttonSize}\n onClick={action.onClick}\n type={action.variant === 'destructive' ? 'danger' : 'secondary'}\n theme={action.variant === 'outline' ? 'outline' : 'solid'}\n className={actionButtonVariants({ size })}\n >\n {actionIcon && iconPosition === 'start' && actionIcon}\n <span>{action.label}</span>\n {actionIcon && iconPosition === 'end' && actionIcon}\n </Button>\n )\n }\n\n return (\n <div className={cn(containerVariants({ variant, size, orientation }), className)}>\n {/* Decorative corner images */}\n <img\n src={scene5}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute bottom-0 left-0 h-auto w-1/3 max-w-[230px] select-none\"\n />\n <img\n src={scene6}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute right-0 bottom-0 h-auto w-1/3 max-w-[200px] select-none\"\n />\n\n <img\n src={scene7}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute top-0 right-4 h-auto w-1/3 max-w-[280px] select-none\"\n />\n\n <div className=\"dark:bg-background border-border relative flex max-w-[224px] flex-col items-center justify-center gap-3.5 rounded-lg border bg-white px-6 py-7\">\n <h3 className={titleVariants({ size })}>\n {`Hey ${userName ?? 'there'}, ${title || ''}`}\n </h3>\n {subtitle && <span className={subtitleVariants({ size })}>{subtitle}</span>}\n {actions.length > 0 && (\n <div className={actionsContainerVariants({ size, spacing })}>\n {actions.map(renderAction)}\n </div>\n )}\n\n <img\n src={miloStamp}\n alt=\"Milo\"\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute -top-4 right-2 h-auto w-7 select-none\"\n />\n </div>\n </div>\n )\n}\n","import type { ChangeEvent } from 'react'\nimport type { ButtonProps } from '../../base/button'\nimport { UploadIcon } from 'lucide-react'\nimport { useRef } from 'react'\nimport { Button } from '../../base/button'\nimport { Icon } from '../../icons/icon-wrapper'\n\nexport interface FileInputButtonProps extends Omit<ButtonProps, 'onClick'> {\n /** Accepted file types (e.g., { 'text/plain': ['.txt', '.zone'] }) */\n accept?: Record<string, string[]>\n /** Maximum file size in bytes */\n maxSize?: number\n /** Minimum file size in bytes */\n minSize?: number\n /** Allow multiple file selection */\n multiple?: boolean\n /** Callback when files are selected */\n onFileSelect?: (files: File[]) => void\n /** Callback when a file validation error occurs (file type/size) */\n onFileError?: (error: Error) => void\n}\n\n/**\n * A simple button that triggers a file input dialog.\n * Alternative to Dropzone for cases where drag-and-drop is not needed.\n *\n * @example\n * ```tsx\n * <FileInputButton\n * accept={{ 'text/plain': ['.txt', '.zone'] }}\n * maxSize={5 * 1024 * 1024} // 5MB\n * onFileSelect={(files) => console.log('Selected:', files)}\n * onFileError={(error) => console.error(error.message)}\n * >\n * Upload File\n * </FileInputButton>\n * ```\n */\nexport function FileInputButton({\n accept,\n maxSize,\n minSize,\n multiple = false,\n onFileSelect,\n onFileError,\n children,\n icon,\n disabled,\n ...buttonProps\n}: FileInputButtonProps) {\n const inputRef = useRef<HTMLInputElement>(null)\n\n const handleClick = () => {\n inputRef.current?.click()\n }\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const fileList = event.target.files\n if (!fileList || fileList.length === 0)\n return\n\n const files = Array.from(fileList)\n\n // Validate each file\n for (const file of files) {\n // Validate file type if accept is specified\n if (accept) {\n const acceptedTypes = Object.keys(accept)\n const acceptedExtensions = Object.values(accept).flat()\n\n const isValidType = acceptedTypes.some((type) => {\n if (type.endsWith('/*')) {\n // Handle wildcard types like 'image/*'\n const baseType = type.replace('/*', '')\n return file.type.startsWith(baseType)\n }\n return file.type === type\n })\n\n const isValidExtension = acceptedExtensions.some(ext =>\n file.name.toLowerCase().endsWith(ext.toLowerCase()),\n )\n\n if (!isValidType && !isValidExtension) {\n onFileError?.(new Error(`File type not accepted: ${file.name}`))\n // Reset input so the same file can be selected again\n event.target.value = ''\n return\n }\n }\n\n // Validate file size\n if (maxSize && file.size > maxSize) {\n onFileError?.(new Error(`File is too large: ${file.name}`))\n event.target.value = ''\n return\n }\n\n if (minSize && file.size < minSize) {\n onFileError?.(new Error(`File is too small: ${file.name}`))\n event.target.value = ''\n return\n }\n }\n\n onFileSelect?.(files)\n\n // Reset input so the same file can be selected again\n event.target.value = ''\n }\n\n // Convert accept object to HTML accept attribute format\n const acceptAttribute = accept\n ? [...Object.keys(accept), ...Object.values(accept).flat()].join(',')\n : undefined\n\n return (\n <>\n <input\n ref={inputRef}\n type=\"file\"\n accept={acceptAttribute}\n multiple={multiple}\n onChange={handleChange}\n disabled={disabled}\n className=\"hidden\"\n aria-hidden=\"true\"\n />\n <Button\n onClick={handleClick}\n disabled={disabled}\n icon={icon ?? <Icon icon={UploadIcon} className=\"size-4\" />}\n {...buttonProps}\n >\n {children}\n </Button>\n </>\n )\n}\n","import type { FormFieldContextValue } from '../types'\nimport * as React from 'react'\n\nconst FieldContext = React.createContext<FormFieldContextValue | null>(null)\n\nexport interface FieldProviderProps {\n children: React.ReactNode\n value: FormFieldContextValue\n}\n\nexport function FieldProvider({ children, value }: FieldProviderProps) {\n return <FieldContext value={value}>{children}</FieldContext>\n}\n\nexport function useFieldContext(): FormFieldContextValue {\n const context = React.use(FieldContext)\n\n if (!context) {\n throw new Error(\n 'useFieldContext must be used within a Form.Field component. '\n + 'Make sure your input component is wrapped with Form.Field.',\n )\n }\n\n return context\n}\n\n/**\n * Optional field context - returns null if not within a Form.Field\n * Useful for components that can work both inside and outside Form.Field\n */\nexport function useOptionalFieldContext(): FormFieldContextValue | null {\n return React.use(FieldContext)\n}\n\nexport { FieldContext }\n","import type { AutocompleteOption, FormAutocompleteProps } from '../../autocomplete/autocomplete.types'\nimport { useInputControl } from '@conform-to/react'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Autocomplete } from '../../autocomplete'\nimport { useFieldContext } from '../context/field-context'\n\n/**\n * Form.Autocomplete - Searchable select component\n *\n * Automatically wired to the parent Form.Field context.\n * Supports flat/grouped options, virtualization, custom rendering, and async search.\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field name=\"timezone\" label=\"Timezone\" required>\n * <Form.Autocomplete\n * options={timezones}\n * placeholder=\"Select timezone...\"\n * />\n * </Form.Field>\n * ```\n *\n * @example Async search\n * ```tsx\n * <Form.Field name=\"userId\" label=\"User\">\n * <Form.Autocomplete\n * options={users ?? []}\n * onSearchChange={setSearch}\n * loading={isLoading}\n * placeholder=\"Search users...\"\n * />\n * </Form.Field>\n * ```\n *\n * @example Grouped options\n * ```tsx\n * <Form.Field name=\"role\" label=\"Role\" required>\n * <Form.Autocomplete\n * options={roleGroups}\n * placeholder=\"Select a role...\"\n * />\n * </Form.Field>\n * ```\n */\nexport function FormAutocomplete<T extends AutocompleteOption = AutocompleteOption>({\n disabled,\n className,\n ...props\n}: FormAutocompleteProps<T>) {\n const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext()\n const control = useInputControl(fieldMeta as any)\n\n const isDisabled = disabled ?? fieldDisabled\n const hasErrors = errors && errors.length > 0\n\n // Ensure value is always a string\n const selectValue = Array.isArray(control.value) ? control.value[0] : control.value\n\n return (\n <Autocomplete<T>\n {...props}\n name={fieldMeta.name}\n id={fieldMeta.id}\n value={selectValue ?? ''}\n onValueChange={control.change}\n disabled={isDisabled}\n triggerClassName={cn(hasErrors && 'border-destructive', props.triggerClassName)}\n className={className}\n />\n )\n}\n\nFormAutocomplete.displayName = 'Form.Autocomplete'\n","import type { FieldMetadata } from '@conform-to/react'\nimport type { FormContextValue } from '../types'\nimport * as React from 'react'\n\nconst FormContext = React.createContext<FormContextValue | null>(null)\n\nexport interface FormProviderProps {\n children: React.ReactNode\n value: FormContextValue\n}\n\nexport function FormProvider({ children, value }: FormProviderProps) {\n return <FormContext value={value}>{children}</FormContext>\n}\n\nexport function useFormContext<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(): FormContextValue<T> {\n const context = React.use(FormContext)\n\n if (!context) {\n throw new Error('useFormContext must be used within a Form.Root component')\n }\n\n return context as FormContextValue<T>\n}\n\n/**\n * Get a specific field from the form context\n */\nexport function useFormField(name: string): FieldMetadata<unknown> | undefined {\n const { fields } = useFormContext()\n return fields[name]\n}\n\n/**\n * Check if the form is currently submitting\n */\nexport function useFormSubmitting(): boolean {\n const { isSubmitting } = useFormContext()\n return isSubmitting\n}\n\nexport { FormContext }\n","import type { FormButtonProps } from '../types'\nimport * as React from 'react'\nimport { Button } from '../../..'\nimport { useFormContext } from '../context/form-context'\n\n/**\n * Form.Button - A button for non-submit actions within a form\n *\n * Automatically gets disabled when the form is submitting.\n * Use this for cancel buttons, reset buttons, or other actions.\n *\n * @example\n * ```tsx\n * <Form.Button onClick={() => navigate(-1)}>\n * Cancel\n * </Form.Button>\n *\n * <Form.Button onClick={() => form.reset()} type=\"secondary\">\n * Reset\n * </Form.Button>\n * ```\n */\nexport function FormButton({\n children,\n onClick,\n type = 'quaternary',\n theme = 'borderless',\n size,\n disabled,\n className,\n disableOnSubmit = true,\n}: FormButtonProps) {\n const { isSubmitting } = useFormContext()\n\n const isDisabled = disabled || (disableOnSubmit && isSubmitting)\n\n return (\n <Button\n htmlType=\"button\"\n type={type}\n theme={theme}\n size={size}\n disabled={isDisabled}\n className={className}\n onClick={onClick}\n >\n {children}\n </Button>\n )\n}\n\nFormButton.displayName = 'Form.Button'\n","import type { FormCheckboxProps } from '../types'\nimport { useInputControl } from '@conform-to/react'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { Checkbox } from '../../../base/checkbox'\nimport { Label } from '../../../base/label'\nimport { useFieldContext } from '../context/field-context'\n\n/**\n * Form.Checkbox - Checkbox input component\n *\n * Automatically wired to the parent Form.Field context.\n *\n * @example\n * ```tsx\n * <Form.Field name=\"terms\">\n * <Form.Checkbox label=\"I agree to the terms and conditions\" />\n * </Form.Field>\n * ```\n */\nexport function FormCheckbox({ label, disabled, className }: FormCheckboxProps) {\n const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext()\n\n const control = useInputControl(fieldMeta as any)\n const isDisabled = disabled ?? fieldDisabled\n const hasErrors = errors && errors.length > 0\n\n // Convert string value to boolean\n const isChecked = control.value === 'on' || control.value === 'true'\n\n const handleCheckedChange = (checked: boolean) => {\n control.change(checked ? 'on' : '')\n }\n\n const checkboxId = fieldMeta.id\n\n return (\n <div className={cn('flex items-center space-x-2', className)}>\n <Checkbox\n id={checkboxId}\n name={fieldMeta.name}\n checked={isChecked}\n onCheckedChange={handleCheckedChange}\n disabled={isDisabled}\n aria-invalid={hasErrors || undefined}\n aria-describedby={hasErrors ? `${fieldMeta.id}-error` : undefined}\n />\n {label && (\n <Label\n htmlFor={checkboxId}\n className={cn(\n 'cursor-pointer text-sm font-normal',\n isDisabled && 'cursor-not-allowed opacity-70',\n )}\n >\n {label}\n </Label>\n )}\n </div>\n )\n}\n\nFormCheckbox.displayName = 'Form.Checkbox'\n","import * as React from 'react'\nimport { Toaster as SonnerToaster } from 'sonner'\n\nexport type ToasterProps = React.ComponentProps<typeof SonnerToaster>\n\n/**\n * Sonner Toaster configured for \"headless\" usage.\n *\n * We render our own toast markup via `toast.custom`, so we remove Sonner's default styling.\n */\nexport function Toaster({ toastOptions, ...props }: ToasterProps) {\n return <SonnerToaster toastOptions={{ unstyled: true, ...toastOptions }} {...props} />\n}\n","import type { Toast } from './types'\nimport { useEffect } from 'react'\n/**\n * Sonner is a toast library for React.\n * Implementation based on github.com/epicweb-dev/epic-stack\n */\nimport { toast } from './toast'\n\nexport function useToast(toastData?: Toast | null) {\n useEffect(() => {\n if (toastData) {\n setTimeout(() => {\n toast[toastData.type](toastData.title ?? toastData.description, {\n id: toastData.id,\n description: toastData.title ? toastData.description : undefined,\n })\n }, 0)\n }\n }, [toastData])\n}\n","import { useInputControl } from '@conform-to/react'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { CheckIcon, CopyIcon } from 'lucide-react'\nimport * as React from 'react'\nimport { Button, toast } from '../../..'\nimport { useCopyToClipboard } from '../../../../hooks/use-copy-to-clipboard'\nimport { useFieldContext } from '../context/field-context'\n\nexport interface FormCopyBoxProps {\n /** Display variant: 'default' shows Copy button, 'icon-only' shows icon */\n variant?: 'default' | 'icon-only'\n /** Custom className for the wrapper */\n className?: string\n /** Custom className for the content area */\n contentClassName?: string\n /** Custom className for the button */\n buttonClassName?: string\n /** Placeholder text when value is empty */\n placeholder?: string\n}\n\n/**\n * Form.CopyBox - Read-only field with copy-to-clipboard functionality\n *\n * Displays field value in a read-only box with a copy button.\n * Automatically gets value from Form.Field context.\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field name=\"organizationId\" label=\"Organization ID\">\n * <Form.CopyBox />\n * </Form.Field>\n * ```\n *\n * @example With icon-only button\n * ```tsx\n * <Form.Field name=\"apiKey\" label=\"API Key\">\n * <Form.CopyBox variant=\"icon-only\" />\n * </Form.Field>\n * ```\n *\n * @example With placeholder\n * ```tsx\n * <Form.Field name=\"webhookUrl\" label=\"Webhook URL\">\n * <Form.CopyBox placeholder=\"Not configured\" />\n * </Form.Field>\n * ```\n */\nexport function FormCopyBox({\n variant = 'default',\n className,\n contentClassName,\n buttonClassName,\n placeholder = '',\n}: FormCopyBoxProps) {\n const { fieldMeta } = useFieldContext()\n // Cast to any to bypass TypeScript's strict checking for useInputControl\n // This is safe because fieldMeta comes from Conform and has the right shape\n const control = useInputControl(fieldMeta as any)\n const [_, copy] = useCopyToClipboard()\n const [copied, setCopied] = React.useState(false)\n\n // Get the reactive value from input control\n const value = control.value ?? placeholder\n\n const copyToClipboard = () => {\n const stringValue = String(value)\n if (!stringValue)\n return\n\n copy(stringValue).then(() => {\n toast.success('Copied to clipboard')\n setCopied(true)\n setTimeout(() => {\n setCopied(false)\n }, 2000)\n })\n }\n\n return (\n <div\n className={cn(\n 'group border-input flex h-10 w-full overflow-hidden rounded-lg border bg-[#F6F6F580] text-xs focus-within:outline-hidden',\n className,\n )}\n >\n <div\n className={cn(\n 'flex w-full items-center overflow-hidden px-3 py-2 text-xs opacity-50',\n contentClassName,\n )}\n >\n <span className=\"truncate\">{String(value)}</span>\n </div>\n <div className=\"flex items-center py-2 pr-3\">\n {variant === 'icon-only'\n ? (\n <button\n type=\"button\"\n className={cn(\n 'text-muted-foreground hover:text-foreground flex size-7 items-center justify-center rounded-sm transition-colors',\n buttonClassName,\n )}\n onClick={copyToClipboard}\n >\n {copied ? <CheckIcon className=\"size-4\" /> : <CopyIcon className=\"size-4\" />}\n </button>\n )\n : (\n <Button\n type=\"quaternary\"\n theme=\"outline\"\n size=\"small\"\n className={cn('h-7 w-fit gap-1 px-2 text-xs', buttonClassName)}\n onClick={copyToClipboard}\n >\n <CopyIcon className=\"size-3!\" />\n {copied ? 'Copied' : 'Copy'}\n </Button>\n )}\n </div>\n </div>\n )\n}\n","import type { FormCustomProps, FormCustomRenderProps } from '../types'\nimport * as React from 'react'\nimport { useFormContext } from '../context/form-context'\n\n/**\n * Form.Custom - Escape hatch for custom implementations\n *\n * Provides access to the underlying form context for complex use cases\n * that don't fit the standard component patterns.\n *\n * @example\n * ```tsx\n * <Form.Custom>\n * {({ form, fields, submit, reset }) => (\n * <MyCustomComponent\n * fields={fields}\n * onCustomAction={() => {\n * // Do something custom\n * submit();\n * }}\n * />\n * )}\n * </Form.Custom>\n * ```\n */\nexport function FormCustom({ children }: FormCustomProps) {\n const { form, fields, isSubmitting, submit, reset } = useFormContext()\n\n const renderProps: FormCustomRenderProps = {\n form: form as any,\n fields: fields as any,\n isSubmitting,\n submit,\n reset,\n }\n\n return <>{children(renderProps)}</>\n}\n\nFormCustom.displayName = 'Form.Custom'\n","import type { FormDescriptionProps } from '../types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { useOptionalFieldContext } from '../context/field-context'\n\n/**\n * Form.Description - Display field description/helper text\n *\n * @example\n * ```tsx\n * <Form.Field name=\"password\">\n * <Form.Input type=\"password\" />\n * <Form.Description>\n * Must be at least 8 characters with one uppercase letter\n * </Form.Description>\n * </Form.Field>\n * ```\n */\nexport function FormDescription({ children, className }: FormDescriptionProps) {\n const fieldContext = useOptionalFieldContext()\n const id = fieldContext ? `${fieldContext.id}-description` : undefined\n\n return (\n <p id={id} className={cn('text-muted-foreground text-xs text-wrap', className)}>\n {children}\n </p>\n )\n}\n\nFormDescription.displayName = 'Form.Description'\n","import type { z } from 'zod'\nimport type { FormDialogProps, FormRootRenderProps } from '../types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { Form } from '..'\nimport { Dialog } from '../../../base/dialog'\n\n/**\n * Form.Dialog - A dialog with an integrated form\n *\n * Combines Dialog and Form.Root into a single component with:\n * - Automatic dialog state management (controlled or uncontrolled)\n * - Built-in header with title and description\n * - Built-in footer with submit and cancel buttons\n * - Auto-close on successful submission\n * - Prevents accidental close during submission\n * - Supports render function pattern for form state access\n *\n * @example Basic usage\n * ```tsx\n * <Form.Dialog\n * title=\"Add User\"\n * description=\"Enter user details\"\n * schema={userSchema}\n * onSubmit={handleSubmit}\n * trigger={<Button>Add User</Button>}\n * >\n * <Form.Field name=\"name\" label=\"Name\" required>\n * <Form.Input />\n * </Form.Field>\n * <Form.Field name=\"email\" label=\"Email\" required>\n * <Form.Input type=\"email\" />\n * </Form.Field>\n * </Form.Dialog>\n * ```\n *\n * @example With render function for form state access\n * ```tsx\n * <Form.Dialog\n * title=\"Edit User\"\n * schema={userSchema}\n * defaultValues={user}\n * onSubmit={handleSubmit}\n * trigger={<Button>Edit</Button>}\n * >\n * {({ form, fields, isSubmitting, reset }) => (\n * <>\n * <Form.Field name=\"name\" label=\"Name\">\n * <Form.Input />\n * </Form.Field>\n * <Button variant=\"ghost\" onClick={reset} disabled={isSubmitting}>\n * Reset\n * </Button>\n * </>\n * )}\n * </Form.Dialog>\n * ```\n */\nexport function FormDialog<T extends z.ZodType>({\n // Dialog props\n open,\n onOpenChange,\n defaultOpen,\n title,\n description,\n trigger,\n\n // Form props\n schema,\n defaultValues,\n onSubmit,\n onSuccess,\n onError,\n\n // Footer props\n submitText = 'Submit',\n submitTextLoading = 'Submitting...',\n cancelText = 'Cancel',\n showCancel = true,\n submitType = 'primary',\n\n // Loading state\n loading,\n\n // Form customization\n formComponent,\n telemetry,\n\n // Styling\n className,\n formClassName,\n\n // Children\n children,\n}: FormDialogProps<T>) {\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false)\n const [internalIsSubmitting, setInternalIsSubmitting] = React.useState(false)\n\n // Use external loading if provided, otherwise use internal state\n const isSubmitting = loading ?? internalIsSubmitting\n\n // Determine if controlled or uncontrolled\n const isControlled = open !== undefined\n const isOpen = isControlled ? open : internalOpen\n\n const handleOpenChange = React.useCallback(\n (value: boolean) => {\n // Prevent closing while submitting\n if (!value && isSubmitting) {\n return\n }\n\n if (!isControlled) {\n setInternalOpen(value)\n }\n onOpenChange?.(value)\n },\n [isControlled, isSubmitting, onOpenChange],\n )\n\n const handleSubmit = React.useCallback(\n async (data: z.infer<T>) => {\n // Only manage internal state if not using external loading\n if (loading === undefined) {\n setInternalIsSubmitting(true)\n }\n try {\n await onSubmit?.(data)\n onSuccess?.(data)\n }\n catch (error) {\n console.error('Form submission error:', error)\n throw error\n }\n finally {\n if (loading === undefined) {\n setInternalIsSubmitting(false)\n }\n }\n },\n [onSubmit, onSuccess, loading],\n )\n\n const handleCancel = React.useCallback(() => {\n handleOpenChange(false)\n }, [handleOpenChange])\n\n return (\n <Dialog open={isOpen} onOpenChange={handleOpenChange}>\n {trigger && <Dialog.Trigger>{trigger}</Dialog.Trigger>}\n\n <Dialog.Content className={className}>\n <Form.Root\n schema={schema}\n defaultValues={defaultValues}\n onSubmit={handleSubmit}\n onError={onError}\n isSubmitting={isSubmitting}\n mode=\"onSubmit\"\n formComponent={formComponent}\n telemetry={telemetry}\n className={cn('space-y-0', formClassName)}\n >\n {(renderProps: FormRootRenderProps) => (\n <>\n <Dialog.Header\n title={title}\n description={description}\n onClose={handleCancel}\n className=\"border-b\"\n descriptionClassName=\"text-foreground/80\"\n />\n\n <Dialog.Body className=\"space-y-0\">\n {/* Render children - support both patterns */}\n {typeof children === 'function' ? children(renderProps) : children}\n </Dialog.Body>\n <Dialog.Footer className=\"border-t\">\n {showCancel && (\n <Form.Button\n type=\"quaternary\"\n theme=\"outline\"\n onClick={handleCancel}\n disableOnSubmit\n >\n {cancelText}\n </Form.Button>\n )}\n <Form.Submit type={submitType}>\n {isSubmitting ? submitTextLoading : submitText}\n </Form.Submit>\n </Dialog.Footer>\n </>\n )}\n </Form.Root>\n </Dialog.Content>\n </Dialog>\n )\n}\n\nFormDialog.displayName = 'Form.Dialog'\n","import type { FormErrorProps } from '../types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { useOptionalFieldContext } from '../context/field-context'\n\n/**\n * Form.Error - Display field errors\n *\n * Can be used inside Form.Field to display errors automatically,\n * or standalone with custom rendering.\n *\n * @example\n * ```tsx\n * // Inside Form.Field - displays field errors automatically\n * <Form.Field name=\"email\">\n * <Form.Input />\n * <Form.Error />\n * </Form.Field>\n *\n * // Custom rendering\n * <Form.Field name=\"email\">\n * <Form.Input />\n * <Form.Error>\n * {(errors) => errors.map(e => <span key={e}>{e}</span>)}\n * </Form.Error>\n * </Form.Field>\n * ```\n */\nexport function FormError({ children, className }: FormErrorProps) {\n const fieldContext = useOptionalFieldContext()\n const errors = fieldContext?.errors\n\n if (!errors || errors.length === 0) {\n return null\n }\n\n // Custom render function\n if (typeof children === 'function') {\n return <>{children(errors)}</>\n }\n\n // Default rendering\n return (\n <ul\n className={cn(\n 'text-destructive space-y-1 text-sm font-medium',\n errors.length > 1 && 'list-disc pl-4',\n className,\n )}\n role=\"alert\"\n aria-live=\"polite\"\n >\n {errors.map(error => (\n <li key={error} className=\"text-wrap\">\n {error}\n </li>\n ))}\n </ul>\n )\n}\n\nFormError.displayName = 'Form.Error'\n","import type { FormFieldContextValue, FormFieldProps, FormFieldRenderProps } from '../types'\nimport { useInputControl } from '@conform-to/react'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { CircleHelp } from 'lucide-react'\nimport * as React from 'react'\nimport { Label } from '../../../base/label'\nimport { Tooltip } from '../../../base/tooltip'\nimport { Icon } from '../../../icons/icon-wrapper'\nimport { FieldProvider } from '../context/field-context'\nimport { useFormContext } from '../context/form-context'\n\n/**\n * Internal FieldLabel component with hover-reveal tooltip\n */\nfunction FieldLabel({\n htmlFor,\n label,\n hasErrors,\n required,\n tooltip,\n className,\n}: {\n htmlFor: string\n label: React.ReactNode\n hasErrors?: boolean\n required?: boolean\n tooltip?: string | React.ReactNode\n className?: string\n}) {\n const [isTooltipVisible, setIsTooltipVisible] = React.useState(false)\n\n return (\n <div className=\"relative flex w-fit items-center space-x-2\">\n <Label\n htmlFor={htmlFor}\n className={cn(\n 'text-foreground/80 gap-0 text-xs font-semibold',\n hasErrors && 'text-destructive',\n className,\n )}\n >\n {label}\n {required && (\n <span className=\"text-destructive/80 align-super text-sm leading-0\" aria-hidden=\"true\">\n *\n </span>\n )}\n </Label>\n {tooltip && (\n <Tooltip\n message={tooltip}\n open={isTooltipVisible}\n onOpenChange={setIsTooltipVisible}\n side=\"bottom\"\n contentClassName=\"max-w-xs text-wrap\"\n >\n <Icon\n icon={CircleHelp}\n className={cn(\n 'text-ring absolute top-0.5 -right-3 size-3.5 cursor-pointer transition-opacity duration-400',\n )}\n />\n </Tooltip>\n )}\n </div>\n )\n}\n\n/**\n * Form.Field - Field wrapper component\n *\n * Provides field context to children with:\n * - Automatic label rendering\n * - Error display\n * - Description text\n * - Required indicator\n * - Accessibility attributes\n *\n * Supports two patterns:\n * 1. ReactNode children - for standard Form inputs\n * 2. Render function - for custom components needing field access\n *\n * @example Standard usage\n * ```tsx\n * <Form.Field name=\"email\" label=\"Email Address\" required>\n * <Form.Input type=\"email\" />\n * </Form.Field>\n * ```\n *\n * @example Render function for custom components\n * ```tsx\n * <Form.Field name=\"role\" label=\"Role\" required>\n * {({ control, meta, fields }) => (\n * <CustomSelect\n * name={meta.name}\n * value={control.value}\n * onChange={control.change}\n * />\n * )}\n * </Form.Field>\n * ```\n */\nexport function FormField({\n name,\n children,\n label,\n description,\n tooltip,\n required = false,\n disabled = false,\n className,\n labelClassName,\n}: FormFieldProps) {\n const { fields, form, isSubmitting } = useFormContext()\n\n // Get field metadata - support nested paths\n const fieldMeta = React.useMemo(() => {\n const parts = name.split('.')\n let current: any = fields\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]!\n if (!current)\n break\n\n // Handle array access like \"items.0.name\"\n if (/^\\d+$/.test(part)) {\n const fieldList = current.getFieldList?.()\n if (fieldList) {\n const item = fieldList[Number.parseInt(part, 10)]\n // If there are more parts, get the fieldset\n if (i < parts.length - 1 && item?.getFieldset) {\n current = item.getFieldset()\n }\n else {\n current = item\n }\n }\n else {\n current = current[part as keyof typeof current]\n }\n }\n else {\n // First check if it's a direct property (top-level field)\n if (current[part as keyof typeof current] !== undefined) {\n current = current[part as keyof typeof current]\n }\n else if (typeof current.getFieldset === 'function') {\n // Try getFieldset for nested objects\n current = current.getFieldset()[part as keyof ReturnType<typeof current.getFieldset>]\n }\n else {\n current = undefined\n }\n }\n }\n\n return current\n }, [fields, name])\n\n // Derive values from fieldMeta (may be undefined)\n const errors = fieldMeta?.errors\n const hasErrors = errors && errors.length > 0\n const fieldId = fieldMeta?.id ?? ''\n const descriptionId = description ? `${fieldId}-description` : undefined\n const errorId = hasErrors ? `${fieldId}-error` : undefined\n\n // Context value - defined before early return to follow hooks rules\n const contextValue: FormFieldContextValue = React.useMemo(\n () => ({\n name: fieldMeta?.name ?? '',\n id: fieldId,\n errors,\n required,\n disabled,\n fieldMeta,\n }),\n [fieldMeta, fieldId, errors, required, disabled],\n )\n\n // Early return after all hooks\n if (!fieldMeta) {\n console.warn(`Form.Field: Field \"${name}\" not found in form schema`)\n return null\n }\n\n // Determine if children is a render function\n const isRenderFunction = typeof children === 'function'\n\n // Render the field content\n const renderContent = () => {\n if (isRenderFunction) {\n // Use the render function pattern\n return (\n <FormFieldRenderContent\n fieldMeta={fieldMeta}\n fields={fields}\n form={form}\n isSubmitting={isSubmitting}\n required={required}\n disabled={disabled}\n >\n {children}\n </FormFieldRenderContent>\n )\n }\n // Standard ReactNode children\n return children\n }\n\n return (\n <FieldProvider value={contextValue}>\n <div className={cn('flex flex-col space-y-2', className)}>\n {/* Label */}\n {label && (\n <FieldLabel\n htmlFor={fieldId}\n label={label}\n hasErrors={hasErrors}\n required={required}\n tooltip={tooltip}\n className={labelClassName}\n />\n )}\n\n {/* Field Input */}\n {renderContent()}\n\n {/* Description */}\n {description && (\n <p id={descriptionId} className=\"text-ring text-xs text-wrap\">\n {description}\n </p>\n )}\n\n {/* Errors */}\n {hasErrors && (\n <ul\n id={errorId}\n className={cn(\n 'text-destructive space-y-1 text-xs font-medium',\n errors.length > 1 && 'list-disc pl-4',\n )}\n role=\"alert\"\n aria-live=\"polite\"\n >\n {errors.map((error: string) => (\n <li key={error} className=\"text-wrap\">\n {error}\n </li>\n ))}\n </ul>\n )}\n </div>\n </FieldProvider>\n )\n}\n\n/**\n * Internal component to handle render function pattern\n * This is needed because hooks (useInputControl) must be called unconditionally\n */\nfunction FormFieldRenderContent({\n fieldMeta,\n fields,\n form,\n isSubmitting,\n required,\n disabled,\n children,\n}: {\n fieldMeta: any\n fields: Record<string, any>\n form: any\n isSubmitting: boolean\n required: boolean\n disabled: boolean\n children: (props: FormFieldRenderProps) => React.ReactNode\n}) {\n const control = useInputControl(fieldMeta)\n\n const meta = React.useMemo(\n () => ({\n name: fieldMeta.name,\n id: fieldMeta.id,\n errors: fieldMeta.errors,\n required,\n disabled,\n }),\n [fieldMeta.name, fieldMeta.id, fieldMeta.errors, required, disabled],\n )\n\n const renderProps: FormFieldRenderProps = {\n field: fieldMeta,\n control: {\n value: control.value,\n change: control.change,\n blur: control.blur,\n focus: control.focus,\n },\n meta,\n fields,\n form,\n isSubmitting,\n }\n\n return <>{children(renderProps)}</>\n}\n\nFormField.displayName = 'Form.Field'\n","import type { FormFieldArrayProps, FormFieldArrayRenderProps } from '../types'\nimport { useFormMetadata } from '@conform-to/react'\nimport * as React from 'react'\nimport { useFormContext } from '../context/form-context'\n\n/**\n * Form.FieldArray - Dynamic array of fields\n *\n * Provides helpers for managing arrays of form fields.\n *\n * @example\n * ```tsx\n * <Form.FieldArray name=\"members\">\n * {({ fields, append, remove }) => (\n * <>\n * {fields.map((field, index) => (\n * <div key={field.key} className=\"flex gap-2\">\n * <Form.Field name={`members.${index}.email`} label=\"Email\">\n * <Form.Input type=\"email\" />\n * </Form.Field>\n * <Form.Field name={`members.${index}.role`} label=\"Role\">\n * <Form.Select>\n * <Form.SelectItem value=\"admin\">Admin</Form.SelectItem>\n * <Form.SelectItem value=\"user\">User</Form.SelectItem>\n * </Form.Select>\n * </Form.Field>\n * <button type=\"button\" onClick={() => remove(index)}>\n * Remove\n * </button>\n * </div>\n * ))}\n * <button type=\"button\" onClick={() => append({ email: '', role: 'user' })}>\n * Add Member\n * </button>\n * </>\n * )}\n * </Form.FieldArray>\n * ```\n */\nexport function FormFieldArray({ name, children }: FormFieldArrayProps) {\n const { fields, formId } = useFormContext()\n const form = useFormMetadata(formId)\n\n // Get the array field metadata\n const arrayField = React.useMemo(() => {\n const parts = name.split('.')\n let current: any = fields\n\n for (const part of parts) {\n if (!current)\n break\n\n if (typeof current.getFieldset === 'function') {\n current = current.getFieldset()[part]\n }\n else {\n current = current[part]\n }\n }\n\n return current\n }, [fields, name])\n\n // Get the array field name for callbacks (use empty string if not found)\n const arrayFieldName = arrayField?.name ?? ''\n\n // Append handler - defined before early return to follow hooks rules\n const append = React.useCallback(\n (value: Record<string, unknown> = {}) => {\n if (!arrayFieldName)\n return\n form.insert({\n name: arrayFieldName,\n defaultValue: value as any,\n })\n },\n [form, arrayFieldName],\n )\n\n // Remove handler - defined before early return to follow hooks rules\n const remove = React.useCallback(\n (index: number) => {\n if (!arrayFieldName)\n return\n form.remove({\n name: arrayFieldName,\n index,\n })\n },\n [form, arrayFieldName],\n )\n\n // Move handler - defined before early return to follow hooks rules\n const move = React.useCallback(\n (from: number, to: number) => {\n if (!arrayFieldName)\n return\n form.reorder({\n name: arrayFieldName,\n from,\n to,\n })\n },\n [form, arrayFieldName],\n )\n\n // Early return after all hooks\n if (!arrayField) {\n console.warn(`Form.FieldArray: Field \"${name}\" not found in form schema`)\n return null\n }\n\n // Get the field list\n const fieldList = arrayField.getFieldList?.() ?? []\n\n // Create the fields array with id, key, and name\n const formFields: FormFieldArrayRenderProps['fields'] = fieldList.map(\n (field: any, index: number) => ({\n id: field.id,\n key: field.key,\n name: `${name}.${index}`,\n }),\n )\n\n const renderProps: FormFieldArrayRenderProps = {\n fields: formFields,\n append,\n remove,\n move,\n }\n\n return <>{children(renderProps)}</>\n}\n\nFormFieldArray.displayName = 'Form.FieldArray'\n","import type { FormInputProps } from '../types'\nimport { getInputProps } from '@conform-to/react'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { Input } from '../../../base/input'\nimport { useFieldContext } from '../context/field-context'\n\n/**\n * Form.Input - Text input component\n *\n * Automatically wired to the parent Form.Field context.\n *\n * @example\n * ```tsx\n * <Form.Field name=\"email\" label=\"Email\" required>\n * <Form.Input type=\"email\" placeholder=\"john@example.com\" />\n * </Form.Field>\n * ```\n */\nexport function FormInput({ ref, type = 'text', className, disabled, ...props }: FormInputProps & { ref?: React.RefObject<HTMLInputElement | null> }) {\n const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext()\n\n const inputProps = getInputProps(fieldMeta, { type })\n const isDisabled = disabled ?? fieldDisabled\n const hasErrors = errors && errors.length > 0\n\n return (\n <Input\n ref={ref}\n {...inputProps}\n {...props}\n type={type}\n disabled={isDisabled}\n aria-invalid={hasErrors || undefined}\n aria-describedby={hasErrors ? `${fieldMeta.id}-error` : undefined}\n className={cn('!text-xs', className)}\n />\n )\n}\n\nFormInput.displayName = 'Form.Input'\n","import type { FormRadioGroupProps, FormRadioItemProps } from '../types'\nimport { useInputControl } from '@conform-to/react'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { Label } from '../../../base/label'\nimport { RadioGroup, RadioGroupItem } from '../../../base/radio-group'\nimport { useFieldContext } from '../context/field-context'\n\n/**\n * Form.RadioGroup - Radio button group component\n *\n * Automatically wired to the parent Form.Field context.\n *\n * @example\n * ```tsx\n * <Form.Field name=\"plan\" label=\"Select Plan\" required>\n * <Form.RadioGroup orientation=\"vertical\">\n * <Form.RadioItem value=\"free\" label=\"Free\" description=\"Basic features\" />\n * <Form.RadioItem value=\"pro\" label=\"Pro\" description=\"Advanced features\" />\n * <Form.RadioItem value=\"enterprise\" label=\"Enterprise\" description=\"Custom solutions\" />\n * </Form.RadioGroup>\n * </Form.Field>\n * ```\n */\nexport function FormRadioGroup({\n orientation = 'vertical',\n disabled,\n className,\n children,\n}: FormRadioGroupProps) {\n const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext()\n\n const control = useInputControl(fieldMeta as any)\n const isDisabled = disabled ?? fieldDisabled\n const hasErrors = errors && errors.length > 0\n\n // Ensure value is always a string for RadioGroup\n const radioValue = Array.isArray(control.value) ? control.value[0] : control.value\n\n return (\n <RadioGroup\n name={fieldMeta.name}\n value={radioValue ?? ''}\n onValueChange={control.change}\n disabled={isDisabled}\n aria-invalid={hasErrors || undefined}\n aria-describedby={hasErrors ? `${fieldMeta.id}-error` : undefined}\n className={cn(\n orientation === 'horizontal' ? 'flex flex-row space-x-4' : 'flex flex-col space-y-2',\n className,\n )}\n >\n {children}\n </RadioGroup>\n )\n}\n\nFormRadioGroup.displayName = 'Form.RadioGroup'\n\n/**\n * Form.RadioItem - Individual radio button option\n *\n * @example\n * ```tsx\n * <Form.RadioItem value=\"option1\" label=\"Option 1\" />\n * ```\n */\nexport function FormRadioItem({ value, label, description, disabled }: FormRadioItemProps) {\n const radioId = `radio-${value}`\n\n return (\n <div className=\"flex items-start space-x-2\">\n <RadioGroupItem id={radioId} value={value} disabled={disabled} className=\"mt-1\" />\n <div className=\"flex flex-col\">\n <Label\n htmlFor={radioId}\n className={cn(\n 'cursor-pointer text-sm font-normal',\n disabled && 'cursor-not-allowed opacity-70',\n )}\n >\n {label}\n </Label>\n {description && <span className=\"text-muted-foreground text-xs\">{description}</span>}\n </div>\n </div>\n )\n}\n\nFormRadioItem.displayName = 'Form.RadioItem'\n","import type { z } from 'zod'\nimport type { FormRootProps, FormRootRenderProps } from '../types'\nimport { FormProvider as ConformFormProvider, getFormProps, useForm } from '@conform-to/react'\nimport { getZodConstraint, parseWithZod } from '@conform-to/zod/v4'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { FormProvider } from '../context/form-context'\n\n/**\n * Form.Root - The root form component\n *\n * Provides form context to all children with built-in:\n * - Zod schema validation\n * - Conform integration\n * - Optional telemetry callbacks\n *\n * Supports two patterns:\n * 1. ReactNode children - for standard forms\n * 2. Render function - for forms needing access to form state\n *\n * @example Standard usage\n * ```tsx\n * <Form.Root schema={userSchema} onSubmit={handleSubmit}>\n * <Form.Field name=\"email\" label=\"Email\" required>\n * <Form.Input type=\"email\" />\n * </Form.Field>\n * <Form.Submit>Save</Form.Submit>\n * </Form.Root>\n * ```\n *\n * @example Render function for form state access\n * ```tsx\n * <Form.Root schema={userSchema} onSubmit={handleSubmit}>\n * {({ form, fields, isSubmitting }) => (\n * <>\n * <Form.Field name=\"email\" label=\"Email\" required>\n * <Form.Input type=\"email\" />\n * </Form.Field>\n * <Button\n * disabled={isSubmitting}\n * onClick={() => form.update({ value: { email: '' } })}\n * >\n * Cancel\n * </Button>\n * <Form.Submit>Save</Form.Submit>\n * </>\n * )}\n * </Form.Root>\n * ```\n */\nexport function FormRoot<T extends z.ZodType>({\n schema,\n children,\n onSubmit,\n action,\n method = 'POST',\n formComponent: FormComp = 'form',\n id,\n name,\n defaultValues,\n mode = 'onBlur',\n isSubmitting: externalIsSubmitting,\n onError,\n onSuccess,\n telemetry,\n className,\n}: FormRootProps<T>) {\n const [internalIsSubmitting, setInternalIsSubmitting] = React.useState(false)\n // Use external isSubmitting if provided, otherwise use internal state\n const isSubmitting = externalIsSubmitting ?? internalIsSubmitting\n const formRef = React.useRef<HTMLFormElement>(null)\n\n // Map mode to Conform's expected values\n const shouldValidate = mode === 'onChange' ? 'onInput' : mode\n\n const [form, fields] = useForm({\n id,\n constraint: getZodConstraint(schema),\n shouldValidate,\n shouldRevalidate: mode === 'onSubmit' ? 'onSubmit' : 'onInput',\n defaultValue: defaultValues as any,\n onValidate({ formData }) {\n return parseWithZod(formData, { schema }) as any\n },\n async onSubmit(event, { submission }) {\n const formName = name || id || 'unnamed-form'\n\n // Track form submission attempt\n telemetry?.onSubmit?.({ formName, formId: id })\n\n // If no onSubmit handler is provided, let React Router handle the submission\n // This allows the form to submit to the current route's action or a specified action\n if (!onSubmit) {\n // Set submitting state for UI feedback\n setInternalIsSubmitting(true)\n return\n }\n\n // Client-side submission - prevent default to handle it ourselves\n event.preventDefault()\n\n if (submission?.status === 'success') {\n setInternalIsSubmitting(true)\n try {\n await onSubmit(submission.value as z.infer<T>)\n onSuccess?.(submission.value as z.infer<T>)\n telemetry?.onSuccess?.({ formName, formId: id })\n }\n catch (error) {\n telemetry?.onError?.({ formName, formId: id, error: error as Error })\n telemetry?.captureError?.(error as Error, {\n message: `Form submission error: ${formName}`,\n tags: { 'form.name': formName, 'form.id': id || 'unknown' },\n })\n onError?.(error as z.ZodError<z.infer<T>>)\n }\n finally {\n setInternalIsSubmitting(false)\n }\n }\n else if (submission?.status === 'error') {\n // Track validation errors\n telemetry?.onValidationError?.({\n formName,\n formId: id,\n fieldErrors: (submission.error as Record<string, string[]>) ?? {},\n })\n\n if (onError) {\n // Handle validation errors\n const { ZodError } = await import('zod')\n const zodError = new ZodError(\n Object.entries(submission.error ?? {}).flatMap(([path, messages]) =>\n (messages ?? []).map(message => ({\n code: 'custom' as const,\n path: path.split('.'),\n message,\n })),\n ),\n )\n onError(zodError as z.ZodError<z.infer<T>>)\n }\n }\n },\n })\n\n const submit = React.useCallback(() => {\n formRef.current?.requestSubmit()\n }, [])\n\n const reset = React.useCallback(() => {\n form.reset()\n }, [form])\n\n const contextValue = React.useMemo(\n () => ({\n form: form as any,\n fields: fields as unknown as Record<string, any>,\n isSubmitting,\n submit,\n reset,\n formId: form.id,\n }),\n [form, fields, isSubmitting, submit, reset],\n )\n\n // Determine if children is a render function\n const isRenderFunction = typeof children === 'function'\n\n // Create render props for render function pattern\n const renderProps: FormRootRenderProps = React.useMemo(\n () => ({\n form: form as any,\n fields: fields as unknown as Record<string, any>,\n isSubmitting,\n submit,\n reset,\n }),\n [form, fields, isSubmitting, submit, reset],\n )\n\n // Render children - either as ReactNode or render function\n const renderChildren = () => {\n if (isRenderFunction) {\n return (children as (props: FormRootRenderProps) => React.ReactNode)(renderProps)\n }\n return children\n }\n\n // Extract Conform's onSubmit so we can wrap it with stopPropagation.\n // This prevents nested forms (e.g. Form.Dialog inside another form)\n // from triggering the parent form's Conform handler via React's\n // synthetic event bubbling through portals.\n const { onSubmit: conformOnSubmit, ...conformFormProps } = getFormProps(form)\n\n return (\n <FormProvider value={contextValue}>\n <ConformFormProvider context={form.context}>\n <FormComp\n ref={formRef}\n {...conformFormProps}\n onSubmit={(e: React.FormEvent<HTMLFormElement>) => {\n e.stopPropagation()\n conformOnSubmit(e)\n }}\n method={method}\n action={action}\n className={cn('space-y-6', className)}\n autoComplete=\"off\"\n >\n {renderChildren()}\n </FormComp>\n </ConformFormProvider>\n </FormProvider>\n )\n}\n\nFormRoot.displayName = 'Form.Root'\n","import type { FormSelectItemProps, FormSelectProps } from '../types'\nimport { useInputControl } from '@conform-to/react'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../../../base/select'\nimport { useFieldContext } from '../context/field-context'\n\n/**\n * Form.Select - Select dropdown component\n *\n * Automatically wired to the parent Form.Field context.\n *\n * @example\n * ```tsx\n * <Form.Field name=\"country\" label=\"Country\" required>\n * <Form.Select placeholder=\"Select a country\">\n * <Form.SelectItem value=\"us\">United States</Form.SelectItem>\n * <Form.SelectItem value=\"uk\">United Kingdom</Form.SelectItem>\n * <Form.SelectItem value=\"ca\">Canada</Form.SelectItem>\n * </Form.Select>\n * </Form.Field>\n * ```\n */\nexport function FormSelect({ placeholder, disabled, className, children }: FormSelectProps) {\n const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext()\n\n const control = useInputControl(fieldMeta as any)\n const isDisabled = disabled ?? fieldDisabled\n const hasErrors = errors && errors.length > 0\n\n // Ensure value is always a string for Select\n const selectValue = Array.isArray(control.value) ? control.value[0] : control.value\n\n return (\n <Select\n name={fieldMeta.name}\n value={selectValue ?? ''}\n onValueChange={control.change}\n disabled={isDisabled}\n >\n <SelectTrigger\n id={fieldMeta.id}\n aria-invalid={hasErrors || undefined}\n aria-describedby={hasErrors ? `${fieldMeta.id}-error` : undefined}\n className={cn(className)}\n >\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent>{children}</SelectContent>\n </Select>\n )\n}\n\nFormSelect.displayName = 'Form.Select'\n\n/**\n * Form.SelectItem - Individual select option\n *\n * @example\n * ```tsx\n * <Form.SelectItem value=\"option1\">Option 1</Form.SelectItem>\n * ```\n */\nexport function FormSelectItem({ value, children, disabled }: FormSelectItemProps) {\n return (\n <SelectItem value={value} disabled={disabled}>\n {children}\n </SelectItem>\n )\n}\n\nFormSelectItem.displayName = 'Form.SelectItem'\n","import type { FormSubmitProps } from '../types'\nimport { Button } from '../../..'\nimport { useFormContext } from '../context/form-context'\n\n/**\n * Form.Submit - Submit button with automatic loading state\n *\n * @example\n * ```tsx\n * <Form.Submit loadingText=\"Saving...\">\n * Save Changes\n * </Form.Submit>\n * ```\n */\nexport function FormSubmit({ children, loadingText, loading = false, ...props }: FormSubmitProps) {\n const { isSubmitting } = useFormContext()\n\n const isLoading = loading || isSubmitting\n\n return (\n <Button htmlType=\"submit\" disabled={props.disabled || isLoading} loading={isLoading} {...props}>\n {isLoading && loadingText ? loadingText : children}\n </Button>\n )\n}\n\nFormSubmit.displayName = 'Form.Submit'\n","import type { FormSwitchProps } from '../types'\nimport { useInputControl } from '@conform-to/react'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { Label } from '../../../base/label'\nimport { Switch } from '../../../base/switch'\nimport { useFieldContext } from '../context/field-context'\n\n/**\n * Form.Switch - Toggle switch component\n *\n * Automatically wired to the parent Form.Field context.\n *\n * @example\n * ```tsx\n * <Form.Field name=\"notifications\">\n * <Form.Switch label=\"Enable email notifications\" />\n * </Form.Field>\n * ```\n */\nexport function FormSwitch({ label, disabled, className }: FormSwitchProps) {\n const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext()\n\n const control = useInputControl(fieldMeta as any)\n const isDisabled = disabled ?? fieldDisabled\n const hasErrors = errors && errors.length > 0\n\n // Convert string value to boolean\n const isChecked = control.value === 'on' || control.value === 'true'\n\n const handleCheckedChange = (checked: boolean) => {\n control.change(checked ? 'on' : '')\n }\n\n const switchId = fieldMeta.id\n\n return (\n <div className={cn('flex items-center space-x-2', className)}>\n <Switch\n id={switchId}\n name={fieldMeta.name}\n checked={isChecked}\n onCheckedChange={handleCheckedChange}\n disabled={isDisabled}\n aria-invalid={hasErrors || undefined}\n aria-describedby={hasErrors ? `${fieldMeta.id}-error` : undefined}\n />\n {label && (\n <Label\n htmlFor={switchId}\n className={cn(\n 'cursor-pointer text-sm font-normal',\n isDisabled && 'cursor-not-allowed opacity-70',\n )}\n >\n {label}\n </Label>\n )}\n </div>\n )\n}\n\nFormSwitch.displayName = 'Form.Switch'\n","import type { FormTextareaProps } from '../types'\nimport { getTextareaProps } from '@conform-to/react'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { Textarea } from '../../../base/textarea'\nimport { useFieldContext } from '../context/field-context'\n\n/**\n * Form.Textarea - Multi-line text input component\n *\n * Automatically wired to the parent Form.Field context.\n *\n * @example\n * ```tsx\n * <Form.Field name=\"bio\" label=\"Bio\">\n * <Form.Textarea rows={4} placeholder=\"Tell us about yourself...\" />\n * </Form.Field>\n * ```\n */\nexport function FormTextarea({ ref, className, disabled, rows = 3, ...props }: FormTextareaProps & { ref?: React.RefObject<HTMLTextAreaElement | null> }) {\n const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext()\n\n const textareaProps = getTextareaProps(fieldMeta)\n const isDisabled = disabled ?? fieldDisabled\n const hasErrors = errors && errors.length > 0\n\n return (\n <Textarea\n ref={ref}\n {...textareaProps}\n {...props}\n rows={rows}\n disabled={isDisabled}\n aria-invalid={hasErrors || undefined}\n aria-describedby={hasErrors ? `${fieldMeta.id}-error` : undefined}\n className={cn(className)}\n />\n )\n}\n\nFormTextarea.displayName = 'Form.Textarea'\n","import { useInputControl } from '@conform-to/react'\nimport * as React from 'react'\nimport { useFormContext } from '../context/form-context'\n\n/**\n * Hook to watch a field's value\n * Triggers re-render when the watched field value changes\n *\n * @example\n * ```tsx\n * function ConditionalField() {\n * const contactMethod = useWatch('contactMethod');\n *\n * if (contactMethod === 'email') {\n * return <Form.Field name=\"email\"><Form.Input type=\"email\" /></Form.Field>;\n * }\n *\n * if (contactMethod === 'phone') {\n * return <Form.Field name=\"phone\"><Form.Input type=\"tel\" /></Form.Field>;\n * }\n *\n * return null;\n * }\n * ```\n */\nexport function useWatch<T = unknown>(name: string): T | undefined {\n const { fields } = useFormContext()\n\n // Get the field metadata - support nested paths\n const field = React.useMemo(() => {\n const parts = name.split('.')\n let current: any = fields\n\n for (const part of parts) {\n if (!current)\n break\n\n // Handle array access like \"items.0.name\"\n if (/^\\d+$/.test(part)) {\n const fieldList = current.getFieldList?.()\n if (fieldList) {\n const fieldset = fieldList[Number.parseInt(part, 10)]?.getFieldset?.()\n current = fieldset\n }\n else {\n current = current[part]\n }\n }\n else {\n // Try getFieldset for nested objects\n if (typeof current.getFieldset === 'function') {\n current = current.getFieldset()[part]\n }\n else {\n current = current[part]\n }\n }\n }\n\n return current\n }, [fields, name])\n\n // Use input control to get reactive value\n const control = useInputControl(field)\n\n return control.value as T | undefined\n}\n\n/**\n * Hook to watch multiple fields at once\n *\n * @example\n * ```tsx\n * function Summary() {\n * const values = useWatchAll(['firstName', 'lastName', 'email']);\n *\n * return (\n * <div>\n * Name: {values.firstName} {values.lastName}\n * Email: {values.email}\n * </div>\n * );\n * }\n * ```\n */\nexport function useWatchAll<T extends Record<string, unknown>>(names: string[]): Partial<T> {\n const { fields } = useFormContext()\n\n return React.useMemo(() => {\n const result: Record<string, unknown> = {}\n\n for (const name of names) {\n const parts = name.split('.')\n let current: any = fields\n\n for (const part of parts) {\n if (!current)\n break\n\n if (/^\\d+$/.test(part)) {\n const fieldList = current.getFieldList?.()\n if (fieldList) {\n const fieldset = fieldList[Number.parseInt(part, 10)]?.getFieldset?.()\n current = fieldset\n }\n else {\n current = current[part]\n }\n }\n else {\n if (typeof current.getFieldset === 'function') {\n current = current.getFieldset()[part]\n }\n else {\n current = current[part]\n }\n }\n }\n\n if (current) {\n result[name] = current.value\n }\n }\n\n return result as Partial<T>\n }, [fields, names])\n}\n","import type { FormWhenProps } from '../types'\nimport * as React from 'react'\nimport { useWatch } from '../hooks/use-watch'\n\n/**\n * Form.When - Conditional rendering based on field values\n *\n * Renders children only when the specified field matches the condition.\n *\n * @example\n * ```tsx\n * // Render when field equals value\n * <Form.When field=\"contactMethod\" is=\"email\">\n * <Form.Field name=\"email\"><Form.Input type=\"email\" /></Form.Field>\n * </Form.When>\n *\n * // Render when field does not equal value\n * <Form.When field=\"contactMethod\" isNot=\"none\">\n * <Form.Field name=\"contact\"><Form.Input /></Form.Field>\n * </Form.When>\n *\n * // Render when field value is in array\n * <Form.When field=\"role\" in={['admin', 'moderator']}>\n * <Form.Field name=\"permissions\"><Form.Input /></Form.Field>\n * </Form.When>\n *\n * // Render when field value is not in array\n * <Form.When field=\"status\" notIn={['archived', 'deleted']}>\n * <Form.Field name=\"actions\"><Form.Input /></Form.Field>\n * </Form.When>\n * ```\n */\nexport function FormWhen({ field, is, isNot, in: inArray, notIn, children }: FormWhenProps) {\n const value = useWatch(field)\n\n // Determine if we should render\n let shouldRender = true\n\n // Check \"is\" condition\n if (is !== undefined) {\n shouldRender = value === is\n }\n\n // Check \"isNot\" condition\n if (isNot !== undefined && shouldRender) {\n shouldRender = value !== isNot\n }\n\n // Check \"in\" condition\n if (inArray !== undefined && shouldRender) {\n shouldRender = inArray.includes(value)\n }\n\n // Check \"notIn\" condition\n if (notIn !== undefined && shouldRender) {\n shouldRender = !notIn.includes(value)\n }\n\n if (!shouldRender) {\n return null\n }\n\n return <>{children}</>\n}\n\nFormWhen.displayName = 'Form.When'\n","import type { VariantProps } from 'class-variance-authority'\nimport { Slot } from '@radix-ui/react-slot'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Button } from '@repo/shadcn/ui/button'\nimport * as Stepperize from '@stepperize/react'\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\n\nconst StepperContext = React.createContext<Stepper.ConfigProps | null>(null)\n\nfunction useStepperProvider(): Stepper.ConfigProps {\n const context = React.use(StepperContext)\n if (!context) {\n throw new Error('useStepper must be used within a StepperProvider.')\n }\n return context\n}\n\nconst classForNavigationList = cva('flex gap-2', {\n variants: {\n variant: {\n horizontal: 'flex-row items-center justify-between',\n vertical: 'flex-col',\n circle: 'flex-row items-center justify-between',\n },\n },\n})\n\nconst classForSeparator = cva(\n [\n 'bg-muted',\n 'data-[state=completed]:bg-primary data-[disabled]:opacity-50',\n 'transition-all duration-300 ease-in-out',\n ],\n {\n variants: {\n orientation: {\n horizontal: 'h-0.5 flex-1',\n vertical: 'h-full w-0.5',\n },\n labelOrientation: {\n vertical: 'absolute left-[calc(50%+30px)] right-[calc(-50%+20px)] top-5 block shrink-0',\n },\n },\n },\n)\n\nfunction defineStepper<const Steps extends Stepperize.Step[]>(...steps: Steps): Stepper.DefineProps<Steps> {\n const {\n Scoped,\n useStepper,\n steps: stepList,\n Stepper: StepperizePrimitives,\n } = Stepperize.defineStepper(...steps)\n\n const StepperContainer = ({\n children,\n className,\n ...props\n }: Omit<React.ComponentProps<'div'>, 'children'> & {\n children:\n | React.ReactNode\n | ((props: { methods: Stepperize.Stepper<Steps> }) => React.ReactNode)\n }) => {\n const methods = useStepper()\n\n return (\n <div date-component=\"stepper\" className={cn('w-full', className)} {...props}>\n {typeof children === 'function' ? children({ methods }) : children}\n </div>\n )\n }\n\n return {\n steps: stepList,\n useStepper,\n Stepper: {\n ...StepperizePrimitives,\n Provider: ({\n variant = 'horizontal',\n labelOrientation = 'horizontal',\n tracking = false,\n children,\n className,\n ...props\n }) => {\n return (\n <StepperContext value={{ variant, labelOrientation, tracking }}>\n <Scoped initialStep={props.initialStep} initialMetadata={props.initialMetadata}>\n <StepperContainer className={className} {...props}>\n {children}\n </StepperContainer>\n </Scoped>\n </StepperContext>\n )\n },\n Navigation: ({ children, 'aria-label': ariaLabel = 'Stepper Navigation', ...props }) => {\n const { variant } = useStepperProvider()\n return (\n <nav date-component=\"stepper-navigation\" aria-label={ariaLabel} role=\"tablist\" {...props}>\n <ol\n date-component=\"stepper-navigation-list\"\n className={classForNavigationList({ variant })}\n >\n {children}\n </ol>\n </nav>\n )\n },\n Step: ({ children, className, icon, ...props }) => {\n const { variant, labelOrientation } = useStepperProvider()\n const stepper = useStepper()\n\n const steps = stepList\n\n const stepIndex = stepper.lookup.getIndex(props.of)\n const step = steps[stepIndex]!\n const currentIndex = stepper.lookup.getIndex(stepper.state.current.data.id)\n\n const isLast = stepper.lookup.getLast().id === props.of\n const isActive = stepper.state.current.data.id === props.of\n\n const dataState = getStepState(currentIndex, stepIndex)\n const childMap = useStepChildren(children)\n\n const title = childMap.get('title')\n const description = childMap.get('description')\n const panel = childMap.get('panel')\n\n if (variant === 'circle') {\n return (\n <li\n date-component=\"stepper-step\"\n className={cn(\n 'flex shrink-0 items-center gap-4 rounded-md transition-colors',\n className,\n )}\n >\n <CircleStepIndicator currentStep={stepIndex + 1} totalSteps={steps.length} />\n <div\n date-component=\"stepper-step-content\"\n className=\"flex flex-col items-start gap-1\"\n >\n {title}\n {description}\n </div>\n </li>\n )\n }\n\n return (\n <>\n <li\n date-component=\"stepper-step\"\n className={cn([\n 'group peer relative flex items-center gap-2',\n 'data-[variant=vertical]:flex-row',\n 'data-[label-orientation=vertical]:w-full',\n 'data-[label-orientation=vertical]:flex-col',\n 'data-[label-orientation=vertical]:justify-center',\n ])}\n data-variant={variant}\n data-label-orientation={labelOrientation}\n data-state={dataState}\n data-disabled={props.disabled}\n >\n <Button\n id={`step-${step.id}`}\n date-component=\"stepper-step-indicator\"\n type=\"button\"\n role=\"tab\"\n tabIndex={dataState !== 'inactive' ? 0 : -1}\n className={cn('rounded-full', className)}\n variant={dataState !== 'inactive' ? 'default' : 'secondary'}\n size=\"icon\"\n aria-controls={`step-panel-${props.of}`}\n aria-current={isActive ? 'step' : undefined}\n aria-posinset={stepIndex + 1}\n aria-setsize={steps.length}\n aria-selected={isActive}\n onKeyDown={e =>\n onStepKeyDown(\n e,\n stepper.lookup.getNext(props.of),\n stepper.lookup.getPrev(props.of),\n )}\n {...props}\n >\n {icon ?? stepIndex + 1}\n </Button>\n {variant === 'horizontal' && labelOrientation === 'vertical' && (\n <StepperSeparator\n orientation=\"horizontal\"\n labelOrientation={labelOrientation}\n isLast={isLast}\n state={dataState}\n disabled={props.disabled}\n />\n )}\n <div date-component=\"stepper-step-content\" className=\"flex flex-col items-start\">\n {title}\n {description}\n </div>\n </li>\n\n {variant === 'horizontal' && labelOrientation === 'horizontal' && (\n <StepperSeparator\n orientation=\"horizontal\"\n isLast={isLast}\n state={dataState}\n disabled={props.disabled}\n />\n )}\n\n {variant === 'vertical' && (\n <div className=\"flex gap-4\">\n {!isLast && (\n <div className=\"flex justify-center ps-[calc(var(--spacing)_*_4.5_-_1px)]\">\n <StepperSeparator\n orientation=\"vertical\"\n isLast={isLast}\n state={dataState}\n disabled={props.disabled}\n />\n </div>\n )}\n <div className=\"my-3 flex-1 ps-4\">{panel}</div>\n </div>\n )}\n </>\n )\n },\n Title,\n Description,\n Panel: ({ children, asChild, ...props }) => {\n const Comp = asChild ? Slot : 'div'\n const { tracking } = useStepperProvider()\n\n return (\n <Comp\n date-component=\"stepper-step-panel\"\n ref={node => scrollIntoStepperPanel(node, tracking)}\n {...props}\n >\n {children}\n </Comp>\n )\n },\n Controls: ({ children, className, asChild, ...props }) => {\n const Comp = asChild ? Slot : 'div'\n return (\n <Comp\n date-component=\"stepper-controls\"\n className={cn('flex justify-end gap-4', className)}\n {...props}\n >\n {children}\n </Comp>\n )\n },\n },\n }\n}\n\nfunction Title({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<'h4'> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'h4'\n\n return (\n <Comp\n date-component=\"stepper-step-title\"\n className={cn('text-base font-medium', className)}\n {...props}\n >\n {children}\n </Comp>\n )\n}\n\nfunction Description({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<'p'> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'p'\n\n return (\n <Comp\n date-component=\"stepper-step-description\"\n className={cn('text-muted-foreground text-sm', className)}\n {...props}\n >\n {children}\n </Comp>\n )\n}\n\nfunction StepperSeparator({\n orientation,\n isLast,\n labelOrientation,\n state,\n disabled,\n}: {\n isLast: boolean\n state: string\n disabled?: boolean\n} & VariantProps<typeof classForSeparator>) {\n if (isLast) {\n return null\n }\n return (\n <div\n date-component=\"stepper-separator\"\n data-orientation={orientation}\n data-state={state}\n data-disabled={disabled}\n role=\"separator\"\n tabIndex={-1}\n className={classForSeparator({ orientation, labelOrientation })}\n />\n )\n}\n\nfunction CircleStepIndicator({\n currentStep,\n totalSteps,\n size = 80,\n strokeWidth = 6,\n}: Stepper.CircleStepIndicatorProps) {\n const radius = (size - strokeWidth) / 2\n const circumference = radius * 2 * Math.PI\n const fillPercentage = (currentStep / totalSteps) * 100\n const dashOffset = circumference - (circumference * fillPercentage) / 100\n return (\n <div\n date-component=\"stepper-step-indicator\"\n role=\"progressbar\"\n aria-valuenow={currentStep}\n aria-valuemin={1}\n aria-valuemax={totalSteps}\n tabIndex={-1}\n className=\"relative inline-flex items-center justify-center\"\n >\n <svg width={size} height={size}>\n <title>Step Indicator</title>\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n className=\"text-muted-foreground\"\n />\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeDasharray={circumference}\n strokeDashoffset={dashOffset}\n className=\"text-primary transition-all duration-300 ease-in-out\"\n transform={`rotate(-90 ${size / 2} ${size / 2})`}\n />\n </svg>\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <span className=\"text-sm font-medium\" aria-live=\"polite\">\n {currentStep}\n {' '}\n of\n {totalSteps}\n </span>\n </div>\n </div>\n )\n}\n\nfunction scrollIntoStepperPanel(node: HTMLDivElement | null, tracking?: boolean) {\n if (tracking) {\n node?.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n}\n\nfunction useStepChildren(children: React.ReactNode) {\n return React.useMemo(() => extractChildren(children), [children])\n}\n\nfunction extractChildren(children: React.ReactNode) {\n const childrenArray = React.Children.toArray(children)\n const map = new Map<string, React.ReactNode>()\n\n for (const child of childrenArray) {\n if (React.isValidElement(child)) {\n if (child.type === Title) {\n map.set('title', child)\n }\n else if (child.type === Description) {\n map.set('description', child)\n }\n else {\n map.set('panel', child)\n }\n }\n }\n\n return map\n}\n\nfunction onStepKeyDown(e: React.KeyboardEvent<HTMLButtonElement>, nextStep: Stepperize.Step, prevStep: Stepperize.Step) {\n const { key } = e\n const directions = {\n next: ['ArrowRight', 'ArrowDown'],\n prev: ['ArrowLeft', 'ArrowUp'],\n }\n\n if (directions.next.includes(key) || directions.prev.includes(key)) {\n const direction = directions.next.includes(key) ? 'next' : 'prev'\n const step = direction === 'next' ? nextStep : prevStep\n\n if (!step) {\n return\n }\n\n const stepElement = document.getElementById(`step-${step.id}`)\n if (!stepElement) {\n return\n }\n\n const isActive = stepElement.parentElement?.getAttribute('data-state') !== 'inactive'\n if (isActive || direction === 'prev') {\n stepElement.focus()\n }\n }\n}\n\nfunction getStepState(currentIndex: number, stepIndex: number) {\n if (currentIndex === stepIndex) {\n return 'active'\n }\n if (currentIndex > stepIndex) {\n return 'completed'\n }\n return 'inactive'\n}\n\n// eslint-disable-next-line ts/no-namespace\nnamespace Stepper {\n export type StepperVariant = 'horizontal' | 'vertical' | 'circle'\n export type StepperLabelOrientation = 'horizontal' | 'vertical'\n\n export interface ConfigProps {\n variant?: StepperVariant\n labelOrientation?: StepperLabelOrientation\n tracking?: boolean\n }\n\n export type DefineProps<Steps extends Stepperize.Step[]> = Omit<\n Stepperize.StepperReturn<Steps>,\n 'Scoped'\n > & {\n Stepper: {\n Provider: (\n props: Omit<Stepperize.ScopedProps<Steps>, 'children'>\n & Omit<React.ComponentProps<'div'>, 'children'>\n & Stepper.ConfigProps & {\n children:\n | React.ReactNode\n | ((props: { methods: Stepperize.Stepper<Steps> }) => React.ReactNode)\n },\n ) => React.ReactElement\n Navigation: (props: React.ComponentProps<'nav'>) => React.ReactElement\n Step: (\n props: React.ComponentProps<'button'> & {\n of: Stepperize.Get.Id<Steps>\n icon?: React.ReactNode\n variant?: 'default' | 'secondary'\n },\n ) => React.ReactElement\n Title: (props: AsChildProps<'h4'>) => React.ReactElement\n Description: (props: AsChildProps<'p'>) => React.ReactElement\n Panel: (props: AsChildProps<'div'>) => React.ReactElement\n Controls: (props: AsChildProps<'div'>) => React.ReactElement\n }\n }\n\n export interface CircleStepIndicatorProps {\n currentStep: number\n totalSteps: number\n size?: number\n strokeWidth?: number\n }\n}\n\ntype AsChildProps<T extends React.ElementType> = React.ComponentProps<T> & {\n asChild?: boolean\n}\n\nexport { defineStepper }\n","import type * as Stepperize from '@stepperize/react'\nimport type { FormStepperProps, FormStepperRenderProps, StepConfig } from '../../types'\nimport { FormProvider as ConformFormProvider, getFormProps, useForm } from '@conform-to/react'\nimport { getZodConstraint, parseWithZod } from '@conform-to/zod/v4'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { defineStepper } from '../../../stepper'\nimport { FormProvider } from '../../context/form-context'\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface FormStepperContextValue {\n /** All step configurations */\n steps: StepConfig[]\n /** Current step config */\n current: StepConfig\n /** Current step index */\n currentIndex: number\n /** Go to next step */\n next: () => void\n /** Go to previous step */\n prev: () => void\n /** Go to specific step by ID */\n goTo: (stepId: string) => void\n /** Whether current step is first */\n isFirst: boolean\n /** Whether current step is last */\n isLast: boolean\n /** Get metadata for a specific step */\n getStepData: (stepId: string) => Record<string, unknown> | undefined\n /** Get all metadata from all steps */\n getAllStepData: () => Record<string, unknown>\n /** Stepperize utils */\n utils: {\n getIndex: (id: string) => number\n }\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst FormStepperContext = React.createContext<FormStepperContextValue | null>(null)\n\nexport function useFormStepperContext(): FormStepperContextValue {\n const context = React.use(FormStepperContext)\n if (!context) {\n throw new Error('useFormStepperContext must be used within a Form.Stepper component')\n }\n return context\n}\n\n// ============================================================================\n// Schema Utilities\n// ============================================================================\n\n/**\n * Recursively unwrap ZodIntersection (from .and()) to extract the base ZodObject.\n *\n * Zod v4 schema types use `def.type` as a string discriminant:\n * - \"intersection\" (from .and()): merge left + right base objects\n * - \"object\": return directly\n *\n * Note: In Zod v4, .superRefine() and .refine() return `this` (no wrapper),\n * so only ZodIntersection needs unwrapping.\n */\nfunction getBaseObject(schema: z.ZodType): z.ZodObject<any> {\n if (schema.def.type === 'intersection') {\n // Zod v4's `def` is typed as an opaque union; cast to access `left`/`right` branches.\n const intersectionDef = schema.def as unknown as { left: z.ZodType, right: z.ZodType }\n const left = getBaseObject(intersectionDef.left)\n const right = getBaseObject(intersectionDef.right)\n return left.merge(right)\n }\n\n if (schema.def.type !== 'object') {\n console.warn(\n `mergeSchemas: expected ZodObject or ZodIntersection but got \"${schema.def.type}\". `\n + 'Falling back to empty object.',\n )\n return z.object({})\n }\n\n return schema as z.ZodObject<any>\n}\n\n/**\n * Merge multiple zod schemas into one ZodObject for HTML constraint generation.\n * Handles ZodIntersection (.and()) by unwrapping to base ZodObject shapes.\n * Per-step validation still uses the original schemas with all refinements intact.\n */\nfunction mergeSchemas(steps: StepConfig[]): z.ZodObject<any> {\n if (steps.length === 0) {\n throw new Error('Form.Stepper requires at least one step')\n }\n\n return steps.reduce((acc, step, index) => {\n const base = getBaseObject(step.schema)\n\n if (index === 0) {\n return base\n }\n\n return acc.merge(base)\n }, {} as z.ZodObject<any>)\n}\n\n/**\n * Convert StepConfig[] to Stepperize step format\n */\nfunction toStepperizeSteps(steps: StepConfig[]): Stepperize.Step[] {\n return steps.map(step => ({\n id: step.id,\n label: step.label,\n description: step.description,\n })) as Stepperize.Step[]\n}\n\n// ============================================================================\n// FormStepper Component\n// ============================================================================\n\n/**\n * Form.Stepper - Multi-step form container\n *\n * Uses Stepperize internally for step navigation and a single Conform form\n * instance for all steps. Schemas are auto-merged for unified validation.\n *\n * @example\n * ```tsx\n * const steps = [\n * { id: 'account', label: 'Account', schema: accountSchema },\n * { id: 'profile', label: 'Profile', schema: profileSchema },\n * ];\n *\n * <Form.Stepper steps={steps} onComplete={handleComplete}>\n * <Form.StepperNavigation />\n *\n * <Form.Step id=\"account\">\n * <Form.Field name=\"email\" label=\"Email\" required>\n * <Form.Input type=\"email\" />\n * </Form.Field>\n * </Form.Step>\n *\n * <Form.Step id=\"profile\">\n * <Form.Field name=\"name\" label=\"Full Name\" required>\n * <Form.Input />\n * </Form.Field>\n * </Form.Step>\n *\n * <Form.StepperControls />\n * </Form.Stepper>\n * ```\n */\nexport function FormStepper({\n steps,\n children,\n onComplete,\n onStepChange,\n initialStep,\n className,\n defaultValues,\n id,\n formComponent,\n}: FormStepperProps & {\n defaultValues?: Record<string, unknown>\n id?: string\n formComponent?: React.ElementType\n}) {\n // Create stepperize definition - memoized to prevent recreation\n const stepperDef = React.useMemo(() => {\n const stepperizeSteps = toStepperizeSteps(steps)\n return defineStepper(...stepperizeSteps)\n }, [steps])\n\n // Determine initial step index\n const initialStepIndex = React.useMemo(() => {\n if (!initialStep)\n return undefined\n const index = steps.findIndex(s => s.id === initialStep)\n return index >= 0 ? steps[index]!.id : undefined\n }, [initialStep, steps])\n\n const { Stepper } = stepperDef\n\n // Note: initialStep is handled by Stepperize's Scoped component internally\n const providerProps = initialStepIndex ? { initialStep: initialStepIndex as any } : {}\n\n return (\n // eslint-disable-next-line react/no-context-provider -- Stepperize's Stepper is not a React Context; .Provider is required\n <Stepper.Provider {...providerProps}>\n <FormStepperContent\n steps={steps}\n stepperDef={stepperDef}\n onComplete={onComplete}\n onStepChange={onStepChange}\n className={className}\n defaultValues={defaultValues}\n id={id}\n formComponent={formComponent}\n >\n {children}\n </FormStepperContent>\n </Stepper.Provider>\n )\n}\n\nFormStepper.displayName = 'Form.Stepper'\n\n// ============================================================================\n// FormStepperContent - Internal component with access to Stepperize context\n// ============================================================================\n\ninterface FormStepperContentProps {\n steps: StepConfig[]\n stepperDef: ReturnType<typeof defineStepper>\n children: React.ReactNode | ((props: FormStepperRenderProps) => React.ReactNode)\n onComplete: FormStepperProps['onComplete']\n onStepChange?: FormStepperProps['onStepChange']\n className?: string\n defaultValues?: Record<string, unknown>\n id?: string\n formComponent?: React.ElementType\n}\n\nfunction FormStepperContent({\n steps,\n stepperDef,\n children,\n onComplete,\n onStepChange,\n className,\n defaultValues,\n id,\n formComponent,\n}: FormStepperContentProps) {\n const { useStepper } = stepperDef\n const stepper = useStepper()\n\n // Find current step config\n const currentStepConfig = React.useMemo(\n () => steps.find(s => s.id === stepper.state.current.data.id) ?? steps[0]!,\n [steps, stepper.state.current.data.id],\n )\n\n // Merge all schemas into one combined schema\n const combinedSchema = React.useMemo(() => mergeSchemas(steps), [steps])\n\n // Collect all stored metadata as default values\n const storedValues = React.useMemo(() => {\n const allMetadata = steps.reduce(\n (acc, step) => ({\n ...acc,\n ...(stepper.metadata.get(step.id as any) || {}),\n }),\n {},\n )\n return { ...defaultValues, ...allMetadata }\n }, [steps, stepper, defaultValues, stepper.state.current.data.id]) // Include current.id to recompute on step change\n\n return (\n <StepForm\n key={stepper.state.current.data.id} // Force remount on step change\n steps={steps}\n stepper={stepper}\n currentStepConfig={currentStepConfig}\n combinedSchema={combinedSchema}\n storedValues={storedValues}\n onComplete={onComplete}\n onStepChange={onStepChange}\n className={className}\n id={id}\n formComponent={formComponent}\n >\n {children}\n </StepForm>\n )\n}\n\n// ============================================================================\n// StepForm - Keyed component that recreates form on step change\n// ============================================================================\n\ninterface StepFormProps {\n steps: StepConfig[]\n stepper: any\n currentStepConfig: StepConfig\n combinedSchema: z.ZodObject<any>\n storedValues: Record<string, unknown>\n children: React.ReactNode | ((props: FormStepperRenderProps) => React.ReactNode)\n onComplete: FormStepperProps['onComplete']\n onStepChange?: FormStepperProps['onStepChange']\n className?: string\n id?: string\n formComponent?: React.ElementType\n}\n\nfunction StepForm({\n steps,\n stepper,\n currentStepConfig,\n combinedSchema,\n storedValues,\n children,\n onComplete,\n onStepChange,\n className,\n id,\n formComponent: FormComp = 'form',\n}: StepFormProps) {\n const [isSubmitting, setIsSubmitting] = React.useState(false)\n const formRef = React.useRef<HTMLFormElement>(null)\n\n // Single form instance - recreated when this component remounts (step changes)\n const [form, fields] = useForm({\n id: id ?? 'stepper-form',\n constraint: getZodConstraint(combinedSchema),\n shouldValidate: 'onBlur',\n shouldRevalidate: 'onInput',\n defaultValue: storedValues as Record<string, string | null | undefined>,\n onValidate({ formData }) {\n // Validate against current step's schema only (for per-step validation)\n const result = parseWithZod(formData, { schema: currentStepConfig.schema })\n return result as any\n },\n async onSubmit(event, { submission }) {\n event.preventDefault()\n\n if (submission?.status !== 'success') {\n return\n }\n\n // Store current step's validated data in metadata\n if (submission.value) {\n stepper.metadata.set(\n stepper.state.current.data.id as any,\n submission.value as Record<string, unknown>,\n )\n }\n\n if (stepper.state.isLast) {\n // Final step - collect all metadata and complete\n setIsSubmitting(true)\n try {\n const allData = steps.reduce(\n (acc, step) => ({\n ...acc,\n ...(stepper.metadata.get(step.id as any) || {}),\n }),\n {},\n )\n // Include current submission value to ensure latest data\n const finalData = { ...allData, ...(submission.value as Record<string, unknown>) }\n\n await onComplete(finalData)\n }\n catch (error) {\n console.error('Stepper form completion error:', error)\n }\n finally {\n setIsSubmitting(false)\n }\n }\n else {\n // Move to next step\n const nextStepId = stepper.lookup.getNext(stepper.state.current.data.id as any)?.id\n if (nextStepId) {\n stepper.navigation.goTo(nextStepId as any)\n onStepChange?.(nextStepId, 'next')\n }\n }\n },\n })\n\n // Navigation helpers\n const next = React.useCallback(() => {\n // Trigger form submission which will validate and advance\n formRef.current?.requestSubmit()\n }, [])\n\n const prev = React.useCallback(() => {\n // Before going back, save current form data to metadata (without validation)\n if (formRef.current) {\n const formData = new FormData(formRef.current)\n const currentData: Record<string, unknown> = {}\n formData.forEach((value, key) => {\n if (!key.startsWith('$')) {\n currentData[key] = value\n }\n })\n if (Object.keys(currentData).length > 0) {\n stepper.metadata.set(stepper.state.current.data.id as any, currentData)\n }\n }\n\n const prevStepId = stepper.lookup.getPrev(stepper.state.current.data.id as any)?.id\n if (prevStepId) {\n stepper.navigation.goTo(prevStepId as any)\n onStepChange?.(prevStepId, 'prev')\n }\n }, [stepper, onStepChange])\n\n const goTo = React.useCallback(\n (stepId: string) => {\n const currentIndex = stepper.lookup.getIndex(stepper.state.current.data.id as any)\n const targetIndex = stepper.lookup.getIndex(stepId as any)\n\n // Only allow going back without validation\n if (targetIndex < currentIndex) {\n stepper.navigation.goTo(stepId as any)\n onStepChange?.(stepId, 'prev')\n }\n // Going forward requires validation - use next() instead\n },\n [stepper, onStepChange],\n )\n\n // Helper to get step data from metadata\n const getStepData = React.useCallback(\n (stepId: string) => stepper.metadata.get(stepId as any) as Record<string, unknown> | undefined,\n [stepper],\n )\n\n // Helper to get all step data\n const getAllStepData = React.useCallback(() => {\n return steps.reduce(\n (acc, step) => ({\n ...acc,\n ...(stepper.metadata.get(step.id as any) || {}),\n }),\n {},\n )\n }, [steps, stepper])\n\n // Build context value\n const stepperContextValue: FormStepperContextValue = React.useMemo(\n () => ({\n steps,\n current: currentStepConfig,\n currentIndex: stepper.lookup.getIndex(stepper.state.current.data.id as any),\n next,\n prev,\n goTo,\n isFirst: stepper.state.isFirst,\n isLast: stepper.state.isLast,\n getStepData,\n getAllStepData,\n utils: {\n getIndex: (id: string) => stepper.lookup.getIndex(id as any),\n },\n }),\n [steps, currentStepConfig, stepper, next, prev, goTo, getStepData, getAllStepData],\n )\n\n // Form context value\n const formContextValue = React.useMemo(\n () => ({\n form: form as any,\n fields: fields as unknown as Record<string, any>,\n isSubmitting,\n submit: () => formRef.current?.requestSubmit(),\n reset: () => form.reset(),\n formId: form.id,\n }),\n [form, fields, isSubmitting],\n )\n\n // Build render props for children function\n const renderProps: FormStepperRenderProps = {\n steps,\n current: currentStepConfig,\n currentIndex: stepper.lookup.getIndex(stepper.state.current.data.id as any),\n next,\n prev,\n goTo,\n isFirst: stepper.state.isFirst,\n isLast: stepper.state.isLast,\n getStepData,\n getAllStepData,\n }\n\n // Resolve children - support both ReactNode and render function\n const resolvedChildren = typeof children === 'function' ? children(renderProps) : children\n\n return (\n <FormStepperContext value={stepperContextValue}>\n <FormProvider value={formContextValue}>\n <ConformFormProvider context={form.context}>\n <FormComp\n ref={formRef}\n {...getFormProps(form)}\n method=\"POST\"\n className={cn('space-y-6', className)}\n autoComplete=\"off\"\n >\n {resolvedChildren}\n </FormComp>\n </ConformFormProvider>\n </FormProvider>\n </FormStepperContext>\n )\n}\n","import type { FormStepProps } from '../../types'\nimport * as React from 'react'\nimport { useFormStepperContext } from './form-stepper'\n\n/**\n * Form.Step - Individual step content container\n *\n * Only renders its children when the step is active.\n * Works with the single-form architecture - fields remain registered\n * even when unmounted, preserving their values.\n *\n * @example\n * ```tsx\n * <Form.Step id=\"account\">\n * <Form.Field name=\"email\" label=\"Email\" required>\n * <Form.Input type=\"email\" />\n * </Form.Field>\n * </Form.Step>\n * ```\n */\nexport function FormStep({ id, children }: FormStepProps) {\n const { current } = useFormStepperContext()\n\n // Only render if this step is active\n if (current.id !== id) {\n return null\n }\n\n return <>{children}</>\n}\n\nFormStep.displayName = 'Form.Step'\n","import type { StepperControlsProps } from '../../types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { Button } from '../../../..'\nimport { useFormContext } from '../../context/form-context'\nimport { useFormStepperContext } from './form-stepper'\n\n/**\n * Form.StepperControls - Navigation buttons (Previous/Next/Submit)\n *\n * Provides Previous and Next/Submit buttons for navigating between steps.\n * The Next button triggers form validation before advancing.\n * The Previous button navigates back without validation.\n *\n * @example\n * ```tsx\n * <Form.StepperControls\n * prevLabel={(isFirst) => isFirst ? 'Cancel' : 'Previous'}\n * nextLabel={(isLast) => isLast ? 'Submit' : 'Next'}\n * loadingText=\"Creating...\"\n * onCancel={() => setOpen(false)}\n * />\n * ```\n *\n * @example With external loading state\n * ```tsx\n * <Form.StepperControls\n * loading={fetcher.state === 'submitting'}\n * disabled={!isValid}\n * loadingText=\"Saving...\"\n * />\n * ```\n */\nexport function StepperControls({\n prevLabel = 'Previous',\n nextLabel = (isLast: boolean) => (isLast ? 'Submit' : 'Next'),\n loadingText = 'Submitting...',\n showPrev = true,\n loading,\n disabled,\n onPrev,\n onCancel,\n className,\n}: StepperControlsProps) {\n const { prev, isFirst, isLast } = useFormStepperContext()\n const { isSubmitting: formIsSubmitting } = useFormContext()\n\n // Use external loading state if provided, otherwise use internal form state\n const isLoading = loading ?? formIsSubmitting\n const isDisabled = disabled ?? false\n\n const getPrevLabel = () => {\n if (typeof prevLabel === 'function') {\n return prevLabel(isFirst)\n }\n return prevLabel\n }\n\n const getNextLabel = () => {\n if (typeof nextLabel === 'function') {\n return nextLabel(isLast)\n }\n return nextLabel\n }\n\n const handlePrev = () => {\n if (isFirst && onCancel) {\n onCancel()\n }\n else {\n onPrev?.()\n prev()\n }\n }\n\n return (\n <div className={cn('flex items-center justify-between gap-3', className)}>\n <div>\n {showPrev && (\n <Button\n htmlType=\"button\"\n type=\"quaternary\"\n theme=\"outline\"\n size=\"small\"\n onClick={handlePrev}\n disabled={isLoading || isDisabled}\n >\n {getPrevLabel()}\n </Button>\n )}\n </div>\n\n <Button\n htmlType=\"submit\"\n type=\"primary\"\n size=\"small\"\n loading={isLoading}\n disabled={isLoading || isDisabled}\n >\n {isLoading && isLast ? loadingText : getNextLabel()}\n </Button>\n </div>\n )\n}\n\nStepperControls.displayName = 'Form.StepperControls'\n","import type { StepperNavigationProps } from '../../types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { CheckIcon } from 'lucide-react'\nimport * as React from 'react'\nimport { useFormStepperContext } from './form-stepper'\n\n/**\n * Form.StepperNavigation - Step indicators/progress\n *\n * Displays visual step indicators showing current progress through the form.\n * Supports horizontal and vertical variants with optional label orientation.\n *\n * @example\n * ```tsx\n * <Form.StepperNavigation variant=\"horizontal\" labelOrientation=\"vertical\" />\n * ```\n */\nexport function StepperNavigation({\n variant = 'horizontal',\n labelOrientation = 'vertical',\n className,\n}: StepperNavigationProps) {\n const { steps, currentIndex } = useFormStepperContext()\n\n if (variant === 'horizontal' && labelOrientation === 'vertical') {\n // Horizontal with vertical labels - use relative positioning for connector\n return (\n <nav\n aria-label=\"Form steps\"\n className={cn('flex flex-row items-start justify-between', className)}\n >\n {steps.map((step, index) => {\n const isActive = index === currentIndex\n const isCompleted = index < currentIndex\n const isLast = index === steps.length - 1\n\n return (\n <div key={step.id} className=\"relative flex flex-1 flex-col items-center\">\n {/* Connector line - positioned absolutely between circles */}\n {!isLast && (\n <div className=\"bg-stepper-line absolute top-4 right-[calc(-50%+20px)] left-[calc(50%+20px)] h-0.5\" />\n )}\n\n {/* Step indicator */}\n <div\n className={cn(\n 'relative z-10 flex h-8 w-8 items-center justify-center rounded-full border bg-transparent text-sm font-medium transition-colors',\n isActive && 'border-primary bg-primary text-primary-foreground',\n isCompleted && 'border-tertiary-foreground bg-tertiary-foreground text-tertiary',\n !isActive && !isCompleted && 'border-stepper-label text-stepper-label',\n )}\n aria-current={isActive ? 'step' : undefined}\n >\n {isCompleted ? <CheckIcon className=\"text-tertiary h-4 w-4\" /> : index + 1}\n </div>\n\n {/* Label */}\n <div className=\"mt-1\">\n <span\n className={cn(\n 'text-xs font-medium',\n isActive && 'text-foreground',\n isCompleted && 'text-stepper-label',\n !isActive && !isCompleted && 'text-stepper-label',\n )}\n >\n {step.label}\n </span>\n {step.description && (\n <p className=\"text-muted-foreground mt-0.5 text-xs\">{step.description}</p>\n )}\n </div>\n </div>\n )\n })}\n </nav>\n )\n }\n\n if (variant === 'horizontal') {\n // Horizontal with horizontal labels\n return (\n <nav aria-label=\"Form steps\" className={cn('flex flex-row items-center', className)}>\n {steps.map((step, index) => {\n const isActive = index === currentIndex\n const isCompleted = index < currentIndex\n const isLast = index === steps.length - 1\n\n return (\n <React.Fragment key={step.id}>\n <div className=\"flex items-center\">\n {/* Step indicator */}\n <div\n className={cn(\n 'flex h-8 w-8 items-center justify-center rounded-full border text-sm font-medium transition-colors',\n isActive && 'border-primary bg-primary text-primary-foreground',\n isCompleted\n && 'border-tertiary-foreground bg-tertiary-foreground text-tertiary',\n !isActive && !isCompleted && 'border-stepper-label text-stepper-label',\n )}\n aria-current={isActive ? 'step' : undefined}\n >\n {isCompleted ? <CheckIcon className=\"text-tertiary size-4\" /> : index + 1}\n </div>\n\n {/* Label */}\n <div className=\"ml-2\">\n <span\n className={cn(\n 'text-sm font-medium',\n isActive && 'text-foreground',\n isCompleted && 'text-stepper-label',\n !isActive && !isCompleted && 'text-stepper-label',\n )}\n >\n {step.label}\n </span>\n </div>\n </div>\n\n {/* Connector line */}\n {!isLast && <div className=\"bg-stepper-line mx-4 h-0.5 min-w-8 flex-1\" />}\n </React.Fragment>\n )\n })}\n </nav>\n )\n }\n\n // Vertical variant\n return (\n <nav aria-label=\"Form steps\" className={cn('flex flex-col', className)}>\n {steps.map((step, index) => {\n const isActive = index === currentIndex\n const isCompleted = index < currentIndex\n const isLast = index === steps.length - 1\n\n return (\n <div key={step.id} className=\"flex flex-row\">\n <div className=\"flex flex-col items-center\">\n {/* Step indicator */}\n <div\n className={cn(\n 'flex h-8 w-8 items-center justify-center rounded-full border text-sm font-medium transition-colors',\n isActive && 'border-primary bg-primary text-primary-foreground',\n isCompleted && 'border-tertiary-foreground bg-tertiary-foreground text-tertiary',\n !isActive && !isCompleted && 'border-stepper-label text-stepper-label',\n )}\n aria-current={isActive ? 'step' : undefined}\n >\n {isCompleted ? <CheckIcon className=\"text-tertiary size-4\" /> : index + 1}\n </div>\n\n {/* Connector line */}\n {!isLast && <div className=\"bg-stepper-line my-1 min-h-8 w-0.5 flex-1\" />}\n </div>\n\n {/* Label */}\n <div className=\"ml-3 pb-8\">\n <span\n className={cn(\n 'text-sm font-medium',\n isActive && 'text-foreground',\n isCompleted && 'text-stepper-label',\n !isActive && !isCompleted && 'text-stepper-label',\n )}\n >\n {step.label}\n </span>\n {step.description && (\n <p className=\"text-muted-foreground mt-0.5 text-xs\">{step.description}</p>\n )}\n </div>\n </div>\n )\n })}\n </nav>\n )\n}\n\nStepperNavigation.displayName = 'Form.StepperNavigation'\n","import { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\n\nexport interface InputWithAddonsProps extends React.InputHTMLAttributes<HTMLInputElement> {\n leading?: React.ReactNode\n trailing?: React.ReactNode\n containerClassName?: string\n}\n\nfunction InputWithAddons({ ref, leading, trailing, containerClassName, className, ...props }: InputWithAddonsProps & { ref?: React.RefObject<HTMLInputElement | null> }) {\n return (\n <div\n className={cn(\n 'border-input-border bg-input-background/50 text-input-foreground placeholder:text-input-placeholder',\n 'focus-within:border-input-focus-border focus-within:shadow-(--input-focus-shadow)',\n 'group flex h-10 w-full items-stretch overflow-hidden rounded-lg border transition-all',\n 'focus-within:ring-0 focus-within:ring-offset-0 focus-within:outline-hidden',\n\n containerClassName,\n )}\n >\n {leading\n ? (\n <div className=\"text-muted-foreground flex items-center bg-transparent pl-3\">\n {leading}\n </div>\n )\n : null}\n <input\n className={cn(\n 'flex-1 bg-transparent px-3 text-base md:text-sm',\n 'placeholder:text-input-placeholder text-input-foreground',\n 'focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:outline-hidden',\n 'focus-visible:border-transparent focus-visible:shadow-none',\n 'read-only:cursor-not-allowed read-only:opacity-50 disabled:cursor-not-allowed disabled:opacity-50',\n 'file:text-foreground file:border-0 file:bg-transparent file:text-sm file:font-medium',\n leading && 'pl-2',\n trailing && 'pr-2',\n className,\n )}\n data-slot=\"input-with-addons\"\n ref={ref}\n {...props}\n />\n {trailing\n ? (\n <div className=\"text-muted-foreground flex items-center bg-transparent pr-3\">\n {trailing}\n </div>\n )\n : null}\n </div>\n )\n}\nInputWithAddons.displayName = 'InputWithAddons'\n\nexport { InputWithAddons }\n","import type { InputWithAddonsProps } from '../../input-with-addons'\nimport { getInputProps } from '@conform-to/react'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport * as React from 'react'\nimport { InputWithAddons } from '../../input-with-addons'\nimport { useFieldContext } from '../context/field-context'\n\n/**\n * Form.Input - Text input component\n *\n * Automatically wired to the parent Form.Field context.\n *\n * @example\n * ```tsx\n * <Form.Field name=\"email\" label=\"Email\" required>\n * <Form.Input type=\"email\" placeholder=\"john@example.com\" />\n * </Form.Field>\n * ```\n */\nexport function FormInputGroup({ ref, type = 'text', className, disabled, ...props }: InputWithAddonsProps & { ref?: React.RefObject<HTMLInputElement | null> }) {\n const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext()\n\n // getInputProps expects a narrower type than HTMLInputTypeAttribute\n // Type assertion is safe here since invalid types will be handled by the input element\n const inputProps = getInputProps(fieldMeta, {\n type: type as\n | 'text'\n | 'email'\n | 'password'\n | 'number'\n | 'tel'\n | 'url'\n | 'search'\n | 'date'\n | 'time'\n | 'datetime-local',\n })\n const isDisabled = disabled ?? fieldDisabled\n const hasErrors = errors && errors.length > 0\n\n return (\n <InputWithAddons\n ref={ref}\n {...inputProps}\n {...props}\n type={type}\n disabled={isDisabled}\n aria-invalid={hasErrors || undefined}\n aria-describedby={hasErrors ? `${fieldMeta.id}-error` : undefined}\n className={cn('text-xs!', className)}\n />\n )\n}\n\nFormInputGroup.displayName = 'Form.InputGroup'\n","import type { UseFieldReturn } from '../types'\nimport { useInputControl } from '@conform-to/react'\nimport * as React from 'react'\nimport { useFormContext } from '../context/form-context'\n\n/**\n * Hook to access and control a specific field\n * Provides field metadata, control methods, and errors\n *\n * @example\n * ```tsx\n * function MyCustomInput({ name }: { name: string }) {\n * const { field, control, meta, errors } = useField(name);\n *\n * return (\n * <div>\n * <input\n * name={meta.name}\n * id={meta.id}\n * value={control.value ?? ''}\n * onChange={(e) => control.change(e.target.value)}\n * onBlur={control.blur}\n * aria-invalid={!!errors?.length}\n * />\n * {errors?.map((error) => (\n * <span key={error} className=\"text-red-500\">{error}</span>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useField(name: string): UseFieldReturn {\n const { fields } = useFormContext()\n\n // Get the field metadata - support nested paths\n const field = React.useMemo(() => {\n const parts = name.split('.')\n let current: any = fields\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]!\n if (!current)\n break\n\n // Handle array access like \"items.0.name\"\n if (/^\\d+$/.test(part)) {\n const fieldList = current.getFieldList?.()\n if (fieldList) {\n const item = fieldList[Number.parseInt(part, 10)]\n // If there are more parts, get the fieldset\n if (i < parts.length - 1 && item?.getFieldset) {\n current = item.getFieldset()\n }\n else {\n current = item\n }\n }\n else {\n current = current[part as keyof typeof current]\n }\n }\n else {\n // First check if it's a direct property (top-level field)\n if (current[part as keyof typeof current] !== undefined) {\n current = current[part as keyof typeof current]\n }\n else if (typeof current.getFieldset === 'function') {\n // Try getFieldset for nested objects\n current = current.getFieldset()[part as keyof ReturnType<typeof current.getFieldset>]\n }\n else {\n current = undefined\n }\n }\n }\n\n return current\n }, [fields, name])\n\n if (!field) {\n throw new Error(\n `Field \"${name}\" not found in form. Make sure the field name matches your schema.`,\n )\n }\n\n const control = useInputControl(field as any)\n\n // Ensure value is a string (not string[])\n const controlValue = Array.isArray(control.value) ? control.value[0] : control.value\n\n const meta = React.useMemo(\n () => ({\n name: field.name,\n id: field.id,\n errors: field.errors,\n required: field.required ?? false,\n disabled: field.disabled ?? false,\n }),\n [field.name, field.id, field.errors, field.required, field.disabled],\n )\n\n return {\n field,\n control: {\n value: controlValue,\n change: control.change,\n blur: control.blur,\n focus: control.focus,\n },\n meta,\n errors: field.errors,\n }\n}\n","import type { FormFieldContextValue } from '../types'\nimport { useFieldContext as useFieldContextInternal } from '../context/field-context'\n\n/**\n * Hook to access the current field context\n * Must be used within a Form.Field component\n *\n * @example\n * ```tsx\n * function MyInput() {\n * const { name, id, errors, required, disabled, fieldMeta } = useFieldContext();\n *\n * return (\n * <input\n * name={name}\n * id={id}\n * required={required}\n * disabled={disabled}\n * aria-invalid={!!errors?.length}\n * />\n * );\n * }\n * ```\n */\nexport function useFieldContext(): FormFieldContextValue {\n return useFieldContextInternal()\n}\n","import type { FormContextValue } from '../types'\nimport { useFormContext as useFormContextInternal } from '../context/form-context'\n\n/**\n * Hook to access the form context\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { form, fields, isSubmitting, submit, reset } = useFormContext();\n *\n * return (\n * <button onClick={submit} disabled={isSubmitting}>\n * Submit\n * </button>\n * );\n * }\n * ```\n */\nexport function useFormContext<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(): FormContextValue<T> {\n return useFormContextInternal<T>()\n}\n","import type { StepConfig } from '../types'\nimport { useFormStepperContext } from '../components/stepper/form-stepper'\n\n/**\n * Return type for useStepper hook\n */\nexport interface UseStepperReturn {\n /** All step configurations */\n steps: StepConfig[]\n /** Current step config */\n current: StepConfig\n /** Current step index (0-based) */\n currentIndex: number\n /** Go to next step (triggers validation) */\n next: () => void\n /** Go to previous step (no validation) */\n prev: () => void\n /** Go to specific step by ID (only backwards without validation) */\n goTo: (stepId: string) => void\n /** Whether current step is first */\n isFirst: boolean\n /** Whether current step is last */\n isLast: boolean\n /** Get data from a specific step by ID */\n getStepData: (stepId: string) => Record<string, unknown> | undefined\n /** Get all data from all completed steps */\n getAllStepData: () => Record<string, unknown>\n}\n\n/**\n * Hook to access the stepper context\n * Must be used within a Form.Stepper component\n *\n * @example\n * ```tsx\n * function StepContent() {\n * const {\n * current,\n * currentIndex,\n * steps,\n * next,\n * prev,\n * goTo,\n * isFirst,\n * isLast,\n * } = useStepper();\n *\n * return (\n * <div>\n * <h2>Step {currentIndex + 1}: {current.label}</h2>\n * <button onClick={prev} disabled={isFirst}>Previous</button>\n * <button onClick={next} disabled={isLast}>Next</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useStepper(): UseStepperReturn {\n const context = useFormStepperContext()\n\n return {\n steps: context.steps,\n current: context.current,\n currentIndex: context.currentIndex,\n next: context.next,\n prev: context.prev,\n goTo: context.goTo,\n isFirst: context.isFirst,\n isLast: context.isLast,\n getStepData: context.getStepData,\n getAllStepData: context.getAllStepData,\n }\n}\n","/**\n * Datum Form Library\n *\n * A compound component pattern form library built on top of Conform.js and Zod\n * for easy form creation with built-in validation, error handling, and accessibility features.\n *\n * @example Basic Usage\n * ```tsx\n * import { Form } from './';\n * import { z } from 'zod';\n *\n * const userSchema = z.object({\n * name: z.string().min(2),\n * email: z.string().email(),\n * });\n *\n * function UserForm() {\n * return (\n * <Form.Root schema={userSchema} onSubmit={(data) => console.log(data)}>\n * <Form.Field name=\"name\" label=\"Name\" required>\n * <Form.Input />\n * </Form.Field>\n * <Form.Field name=\"email\" label=\"Email\" required>\n * <Form.Input type=\"email\" />\n * </Form.Field>\n * <Form.Submit>Save</Form.Submit>\n * </Form.Root>\n * );\n * }\n * ```\n *\n * @example Multi-Step Form\n * ```tsx\n * const steps = [\n * { id: 'account', label: 'Account', schema: accountSchema },\n * { id: 'profile', label: 'Profile', schema: profileSchema },\n * ];\n *\n * <Form.Stepper steps={steps} onComplete={handleComplete}>\n * <Form.StepperNavigation />\n * <Form.Step id=\"account\">...</Form.Step>\n * <Form.Step id=\"profile\">...</Form.Step>\n * <Form.StepperControls />\n * </Form.Stepper>\n * ```\n *\n * @example Conditional Fields\n * ```tsx\n * <Form.Field name=\"contactMethod\">\n * <Form.Select>\n * <Form.SelectItem value=\"email\">Email</Form.SelectItem>\n * <Form.SelectItem value=\"phone\">Phone</Form.SelectItem>\n * </Form.Select>\n * </Form.Field>\n *\n * <Form.When field=\"contactMethod\" is=\"email\">\n * <Form.Field name=\"email\"><Form.Input type=\"email\" /></Form.Field>\n * </Form.When>\n * ```\n */\n// Import all components\nimport {\n FormAutocomplete,\n FormButton,\n FormCheckbox,\n FormCopyBox,\n FormCustom,\n FormDescription,\n FormDialog,\n FormError,\n FormField,\n FormFieldArray,\n FormInput,\n FormRadioGroup,\n FormRadioItem,\n FormRoot,\n FormSelect,\n FormSelectItem,\n FormStep,\n FormStepper,\n FormSubmit,\n FormSwitch,\n FormTextarea,\n FormWhen,\n StepperControls,\n StepperNavigation,\n} from './components'\nimport { FormInputGroup } from './components/form-input-group'\n// Import hooks\nimport {\n useField,\n useFieldContext,\n useFormContext,\n useStepper,\n useWatch,\n useWatchAll,\n} from './hooks'\n\n/**\n * Form compound component\n *\n * Contains all form-related components as properties:\n * - Form.Root - Main form container\n * - Form.Field - Field wrapper with label and error handling\n * - Form.Input - Text input\n * - Form.Textarea - Multi-line text input\n * - Form.Select - Dropdown select\n * - Form.SelectItem - Select option\n * - Form.Checkbox - Checkbox input\n * - Form.Switch - Toggle switch\n * - Form.RadioGroup - Radio button group\n * - Form.RadioItem - Radio button option\n * - Form.Submit - Submit button with loading state\n * - Form.Error - Error display\n * - Form.Description - Helper text\n * - Form.Autocomplete - Searchable select with virtualization\n * - Form.When - Conditional rendering\n * - Form.FieldArray - Dynamic array of fields\n * - Form.Custom - Escape hatch for custom implementations\n * - Form.Stepper - Multi-step form container\n * - Form.Step - Individual step content\n * - Form.StepperNavigation - Step progress indicators\n * - Form.StepperControls - Previous/Next/Submit buttons\n *\n * Hooks available:\n * - Form.useFormContext - Access form context\n * - Form.useFieldContext - Access field context\n * - Form.useField - Access and control a specific field\n * - Form.useWatch - Watch a field's value\n * - Form.useWatchAll - Watch multiple fields\n * - Form.useStepper - Access stepper context\n */\nexport const Form = {\n // Core\n Root: FormRoot,\n Field: FormField,\n Submit: FormSubmit,\n Button: FormButton,\n Error: FormError,\n Description: FormDescription,\n\n // Inputs\n Input: FormInput,\n Textarea: FormTextarea,\n Select: FormSelect,\n SelectItem: FormSelectItem,\n Checkbox: FormCheckbox,\n Switch: FormSwitch,\n RadioGroup: FormRadioGroup,\n RadioItem: FormRadioItem,\n CopyBox: FormCopyBox,\n Autocomplete: FormAutocomplete,\n InputGroup: FormInputGroup,\n\n // Advanced\n When: FormWhen,\n FieldArray: FormFieldArray,\n Custom: FormCustom,\n\n // Stepper\n Stepper: FormStepper,\n Step: FormStep,\n StepperNavigation,\n StepperControls,\n\n // Dialog\n Dialog: FormDialog,\n\n // Hooks\n useFormContext,\n useFieldContext,\n useField,\n useWatch,\n useWatchAll,\n useStepper,\n} as const\n\n// Named exports for direct imports\nexport {\n FormAutocomplete,\n FormButton,\n FormCheckbox,\n FormCopyBox,\n FormCustom,\n FormDescription,\n\n // Dialog\n FormDialog,\n FormError,\n FormField,\n FormFieldArray,\n // Inputs\n FormInput,\n FormRadioGroup,\n FormRadioItem,\n // Core\n FormRoot,\n FormSelect,\n FormSelectItem,\n\n FormStep,\n // Stepper\n FormStepper,\n FormSubmit,\n\n FormSwitch,\n FormTextarea,\n // Advanced\n FormWhen,\n StepperControls,\n\n StepperNavigation,\n\n useField,\n useFieldContext,\n // Hooks\n useFormContext,\n useStepper,\n useWatch,\n useWatchAll,\n}\n\n// Export types\nexport type {\n AutocompleteGroup,\n AutocompleteOption,\n AutocompleteProps,\n FormAutocompleteProps,\n FormButtonProps,\n FormCheckboxProps,\n FormContextValue,\n FormCopyBoxProps,\n FormCustomProps,\n FormCustomRenderProps,\n FormDescriptionProps,\n FormDialogProps,\n FormErrorProps,\n FormFieldArrayProps,\n FormFieldArrayRenderProps,\n FormFieldContextValue,\n FormFieldProps,\n FormFieldRenderProps,\n FormInputProps,\n FormRadioGroupProps,\n FormRadioItemProps,\n FormRootProps,\n FormRootRenderProps,\n FormSelectItemProps,\n FormSelectProps,\n FormStepperProps,\n FormStepProps,\n FormSubmitProps,\n FormSwitchProps,\n FormTelemetry,\n FormTextareaProps,\n FormWhenProps,\n StepConfig,\n StepperContextValue,\n StepperControlsProps,\n StepperNavigationProps,\n UseFieldReturn,\n UseWatchReturn,\n} from './types'\n","export const GRID_BREAKPOINTS = {\n xs: 480,\n sm: 576,\n md: 768,\n lg: 992,\n xl: 1200,\n xxl: 1600,\n} as const\n\nexport const GRID_COLUMNS = 24\n\nexport const GRID_PREFIX = 'grid'\n\nexport const RESPONSIVE_ARRAY = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs'] as const\n\nexport const RESPONSIVE_MAP = {\n xs: '(max-width: 575px)',\n sm: '(min-width: 576px)',\n md: '(min-width: 768px)',\n lg: '(min-width: 992px)',\n xl: '(min-width: 1200px)',\n xxl: '(min-width: 1600px)',\n} as const\n\nexport type Breakpoint = keyof typeof GRID_BREAKPOINTS\nexport type ResponsiveArray = typeof RESPONSIVE_ARRAY\n","import type { Breakpoint } from '../constants/grid.constants'\nimport type { Gutter } from '../types/grid.types'\nimport { RESPONSIVE_ARRAY } from '../constants/grid.constants'\n\nexport interface MediaQueryCallback {\n match: () => void\n unmatch: () => void\n}\n\nexport function registerMediaQuery(query: string, callback: MediaQueryCallback): () => void {\n const mediaQuery = window.matchMedia(query)\n\n const handleChange = (event: MediaQueryListEvent) => {\n if (event.matches) {\n callback.match()\n }\n else {\n callback.unmatch()\n }\n }\n\n // Initial check\n if (mediaQuery.matches) {\n callback.match()\n }\n\n // Add listener\n mediaQuery.addEventListener('change', handleChange)\n\n // Return cleanup function\n return () => {\n mediaQuery.removeEventListener('change', handleChange)\n }\n}\n\nexport function getGutter(\n gutter: Gutter | [Gutter, Gutter] = 0,\n screens: Partial<Record<Breakpoint, boolean>>,\n): [number, number] {\n const results: [number, number] = [0, 0]\n const normalizedGutter = Array.isArray(gutter) ? gutter.slice(0, 2) : [gutter, 0]\n\n normalizedGutter.forEach((g, index) => {\n if (typeof g === 'object') {\n for (let i = 0; i < RESPONSIVE_ARRAY.length; i++) {\n const breakpoint = RESPONSIVE_ARRAY[i]!\n if (screens[breakpoint] && g[breakpoint] !== undefined) {\n results[index] = g[breakpoint]!\n break\n }\n }\n }\n else {\n results[index] = g || 0\n }\n })\n\n return results\n}\n\nexport function getResponsiveValue<T>(\n value: T | Partial<Record<Breakpoint, T>>,\n screens: Partial<Record<Breakpoint, boolean>>,\n): T | undefined {\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n const responsiveValue = value as Partial<Record<Breakpoint, T>>\n for (let i = 0; i < RESPONSIVE_ARRAY.length; i++) {\n const breakpoint = RESPONSIVE_ARRAY[i]!\n if (screens[breakpoint] && responsiveValue[breakpoint] !== undefined) {\n return responsiveValue[breakpoint]\n }\n }\n }\n return value as T\n}\n","import type { RowContextType, RowProps, RowState } from '../types/grid.types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport React, { useEffect, useState } from 'react'\nimport { GRID_PREFIX, RESPONSIVE_MAP } from '../constants/grid.constants'\nimport { getGutter, registerMediaQuery } from '../utils/responsive'\n\nexport const RowContext = React.createContext<RowContextType | null>(null)\n\nconst Row: React.FC<RowProps> = ({\n type,\n align,\n justify,\n className,\n style,\n children,\n gutter = 0,\n prefixCls = GRID_PREFIX,\n ...rest\n}) => {\n const [screens, setScreens] = useState<RowState['screens']>({\n xs: true,\n sm: true,\n md: true,\n lg: true,\n xl: true,\n xxl: true,\n })\n\n const [unRegisters, setUnRegisters] = useState<Array<() => void>>([])\n\n useEffect(() => {\n if (typeof gutter === 'object' && !Array.isArray(gutter)) {\n const newUnRegisters = Object.keys(RESPONSIVE_MAP).map(screen =>\n registerMediaQuery(RESPONSIVE_MAP[screen as keyof typeof RESPONSIVE_MAP], {\n match: () => {\n setScreens(prevState => ({\n ...prevState,\n [screen]: true,\n }))\n },\n unmatch: () => {\n setScreens(prevState => ({\n ...prevState,\n [screen]: false,\n }))\n },\n }),\n )\n setUnRegisters(newUnRegisters)\n }\n\n return () => {\n unRegisters.forEach(unRegister => unRegister())\n }\n }, [gutter])\n\n const gutters = getGutter(gutter, screens)\n const prefix = `${prefixCls}-row`\n\n const classes = cn(\n {\n [prefix]: type !== 'flex',\n [`${prefix}-${type}`]: type,\n [`${prefix}-${type}-${justify}`]: type && justify,\n [`${prefix}-${type}-${align}`]: type && align,\n },\n className,\n )\n\n const rowStyle: React.CSSProperties = {\n ...(gutters[0] > 0\n ? {\n marginLeft: gutters[0] / -2,\n marginRight: gutters[0] / -2,\n }\n : {}),\n ...(gutters[1] > 0\n ? {\n marginTop: gutters[1] / -2,\n marginBottom: gutters[1] / -2,\n }\n : {}),\n ...style,\n }\n\n const contextValue: RowContextType = {\n gutters,\n }\n\n return (\n <RowContext value={contextValue}>\n <div {...rest} className={classes} style={rowStyle}>\n {children}\n </div>\n </RowContext>\n )\n}\n\nexport default Row\n","import type { ColProps, ColSize } from '../types/grid.types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport React, { use } from 'react'\nimport { GRID_PREFIX, RESPONSIVE_ARRAY } from '../constants/grid.constants'\nimport { RowContext } from './row'\n\nconst Col: React.FC<ColProps> = ({\n span,\n order,\n offset,\n push,\n pull,\n className,\n prefixCls = GRID_PREFIX,\n style,\n children,\n ...rest\n}) => {\n const context = use(RowContext)\n const prefix = `${prefixCls}-col`\n\n let sizeClassObj: Record<string, boolean> = {}\n\n // Handle responsive props\n RESPONSIVE_ARRAY.forEach((size) => {\n let sizeProps: ColSize = {}\n const sizeValue = rest[size as keyof typeof rest]\n\n if (typeof sizeValue === 'number') {\n sizeProps.span = sizeValue\n }\n else if (typeof sizeValue === 'object') {\n sizeProps = sizeValue || {}\n }\n\n delete rest[size as keyof typeof rest]\n\n sizeClassObj = {\n ...sizeClassObj,\n [`${prefix}-${size}-${sizeProps.span}`]: sizeProps.span !== undefined,\n [`${prefix}-${size}-order-${sizeProps.order}`]: sizeProps.order !== undefined,\n [`${prefix}-${size}-offset-${sizeProps.offset}`]: sizeProps.offset !== undefined,\n [`${prefix}-${size}-push-${sizeProps.push}`]: sizeProps.push !== undefined,\n [`${prefix}-${size}-pull-${sizeProps.pull}`]: sizeProps.pull !== undefined,\n }\n })\n\n const classes = cn(\n prefix,\n {\n [`${prefix}-${span}`]: span !== undefined,\n [`${prefix}-order-${order}`]: order !== undefined,\n [`${prefix}-offset-${offset}`]: offset !== undefined,\n [`${prefix}-push-${push}`]: push !== undefined,\n [`${prefix}-pull-${pull}`]: pull !== undefined,\n ...sizeClassObj,\n },\n className,\n )\n\n const colStyle: React.CSSProperties = { ...style }\n\n // Apply gutters from context\n if (context && context.gutters) {\n const [horizontalGutter, verticalGutter] = context.gutters\n\n if (horizontalGutter > 0) {\n colStyle.paddingLeft = horizontalGutter / 2\n colStyle.paddingRight = horizontalGutter / 2\n }\n\n if (verticalGutter > 0) {\n colStyle.paddingTop = verticalGutter / 2\n colStyle.paddingBottom = verticalGutter / 2\n }\n }\n\n return (\n <div {...rest} style={colStyle} className={classes}>\n {children}\n </div>\n )\n}\n\nexport default Col\n","import type { NumericFormatProps } from 'react-number-format'\nimport { Button } from '@repo/shadcn/ui/button'\nimport { ChevronDown, ChevronUp } from 'lucide-react'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { NumericFormat } from 'react-number-format'\nimport { Input } from '../..'\nimport { Icon } from '../../icons/icon-wrapper'\n\nexport interface NumberInputProps extends Omit<NumericFormatProps, 'value' | 'onValueChange'> {\n stepper?: number\n thousandSeparator?: string\n placeholder?: string\n defaultValue?: number\n min?: number\n max?: number\n value?: number // Controlled value\n suffix?: string\n prefix?: string\n onValueChange?: (value: number | undefined) => void\n fixedDecimalScale?: boolean\n decimalScale?: number\n}\n\nexport function InputNumber({ ref, stepper, thousandSeparator, placeholder, defaultValue, min = -Infinity, max = Infinity, onValueChange, fixedDecimalScale = false, decimalScale = 0, suffix, prefix, value: controlledValue, ...props }: NumberInputProps & { ref?: React.RefObject<HTMLInputElement | null> }) {\n const internalRef = useRef<HTMLInputElement>(null) // Create an internal ref\n const combinedRef = ref || internalRef // Use provided ref or internal ref\n const [value, setValue] = useState<number | undefined>(controlledValue ?? defaultValue)\n\n const handleIncrement = useCallback(() => {\n setValue(prev =>\n prev === undefined ? (stepper ?? 1) : Math.min(prev + (stepper ?? 1), max),\n )\n }, [stepper, max])\n\n const handleDecrement = useCallback(() => {\n setValue(prev =>\n prev === undefined ? -(stepper ?? 1) : Math.max(prev - (stepper ?? 1), min),\n )\n }, [stepper, min])\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (document.activeElement === (combinedRef as React.RefObject<HTMLInputElement>).current) {\n if (e.key === 'ArrowUp') {\n handleIncrement()\n }\n else if (e.key === 'ArrowDown') {\n handleDecrement()\n }\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [handleIncrement, handleDecrement, combinedRef])\n\n useEffect(() => {\n if (controlledValue !== undefined) {\n setValue(controlledValue)\n }\n }, [controlledValue])\n\n const handleChange = (values: { value: string, floatValue: number | undefined }) => {\n const newValue = values.floatValue === undefined ? undefined : values.floatValue\n setValue(newValue)\n if (onValueChange) {\n onValueChange(newValue)\n }\n }\n\n const handleBlur = () => {\n if (value !== undefined) {\n if (value < min) {\n setValue(min);\n (ref as React.RefObject<HTMLInputElement>).current!.value = String(min)\n }\n else if (value > max) {\n setValue(max);\n (ref as React.RefObject<HTMLInputElement>).current!.value = String(max)\n }\n }\n }\n\n return (\n <div className=\"flex items-center\">\n <NumericFormat\n value={value}\n onValueChange={handleChange}\n thousandSeparator={thousandSeparator}\n decimalScale={decimalScale}\n fixedDecimalScale={fixedDecimalScale}\n allowNegative={min < 0}\n valueIsNumericString\n onBlur={handleBlur}\n max={max}\n min={min}\n suffix={suffix}\n prefix={prefix}\n customInput={Input}\n placeholder={placeholder}\n className=\"relative [appearance:textfield] rounded-r-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none\"\n getInputRef={combinedRef} // Use combined ref\n {...props}\n />\n <div className=\"flex flex-col\">\n <Button\n type=\"button\"\n aria-label=\"Increase value\"\n className=\"border-input h-5 rounded-l-none rounded-br-none border-b-[0.5px] border-l-0 px-2 focus-visible:relative\"\n variant=\"outline\"\n onClick={handleIncrement}\n disabled={value === max}\n >\n <Icon icon={ChevronUp} size={15} />\n </Button>\n <Button\n type=\"button\"\n aria-label=\"Decrease value\"\n className=\"border-input h-5 rounded-l-none rounded-tr-none border-t-[0.5px] border-l-0 px-2 focus-visible:relative\"\n variant=\"outline\"\n onClick={handleDecrement}\n disabled={value === min}\n >\n <Icon icon={ChevronDown} size={15} />\n </Button>\n </div>\n </div>\n )\n}\n\nInputNumber.displayName = 'InputNumber'\n","import { cn } from '@repo/shadcn/lib/utils'\nimport { Ellipsis } from 'lucide-react'\nimport { useState } from 'react'\nimport { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Tooltip } from '../..'\n\nexport interface MoreActionsProps<TData> {\n key: string\n label: string\n variant?: 'default' | 'destructive'\n icon?: React.ReactNode\n className?: string\n action: (row?: TData) => void | Promise<void>\n disabled?: (row?: TData) => boolean\n hidden?: (row?: TData) => boolean\n tooltip?: string | ((row?: TData) => string) // Tooltip text - can be static string or function that receives row data\n}\n\nexport function MoreActions<TData,>({\n row,\n actions,\n className,\n disabled = false,\n iconClassName,\n}: {\n row?: TData\n actions: MoreActionsProps<TData>[]\n className?: string\n disabled?: boolean\n iconClassName?: string\n}) {\n const [open, setOpen] = useState<boolean>(false)\n // Filter visible actions\n const visibleActions = actions.filter(action => !action.hidden?.(row))\n\n // Hide if no visible actions remain\n if (visibleActions.length === 0) {\n return null\n }\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <Button\n onClick={() => setOpen(!open)}\n type=\"quaternary\"\n theme=\"borderless\"\n size=\"icon\"\n disabled={disabled}\n className={cn(\n 'data-[state=open]:bg-accent size-7 p-0 focus-visible:ring-0 focus-visible:ring-offset-0',\n className,\n )}\n >\n <Ellipsis className={cn('size-5', iconClassName)} />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {visibleActions.map((action) => {\n // Generate tooltip text from action config or fallback to label\n const tooltipText\n = typeof action.tooltip === 'function'\n ? action.tooltip(row)\n : (action.tooltip ?? action.label)\n\n const menuItem = (\n <DropdownMenuItem\n onClick={(event) => {\n event.preventDefault()\n event.stopPropagation()\n setOpen(false)\n action.action(row)\n }}\n className={cn(\n 'cursor-pointer text-xs',\n action.variant === 'destructive'\n && 'text-destructive [&_svg]:!text-destructive hover:!text-destructive hover:[&_svg]:!text-destructive',\n action.className,\n )}\n disabled={action.disabled?.(row) ?? false}\n >\n {action.icon}\n {action.label}\n </DropdownMenuItem>\n )\n\n // Wrap with tooltip if tooltip text differs from label (shows additional context)\n if (tooltipText && tooltipText !== action.label) {\n return (\n <Tooltip key={action.key} message={tooltipText}>\n {menuItem}\n </Tooltip>\n )\n }\n\n return <div key={action.key}>{menuItem}</div>\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n","/**\n * NProgress Module\n *\n * Provides progress bar functionality with custom styling.\n * Styles are located in ./nprogress.css and imported via @app/styles/root.css\n */\nimport NProgress from 'nprogress'\n\nlet timeout: ReturnType<typeof setTimeout> | null = null\n\nexport function startProgress() {\n if (timeout)\n clearTimeout(timeout)\n timeout = setTimeout(() => {\n NProgress.start()\n }, 150)\n}\n\nexport function stopProgress() {\n if (timeout) {\n clearTimeout(timeout)\n timeout = null\n }\n NProgress.done()\n}\n\nexport function configureProgress() {\n NProgress.configure({\n showSpinner: false,\n trickleSpeed: 100,\n })\n}\n","import { cn } from '@repo/shadcn/lib/utils'\n\nexport interface PageTitleProps {\n title?: string\n description?: React.ReactNode\n actions?: React.ReactNode\n className?: string\n titleClassName?: string\n descriptionClassName?: string\n actionsClassName?: string\n actionsPosition?: 'inline' | 'bottom'\n}\n\nexport function PageTitle({\n title,\n description,\n actions,\n className,\n titleClassName,\n descriptionClassName,\n actionsClassName,\n actionsPosition = 'inline',\n}: PageTitleProps) {\n const isInline = actionsPosition === 'inline'\n\n return (\n <div\n className={cn(\n 'flex w-full',\n isInline ? 'items-center justify-between' : 'flex-col gap-3',\n className,\n )}\n >\n <div\n className={cn('flex', isInline ? 'flex-col justify-start gap-1' : 'w-full flex-col gap-1')}\n >\n {title && (\n <span className={cn('text-2xl leading-none font-medium', titleClassName)}>{title}</span>\n )}\n {description && (\n <div className={cn('text-sm font-normal', descriptionClassName)}>{description}</div>\n )}\n </div>\n {actions && (\n <div\n className={cn('flex gap-1', isInline ? 'justify-end pl-2' : 'w-full', actionsClassName)}\n >\n {actions}\n </div>\n )}\n </div>\n )\n}\n","import type { LucideIcon } from 'lucide-react'\nimport type {\n ComponentProps,\n ElementType,\n} from 'react'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@repo/shadcn/ui/collapsible'\nimport { ChevronRight, ExternalLinkIcon } from 'lucide-react'\nimport { motion } from 'motion/react'\nimport {\n Fragment,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarSeparator,\n useSidebar,\n} from '..'\nimport { Icon } from '../../icons/icon-wrapper'\n\nexport interface NavItem {\n title: string\n href: string | null\n type: 'link' | 'group' | 'collapsible' | 'externalLink'\n disabled?: boolean\n count?: number\n icon?: LucideIcon\n children?: NavItem[]\n open?: boolean\n hidden?: boolean\n showSeparatorAbove?: boolean\n showSeparatorBelow?: boolean\n\n // Exclude specific sub-paths from activating this nav item\n // Use this for sibling routes like `/export-policies` and `/export-policies/new`\n // where `/export-policies` should NOT be active when on `/export-policies/new`\n // but SHOULD be active for detail routes like `/export-policies/:id/overview`\n excludePaths?: string[]\n\n // Tab Child Links - used to highlight parent nav item when on child tab routes\n // TODO: Replace with proper route hierarchy detection or nested route structure\n // Currently needed to mark parent nav items as active when user is on tab child routes\n // Mixed layout scenario: `/account/preferences` and `/account/activity` use tabs layout,\n // while `/account/organizations` uses sidebar layout, but all share the same parent sidebar nav\n tabChildLinks?: string[]\n\n /** Called when the user hovers over the link (e.g. to prefetch route data). */\n onPrefetch?: () => void\n}\n\n// Centralized style constants for nav menu buttons\nconst NAV_STYLES = {\n menuButton:\n 'rounded-xl h-8 font-normal text-xs transition-all px-2 py-1 data-[active=true]:bg-sidebar data-[active=true]:text-foreground data-[active=true]:text-sidebar-primary data-[active=true]:[&>svg]:text-primary hover:bg-sidebar hover:text-sidebar-primary hover:[&>svg]:text-sidebar-primary hover:bg-sidebar-accent data-[active=true]:bg-sidebar-accent hover:font-semibold data-[active=true]:hover:[&>svg]:text-sidebar-primary transition-colors duration-300 gap-2.5 text-foreground [&>svg]:text-icon-primary',\n disabled: 'pointer-events-none opacity-50',\n icon: 'duration-300 transition-all',\n iconSmall: 'size-4 duration-300 transition-all',\n} as const\n\n// Centralized icon renderer component\nfunction NavIcon({\n icon: IconComponent,\n className,\n size = 'default',\n}: {\n icon?: LucideIcon\n className?: string\n size?: 'default' | 'small'\n}) {\n if (!IconComponent)\n return null\n return (\n <Icon\n icon={IconComponent}\n className={cn(size === 'small' ? NAV_STYLES.iconSmall : NAV_STYLES.icon, className)}\n />\n )\n}\n\nNavIcon.displayName = 'NavIcon'\n\n// Wrapper component for NavSidebarMenuButton\ntype NavSidebarMenuButtonProps = ComponentProps<typeof SidebarMenuButton> & {\n item: Pick<NavItem, 'disabled' | 'icon' | 'title'>\n isActive?: boolean\n disableTooltip?: boolean\n}\n\nfunction NavSidebarMenuButton({ ref, item, isActive, disableTooltip, className, children, asChild, ...props }: NavSidebarMenuButtonProps & { ref?: React.RefObject<HTMLButtonElement | null> }) {\n return (\n <SidebarMenuButton\n ref={ref}\n tooltip={disableTooltip ? undefined : item.title}\n isActive={isActive}\n disabled={item.disabled}\n asChild={asChild}\n className={cn(NAV_STYLES.menuButton, item.disabled && NAV_STYLES.disabled, className)}\n {...props}\n >\n {asChild\n ? (\n children\n )\n : (\n <>\n <NavIcon icon={item.icon} />\n {children}\n </>\n )}\n </SidebarMenuButton>\n )\n}\n\nNavSidebarMenuButton.displayName = 'NavSidebarMenuButton'\n\nexport function NavMain({ ref, className, items, currentPath, linkComponent: LinkComp = 'a', overrideState, itemClassName, disableTooltip, closeOnNavigation, ...props }: ComponentProps<'ul'> & {\n items: NavItem[]\n /** Current URL pathname — replaces internal useLocation() */\n currentPath: string\n /** Link component to render navigation links (defaults to native `<a>`) */\n linkComponent?: ElementType\n overrideState?: 'expanded' | 'collapsed'\n itemClassName?: string\n disableTooltip?: boolean\n closeOnNavigation?: boolean\n} & { ref?: React.RefObject<HTMLUListElement | null> }) {\n const pathname = currentPath\n const { state: sidebarState, isMobile, closeForNavigation, setOpen } = useSidebar()\n const [openItems, setOpenItems] = useState<Record<string, boolean>>({})\n const isInitialMount = useRef(true)\n const previousOpenItems = useRef<Record<string, boolean>>({})\n const previousPathname = useRef(pathname)\n\n // Use overrideState if provided, otherwise use sidebar state\n const state = overrideState ?? sidebarState\n const previousState = useRef(state)\n\n // Track previous open state to detect transitions\n useEffect(() => {\n previousOpenItems.current = openItems\n // Mark initial mount as complete after first render\n if (isInitialMount.current) {\n isInitialMount.current = false\n }\n }, [openItems])\n\n // Track pathname changes\n useEffect(() => {\n previousPathname.current = pathname\n }, [pathname])\n\n const activeNavItem = useCallback(\n (item: NavItem) => {\n // pathname is from useLocation() in the outer scope.\n // item is the nav item object with href and tabChildLinks.\n\n const normalize = (p: string): string => {\n let result = p.startsWith('/') ? p : `/${p}`\n // Remove trailing slash, unless it's the root path itself\n if (result !== '/' && result.endsWith('/')) {\n result = result.slice(0, -1)\n }\n return result\n }\n\n const cleanCurrentPath = normalize(pathname)\n\n // If no href, can't be active\n if (!item.href) {\n return false\n }\n\n const cleanNavPath = normalize(item.href)\n\n // Handle root path case: nav item is '/'\n if (cleanNavPath === '/') {\n return cleanCurrentPath === '/' // Active if current path is also root\n }\n\n // Helper to recursively check if any descendant matches the pathname\n const hasActiveDescendant = (navItem: NavItem): boolean => {\n if (!navItem.children || navItem.children.length === 0) {\n return false\n }\n\n return navItem.children.some((child) => {\n if (!child.href) {\n // If child has no href but has children, check its descendants\n return hasActiveDescendant(child)\n }\n\n const cleanChildPath = normalize(child.href)\n const childMatches\n = cleanCurrentPath === cleanChildPath\n || cleanCurrentPath.startsWith(`${cleanChildPath}/`)\n\n // If this child matches, return true\n if (childMatches) {\n return true\n }\n\n // Otherwise, check this child's descendants\n return hasActiveDescendant(child)\n })\n }\n\n // If item has children, check if any descendant is active\n const hasChildren = (item.children || []).length > 0\n if (hasChildren) {\n // If a descendant is active, parent should not be active\n if (hasActiveDescendant(item)) {\n return false\n }\n\n // If no descendant is active, only exact match for parent\n return cleanCurrentPath === cleanNavPath\n }\n\n // For items without children, check for exact match or sub-path\n // Check if current path is in the excluded paths list\n const isExcluded\n = item.excludePaths?.some((excludePath) => {\n const cleanExcludePath = normalize(excludePath)\n return (\n cleanCurrentPath === cleanExcludePath\n || cleanCurrentPath.startsWith(`${cleanExcludePath}/`)\n )\n }) ?? false\n\n // Match exact path, or sub-paths that are not excluded\n const isDirectMatch\n = cleanCurrentPath === cleanNavPath\n || (!isExcluded && cleanCurrentPath.startsWith(`${cleanNavPath}/`))\n\n // Check tabChildLinks for mixed layout scenarios (tabs + sidebar)\n const isTabChildMatch\n = item.tabChildLinks?.some((childPath) => {\n const cleanChildPath = normalize(childPath)\n return (\n cleanCurrentPath === cleanChildPath\n || cleanCurrentPath.startsWith(`${cleanChildPath}/`)\n )\n }) ?? false\n\n return isDirectMatch || isTabChildMatch\n },\n [pathname],\n )\n\n // Helper function to check if an item or any of its children are active\n const hasActiveDescendant = useCallback(\n (item: NavItem): boolean => {\n if (activeNavItem(item)) {\n return true\n }\n if (item.children) {\n return item.children.some(child => hasActiveDescendant(child))\n }\n return false\n },\n [activeNavItem],\n )\n\n // Helper function to find item by href in the items tree\n const findItemByHref = useCallback((href: string, items: NavItem[]): NavItem | null => {\n for (const item of items) {\n if (item.href === href) {\n return item\n }\n if (item.children) {\n const found = findItemByHref(href, item.children)\n if (found)\n return found\n }\n }\n return null\n }, [])\n\n // Close collapsibles when sidebar collapses (unless they have active children)\n useEffect(() => {\n if (previousState.current === 'expanded' && state === 'collapsed') {\n setOpenItems((prev) => {\n const newOpenItems: Record<string, boolean> = {}\n // Keep only items that have active children open\n Object.keys(prev).forEach((itemHref) => {\n const item = findItemByHref(itemHref, items)\n if (item && hasActiveDescendant(item)) {\n newOpenItems[itemHref] = true\n }\n })\n return newOpenItems\n })\n }\n previousState.current = state\n }, [state, items, hasActiveDescendant, findItemByHref])\n\n const toggleItem = (itemId: string) => {\n setOpenItems(prev => ({ ...prev, [itemId]: !prev[itemId] }))\n }\n\n // Handler to close sidebar on navigation (only on desktop when closeOnNavigation prop is enabled)\n // Uses closeForNavigation method which clears hover state and temporarily locks hover expansion\n const handleNavigation = useCallback(() => {\n if (closeOnNavigation && !isMobile) {\n closeForNavigation()\n }\n }, [closeOnNavigation, isMobile, closeForNavigation])\n\n const renderNavItem = (item: NavItem, level = 0) => {\n if ('hidden' in item && item.hidden) {\n return null\n }\n\n const itemKey = `${item.title}-${item.href || ''}-${level}`\n\n if ('type' in item && item.type === 'group') {\n return (\n <Fragment key={itemKey}>\n <SidebarGroup className=\"mb-2 p-0! px-2\">\n {item.title && (\n <SidebarGroupLabel className=\"lowercase group-data-[state=collapsed]:hidden first-letter:uppercase\">\n {item.title}\n </SidebarGroupLabel>\n )}\n <SidebarGroupContent className=\"flex flex-col gap-1\">\n {(item.children || []).map(child => renderNavItem(child, level + 1))}\n </SidebarGroupContent>\n </SidebarGroup>\n <SidebarSeparator className=\"my-2 hidden group-data-[state=collapsed]:block\" />\n </Fragment>\n )\n }\n\n const isActive = activeNavItem(item)\n const pathnameExistInDropdowns\n = item.children?.filter((dropdownItem: NavItem) =>\n pathname.includes(dropdownItem.href as string),\n ) || []\n\n const hasChildren = (item.children || []).length > 0\n const isOpen\n = openItems[item.href as string] !== undefined\n ? openItems[item.href as string]\n : Boolean(pathnameExistInDropdowns.length)\n const hasActiveChild = pathnameExistInDropdowns.length > 0\n\n // Handle collapsed state - expand sidebar when clicking items with children\n if (state === 'collapsed' && !isMobile && level <= 2 && hasChildren) {\n return (\n <Fragment key={itemKey}>\n {item.showSeparatorAbove && <SidebarSeparator className=\"my-1\" />}\n <SidebarMenu>\n <div className=\"flex flex-col px-2\">\n <NavSidebarMenuButton\n item={item}\n isActive={isActive}\n disableTooltip={disableTooltip}\n className={itemClassName}\n onClick={() => {\n // Expand sidebar when clicking an item with children\n setOpen(true)\n // Also open the collapsible for this item\n if (item.href) {\n setOpenItems(prev => ({ ...prev, [item.href as string]: true }))\n }\n }}\n />\n {/* Show dots for each sub-item only if one is active */}\n {hasActiveChild && (\n <motion.div\n variants={{\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.05,\n delayChildren: 0.1,\n },\n },\n }}\n initial=\"hidden\"\n animate=\"visible\"\n className=\"flex flex-col gap-0.5\"\n >\n {item.children?.map((subItem) => {\n const isSubItemActive = activeNavItem(subItem)\n return (\n <motion.div\n key={`collapsed-dot-${subItem.href}-${level}`}\n variants={{\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n duration: 0.2,\n ease: 'easeOut',\n },\n },\n }}\n >\n <SidebarMenuButton\n tooltip={subItem.title}\n isActive={isSubItemActive}\n className=\"h-6 p-0 group-data-[collapsible=icon]:h-6! group-data-[collapsible=icon]:p-0!\"\n asChild\n >\n <LinkComp\n className=\"flex items-center justify-center\"\n {...(LinkComp === 'a'\n ? { href: subItem.href || '' }\n : { to: subItem.href || '' })}\n onClick={() => {\n handleNavigation()\n }}\n >\n <span\n className={cn(\n 'size-1 rounded-full',\n isSubItemActive ? 'bg-primary' : 'bg-sidebar-primary-foreground',\n )}\n />\n </LinkComp>\n </SidebarMenuButton>\n </motion.div>\n )\n })}\n </motion.div>\n )}\n </div>\n </SidebarMenu>\n {item.showSeparatorBelow && <SidebarSeparator className=\"my-2\" />}\n </Fragment>\n )\n }\n\n // Handle expanded state with collapsible menus (for levels 0-3)\n if (hasChildren && level <= 3) {\n return (\n <Fragment key={itemKey}>\n {item.showSeparatorAbove && <SidebarSeparator className=\"my-2\" />}\n <SidebarMenu className=\"px-2\">\n <Collapsible\n key={`collapsed-item-drop-down-item-${item.title}-${level}`}\n asChild\n open={isOpen}\n onOpenChange={(open) => {\n if (item.href) {\n // Allow toggling even if it has an active child\n setOpenItems(prev => ({ ...prev, [item.href as string]: open }))\n }\n }}\n className=\"group/collapsible\"\n >\n <SidebarMenuItem>\n <CollapsibleTrigger asChild className=\"w-full\">\n <NavSidebarMenuButton\n item={item}\n isActive={isActive}\n disableTooltip={disableTooltip}\n className={itemClassName}\n >\n <span>{item.title}</span>\n <Icon\n icon={ChevronRight}\n className=\"ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90\"\n />\n </NavSidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent className=\"data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up overflow-hidden\">\n <div style={{ minHeight: 0, overflow: 'hidden' }}>\n <motion.div\n key={`collapsible-${item.href}-${isOpen}`}\n variants={{\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.05,\n delayChildren: 0.1,\n },\n },\n }}\n initial={\n isInitialMount.current\n || (previousOpenItems.current[item.href as string]\n === openItems[item.href as string]\n && previousState.current === state\n && previousPathname.current === pathname\n && !hasActiveChild)\n ? 'visible'\n : 'hidden'\n }\n animate={isOpen ? 'visible' : 'hidden'}\n >\n <SidebarMenuSub\n className={cn(\n level >= 1 ? 'mr-0 pr-[.1rem]' : '',\n level === 2 ? 'pl-4' : '',\n level === 3 ? 'pl-6' : '',\n 'mr-0 gap-0.5 pr-0',\n )}\n >\n {item.children?.map((subItem, index) => (\n <motion.div\n key={`${subItem.href}-${level}-${index}`}\n variants={{\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n duration: 0.2,\n ease: 'easeOut',\n },\n },\n }}\n >\n {renderNavItem(subItem, level + 1)}\n </motion.div>\n ))}\n </SidebarMenuSub>\n </motion.div>\n </div>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n </SidebarMenu>\n {item.showSeparatorBelow && <SidebarSeparator className=\"my-2\" />}\n </Fragment>\n )\n }\n\n const renderCollapsible = (currentItem: NavItem, currentLevel: number) => {\n const currentItemIsActive = activeNavItem(currentItem)\n const currentItemPathnameExistInDropdowns\n = currentItem.children?.filter((dropdownItem: NavItem) =>\n pathname.includes(dropdownItem.href as string),\n ) || []\n const currentItemIsOpen\n = openItems[currentItem.href as string]\n || Boolean(currentItemPathnameExistInDropdowns.length)\n\n return (\n <Collapsible\n key={`collapsed-item-drop-down-item-${currentItem.title}-${currentLevel}`}\n asChild\n open={currentItemIsOpen}\n onOpenChange={(open) => {\n if (currentItem.href) {\n setOpenItems(prev => ({ ...prev, [currentItem.href as string]: open }))\n }\n }}\n className=\"group/collapsible\"\n >\n <SidebarMenuItem key={`collapsible-sidebar-${currentItem.title}-${currentLevel}`}>\n <CollapsibleTrigger asChild className=\"w-full\">\n <NavSidebarMenuButton\n item={currentItem}\n isActive={currentItemIsActive}\n disableTooltip={disableTooltip}\n className={itemClassName}\n >\n <span>{currentItem.title}</span>\n <Icon\n icon={ChevronRight}\n className=\"ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90\"\n />\n </NavSidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent className=\"data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up overflow-hidden\">\n <div style={{ minHeight: 0, overflow: 'hidden' }}>\n <SidebarMenuSub\n className={cn(currentLevel >= 1 ? 'mr-0 pr-[.1rem]' : '', 'gap-0.5')}\n >\n {currentItem.children?.map(subItem =>\n renderNavItem(subItem, currentLevel + 1),\n )}\n </SidebarMenuSub>\n </div>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n )\n }\n\n if (level <= 2 && hasChildren) {\n return (\n <Fragment key={itemKey}>\n {item.showSeparatorAbove && <SidebarSeparator className=\"my-2\" />}\n <SidebarMenu className=\"px-2\">{renderCollapsible(item, level)}</SidebarMenu>\n {item.showSeparatorBelow && <SidebarSeparator className=\"my-2\" />}\n </Fragment>\n )\n }\n\n return (\n <Fragment key={itemKey}>\n {item.showSeparatorAbove && <SidebarSeparator className=\"my-2\" />}\n <SidebarMenu className={cn(`level_${level} px-2`)}>\n <SidebarMenuItem>\n <NavSidebarMenuButton\n asChild\n item={item}\n isActive={isActive && !hasActiveChild}\n disableTooltip={disableTooltip}\n onClick={() => hasChildren && toggleItem(item.href as string)}\n className={cn(level >= 1 && 'h-6', itemClassName)}\n >\n {item.type === 'externalLink'\n ? (\n <a\n href={item.href || ''}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center justify-between\"\n >\n <div className=\"flex items-center gap-2\">\n {item?.icon && (\n <Icon icon={item.icon} className=\"size-4 transition-all duration-300\" />\n )}\n <span>{item.title}</span>\n </div>\n <Icon icon={ExternalLinkIcon} className=\"ml-auto size-4\" />\n </a>\n )\n : (\n <LinkComp\n {...(LinkComp === 'a' ? { href: item.href || '' } : { to: item.href || '' })}\n onClick={handleNavigation}\n onMouseEnter={() => item.onPrefetch?.()}\n >\n {item?.icon && (\n <Icon\n icon={item.icon}\n className=\"text-sidebar-primary transition-all duration-300\"\n />\n )}\n <span>{item.title}</span>\n </LinkComp>\n )}\n </NavSidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n {item.showSeparatorBelow && <SidebarSeparator className=\"my-2\" />}\n </Fragment>\n )\n }\n\n return (\n <ul\n ref={ref}\n data-sidebar=\"menu\"\n className={cn('flex h-full w-full min-w-0 flex-col gap-0.5 py-2', className)}\n {...props}\n >\n {(items || []).map(item => renderNavItem(item))}\n </ul>\n )\n}\n\nNavMain.displayName = 'NavMain'\n","import type { NavItem } from './nav-main'\nimport { useEffect } from 'react'\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarTrigger,\n useSidebar,\n} from '..'\nimport { NavMain } from './nav-main'\n\nexport function AppSidebar({\n navItems,\n title,\n closeOnNavigation,\n defaultOpen,\n currentPath,\n linkComponent,\n ...props\n}: React.ComponentProps<typeof Sidebar> & {\n navItems: NavItem[]\n title?: string | React.ReactNode\n closeOnNavigation?: boolean\n /** Controls sidebar open state — when false, sidebar closes on mount */\n defaultOpen?: boolean\n /** Current URL pathname — passed through to NavMain */\n currentPath: string\n /** Link component — passed through to NavMain (defaults to native `<a>`) */\n linkComponent?: React.ElementType\n}) {\n const { setOpen } = useSidebar()\n\n useEffect(() => {\n if (defaultOpen === false) {\n setOpen(false)\n }\n }, [defaultOpen, setOpen])\n\n return (\n <Sidebar collapsible={props.collapsible ?? 'offcanvas'} {...props}>\n <SidebarContent className=\"gap-0\">\n {title && <SidebarHeader className=\"px-4 pt-4 pb-0\">{title}</SidebarHeader>}\n\n {navItems.length > 0 && (\n <NavMain\n className=\"h-fit py-2\"\n items={navItems}\n currentPath={currentPath}\n linkComponent={linkComponent}\n closeOnNavigation={closeOnNavigation}\n />\n )}\n\n {props.collapsible !== 'none' && (\n <SidebarFooter className=\"mt-auto p-2\">\n <SidebarTrigger />\n </SidebarFooter>\n )}\n </SidebarContent>\n </Sidebar>\n )\n}\n","import type { VariantProps } from 'class-variance-authority'\nimport { Slot } from '@radix-ui/react-slot'\nimport { useIsMobile } from '@repo/shadcn/hooks/use-mobile'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Button } from '@repo/shadcn/ui/button'\nimport { Separator } from '@repo/shadcn/ui/separator'\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from '@repo/shadcn/ui/sheet'\nimport { Skeleton } from '@repo/shadcn/ui/skeleton'\nimport { TooltipProvider } from '@repo/shadcn/ui/tooltip'\nimport { cva } from 'class-variance-authority'\nimport { PanelLeftCloseIcon, PanelLeftOpenIcon } from 'lucide-react'\nimport * as React from 'react'\nimport { Input } from '../../base/input/input'\nimport { Tooltip } from '../../base/tooltip/tooltip'\nimport { Icon } from '../../icons/icon-wrapper'\n\nconst SIDEBAR_COOKIE_NAME = 'sidebar_state'\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nconst SIDEBAR_WIDTH = '13rem'\nconst SIDEBAR_WIDTH_MOBILE = '18rem'\nconst SIDEBAR_WIDTH_ICON = '3rem'\nconst SIDEBAR_KEYBOARD_SHORTCUT = 'b'\n\ninterface SidebarContext {\n state: 'expanded' | 'collapsed'\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n handleMouseEnter: () => void\n handleMouseLeave: () => void\n forceClose: () => void\n closeForNavigation: () => void\n hasSubLayout: boolean\n setHasSubLayout: (value: boolean) => void\n expandBehavior: 'push' | 'overlay'\n showBackdrop: boolean\n}\n\n// eslint-disable-next-line ts/no-redeclare\nconst SidebarContext = React.createContext<SidebarContext | null>(null)\n\nfunction useSidebar() {\n const context = React.use(SidebarContext)\n if (!context) {\n throw new Error('useSidebar must be used within a SidebarProvider.')\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n expandOnHover = false,\n expandBehavior = 'push',\n showBackdrop = false,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<'div'> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n expandOnHover?: boolean\n expandBehavior?: 'push' | 'overlay'\n showBackdrop?: boolean\n}) {\n const isMobile = useIsMobile()\n const [openMobile, setOpenMobile] = React.useState(false)\n const [isHovered, setIsHovered] = React.useState(false)\n const [hasSubLayout, setHasSubLayout] = React.useState(false)\n const hoverTimeoutRef = React.useRef<NodeJS.Timeout | null>(null)\n const hoverLockRef = React.useRef(false)\n const userClosedSidebarRef = React.useRef(false)\n\n // Use defaultOpen as initial state for both server and client to avoid hydration mismatch.\n // Viewport-based adjustments happen in useLayoutEffect (synchronous, before paint).\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n\n // Synchronously adjust sidebar state based on viewport before first paint.\n // This prevents both hydration mismatch and visual flash.\n const LG_BREAKPOINT = 1024\n React.useLayoutEffect(() => {\n if (isMobile) {\n _setOpen(false)\n setOpenMobile(false)\n }\n else if (window.innerWidth < LG_BREAKPOINT) {\n _setOpen(false)\n }\n }, [isMobile])\n\n // When viewport goes below md, reset \"user closed\" so sidebar auto-opens at lg+.\n React.useEffect(() => {\n if (isMobile) {\n userClosedSidebarRef.current = false\n }\n }, [isMobile])\n\n // Respond to viewport changes: collapse below lg, restore at lg+ (unless user explicitly closed).\n React.useEffect(() => {\n if (isMobile)\n return\n const mql = window.matchMedia(`(min-width: ${LG_BREAKPOINT}px)`)\n const onChange = () => {\n if (window.innerWidth >= LG_BREAKPOINT) {\n if (!userClosedSidebarRef.current)\n _setOpen(true)\n }\n else {\n _setOpen(false)\n }\n }\n mql.addEventListener('change', onChange)\n return () => mql.removeEventListener('change', onChange)\n }, [isMobile])\n\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === 'function' ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n }\n else {\n _setOpen(openState)\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n },\n [setOpenProp, open],\n )\n\n // Handlers for the hover functionality.\n const handleMouseEnter = React.useCallback(() => {\n if (!expandOnHover)\n return\n // Prevent hover expansion if we just closed on navigation\n if (hoverLockRef.current)\n return\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current)\n }\n setIsHovered(true)\n }, [expandOnHover])\n\n const handleMouseLeave = React.useCallback(() => {\n if (!expandOnHover)\n return\n // In overlay mode, use shorter delay for more responsive feel\n // In push mode, use a longer delay for better UX\n const delay = expandBehavior === 'overlay' ? 200 : 300\n hoverTimeoutRef.current = setTimeout(() => {\n setIsHovered(false)\n }, delay)\n }, [expandOnHover, expandBehavior])\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n if (isMobile) {\n setOpenMobile(current => !current)\n return\n }\n\n const newState = !open\n if (!newState)\n userClosedSidebarRef.current = true\n else userClosedSidebarRef.current = false\n setOpen(newState)\n\n // If closing, ensure hover state is also cleared.\n if (!newState && expandOnHover) {\n setIsHovered(false)\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current)\n }\n }\n }, [isMobile, setOpen, open, setOpenMobile, expandOnHover])\n\n // Force close the sidebar (used for backdrop clicks and outside clicks in overlay mode)\n const forceClose = React.useCallback(() => {\n if (isMobile) {\n setOpenMobile(false)\n return\n }\n\n userClosedSidebarRef.current = true\n setOpen(false)\n setIsHovered(false)\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current)\n }\n }, [isMobile, setOpen, setOpenMobile])\n\n // Close sidebar on navigation with hover lock to prevent immediate re-expansion\n // The hover lock prevents the sidebar from immediately re-expanding when clicking\n // menu items while the mouse is still hovering over the sidebar\n const closeForNavigation = React.useCallback(() => {\n if (isMobile) {\n setOpenMobile(false)\n return\n }\n\n setOpen(false)\n setIsHovered(false)\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current)\n }\n // Lock hover expansion for a short time to prevent immediate re-expansion\n // when clicking menu items while mouse is still over the sidebar\n hoverLockRef.current = true\n setTimeout(() => {\n hoverLockRef.current = false\n }, 300)\n }, [isMobile, setOpen, setOpenMobile])\n\n // Adds a keyboard shortcut to toggle the sidebar.\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n toggleSidebar()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n return () => window.removeEventListener('keydown', handleKeyDown)\n }, [toggleSidebar])\n\n // Determine the effective open state, considering hover if enabled.\n const effectiveOpen = open || (expandOnHover && isHovered)\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = effectiveOpen ? 'expanded' : 'collapsed'\n\n const contextValue = React.useMemo<SidebarContext>(\n () => ({\n state,\n open: effectiveOpen,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n handleMouseEnter,\n handleMouseLeave,\n forceClose,\n closeForNavigation,\n hasSubLayout,\n setHasSubLayout,\n expandBehavior,\n showBackdrop,\n }),\n [\n state,\n effectiveOpen,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n handleMouseEnter,\n handleMouseLeave,\n forceClose,\n closeForNavigation,\n hasSubLayout,\n setHasSubLayout,\n expandBehavior,\n showBackdrop,\n ],\n )\n\n return (\n <SidebarContext value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n '--sidebar-width': SIDEBAR_WIDTH,\n '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n 'group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </TooltipProvider>\n </SidebarContext>\n )\n}\n\nfunction Sidebar({\n side = 'left',\n variant = 'sidebar',\n collapsible = 'offcanvas',\n className,\n children,\n ...props\n}: React.ComponentProps<'div'> & {\n side?: 'left' | 'right'\n variant?: 'sidebar' | 'floating' | 'inset'\n collapsible?: 'offcanvas' | 'icon' | 'none'\n}) {\n const {\n isMobile,\n state,\n openMobile,\n setOpenMobile,\n handleMouseEnter,\n handleMouseLeave,\n expandBehavior,\n showBackdrop,\n forceClose,\n } = useSidebar()\n const sidebarRef = React.useRef<HTMLDivElement>(null)\n const [showBackdropElement, setShowBackdropElement] = React.useState(false)\n const [backdropVisible, setBackdropVisible] = React.useState(false)\n\n // Handle backdrop animation state\n React.useEffect(() => {\n if (showBackdrop && expandBehavior === 'overlay' && state === 'expanded') {\n // First mount the element\n setShowBackdropElement(true)\n // Then trigger the animation in the next frame\n requestAnimationFrame(() => {\n setBackdropVisible(true)\n })\n }\n else {\n // First trigger the fade-out animation\n setBackdropVisible(false)\n // Then unmount the element after animation completes\n const timer = setTimeout(() => {\n setShowBackdropElement(false)\n }, 200) // Match the transition duration\n return () => clearTimeout(timer)\n }\n }, [showBackdrop, expandBehavior, state])\n\n if (collapsible === 'none') {\n return (\n <div\n data-slot=\"sidebar\"\n className={cn(\n 'bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col',\n side === 'left' ? 'border-r' : 'border-l',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n onOpenAutoFocus={e => e.preventDefault()}\n className=\"bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden\"\n style={\n {\n '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n side={side}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </SheetContent>\n </Sheet>\n )\n }\n\n return (\n <div\n className=\"group peer text-sidebar-foreground hidden md:block\"\n data-state={state}\n data-collapsible={state === 'collapsed' ? collapsible : ''}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n className={cn(\n 'relative w-(--sidebar-width) bg-transparent transition-[width] duration-300 ease-[cubic-bezier(0.25,0.1,0.25,1)]',\n 'group-data-[collapsible=offcanvas]:w-0',\n 'group-data-[side=right]:rotate-180',\n // In overlay mode, gap stays at collapsed width; in push mode, gap transitions\n expandBehavior === 'overlay'\n ? variant === 'floating' || variant === 'inset'\n ? 'w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'\n : 'w-(--sidebar-width-icon)'\n : variant === 'floating' || variant === 'inset'\n ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'\n : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',\n )}\n />\n <div\n ref={sidebarRef}\n className={cn(\n 'border-sidebar-border fixed inset-y-0 hidden w-(--sidebar-width) transition-[left,right,width] duration-300 ease-[cubic-bezier(0.25,0.1,0.25,1)] md:flex',\n // Z-index: Higher for overlay mode to float above content\n expandBehavior === 'overlay' ? 'z-50' : 'z-10',\n side === 'left'\n ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n // Adjust the padding for floating and inset variants.\n variant === 'floating' || variant === 'inset'\n ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'\n : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l',\n className,\n )}\n {...props}\n >\n <div\n data-sidebar=\"sidebar\"\n className={cn(\n 'bg-sidebar flex h-full w-full flex-col',\n 'group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm',\n // Add shadow when expanded in overlay mode\n expandBehavior === 'overlay' && state === 'expanded' && 'shadow-lg',\n )}\n >\n {children}\n </div>\n </div>\n\n {/* Backdrop/Overlay - only shown in overlay mode when expanded */}\n {showBackdropElement && (\n <div\n className={cn(\n 'fixed inset-0 z-40 hidden bg-black/50 transition-opacity duration-200 ease-in-out md:block',\n backdropVisible ? 'opacity-100' : 'opacity-0',\n )}\n onMouseEnter={() => forceClose()}\n onClick={() => forceClose()}\n aria-hidden=\"true\"\n />\n )}\n </div>\n )\n}\n\nfunction SidebarTrigger({ className, onClick, ...props }: React.ComponentProps<typeof Button>) {\n const { toggleSidebar, open } = useSidebar()\n\n return (\n <Tooltip\n message={open ? 'Close Sidebar' : 'Open Sidebar'}\n side=\"right\"\n align=\"center\"\n delayDuration={500}\n >\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\n 'text-icon-primary hover:bg-sidebar hover:text-sidebar-primary h-8 w-8 rounded-lg transition-all',\n className,\n )}\n onClick={(event) => {\n onClick?.(event)\n toggleSidebar()\n }}\n {...props}\n >\n {open\n ? (\n <Icon icon={PanelLeftCloseIcon} className=\"size-4\" />\n )\n : (\n <Icon icon={PanelLeftOpenIcon} className=\"size-4\" />\n )}\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n </Tooltip>\n )\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<'button'>) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n 'hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-[cubic-bezier(0.25,0.1,0.25,1)] group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex',\n 'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full',\n '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<'main'>) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n 'bg-background relative flex w-full min-w-0 flex-1 flex-col',\n 'md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInput({ className, ...props }: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn('bg-background h-8 w-full shadow-none', className)}\n {...props}\n />\n )\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn('flex flex-col gap-2 p-2', className)}\n {...props}\n />\n )\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn('flex flex-col gap-2 p-2', className)}\n {...props}\n />\n )\n}\n\nfunction SidebarSeparator({ className, ...props }: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn('bg-sidebar-border w-full', className)}\n {...props}\n />\n )\n}\n\nfunction SidebarContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n 'flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn('relative flex w-full min-w-0 flex-col p-2', className)}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupLabel({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<'div'> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'div'\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n 'text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-[cubic-bezier(0.25,0.1,0.25,1)] focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupAction({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<'button'> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'button'\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'group-data-[collapsible=icon]:hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn('w-full text-sm', className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<'ul'>) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn('flex w-full min-w-0 flex-col gap-1', className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<'li'>) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn('group/menu-item relative', className)}\n {...props}\n />\n )\n}\n\nconst sidebarMenuButtonVariants = cva(\n 'peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar data-[active=true]:text-sidebar-primary data-[state=open]:hover:bg-sidebar data-[state=open]:hover:text-sidebar-primary group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',\n {\n variants: {\n variant: {\n default: '',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n size: {\n default: 'h-8 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nfunction SidebarMenuButton({\n asChild = false,\n isActive = false,\n variant = 'default',\n size = 'default',\n tooltip,\n className,\n ...props\n}: React.ComponentProps<'button'> & {\n asChild?: boolean\n isActive?: boolean\n tooltip?:\n | string\n | React.ReactNode\n | {\n message: string | React.ReactNode\n side?: 'top' | 'right' | 'bottom' | 'left'\n align?: 'start' | 'center' | 'end'\n }\n} & VariantProps<typeof sidebarMenuButtonVariants>) {\n const Comp = asChild ? Slot : 'button'\n const { isMobile, state } = useSidebar()\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n )\n\n if (!tooltip) {\n return button\n }\n\n // Handle string or ReactNode tooltip\n const tooltipMessage\n = typeof tooltip === 'string'\n || React.isValidElement(tooltip)\n || (typeof tooltip === 'object' && 'message' in tooltip)\n ? typeof tooltip === 'string' || React.isValidElement(tooltip)\n ? tooltip\n : tooltip.message\n : null\n\n const tooltipProps\n = typeof tooltip === 'object' && 'message' in tooltip\n ? { side: tooltip.side, align: tooltip.align }\n : {}\n\n return (\n <Tooltip\n message={tooltipMessage}\n side=\"right\"\n align=\"center\"\n hidden={state !== 'collapsed' || isMobile}\n {...tooltipProps}\n >\n {button}\n </Tooltip>\n )\n}\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<'button'> & {\n asChild?: boolean\n showOnHover?: boolean\n}) {\n const Comp = asChild ? Slot : 'button'\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n showOnHover\n && 'peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuBadge({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n 'text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none',\n 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<'div'> & {\n showIcon?: boolean\n}) {\n // Random width between 50 to 90%.\n const width = React.useMemo(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n }, [])\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn('flex h-8 items-center gap-2 rounded-md px-2', className)}\n {...props}\n >\n {showIcon && <Skeleton className=\"size-4 rounded-md\" data-sidebar=\"menu-skeleton-icon\" />}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={\n {\n '--skeleton-width': width,\n } as React.CSSProperties\n }\n />\n </div>\n )\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n 'border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col px-2.5',\n 'group-data-[collapsible=icon]:hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubItem({ className, ...props }: React.ComponentProps<'li'>) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn('group/menu-sub-item relative', className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = 'md',\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<'a'> & {\n asChild?: boolean\n size?: 'sm' | 'md'\n isActive?: boolean\n}) {\n const Comp = asChild ? Slot : 'a'\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',\n 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nexport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n}\n","import { cn } from '@repo/shadcn/lib/utils'\nimport { X as RemoveIcon } from 'lucide-react'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Badge, Input } from '../..'\nimport { Icon } from '../../icons/icon-wrapper'\n\n/**\n * Used for identifying split characters when pasting\n * Splits on: newlines, tabs, semicolons, commas, and pipes\n * Does NOT split on dots (.) or slashes (/) to preserve email addresses and URLs\n */\nconst SPLITTER_REGEX = /[\\n\\t;,|]+/\n\n/**\n * Used for trimming leading/trailing whitespace and special characters\n * Preserves alphanumeric characters, dots, @, hyphens, and underscores\n */\nconst FORMATTING_REGEX = /^[\\s\"'<>]+|[\\s\"'<>]+$/g\n\ninterface TagsInputProps extends React.HTMLAttributes<HTMLDivElement> {\n value: string[]\n onValueChange: (value: string[]) => void\n placeholder?: string\n maxItems?: number\n minItems?: number\n /**\n * Optional Zod schema for validating individual tag values\n */\n validator?: z.ZodType<string>\n /**\n * Optional callback for handling validation errors externally\n * This is useful when integrating with form libraries like conform-to\n */\n onValidationError?: (error: string | null) => void\n /**\n * Optional external error message to display\n * This is useful when the error comes from a form library like conform-to\n */\n error?: string | string[]\n /**\n * Whether to show validation errors inline\n * Set to false when handling errors externally with onValidationError\n */\n showValidationErrors?: boolean\n name?: string\n key?: string\n}\n\ninterface TagsInputContextProps {\n value: string[]\n\n onValueChange: (value: any) => void\n inputValue: string\n setInputValue: React.Dispatch<React.SetStateAction<string>>\n activeIndex: number\n setActiveIndex: React.Dispatch<React.SetStateAction<number>>\n validator?: z.ZodType<string>\n validationError: string | null\n setValidationError: React.Dispatch<React.SetStateAction<string | null>>\n}\n\nconst TagInputContext = React.createContext<TagsInputContextProps | null>(null)\n\nexport function TagsInput({ ref, value, onValueChange, placeholder, maxItems, minItems, className, dir, validator, onValidationError, error, showValidationErrors = true, name, key, ...props }: TagsInputProps & { ref?: React.RefObject<HTMLDivElement | null> }) {\n const [activeIndex, setActiveIndex] = React.useState(-1)\n const [inputValue, setInputValue] = React.useState('')\n const [disableInput, setDisableInput] = React.useState(false)\n const [disableButton, setDisableButton] = React.useState(false)\n const [isValueSelected, setIsValueSelected] = React.useState(false)\n const [selectedValue, setSelectedValue] = React.useState('')\n const [validationError, setValidationError] = React.useState<string | null>(null)\n\n const parseMinItems = minItems ?? 0\n const parseMaxItems = maxItems ?? Infinity\n\n const onValueChangeHandler = React.useCallback(\n (val: string) => {\n // Reset validation error\n const setError = (errorMessage: string | null) => {\n setValidationError(errorMessage)\n if (onValidationError) {\n onValidationError(errorMessage)\n }\n }\n\n setError(null)\n\n // Skip empty values\n if (!val.trim())\n return\n\n // Check for duplicates and max items\n if (value.includes(val)) {\n setError('This tag already exists')\n return\n }\n\n if (value.length >= parseMaxItems) {\n setError(`Maximum of ${parseMaxItems} tags allowed`)\n return\n }\n\n // Validate with Zod schema if provided\n if (validator) {\n try {\n validator.parse(val)\n onValueChange([...value, val])\n }\n catch (error) {\n if (error instanceof z.ZodError) {\n // Use Zod's error message directly\n setError((error as z.ZodError).issues[0]?.message || 'Invalid input')\n }\n else {\n setError('Validation failed')\n }\n }\n }\n else {\n // No validator, just add the value\n onValueChange([...value, val])\n }\n },\n [value, validator, parseMaxItems],\n )\n\n const RemoveValue = React.useCallback(\n (val: string) => {\n if (value.includes(val) && value.length > parseMinItems) {\n onValueChange(value.filter(item => item !== val))\n }\n },\n [value],\n )\n\n const handlePaste = React.useCallback(\n (e: React.ClipboardEvent<HTMLInputElement>) => {\n e.preventDefault()\n const pastedText = e.clipboardData.getData('text')\n\n if (!pastedText)\n return\n\n // Split and clean the pasted values\n const values = pastedText\n .split(SPLITTER_REGEX)\n .map(val => val.trim())\n .filter(Boolean)\n .map(val => val.replace(FORMATTING_REGEX, ''))\n\n if (values.length === 0)\n return\n\n // If there's only one value, treat it as a normal input with validation\n if (values.length === 1) {\n onValueChangeHandler(values[0]!)\n return\n }\n\n // For multiple values, validate and add each one\n const validValues: string[] = []\n let hasError = false\n\n for (const val of values) {\n // Skip if already exists\n if (value.includes(val) || validValues.includes(val)) {\n continue\n }\n\n // Check max items limit\n if (value.length + validValues.length >= parseMaxItems) {\n break\n }\n\n // Validate with Zod schema if provided\n if (validator) {\n try {\n validator.parse(val)\n validValues.push(val)\n }\n catch {\n // Skip invalid values when pasting multiple items\n hasError = true\n continue\n }\n }\n else {\n validValues.push(val)\n }\n }\n\n // Add all valid values at once\n if (validValues.length > 0) {\n onValueChange([...value, ...validValues])\n }\n\n // Show error if some values were invalid\n if (hasError && validator) {\n setValidationError('Some pasted values were invalid and skipped')\n if (onValidationError) {\n onValidationError('Some pasted values were invalid and skipped')\n }\n // Clear error after 3 seconds\n setTimeout(() => {\n setValidationError(null)\n if (onValidationError) {\n onValidationError(null)\n }\n }, 3000)\n }\n },\n [value, onValueChangeHandler, validator, parseMaxItems, onValidationError],\n )\n\n const handleSelect = React.useCallback(\n (e: React.SyntheticEvent<HTMLInputElement>) => {\n const target = e.target as HTMLInputElement\n const selection = inputValue.substring(\n target.selectionStart ?? 0,\n target.selectionEnd ?? 0,\n )\n\n setSelectedValue(selection)\n setIsValueSelected(selection === inputValue)\n },\n [inputValue],\n )\n\n React.useEffect(() => {\n const VerifyDisable = () => {\n if (value.length - 1 >= parseMinItems) {\n setDisableButton(false)\n }\n else {\n setDisableButton(true)\n }\n if (value.length + 1 <= parseMaxItems) {\n setDisableInput(false)\n }\n else {\n setDisableInput(true)\n }\n }\n VerifyDisable()\n }, [value, parseMinItems, parseMaxItems])\n\n const handleKeyDown = React.useCallback(\n async (e: React.KeyboardEvent<HTMLInputElement>) => {\n e.stopPropagation()\n\n const moveNext = () => {\n const nextIndex = activeIndex + 1 > value.length - 1 ? -1 : activeIndex + 1\n setActiveIndex(nextIndex)\n }\n\n const movePrev = () => {\n const prevIndex = activeIndex - 1 < 0 ? value.length - 1 : activeIndex - 1\n setActiveIndex(prevIndex)\n }\n\n const moveCurrent = () => {\n const newIndex\n = activeIndex - 1 <= 0 ? (value.length - 1 === 0 ? -1 : 0) : activeIndex - 1\n setActiveIndex(newIndex)\n }\n const target = e.currentTarget\n\n switch (e.key) {\n case 'ArrowLeft': {\n if (dir === 'rtl') {\n if (value.length > 0 && activeIndex !== -1) {\n moveNext()\n }\n }\n else {\n if (value.length > 0 && target.selectionStart === 0) {\n movePrev()\n }\n }\n break\n }\n\n case 'ArrowRight': {\n if (dir === 'rtl') {\n if (value.length > 0 && target.selectionStart === 0) {\n movePrev()\n }\n }\n else {\n if (value.length > 0 && activeIndex !== -1) {\n moveNext()\n }\n }\n break\n }\n\n case 'Backspace':\n case 'Delete': {\n if (value.length > 0) {\n if (activeIndex !== -1 && activeIndex < value.length) {\n RemoveValue(value[activeIndex]!)\n moveCurrent()\n }\n else {\n if (target.selectionStart === 0) {\n if (selectedValue === inputValue || isValueSelected) {\n RemoveValue(value[value.length - 1]!)\n }\n }\n }\n }\n break\n }\n\n case 'Escape': {\n const newIndex = activeIndex === -1 ? value.length - 1 : -1\n setActiveIndex(newIndex)\n break\n }\n\n case 'Enter':\n case ',': {\n if (inputValue.trim() !== '') {\n e.preventDefault()\n onValueChangeHandler(inputValue)\n setInputValue('')\n }\n break\n }\n }\n },\n [\n activeIndex,\n value,\n inputValue,\n RemoveValue,\n dir,\n selectedValue,\n isValueSelected,\n onValueChangeHandler,\n ],\n )\n\n const mousePreventDefault = React.useCallback((e: React.MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n }, [])\n\n const handleChange = React.useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n setInputValue(e.currentTarget.value)\n }, [])\n\n const handleBlur = React.useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n // Don't add tag on blur if we're submitting the form\n // Check if the related target (element receiving focus) is a submit button\n const relatedTarget = e.relatedTarget as HTMLElement\n const isSubmitButton\n = relatedTarget?.tagName === 'BUTTON'\n && (relatedTarget?.getAttribute('type') === 'submit'\n || relatedTarget?.closest('button[type=\"submit\"]'))\n\n // Only add tag if we're not submitting the form\n if (!isSubmitButton && inputValue.trim() !== '') {\n onValueChangeHandler(inputValue)\n setInputValue('')\n }\n },\n [inputValue, onValueChangeHandler],\n )\n\n const contextValue = React.useMemo(\n () => ({\n value,\n onValueChange,\n inputValue,\n setInputValue,\n activeIndex,\n setActiveIndex,\n validator,\n validationError,\n setValidationError,\n }),\n [value, onValueChange, inputValue, activeIndex, validator, validationError],\n )\n\n return (\n <TagInputContext value={contextValue}>\n <div\n {...props}\n ref={ref}\n dir={dir}\n className={cn(\n 'border-input-border bg-input-background/50 text-input-foreground flex min-h-10 flex-wrap items-center gap-1 overflow-hidden rounded-lg border px-3 py-2 transition-all',\n activeIndex === -1\n ? 'focus-within:border-input-focus-border focus-within:shadow-(--input-focus-shadow) focus-within:ring-0 focus-within:ring-offset-0 focus-within:outline-hidden'\n : 'focus-within:ring-0 focus-within:ring-offset-0 focus-within:outline-hidden',\n className,\n )}\n suppressHydrationWarning\n >\n {/* Show validation errors if enabled or show external errors */}\n {((showValidationErrors && validationError) || error) && (\n <div className=\"mb-1 w-full text-sm text-red-500\">\n {error ? (Array.isArray(error) ? error[0] : error) : validationError}\n </div>\n )}\n\n {value.map((item, index) => (\n <Badge\n tabIndex={activeIndex !== -1 ? 0 : activeIndex}\n key={item}\n aria-disabled={disableButton}\n data-active={activeIndex === index}\n className={cn(\n 'data-[active=\\'true\\']:ring-muted-foreground relative flex items-center gap-1 truncate rounded px-1 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 data-[active=\\'true\\']:ring-2',\n )}\n type=\"secondary\"\n >\n <span className=\"text-xs\">{item}</span>\n <button\n type=\"button\"\n aria-label={`Remove ${item} option`}\n aria-roledescription=\"button to remove option\"\n disabled={disableButton}\n onMouseDown={mousePreventDefault}\n onClick={() => RemoveValue(item)}\n className=\"disabled:cursor-not-allowed\"\n >\n <span className=\"sr-only\">\n Remove\n {item}\n {' '}\n option\n </span>\n <Icon icon={RemoveIcon} className=\"hover:stroke-destructive h-4 w-4\" />\n </button>\n </Badge>\n ))}\n <Input\n tabIndex={0}\n aria-label=\"input tag\"\n disabled={disableInput}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onBlur={handleBlur}\n value={inputValue}\n onSelect={handleSelect}\n onChange={activeIndex === -1 ? handleChange : undefined}\n placeholder={placeholder}\n onClick={() => setActiveIndex(-1)}\n className={cn(\n 'text-input-foreground h-6 min-w-fit flex-1 border-0 bg-transparent p-0 py-1 shadow-none',\n 'placeholder:text-input-placeholder',\n 'focus-visible:border-transparent focus-visible:shadow-none focus-visible:ring-0 focus-visible:ring-offset-0',\n activeIndex !== -1 && 'caret-transparent',\n )}\n />\n </div>\n {/* Hidden input for form submission */}\n <select\n name={name}\n id={props.id}\n key={key}\n multiple\n value={value}\n defaultValue={undefined}\n className=\"absolute top-0 left-0 h-0 w-0\"\n onChange={() => undefined}\n >\n <option value=\"\"></option>\n {value.map((option, idx) => (\n <option key={`${option}-${idx}`} value={option} />\n ))}\n </select>\n </TagInputContext>\n )\n}\n\nTagsInput.displayName = 'TagsInput'\n","import type { Task, TaskContext, TaskOutcome } from '../types'\n\nexport interface ExecutorCallbacks {\n onUpdate: (task: Task) => void\n onCancelReady?: (setCancelled: (v: boolean) => void) => void\n onTaskComplete?: () => void\n}\n\nexport function createTaskContext<TItem = unknown, TResult = unknown>(\n task: Task<TResult>,\n callbacks: ExecutorCallbacks,\n): {\n ctx: TaskContext<TItem, TResult>\n getCancelled: () => boolean\n setCancelled: (v: boolean) => void\n getShouldStop: () => boolean\n} {\n let cancelled = false\n let shouldStop = false\n const cleanupCallbacks: Array<() => void> = []\n\n const updateTask = () => {\n callbacks.onUpdate({\n ...task,\n succeededItems: [...task.succeededItems],\n failedItems: [...task.failedItems],\n } as Task)\n }\n\n const ctx: TaskContext<TItem, TResult> = {\n get items() {\n return (task.items ?? []) as TItem[]\n },\n get cancelled() {\n return cancelled || shouldStop\n },\n get failedItems() {\n return [...task.failedItems]\n },\n succeed(itemId?: string) {\n task.completed += 1\n if (itemId) {\n task.succeededItems = [...task.succeededItems, itemId]\n }\n updateTask()\n },\n fail(itemId?: string, message?: string) {\n task.failed += 1\n if (itemId || message) {\n task.failedItems = [\n ...task.failedItems,\n { id: itemId, message: message ?? 'Unknown error' },\n ]\n }\n // Check errorStrategy: 'stop' - set flag to stop processing\n if (task.errorStrategy === 'stop') {\n shouldStop = true\n }\n updateTask()\n },\n setTitle(title: string) {\n task.title = title\n updateTask()\n },\n setResult(result: TResult) {\n task.result = result\n },\n onCancel(cleanup: () => void) {\n cleanupCallbacks.push(cleanup)\n },\n }\n\n return {\n ctx,\n getCancelled: () => cancelled,\n setCancelled: (v: boolean) => {\n cancelled = v\n // Call all cleanup callbacks when cancelled\n if (v) {\n cleanupCallbacks.forEach((cleanup) => {\n try {\n cleanup()\n }\n catch (error) {\n console.error('[TaskQueue] Cleanup callback error:', error)\n }\n })\n }\n },\n getShouldStop: () => shouldStop,\n }\n}\n\nexport async function executeTask<TResult = unknown>(\n task: Task<TResult>,\n callbacks: ExecutorCallbacks,\n): Promise<TaskOutcome<TResult>> {\n const processor = task._processor\n if (!processor) {\n return {\n status: 'failed',\n completed: 0,\n failed: 0,\n failedItems: [{ message: 'No processor attached' }],\n }\n }\n\n task.status = 'running'\n task.startedAt = Date.now()\n // Ensure succeededItems exists (backwards compatibility)\n if (!task.succeededItems) {\n task.succeededItems = []\n }\n callbacks.onUpdate({ ...task } as Task)\n\n const { ctx, getCancelled, setCancelled, getShouldStop } = createTaskContext(task, callbacks)\n\n // Expose setCancelled so the queue can trigger cancellation\n callbacks.onCancelReady?.(setCancelled)\n\n try {\n await processor(ctx)\n\n if (getCancelled()) {\n task.status = 'cancelled'\n }\n else if (getShouldStop() || task.failed > 0) {\n // errorStrategy: 'stop' triggered or has failures\n task.status = 'failed'\n }\n else {\n task.status = 'completed'\n }\n }\n catch (error) {\n task.status = 'failed'\n const message = error instanceof Error ? error.message : 'Unknown error'\n task.failedItems = [...task.failedItems, { message }]\n task.failed += 1\n }\n\n task.completedAt = Date.now()\n callbacks.onUpdate({ ...task } as Task)\n\n // Notify that task has completed (for timeout cleanup)\n callbacks.onTaskComplete?.()\n\n return {\n status: task.status as 'completed' | 'failed' | 'cancelled',\n completed: task.completed,\n failed: task.failed,\n failedItems: [...task.failedItems],\n result: task.result,\n }\n}\n","export const TASK_QUEUE_DEFAULTS = {\n concurrency: 3,\n errorStrategy: 'continue' as const,\n cancelable: true,\n retryable: true,\n} as const\n\nexport const TASK_STORAGE_KEY = 'datum-task-queue'\n","import type { TaskMetadata } from '../types'\n\n/**\n * Check if code is running in a browser environment.\n * Used for SSR safety in storage and other browser-dependent code.\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof localStorage !== 'undefined'\n}\n\nexport function generateTaskId(): string {\n // Use crypto.randomUUID() if available for better uniqueness\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return `task_${crypto.randomUUID()}`\n }\n // Fallback for older environments\n return `task_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`\n}\n\n// --- Item ID Extraction ---\n\n/**\n * Extract an ID from an item using common patterns.\n * Checks: primitives (string/number) → obj.id → obj.name → obj.key → obj.uuid\n */\nexport function extractItemId(item: unknown): string | undefined {\n if (typeof item === 'string' || typeof item === 'number')\n return String(item)\n if (item && typeof item === 'object') {\n const obj = item as Record<string, unknown>\n if (typeof obj.id === 'string' || typeof obj.id === 'number')\n return String(obj.id)\n if (typeof obj.name === 'string')\n return obj.name\n if (typeof obj.key === 'string')\n return obj.key\n if (typeof obj.uuid === 'string')\n return obj.uuid\n }\n return undefined\n}\n\n// --- Metadata Factory Functions ---\n\n/**\n * Create metadata for project-scoped tasks.\n * Use this when enqueueing tasks that operate on project resources.\n */\nexport function createProjectMetadata(\n project: { id: string, name: string },\n org: { id: string, name: string },\n extra?: Record<string, unknown>,\n): TaskMetadata {\n return {\n scope: 'project',\n projectId: project.id,\n projectName: project.name,\n orgId: org.id,\n orgName: org.name,\n ...extra,\n }\n}\n\n/**\n * Create metadata for organization-scoped tasks.\n * Use this when enqueueing tasks that operate on org-level resources.\n */\nexport function createOrgMetadata(\n org: { id: string, name: string },\n extra?: Record<string, unknown>,\n): TaskMetadata {\n return {\n scope: 'org',\n orgId: org.id,\n orgName: org.name,\n ...extra,\n }\n}\n\n/**\n * Create metadata for user-scoped tasks.\n * Use this when enqueueing tasks that operate on user-level resources.\n */\nexport function createUserMetadata(extra?: Record<string, unknown>): TaskMetadata {\n return {\n scope: 'user',\n ...extra,\n }\n}\n","import type { Task, TaskStorage } from '../../types'\nimport { TASK_STORAGE_KEY } from '../../constants'\nimport { isBrowser } from '../../utils'\n\nexport class LocalTaskStorage implements TaskStorage {\n private key: string\n\n constructor(key: string = TASK_STORAGE_KEY) {\n this.key = key\n }\n\n getAll(): Task[] {\n if (!isBrowser())\n return []\n try {\n const raw = localStorage.getItem(this.key)\n return raw ? (JSON.parse(raw) as Task[]) : []\n }\n catch {\n return []\n }\n }\n\n get(id: string): Task | undefined {\n if (!isBrowser())\n return undefined\n return this.getAll().find(t => t.id === id)\n }\n\n set(id: string, task: Task): void {\n if (!isBrowser())\n return\n const tasks = this.getAll()\n const index = tasks.findIndex(t => t.id === id)\n if (index >= 0) {\n tasks[index] = task\n }\n else {\n tasks.push(task)\n }\n this.persist(tasks)\n }\n\n remove(id: string): void {\n if (!isBrowser())\n return\n const tasks = this.getAll().filter(t => t.id !== id)\n this.persist(tasks)\n }\n\n clear(): void {\n if (!isBrowser())\n return\n try {\n localStorage.removeItem(this.key)\n }\n catch {\n // Ignore storage errors\n }\n }\n\n private persist(tasks: Task[]): void {\n try {\n // Strip non-serializable properties but keep _originalItems for retry\n const serializable = tasks.map((task) => {\n const { _processor, _icon, _completionActions, ...rest } = task as Task & {\n _processor?: unknown\n _icon?: unknown\n _completionActions?: unknown\n }\n return rest\n })\n localStorage.setItem(this.key, JSON.stringify(serializable))\n }\n catch (error) {\n if (error instanceof Error && error.name === 'QuotaExceededError') {\n console.warn('[TaskQueue] Storage quota exceeded. Consider dismissing old tasks.')\n }\n }\n }\n}\n","import type { Task, TaskStorage } from '../../types'\n\n/**\n * In-memory task storage.\n *\n * Tasks are stored in a Map and lost on page reload.\n * Use with beforeunload warning to alert users of active tasks.\n *\n * SSR-safe: works on both server and client (just empty on server).\n */\nexport class MemoryTaskStorage implements TaskStorage {\n private tasks: Map<string, Task> = new Map()\n\n getAll(): Task[] {\n return Array.from(this.tasks.values())\n }\n\n get(id: string): Task | undefined {\n return this.tasks.get(id)\n }\n\n set(id: string, task: Task): void {\n this.tasks.set(id, task)\n }\n\n remove(id: string): void {\n this.tasks.delete(id)\n }\n\n clear(): void {\n this.tasks.clear()\n }\n}\n","import type { RedisClient, Task, TaskStorage } from '../../types'\nimport { TASK_STORAGE_KEY } from '../../constants'\nimport { isBrowser } from '../../utils'\n\n// Default TTL: 7 days in seconds\nconst DEFAULT_TTL = 60 * 60 * 24 * 7\n\nexport class RedisTaskStorage implements TaskStorage {\n private client: RedisClient\n private key: string\n private cache: Map<string, Task> = new Map()\n private initialized = false\n private initPromise: Promise<void> | null = null\n private ttl: number\n\n constructor(client: RedisClient, key: string = TASK_STORAGE_KEY, ttl: number = DEFAULT_TTL) {\n this.client = client\n this.key = key\n this.ttl = ttl\n\n // Auto-initialize on client side, store promise to await later\n if (isBrowser()) {\n this.initPromise = this.initialize()\n }\n }\n\n /**\n * Wait for initialization to complete.\n * Call this before accessing data if you need guaranteed consistency.\n */\n async waitForInit(): Promise<void> {\n if (this.initPromise) {\n await this.initPromise\n }\n }\n\n private async initialize(): Promise<void> {\n if (this.initialized)\n return\n if (!isBrowser()) {\n this.initialized = true\n return\n }\n try {\n const raw = await this.client.get(this.key)\n if (raw) {\n const tasks = JSON.parse(raw) as Task[]\n tasks.forEach(t => this.cache.set(t.id, t))\n }\n this.initialized = true\n }\n catch {\n this.initialized = true\n }\n }\n\n getAll(): Task[] {\n return Array.from(this.cache.values())\n }\n\n get(id: string): Task | undefined {\n return this.cache.get(id)\n }\n\n set(id: string, task: Task): void {\n if (!isBrowser())\n return\n this.cache.set(id, task)\n this.syncToRedis()\n }\n\n remove(id: string): void {\n if (!isBrowser())\n return\n this.cache.delete(id)\n this.syncToRedis()\n }\n\n clear(): void {\n if (!isBrowser())\n return\n this.cache.clear()\n this.client.del(this.key).catch(() => {})\n }\n\n private syncToRedis(): void {\n // Strip non-serializable properties but keep _originalItems for retry\n const tasks = this.getAll().map((task) => {\n const { _processor, _icon, _completionActions, ...rest } = task as Task & {\n _processor?: unknown\n _icon?: unknown\n _completionActions?: unknown\n }\n return rest\n })\n\n // Use TTL if the client supports it (ioredis style)\n const value = JSON.stringify(tasks)\n if ('setex' in this.client && typeof (this.client as any).setex === 'function') {\n (this.client as any).setex(this.key, this.ttl, value).catch(() => {})\n }\n else {\n this.client.set(this.key, value).catch(() => {})\n }\n }\n}\n","import type { RedisClient, TaskStorage } from '../../types'\nimport { LocalTaskStorage } from './local-storage'\nimport { MemoryTaskStorage } from './memory-storage'\nimport { RedisTaskStorage } from './redis-storage'\n\ninterface DetectStorageOptions {\n redisClient?: RedisClient | null\n storageKey?: string\n storageType?: 'memory' | 'local' | 'auto'\n}\n\n/**\n * Auto-detects and returns the appropriate storage backend.\n *\n * Storage types:\n * - `memory` (default): In-memory storage, tasks lost on reload\n * - `local`: Browser localStorage, tasks persist across reloads\n * - `auto`: Uses Redis if available, otherwise localStorage\n *\n * All storage backends are SSR-safe and will return empty data on the server.\n */\nexport function detectStorage(options: DetectStorageOptions = {}): TaskStorage {\n const { redisClient, storageKey, storageType = 'memory' } = options\n\n // Explicit memory storage (default)\n if (storageType === 'memory') {\n return new MemoryTaskStorage()\n }\n\n // Explicit local storage\n if (storageType === 'local') {\n return new LocalTaskStorage(storageKey)\n }\n\n // Auto-detect: Redis if available, otherwise localStorage\n if (redisClient && redisClient.status === 'ready') {\n return new RedisTaskStorage(redisClient, storageKey)\n }\n\n return new LocalTaskStorage(storageKey)\n}\n","import type {\n EnqueueOptions,\n ItemContext,\n ProcessItemEnqueueOptions,\n SummaryRenderContent,\n Task,\n TaskContext,\n TaskHandle,\n TaskOutcome,\n TaskQueueConfig,\n TaskStorage,\n TaskSummaryData,\n TaskSummaryItem,\n} from '../types'\nimport { TASK_QUEUE_DEFAULTS } from '../constants'\nimport { extractItemId, generateTaskId } from '../utils'\nimport { executeTask } from './executor'\nimport { detectStorage } from './storage'\n\nexport class TaskQueue {\n private storage: TaskStorage\n private concurrency: number\n private runningCount = 0\n private listeners: Set<() => void> = new Set()\n private taskResolvers: Map<string, (outcome: TaskOutcome) => void>\n = new Map()\n\n private snapshot: Task[] = []\n private notifyScheduled = false\n // Keep processors in memory (can't be serialized to storage)\n private processors: Map<string, Task['_processor']> = new Map()\n // Keep cancel functions in memory for running tasks\n private cancelFunctions: Map<string, (v: boolean) => void> = new Map()\n // Keep onComplete callbacks in memory\n private onCompleteCallbacks: Map<\n string,\n (outcome: TaskOutcome) => void | Promise<void>\n > = new Map()\n\n // Keep timeout timers in memory\n private taskTimeouts: Map<string, ReturnType<typeof setTimeout>> = new Map()\n // Summary dialog state (survives navigation because the queue is a singleton)\n private _activeSummary: TaskSummaryData | null = null\n private _summaryRenderContent: SummaryRenderContent | undefined\n\n constructor(config: TaskQueueConfig = {}) {\n this.concurrency = config.concurrency ?? TASK_QUEUE_DEFAULTS.concurrency\n this.storage\n = config.storage\n ?? detectStorage({\n redisClient: config.redisClient,\n storageKey: config.storageKey,\n storageType: config.storageType,\n })\n this._summaryRenderContent = config.summaryRenderContent\n this.updateSnapshot()\n }\n\n // --- useSyncExternalStore compatibility ---\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n getSnapshot = (): Task[] => {\n return this.snapshot\n }\n\n private notify(): void {\n // Batch notifications using microtask to avoid flooding React with sync updates\n if (this.notifyScheduled)\n return\n this.notifyScheduled = true\n\n queueMicrotask(() => {\n this.notifyScheduled = false\n this.updateSnapshot()\n this.listeners.forEach(listener => listener())\n })\n }\n\n private updateSnapshot(): void {\n this.snapshot = this.storage.getAll()\n }\n\n // --- Public API ---\n\n enqueue = <TItem = unknown, TResult = unknown>(\n options: EnqueueOptions<TItem, TResult>,\n ): TaskHandle<TResult> => {\n const id = generateTaskId()\n const items = options.items as unknown[] | undefined\n\n // Determine processor: use provided processor or build from processItem\n let processor: Task['_processor']\n if ('processItem' in options && options.processItem) {\n processor = this.buildProcessor(\n options as ProcessItemEnqueueOptions<TItem, TResult>,\n ) as Task['_processor']\n }\n else if ('processor' in options && options.processor) {\n processor = options.processor as Task['_processor']\n }\n else {\n throw new Error(\n '[TaskQueue] enqueue: must provide either processor or processItem',\n )\n }\n\n const cancelable = options.cancelable ?? TASK_QUEUE_DEFAULTS.cancelable\n const confirmBeforeUnload = options.confirmBeforeUnload ?? true\n\n const task: Task<TResult> = {\n id,\n title: options.title,\n status: 'pending',\n icon: options.icon,\n category: options.category,\n metadata: options.metadata,\n items,\n total: items?.length,\n completed: 0,\n failed: 0,\n succeededItems: [],\n failedItems: [],\n errorStrategy: options.errorStrategy ?? TASK_QUEUE_DEFAULTS.errorStrategy,\n cancelable,\n retryable: options.retryable ?? TASK_QUEUE_DEFAULTS.retryable,\n confirmBeforeUnload,\n completionActions:\n options.completionActions as Task<TResult>['completionActions'],\n retryCount: 0,\n createdAt: Date.now(),\n _processor: processor as Task<TResult>['_processor'],\n _originalItems: items ? [...items] : undefined,\n }\n\n // Store processor in memory (can't be serialized to storage)\n this.processors.set(id, processor)\n\n // Store onComplete callback if provided\n if (options.onComplete) {\n this.onCompleteCallbacks.set(\n id,\n options.onComplete as (outcome: TaskOutcome) => void,\n )\n }\n\n this.storage.set(id, task as Task)\n this.notify()\n\n // Start timeout timer\n const timeout = options.timeout ?? 300000 // Default 5 minutes\n const timeoutId = setTimeout(() => {\n this.handleTaskTimeout(id)\n }, timeout)\n this.taskTimeouts.set(id, timeoutId)\n\n const promise = new Promise<TaskOutcome<TResult>>((resolve) => {\n this.taskResolvers.set(id, resolve as (outcome: TaskOutcome) => void)\n })\n\n this.drain()\n\n return {\n id,\n cancel: () => this.cancel(id),\n promise,\n }\n }\n\n cancel = (taskId: string): void => {\n const task = this.storage.get(taskId)\n if (!task || task.status !== 'running')\n return\n\n const setCancelled = this.cancelFunctions.get(taskId)\n if (setCancelled) {\n setCancelled(true)\n }\n }\n\n retry = (taskId: string): void => {\n const task = this.storage.get(taskId)\n if (!task)\n return\n if (task.status !== 'failed' && task.status !== 'cancelled')\n return\n\n // Get processor from memory (wasn't serialized to storage)\n const processor = this.processors.get(taskId)\n if (!processor) {\n console.error('[TaskQueue] retry: no processor found for task', taskId)\n return\n }\n\n // Check if this is a batch task (has items) or long process (no items)\n const isBatchTask = task.items && task.items.length > 0\n\n if (isBatchTask) {\n // Batch task: Resume from where it stopped\n const remainingItems = this.getRetryItems(task)\n\n if (!remainingItems || remainingItems.length === 0) {\n // Edge case: All items already succeeded (cancel came too late)\n // Mark as completed instead of doing nothing\n const succeededItems = task.succeededItems ?? []\n const originalItems = task._originalItems ?? task.items ?? []\n\n if (\n succeededItems.length >= originalItems.length\n || task.completed >= (task.total ?? 0)\n ) {\n task.status = 'completed'\n task.completedAt = Date.now()\n this.storage.set(taskId, task)\n this.notify()\n return\n }\n\n console.warn('[TaskQueue] retry: no remaining items for task', taskId)\n return\n }\n\n // Update task in-place for resume\n task.status = 'pending'\n task.items = remainingItems\n // Keep completed count and total for continuous progress\n // Keep succeededItems for tracking\n // Reset only failed items for this retry attempt\n task.failedItems = []\n task.failed = 0\n task.retryCount += 1\n }\n else {\n // Long process: Restart from beginning\n task.status = 'pending'\n task.completed = 0\n task.failed = 0\n task.succeededItems = []\n task.failedItems = []\n task.result = undefined\n task.retryCount += 1\n }\n\n // Clear timestamps for fresh run\n task.startedAt = undefined\n task.completedAt = undefined\n\n // Re-attach processor (ensure it's in the map)\n this.processors.set(taskId, processor)\n\n // Update task in storage\n this.storage.set(taskId, task)\n this.notify()\n this.drain()\n }\n\n private getRetryItems(task: Task): unknown[] | undefined {\n // Use _originalItems if available, otherwise fall back to items\n const originalItems = task._originalItems ?? task.items\n if (!originalItems || originalItems.length === 0)\n return undefined\n\n // Ensure arrays exist (backwards compatibility)\n const succeededItems = task.succeededItems ?? []\n const failedItems = task.failedItems ?? []\n\n // For cancelled tasks: retry items NOT in succeededItems\n if (task.status === 'cancelled' && succeededItems.length > 0) {\n const remaining = originalItems.filter((item) => {\n const itemId = this.resolveItemId(item)\n if (!itemId)\n return true // Can't track, include it\n return !succeededItems.includes(itemId)\n })\n return remaining.length > 0 ? remaining : undefined\n }\n\n // For failed tasks: retry only failed items\n if (task.status === 'failed' && failedItems.length > 0) {\n const failed = originalItems.filter((item) => {\n const itemId = this.resolveItemId(item)\n if (!itemId)\n return false\n return failedItems.some(fi => fi.id === itemId)\n })\n return failed.length > 0 ? failed : undefined\n }\n\n // Fallback: retry all original items\n return originalItems\n }\n\n /** Extract ID from an item using custom extractor or shared utility */\n private resolveItemId<TItem>(\n item: TItem,\n getItemId?: (item: TItem) => string,\n ): string | undefined {\n if (getItemId)\n return getItemId(item)\n\n const id = extractItemId(item)\n if (id !== undefined)\n return id\n\n // Fallback: stringify (only in queue context, not in UI)\n try {\n return JSON.stringify(item)\n }\n catch {\n return undefined\n }\n }\n\n dismiss = (taskId: string): void => {\n const task = this.storage.get(taskId)\n if (!task)\n return\n if (task.status === 'running' || task.status === 'pending')\n return\n this.storage.remove(taskId)\n // Clean up processor from memory\n this.processors.delete(taskId)\n this.onCompleteCallbacks.delete(taskId)\n this.notify()\n }\n\n dismissAll = (): void => {\n const tasks = this.storage.getAll()\n tasks.forEach((task) => {\n if (task.status !== 'running' && task.status !== 'pending') {\n this.storage.remove(task.id)\n // Clean up processor from memory\n this.processors.delete(task.id)\n this.onCompleteCallbacks.delete(task.id)\n }\n })\n this.notify()\n }\n\n showSummary = (title: string, items: TaskSummaryItem[], options?: { renderContent?: SummaryRenderContent }): void => {\n this._activeSummary = { title, items, renderContent: options?.renderContent }\n this.notify()\n }\n\n closeSummary = (): void => {\n this._activeSummary = null\n this.notify()\n }\n\n getActiveSummary = (): TaskSummaryData | null => {\n return this._activeSummary\n }\n\n getSummaryRenderContent = (): SummaryRenderContent | undefined => {\n return this._summaryRenderContent\n }\n\n // --- processItem API ---\n\n private buildProcessor<TItem, TResult>(\n options: ProcessItemEnqueueOptions<TItem, TResult>,\n ): (ctx: TaskContext<TItem, TResult>) => Promise<void> {\n const {\n processItem,\n itemConcurrency = 1,\n getItemId,\n errorStrategy = 'continue',\n } = options\n\n return async (ctx) => {\n const pending = [...ctx.items]\n const inFlight: Promise<void>[] = []\n\n while (pending.length > 0 || inFlight.length > 0) {\n // Check cancellation\n if (ctx.cancelled)\n break\n\n // Check stop-on-error\n if (errorStrategy === 'stop' && ctx.failedItems.length > 0)\n break\n\n // Fill slots up to concurrency limit\n while (inFlight.length < itemConcurrency && pending.length > 0) {\n const item = pending.shift()!\n const itemId = this.resolveItemId(item, getItemId) ?? String(item)\n\n const promise = this.processOneItem(\n item,\n itemId,\n processItem,\n ctx,\n ).finally(() => {\n // Remove from inFlight when done\n const idx = inFlight.indexOf(promise)\n if (idx !== -1)\n inFlight.splice(idx, 1)\n })\n\n inFlight.push(promise)\n }\n\n // Wait for at least one to complete before continuing\n if (inFlight.length > 0) {\n await Promise.race(inFlight)\n }\n }\n }\n }\n\n private async processOneItem<TItem, TResult>(\n item: TItem,\n itemId: string,\n processItem: (item: TItem, ctx: ItemContext) => Promise<void>,\n ctx: TaskContext<TItem, TResult>,\n ): Promise<void> {\n let manuallyHandled = false\n\n const itemCtx: ItemContext = {\n get cancelled() {\n return ctx.cancelled\n },\n succeed: (id?: string) => {\n manuallyHandled = true\n ctx.succeed(id ?? itemId)\n },\n fail: (id?: string, message?: string) => {\n manuallyHandled = true\n ctx.fail(id ?? itemId, message)\n },\n }\n\n try {\n await processItem(item, itemCtx)\n // Auto-succeed if not manually handled\n if (!manuallyHandled) {\n ctx.succeed(itemId)\n }\n }\n catch (error) {\n // Auto-fail if not manually handled\n if (!manuallyHandled) {\n const message\n = error instanceof Error ? error.message : 'Unknown error'\n ctx.fail(itemId, message)\n }\n }\n }\n\n // --- Internal scheduling ---\n\n private drain(): void {\n const tasks = this.storage.getAll()\n const pending = tasks.filter(t => t.status === 'pending')\n\n while (this.runningCount < this.concurrency && pending.length > 0) {\n const next = pending.shift()\n if (!next)\n break\n this.runTask(next)\n }\n }\n\n private async runTask(task: Task): Promise<void> {\n this.runningCount += 1\n\n // Attach processor from memory (wasn't serialized to storage)\n const processor = this.processors.get(task.id)\n if (!processor) {\n console.error('[TaskQueue] No processor found for task', task.id)\n this.runningCount -= 1\n return\n }\n task._processor = processor\n\n try {\n const outcome = await executeTask(task, {\n onUpdate: (updated) => {\n this.storage.set(updated.id, updated)\n this.notify()\n },\n onCancelReady: (setCancelled) => {\n this.cancelFunctions.set(task.id, setCancelled)\n },\n onTaskComplete: () => {\n // Clear timeout when task completes (success or failure)\n this.clearTaskTimeout(task.id)\n },\n })\n\n // Call onComplete callback if provided\n const onComplete = this.onCompleteCallbacks.get(task.id)\n if (onComplete) {\n try {\n await onComplete(outcome)\n }\n catch (error) {\n console.error('[TaskQueue] onComplete callback error:', error)\n }\n }\n\n const resolver = this.taskResolvers.get(task.id)\n if (resolver) {\n resolver(outcome)\n this.taskResolvers.delete(task.id)\n }\n\n // Only clean up processor if task completed successfully (not failed/cancelled)\n // Failed/cancelled tasks keep processor for retry\n if (outcome.status === 'completed') {\n this.processors.delete(task.id)\n this.onCompleteCallbacks.delete(task.id)\n }\n }\n finally {\n this.runningCount -= 1\n // Clean up cancel function\n this.cancelFunctions.delete(task.id)\n this.drain()\n }\n }\n\n private handleTaskTimeout(taskId: string): void {\n const task = this.storage.get(taskId)\n if (!task || task.status !== 'running') {\n // Task already completed or not running, ignore timeout\n return\n }\n\n // Trigger cleanup callbacks (watch unsubscribe, etc.)\n const setCancelled = this.cancelFunctions.get(taskId)\n if (setCancelled) {\n setCancelled(true) // This calls all registered cleanup callbacks\n }\n\n // Mark task as failed with timeout error\n task.status = 'failed'\n task.completedAt = Date.now()\n task.failedItems = [\n ...task.failedItems,\n { message: 'Task timeout: exceeded maximum execution time' },\n ]\n task.failed += 1\n\n this.storage.set(taskId, task)\n this.notify()\n\n // Resolve the promise\n const resolver = this.taskResolvers.get(taskId)\n if (resolver) {\n resolver({\n status: 'failed',\n completed: task.completed,\n failed: task.failed,\n failedItems: [...task.failedItems],\n result: task.result,\n })\n this.taskResolvers.delete(taskId)\n }\n\n // Clean up\n this.processors.delete(taskId)\n this.onCompleteCallbacks.delete(taskId)\n this.cancelFunctions.delete(taskId)\n this.taskTimeouts.delete(taskId)\n }\n\n private clearTaskTimeout(taskId: string): void {\n const timeoutId = this.taskTimeouts.get(taskId)\n if (timeoutId) {\n clearTimeout(timeoutId)\n this.taskTimeouts.delete(taskId)\n }\n }\n}\n","import type { ReactNode } from 'react'\nimport type { TaskQueueConfig } from '../types'\nimport { createContext, useEffect, useMemo, useRef } from 'react'\nimport { TaskQueue } from '../engine'\n\nexport interface TaskQueueContextValue {\n queue: TaskQueue\n}\n\nexport const TaskQueueContext = createContext<TaskQueueContextValue | null>(null)\n\ninterface TaskQueueProviderProps {\n children: ReactNode\n config?: TaskQueueConfig\n}\n\nexport function TaskQueueProvider({ children, config }: TaskQueueProviderProps) {\n const queueRef = useRef<TaskQueue | null>(null)\n\n if (!queueRef.current) {\n queueRef.current = new TaskQueue(config)\n }\n\n // Cleanup on unmount: cancel running tasks to prevent memory leaks\n useEffect(() => {\n const queue = queueRef.current\n return () => {\n if (!queue)\n return\n const tasks = queue.getSnapshot()\n tasks.forEach((task) => {\n if (task.status === 'running') {\n queue.cancel(task.id)\n }\n })\n }\n }, [])\n\n // Warn user before leaving if there are active tasks that require confirmation\n useEffect(() => {\n const handleBeforeUnload = (e: BeforeUnloadEvent) => {\n const tasks = queueRef.current?.getSnapshot() ?? []\n\n // Show confirmation if ANY task is active AND requires confirmation\n // Default confirmBeforeUnload is true, so we respect per-task settings\n const shouldConfirm = tasks.some(\n t => (t.status === 'running' || t.status === 'pending') && t.confirmBeforeUnload !== false, // Explicitly check for false (default is true)\n )\n\n if (shouldConfirm) {\n e.preventDefault()\n // Modern browsers ignore custom messages, but this triggers the dialog\n e.returnValue = 'Tasks in progress will be lost.'\n return e.returnValue\n }\n }\n\n window.addEventListener('beforeunload', handleBeforeUnload)\n return () => window.removeEventListener('beforeunload', handleBeforeUnload)\n }, [])\n\n const value = useMemo<TaskQueueContextValue>(() => ({ queue: queueRef.current! }), [])\n\n return <TaskQueueContext value={value}>{children}</TaskQueueContext>\n}\n","import type { Task, TaskQueueAPI, UseTaskQueueOptions } from '../types'\nimport { use, useMemo, useSyncExternalStore } from 'react'\nimport { TaskQueueContext } from '../provider'\n\n// Cached empty array for server snapshot - MUST be the same reference to avoid infinite loop\nconst EMPTY_TASKS: Task[] = []\n\nexport function useTaskQueue(options?: UseTaskQueueOptions): TaskQueueAPI {\n const context = use(TaskQueueContext)\n if (!context) {\n throw new Error('useTaskQueue must be used within a TaskQueueProvider')\n }\n\n const { queue } = context\n\n // Use the bound methods directly - they're arrow functions on the class\n const allTasks = useSyncExternalStore(queue.subscribe, queue.getSnapshot, () => EMPTY_TASKS)\n\n const tasks = useMemo(() => {\n if (!options?.status)\n return allTasks\n return allTasks.filter(t => t.status === options.status)\n }, [allTasks, options?.status])\n\n // Track activeSummary via useSyncExternalStore so it re-renders correctly\n // even if the task snapshot reference doesn't change.\n const activeSummary = useSyncExternalStore(queue.subscribe, queue.getActiveSummary, () => null)\n\n // Global renderContent from config (stable reference, doesn't need to be a dependency)\n const summaryRenderContent = queue.getSummaryRenderContent()\n\n // queue is a stable reference from context, its methods are arrow functions bound to class instance\n // Only tasks and activeSummary change, so those are the only dependencies needed\n return useMemo(\n () => ({\n enqueue: queue.enqueue,\n cancel: queue.cancel,\n retry: queue.retry,\n dismiss: queue.dismiss,\n dismissAll: queue.dismissAll,\n showSummary: queue.showSummary,\n closeSummary: queue.closeSummary,\n activeSummary,\n summaryRenderContent,\n tasks,\n }),\n [tasks, activeSummary, summaryRenderContent],\n )\n}\n","import type { Task, TaskMetadata } from '../types'\nimport { useMemo } from 'react'\n\n// --- Current Scope Detection ---\n\nexport type CurrentScope\n = | { type: 'project', projectId: string, orgId?: string }\n | { type: 'org', orgId: string }\n | { type: 'global' }\n | { type: 'edge', projectId: string, orgId?: string }\n\n/**\n * Detect the current scope from URL params.\n * Returns project scope if projectId is present, org scope if only orgId, otherwise global.\n *\n * @param params - Route params (e.g. from useParams() in react-router)\n */\nexport function useCurrentScope(params: { projectId?: string, orgId?: string }): CurrentScope {\n return useMemo(() => {\n // Project scope takes precedence (projectId implies orgId context)\n if (params.projectId) {\n return {\n type: 'project',\n projectId: params.projectId,\n orgId: params.orgId,\n }\n }\n\n // Org scope if only orgId is present\n if (params.orgId) {\n return {\n type: 'org',\n orgId: params.orgId,\n }\n }\n\n // Global scope (account pages, etc.)\n return { type: 'global' }\n }, [params.projectId, params.orgId])\n}\n\n// --- Scope Matching ---\n\n/**\n * Check if task metadata matches the current scope.\n */\nexport function matchesCurrentScope(\n metadata: TaskMetadata | undefined,\n scope: CurrentScope,\n): boolean {\n if (!metadata)\n return false\n\n if (scope.type === 'project') {\n return metadata.projectId === scope.projectId\n }\n\n if (scope.type === 'org') {\n // Org scope matches if same org AND not a project-scoped task\n return metadata.orgId === scope.orgId && !metadata.projectId\n }\n\n // Global scope never matches (all tasks show labels)\n return false\n}\n\n/**\n * Get the context label to display for a task.\n * Returns formatted label with scope type: \"Project: Name\", \"Org: Name\", etc.\n */\nexport function getContextLabel(metadata: TaskMetadata | undefined): string | undefined {\n if (!metadata)\n return undefined\n\n const scope = metadata.scope as string | undefined\n\n // Project-scoped task\n if (scope === 'project' && metadata.projectName) {\n return `Project: ${metadata.projectName}`\n }\n\n // Org-scoped task\n if (scope === 'org' && metadata.orgName) {\n return `Org: ${metadata.orgName}`\n }\n\n // User-scoped task\n if (scope === 'user') {\n return 'User'\n }\n\n // Edge-scoped task\n if (scope === 'edge' && metadata.projectName) {\n return `AI Edge: ${metadata.projectName}`\n }\n\n // Fallback: try to infer from available data\n if (metadata.projectName) {\n return `Project: ${metadata.projectName}`\n }\n if (metadata.orgName) {\n return `Org: ${metadata.orgName}`\n }\n\n // Custom scope with no standard name\n if (scope) {\n return scope.charAt(0).toUpperCase() + scope.slice(1)\n }\n\n return undefined\n}\n\n// --- Tasks with Labels Hook ---\n\nexport interface TasksWithLabels {\n tasks: Task[]\n showLabels: boolean\n}\n\n/**\n * Hook that returns tasks with a flag indicating whether to show context labels.\n * Labels are shown when:\n * - User is on a global page (account, etc.)\n * - Tasks are from mixed scopes (not all match current scope)\n *\n * @param tasks - Array of tasks to evaluate\n * @param params - Route params (e.g. from useParams() in react-router)\n */\nexport function useTasksWithLabels(\n tasks: Task[],\n params: { projectId?: string, orgId?: string },\n): TasksWithLabels {\n const currentScope = useCurrentScope(params)\n\n const showLabels = useMemo(() => {\n // No tasks = no labels needed\n if (tasks.length === 0)\n return false\n\n // Global pages always show labels\n if (currentScope.type === 'global')\n return true\n\n // Check if ALL tasks match current scope\n const allMatchCurrent = tasks.every(task => matchesCurrentScope(task.metadata, currentScope))\n\n // Show labels if any task doesn't match\n return !allMatchCurrent\n }, [tasks, currentScope])\n\n return { tasks, showLabels }\n}\n","export function TaskPanelHeader() {\n return (\n <div className=\"border-border flex items-center border-b px-4 py-3\">\n <span className=\"text-sm font-medium\">Tasks</span>\n </div>\n )\n}\n","import type { ButtonProps } from '../../../base/button/button'\nimport type { Task } from '../types'\nimport { Button } from '../../../base/button/button'\nimport { useTaskQueue } from '../hooks/use-task-queue'\nimport { extractItemId } from '../utils'\n\ninterface TaskPanelActionsProps {\n task: Task\n}\n\nexport function TaskPanelActions({ task }: TaskPanelActionsProps) {\n const { showSummary } = useTaskQueue()\n const actions = resolveActions(task)\n\n const hasBatch = task.total != null\n const hasFailedMessages = task.failedItems.length > 0 && task.failedItems.some(f => f.message)\n\n if (!hasBatch && task.status === 'failed' && hasFailedMessages && actions.length === 0) {\n return (\n <div className=\"flex items-center justify-end gap-1.5\">\n <Button\n htmlType=\"button\"\n type=\"quaternary\"\n theme=\"outline\"\n size=\"xs\"\n onClick={() =>\n showSummary(\n task.title,\n task.failedItems.map((item, i) => ({\n id: item.id ?? `error-${i}`,\n label: item.id ?? 'Error',\n status: 'failed',\n message: item.message,\n })),\n )}\n >\n Details\n </Button>\n </div>\n )\n }\n\n if (actions.length === 0)\n return null\n\n return (\n <div className=\"flex items-center justify-end gap-1.5\">\n {actions.map((action, i) => (\n <Button htmlType=\"button\" key={i} {...action} />\n ))}\n </div>\n )\n}\n\nconst TERMINAL_STATUSES = ['completed', 'failed', 'cancelled'] as const\n\nfunction resolveActions(task: Task): ButtonProps[] {\n if (!task.completionActions)\n return []\n if (!TERMINAL_STATUSES.includes(task.status as (typeof TERMINAL_STATUSES)[number]))\n return []\n\n if (typeof task.completionActions === 'function') {\n const originalItems = task._originalItems ?? task.items ?? []\n const failedMap = new Map(task.failedItems.filter(f => f.id).map(f => [f.id, f]))\n const succeededSet = new Set(task.succeededItems)\n\n const items = originalItems\n .map((item) => {\n const id = extractItemId(item)\n if (!id)\n return null\n const failed = failedMap.get(id)\n if (failed)\n return { id, status: 'failed' as const, message: failed.message, data: item }\n if (succeededSet.has(id))\n return { id, status: 'succeeded' as const, data: item }\n return null\n })\n .filter((item): item is NonNullable<typeof item> => item !== null)\n\n return task.completionActions(task.result, {\n status: task.status,\n completed: task.completed,\n failed: task.failed,\n items,\n })\n }\n\n return task.completionActions\n}\n","import type { TaskStatus } from '../types'\nimport { cn } from '@repo/shadcn/lib/utils'\n\ninterface TaskPanelCounterProps {\n total?: number\n completed: number\n failed?: number\n status?: TaskStatus\n}\n\nexport function TaskPanelCounter({ total, completed, failed = 0, status }: TaskPanelCounterProps) {\n const hasBatch = total != null\n\n // Single-item tasks: \"Completed\" | \"Failed\" | \"Cancelled\"\n // Batch running: \"3/10\" or \"3/10, 1 failed\"\n // Batch terminal: \"Completed\" | \"3 completed, 1 failed\" | \"Cancelled, 3 completed\"\n const parts: Array<{ text: string, destructive?: boolean }> = []\n\n if (status === 'completed') {\n parts.push({ text: 'Completed' })\n }\n else if (status === 'failed') {\n if (hasBatch) {\n if (completed > 0)\n parts.push({ text: `${completed} completed` })\n parts.push({ text: `${failed} failed`, destructive: true })\n }\n else {\n parts.push({ text: 'Failed', destructive: true })\n }\n }\n else if (status === 'cancelled') {\n parts.push({ text: 'Cancelled' })\n if (hasBatch && completed > 0)\n parts.push({ text: `${completed} completed` })\n }\n else if (hasBatch) {\n parts.push({ text: `${completed + failed}/${total}` })\n if (failed > 0)\n parts.push({ text: `${failed} failed`, destructive: true })\n }\n\n if (parts.length === 0)\n return null\n\n return (\n <span className=\"text-muted-foreground text-xs\">\n {parts.map((part, i) => (\n <span key={i}>\n {i > 0 && ', '}\n <span className={cn(part.destructive && 'text-destructive')}>{part.text}</span>\n </span>\n ))}\n </span>\n )\n}\n","import type { Task } from '../types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@repo/shadcn/ui/tooltip'\nimport { formatDistanceToNowStrict } from 'date-fns'\nimport {\n Ban,\n CircleAlert,\n CircleCheck,\n CornerDownRightIcon,\n FileIcon,\n X,\n XCircle,\n} from 'lucide-react'\nimport { Icon } from '../../../icons/icon-wrapper'\nimport { SpinnerIcon } from '../../../icons/spinner.icon'\nimport { TaskPanelActions } from './task-panel-actions'\nimport { TaskPanelCounter } from './task-panel-counter'\n\ninterface TaskPanelItemProps {\n task: Task\n contextLabel?: string\n onCancel: () => void\n}\n\nexport function TaskPanelItem({ task, contextLabel, onCancel }: TaskPanelItemProps) {\n const hasBatch = task.total != null\n const isTerminal\n = task.status === 'completed' || task.status === 'failed' || task.status === 'cancelled'\n\n return (\n <div className=\"group border-border flex flex-col gap-1 px-4 py-3 not-first:border-t\">\n <div className=\"flex items-start gap-3\">\n {/* Task icon on the left */}\n <div className=\"mt-0.5 flex shrink-0 items-center\">\n <TaskIcon task={task} />\n </div>\n\n {/* Title and progress */}\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <span className=\"truncate text-sm font-medium\">{task.title}</span>\n\n {task.status === 'pending' && (\n <span className=\"text-muted-foreground text-xs\">Waiting...</span>\n )}\n\n {/* Only show counter for batch tasks */}\n {hasBatch && task.status === 'running' && (\n <TaskPanelCounter total={task.total} completed={task.completed} failed={task.failed} />\n )}\n\n {isTerminal && (\n <TaskPanelCounter\n total={task.total}\n completed={task.completed}\n failed={task.failed}\n status={task.status}\n />\n )}\n\n {contextLabel && (\n <span className=\"text-muted-foreground flex items-center gap-1 text-xs\">\n <Icon icon={CornerDownRightIcon} className=\"size-3 shrink-0 opacity-60\" />\n <span className=\"truncate\">{contextLabel}</span>\n </span>\n )}\n </div>\n\n {/* Right side: action for running/pending, timestamp for terminal */}\n <div className=\"flex shrink-0 items-center\">\n <TaskStatusAction task={task} onCancel={onCancel} />\n </div>\n </div>\n <TaskPanelActions task={task} />\n </div>\n )\n}\n\n/** Left-side task icon - shows task icon when running, status icon when complete */\nfunction TaskIcon({ task }: { task: Task }) {\n // Running or pending: show custom icon or default file icon\n if (task.status === 'running' || task.status === 'pending') {\n if (task.icon) {\n return <span className=\"text-muted-foreground [&>svg]:size-4\">{task.icon}</span>\n }\n return <Icon icon={FileIcon} className=\"text-muted-foreground size-4\" />\n }\n\n // Completed with some failures (partial success)\n if (task.status === 'completed' && task.failed > 0) {\n return <Icon icon={CircleAlert} className=\"size-4 text-amber-500\" />\n }\n\n // Completed successfully\n if (task.status === 'completed') {\n return <Icon icon={CircleCheck} className=\"size-4 text-green-600 dark:text-green-400\" />\n }\n\n // Failed\n if (task.status === 'failed') {\n return <Icon icon={XCircle} className=\"text-destructive size-4\" />\n }\n\n // Cancelled\n if (task.status === 'cancelled') {\n return <Icon icon={Ban} className=\"text-muted-foreground size-4\" />\n }\n\n // Fallback\n return <Icon icon={FileIcon} className=\"text-muted-foreground size-4\" />\n}\n\n/** Format completedAt timestamp as human-readable relative time */\nfunction formatCompletedAt(completedAt?: number): string {\n if (!completedAt)\n return ''\n const elapsedMs = Date.now() - completedAt\n if (elapsedMs < 1000)\n return 'just now'\n const distance = formatDistanceToNowStrict(new Date(completedAt), { addSuffix: false })\n return `${distance} ago`\n}\n\n/** Right-side: spinner/cancel for active tasks, timestamp for terminal tasks */\nfunction TaskStatusAction({ task, onCancel }: { task: Task, onCancel: () => void }) {\n // Running: Spinner → Cancel on hover\n if (task.status === 'running') {\n return (\n <div className=\"relative size-5\">\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center transition-opacity group-hover:opacity-0\">\n <SpinnerIcon size=\"sm\" />\n </div>\n {task.cancelable && (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={onCancel}\n className={cn(\n 'flex size-5 items-center justify-center rounded-md transition-colors',\n 'text-muted-foreground hover:bg-accent hover:text-foreground',\n 'absolute inset-0 opacity-0 transition-opacity group-hover:opacity-100',\n )}\n aria-label=\"Cancel task\"\n >\n <Icon icon={X} className=\"size-4\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"left\">Cancel</TooltipContent>\n </Tooltip>\n )}\n </div>\n )\n }\n\n // Pending: Show spinner (waiting to start)\n if (task.status === 'pending') {\n return (\n <div className=\"flex size-5 items-center justify-center\">\n <SpinnerIcon size=\"sm\" className=\"opacity-50\" />\n </div>\n )\n }\n\n // Terminal states: show completedAt timestamp\n return (\n <span className=\"text-muted-foreground/60 text-xs whitespace-nowrap\">\n {formatCompletedAt(task.completedAt)}\n </span>\n )\n}\n","import { cn } from '@repo/shadcn/lib/utils'\nimport { getContextLabel, useTaskQueue } from '../hooks'\nimport { TaskPanelHeader } from './task-panel-header'\nimport { TaskPanelItem } from './task-panel-item'\n\n/**\n * @deprecated Use TaskQueueDropdown instead — renders as a header-anchored dropdown.\n * TaskPanel is kept for backward compatibility but is no longer used in the main layout.\n */\nexport function TaskPanel() {\n const { tasks, cancel } = useTaskQueue()\n\n if (tasks.length === 0)\n return null\n\n return (\n <div\n className={cn(\n 'bg-background fixed right-4 bottom-4 z-50 w-96 overflow-hidden',\n 'border-border/50 rounded-xl border shadow-xl shadow-black/10',\n 'animate-in slide-in-from-bottom-4 fade-in duration-200',\n )}\n >\n <TaskPanelHeader />\n\n <div className=\"max-h-80 overflow-y-auto\">\n {tasks.map(task => (\n <TaskPanelItem\n key={task.id}\n task={task}\n contextLabel={getContextLabel(task.metadata)}\n onCancel={() => cancel(task.id)}\n />\n ))}\n </div>\n </div>\n )\n}\n","import type { Task } from '../types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { ListTodo } from 'lucide-react'\nimport { useEffect, useRef, useState } from 'react'\nimport { Tooltip } from '../../..'\nimport { Badge } from '../../../base/badge'\nimport { Button } from '../../../base/button'\nimport { Icon } from '../../../icons/icon-wrapper'\n\ninterface TaskQueueTriggerProps {\n tasks: Task[]\n}\n\nexport function TaskQueueTrigger({ ref, tasks, ...props }: TaskQueueTriggerProps & { ref?: React.RefObject<HTMLButtonElement | null> }) {\n const runningCount = tasks.filter(t => t.status === 'running').length\n const pendingCount = tasks.filter(t => t.status === 'pending').length\n const activeCount = runningCount + pendingCount\n const hasRunning = runningCount > 0\n const isAllComplete\n = tasks.length > 0\n && activeCount === 0\n && tasks.every(\n t => t.status === 'completed' || t.status === 'failed' || t.status === 'cancelled',\n )\n\n // Completion flash: detect transition to all-complete\n const [flash, setFlash] = useState(false)\n const prevAllComplete = useRef(false)\n\n useEffect(() => {\n if (isAllComplete && !prevAllComplete.current) {\n prevAllComplete.current = true\n setFlash(true)\n const timer = setTimeout(() => setFlash(false), 5000)\n return () => clearTimeout(timer)\n }\n if (!isAllComplete) {\n prevAllComplete.current = false\n }\n }, [isAllComplete])\n\n // Reset flash when tasks are cleared\n useEffect(() => {\n if (tasks.length === 0) {\n setFlash(false)\n prevAllComplete.current = false\n }\n }, [tasks.length])\n\n return (\n <Tooltip message=\"Tasks\">\n <Button\n ref={ref}\n type=\"quaternary\"\n theme=\"borderless\"\n size=\"small\"\n className={cn(\n 'hover:bg-sidebar-accent relative h-7 w-7 rounded-lg p-0 transition-colors duration-300',\n flash && 'bg-primary/10',\n )}\n aria-label={`Tasks${activeCount > 0 ? ` (${activeCount} active)` : ''}`}\n {...props}\n >\n <Icon\n icon={ListTodo}\n className={cn('text-icon-header size-4', flash ? 'text-primary' : 'text-icon-header')}\n />\n\n {/* Spinning ring when tasks are running */}\n {hasRunning && (\n <span className=\"border-t-primary pointer-events-none absolute inset-[-3px] animate-spin rounded-full border-2 border-transparent\" />\n )}\n\n {/* Active task count badge */}\n {activeCount > 0 && (\n <Badge\n type=\"tertiary\"\n theme=\"solid\"\n className=\"bg-primary text-primary-foreground text-2xs absolute -top-1 -right-1 flex size-4 items-center justify-center rounded-full p-0 leading-0\"\n >\n {activeCount > 99 ? '99+' : activeCount}\n </Badge>\n )}\n </Button>\n </Tooltip>\n )\n}\n","import type { ReactNode } from 'react'\nimport type { TaskSummaryItem } from '../types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@repo/shadcn/ui/table'\nimport { CircleCheck, XCircle } from 'lucide-react'\nimport { useMemo } from 'react'\nimport { Button } from '../../../base/button/button'\nimport { Dialog } from '../../../base/dialog'\nimport { Icon } from '../../../icons/icon-wrapper'\nimport { useTaskQueue } from '../hooks/use-task-queue'\n\ninterface BaseProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n title: string\n description?: string\n actions?: ReactNode\n renderContent?: (items: TaskSummaryItem[]) => ReactNode\n}\n\ntype ItemsMode = BaseProps & {\n items: TaskSummaryItem[]\n taskId?: never\n getItemLabel?: never\n}\n\ntype TaskIdMode = BaseProps & {\n taskId: string\n getItemLabel: (id: string) => string\n items?: never\n}\n\nexport type TaskSummaryDialogProps = ItemsMode | TaskIdMode\n\n// =============================================================================\n// Status Config\n// =============================================================================\n\nfunction getStatusConfig(status: TaskSummaryItem['status']) {\n switch (status) {\n case 'success':\n return { icon: CircleCheck, label: 'Success', className: 'text-green-600' }\n case 'failed':\n return { icon: XCircle, label: 'Failed', className: 'text-destructive' }\n }\n}\n\n// =============================================================================\n// Status Cell\n// =============================================================================\n\nfunction StatusCell({ item }: { item: TaskSummaryItem }) {\n const config = getStatusConfig(item.status)\n return (\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"flex items-center gap-1.5\">\n <Icon icon={config.icon} className={cn('size-4', config.className)} />\n <span className={cn('text-xs font-medium', config.className)}>{config.label}</span>\n </div>\n {item.message && item.status !== 'success' && (\n <span className=\"text-muted-foreground pl-5.5 text-xs text-wrap\">{item.message}</span>\n )}\n </div>\n )\n}\n\n// =============================================================================\n// Default Table Content\n// =============================================================================\n\nfunction DefaultTableContent({ items }: { items: TaskSummaryItem[] }) {\n const sorted = useMemo(() =>\n [...items].sort((a, b) => {\n if (a.status === 'failed' && b.status !== 'failed')\n return -1\n if (a.status !== 'failed' && b.status === 'failed')\n return 1\n return 0\n }), [items])\n\n return (\n <div className=\"max-h-[400px] overflow-auto rounded-xl border\">\n <Table>\n <TableHeader className=\"bg-muted/50 sticky top-0\">\n <TableRow>\n <TableHead>Item</TableHead>\n <TableHead className=\"max-w-80\">Status</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {sorted.length === 0\n ? (\n <TableRow>\n <TableCell colSpan={2} className=\"text-muted-foreground py-6 text-center\">No items</TableCell>\n </TableRow>\n )\n : sorted.map(item => (\n <TableRow key={item.id}>\n <TableCell className=\"font-medium\">{item.label}</TableCell>\n <TableCell className=\"max-w-80 break-all text-wrap whitespace-normal\">\n <StatusCell item={item} />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )\n}\n\n// =============================================================================\n// Hook: Build items from task ID\n// =============================================================================\n\nfunction useTaskSummaryItems(\n taskId: string | undefined,\n getItemLabel: ((id: string) => string) | undefined,\n): TaskSummaryItem[] {\n const { tasks } = useTaskQueue()\n\n return useMemo(() => {\n if (!taskId || !getItemLabel)\n return []\n\n const task = tasks.find(t => t.id === taskId)\n if (!task)\n return []\n\n const succeeded: TaskSummaryItem[] = task.succeededItems.map(id => ({\n id,\n label: getItemLabel(id),\n status: 'success',\n }))\n\n const failed: TaskSummaryItem[] = task.failedItems.map(item => ({\n id: item.id ?? '',\n label: getItemLabel(item.id ?? ''),\n status: 'failed',\n message: item.message,\n }))\n\n return [...failed, ...succeeded]\n }, [taskId, getItemLabel, tasks])\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\nexport function TaskSummaryDialog(props: TaskSummaryDialogProps) {\n const { open, onOpenChange, title, description, actions, renderContent } = props\n\n const taskIdItems = useTaskSummaryItems(\n 'taskId' in props ? props.taskId : undefined,\n 'getItemLabel' in props ? props.getItemLabel : undefined,\n )\n\n const resolvedItems = props.items ?? taskIdItems\n\n const successCount = resolvedItems.filter(i => i.status === 'success').length\n const failedCount = resolvedItems.filter(i => i.status === 'failed').length\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <Dialog.Content className=\"w-full sm:max-w-[774px]\">\n <Dialog.Header\n title={title}\n description={description ?? `${successCount} succeeded, ${failedCount} failed`}\n onClose={() => onOpenChange(false)}\n className=\"border-b-0\"\n />\n <Dialog.Body className=\"px-5 py-0\">\n {renderContent\n ? renderContent(resolvedItems)\n : <DefaultTableContent items={resolvedItems} />}\n </Dialog.Body>\n <Dialog.Footer className=\"border-t-0\">\n {actions}\n <Button type=\"primary\" theme=\"solid\" onClick={() => onOpenChange(false)}>\n Done\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>\n )\n}\n","import { CheckCircle2 } from 'lucide-react'\nimport { useEffect, useState } from 'react'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from '../../dropdown'\n// Context labels are always shown because the dropdown is global (visible from any page).\n// This is intentional — unlike the old TaskPanel which used useTasksWithLabels() to hide\n// labels when all tasks matched the current scope.\nimport { getContextLabel, useTaskQueue } from '../hooks'\nimport { TaskPanelHeader } from './task-panel-header'\nimport { TaskPanelItem } from './task-panel-item'\nimport { TaskQueueTrigger } from './task-queue-trigger'\nimport { TaskSummaryDialog } from './task-summary-dialog'\n\n// Track task IDs that have already triggered an auto-open.\n// Module-level so it survives component remounts during navigation\n// (e.g. navigating between route groups remounts DashboardLayout → Header → TaskQueueDropdown).\n// Pruned automatically when tasks are dismissed.\nconst autoOpenedForIds = new Set<string>()\n\nexport function TaskQueueDropdown() {\n const { tasks, cancel, dismissAll, activeSummary, closeSummary, summaryRenderContent } = useTaskQueue()\n\n // Auto-open only for genuinely new tasks (IDs not yet seen).\n const [open, setOpen] = useState(() => tasks.some(t => !autoOpenedForIds.has(t.id)))\n\n // When new tasks arrive while mounted, open the dropdown and mark them as seen.\n useEffect(() => {\n if (tasks.some(t => !autoOpenedForIds.has(t.id))) {\n setOpen(true)\n }\n for (const t of tasks) autoOpenedForIds.add(t.id)\n\n // Prune IDs of dismissed tasks so the set doesn't grow unbounded\n if (autoOpenedForIds.size > tasks.length) {\n const currentIds = new Set(tasks.map(t => t.id))\n for (const id of autoOpenedForIds) {\n if (!currentIds.has(id))\n autoOpenedForIds.delete(id)\n }\n }\n }, [tasks])\n\n // If there are any tasks that are not running or pending, show the dismiss button.\n const hasDismissable = tasks.some(t => t.status !== 'running' && t.status !== 'pending')\n\n return (\n <>\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <TaskQueueTrigger tasks={tasks} />\n </DropdownMenuTrigger>\n\n <DropdownMenuContent\n align=\"end\"\n className=\"w-96 rounded-lg p-0\"\n onCloseAutoFocus={e => e.preventDefault()}\n >\n <TaskPanelHeader />\n <div className=\"max-h-[350px] overflow-y-auto\">\n {tasks.length === 0 && !activeSummary\n ? (\n <div className=\"flex flex-col items-center justify-center px-4 py-12 text-center\">\n <CheckCircle2 className=\"text-muted-foreground/30 mb-3 h-12 w-12\" />\n <p className=\"text-muted-foreground text-sm\">No tasks currently scheduled</p>\n </div>\n )\n : (\n tasks.map(task => (\n <TaskPanelItem\n key={task.id}\n task={task}\n contextLabel={getContextLabel(task.metadata)}\n onCancel={() => cancel(task.id)}\n />\n ))\n )}\n </div>\n {hasDismissable && (\n <button\n type=\"button\"\n onClick={() => {\n dismissAll()\n }}\n className=\"border-border hover:bg-accent flex w-full cursor-pointer items-center justify-center gap-2 border-t px-3 py-2 transition-colors\"\n >\n <span className=\"text-destructive text-xs\">Clear tasks</span>\n </button>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n\n {activeSummary && (\n <TaskSummaryDialog\n open\n onOpenChange={(isOpen) => {\n if (!isOpen)\n closeSummary()\n }}\n title={activeSummary.title}\n items={activeSummary.items}\n renderContent={activeSummary.renderContent ?? summaryRenderContent}\n />\n )}\n </>\n )\n}\n","// app/modules/datum-ui/components/time-range-picker/utils/timezone.ts\nimport type { TimezoneOption } from '../types'\nimport { format, parse } from 'date-fns'\nimport { fromZonedTime, toZonedTime } from 'date-fns-tz'\n\n/**\n * Get the UTC offset string for a timezone\n * @example getTimezoneOffset('Asia/Jakarta') => '+07:00'\n */\nexport function getTimezoneOffset(timezone: string): string {\n try {\n const now = new Date()\n const formatter = new Intl.DateTimeFormat('en-US', {\n timeZone: timezone,\n timeZoneName: 'shortOffset',\n })\n\n const parts = formatter.formatToParts(now)\n const offsetPart = parts.find(p => p.type === 'timeZoneName')\n\n if (offsetPart) {\n // Convert \"GMT+7\" to \"+07:00\" format\n const match = offsetPart.value.match(/GMT([+-])(\\d+)(?::(\\d+))?/)\n if (match) {\n const sign = match[1]!\n const hours = match[2]!.padStart(2, '0')\n const minutes = match[3]?.padStart(2, '0') ?? '00'\n return `${sign}${hours}:${minutes}`\n }\n // Handle \"GMT\" (UTC)\n if (offsetPart.value === 'GMT') {\n return '+00:00'\n }\n }\n }\n catch {\n // Fall through\n }\n\n return '+00:00'\n}\n\n/**\n * Format a timezone for display\n * @example formatTimezoneLabel('Asia/Jakarta') => 'Asia/Jakarta (UTC+07:00)'\n */\nexport function formatTimezoneLabel(timezone: string): string {\n const offset = getTimezoneOffset(timezone)\n const displayName = timezone.replace(/_/g, ' ')\n return `${displayName} (UTC${offset})`\n}\n\n/**\n * Create a TimezoneOption from a timezone string\n */\nexport function createTimezoneOption(timezone: string): TimezoneOption {\n return {\n value: timezone,\n label: formatTimezoneLabel(timezone),\n offset: getTimezoneOffset(timezone),\n }\n}\n\n/**\n * Get default timezone options (user's timezone + UTC)\n */\nexport function getDefaultTimezoneOptions(userTimezone?: string): TimezoneOption[] {\n const options: TimezoneOption[] = []\n\n // Add user's timezone first\n if (userTimezone && userTimezone !== 'UTC') {\n options.push(createTimezoneOption(userTimezone))\n }\n\n // Always include UTC\n options.push({\n value: 'UTC',\n label: 'UTC (+00:00)',\n offset: '+00:00',\n })\n\n return options\n}\n\n/**\n * Get short offset display (e.g., \"UTC+7\")\n */\nexport function getShortTimezoneDisplay(timezone: string): string {\n const offset = getTimezoneOffset(timezone)\n // Convert \"+07:00\" to \"+7\" or \"-05:30\" to \"-5:30\"\n const match = offset.match(/([+-])(\\d+):(\\d+)/)\n if (match) {\n const sign = match[1]!\n const hours = Number.parseInt(match[2]!, 10)\n const minutes = match[3]!\n if (minutes === '00') {\n return `UTC${sign}${hours}`\n }\n return `UTC${sign}${hours}:${minutes}`\n }\n return `UTC${offset}`\n}\n\n// ============================================\n// TIMEZONE CONVERSION HELPERS\n// ============================================\n\n/**\n * Get the browser's timezone\n */\nexport function getBrowserTimezone(): string {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone\n }\n catch {\n return 'UTC'\n }\n}\n\n/**\n * Convert a UTC Date to a local datetime-local input string in the given timezone\n * @example utcToLocalInputString(new Date('2026-01-16T04:00:00Z'), 'Asia/Jakarta') => '2026-01-16T11:00'\n */\nexport function utcToLocalInputString(utcDate: Date, timezone: string): string {\n const zonedDate = toZonedTime(utcDate, timezone)\n return format(zonedDate, 'yyyy-MM-dd\\'T\\'HH:mm')\n}\n\n/**\n * Convert a local datetime-local input string to a UTC Date\n * @example localInputStringToUtc('2026-01-16T11:00', 'Asia/Jakarta') => Date('2026-01-16T04:00:00Z')\n */\nexport function localInputStringToUtc(localString: string, timezone: string): Date {\n // Parse the local string as a date (without timezone info)\n const parsed = parse(localString, 'yyyy-MM-dd\\'T\\'HH:mm', new Date())\n // Convert from local timezone to UTC\n return fromZonedTime(parsed, timezone)\n}\n\n/**\n * Convert a UTC ISO string to a Date for display in user's timezone\n */\nexport function utcStringToZonedDate(utcString: string, timezone: string): Date {\n const utcDate = new Date(utcString)\n return toZonedTime(utcDate, timezone)\n}\n\n/**\n * Convert a zoned Date to UTC ISO string\n */\nexport function zonedDateToUtcString(zonedDate: Date, timezone: string): string {\n const utcDate = fromZonedTime(zonedDate, timezone)\n return utcDate.toISOString()\n}\n\n/**\n * Format a UTC ISO string for display in user's timezone\n * @example formatUtcForDisplay('2026-01-16T04:00:00Z', 'Asia/Jakarta') => 'Jan 16, 2026 11:00'\n */\nexport function formatUtcForDisplay(\n utcString: string,\n timezone: string,\n formatString: string = 'MMM d, yyyy HH:mm',\n): string {\n const zonedDate = utcStringToZonedDate(utcString, timezone)\n return format(zonedDate, formatString)\n}\n","import { cn } from '@repo/shadcn/lib/utils'\nimport { Popover, PopoverContent, PopoverTrigger } from '@repo/shadcn/ui/popover'\nimport { format } from 'date-fns'\nimport { CalendarIcon } from 'lucide-react'\nimport { useCallback, useEffect, useId, useRef, useState } from 'react'\nimport { Button, Calendar, Input } from '../../..'\n// app/modules/datum-ui/components/time-range-picker/components/absolute-range-panel.tsx\nimport { utcStringToZonedDate, zonedDateToUtcString } from '../utils/timezone'\n\ninterface CustomRangePanelProps {\n /** Start time in UTC ISO format */\n fromUtc: string\n /** End time in UTC ISO format */\n toUtc: string\n /** User's timezone for display */\n timezone: string\n /** Called when range changes (with UTC values) */\n onRangeChange: (from: string, to: string) => void\n /** Disable future dates */\n disableFuture?: boolean\n /** Debounce delay for time inputs in ms */\n debounceMs?: number\n className?: string\n}\n\n/**\n * Parse a zoned date into separate date and time parts\n */\nfunction parseDateTimeParts(zonedDate: Date): { date: Date, time: string } {\n const hours = zonedDate.getHours().toString().padStart(2, '0')\n const minutes = zonedDate.getMinutes().toString().padStart(2, '0')\n return {\n date: zonedDate,\n time: `${hours}:${minutes}`,\n }\n}\n\n/**\n * Combine a date and time string into a single Date\n */\nfunction combineDateAndTime(date: Date, time: string): Date {\n const [hours, minutes] = time.split(':').map(Number)\n const combined = new Date(date)\n combined.setHours(hours || 0, minutes || 0, 0, 0)\n return combined\n}\n\n/**\n * Validate time string format (HH:mm)\n */\nfunction isValidTime(time: string): boolean {\n const match = time.match(/^(\\d{2}):(\\d{2})$/)\n if (!match)\n return false\n const hours = Number.parseInt(match[1]!, 10)\n const minutes = Number.parseInt(match[2]!, 10)\n return hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59\n}\n\nexport function CustomRangePanel({\n fromUtc,\n toUtc,\n timezone,\n onRangeChange,\n disableFuture = false,\n debounceMs = 600,\n className,\n}: CustomRangePanelProps) {\n const startDateId = useId()\n const startTimeId = useId()\n const endDateId = useId()\n const endTimeId = useId()\n\n // Track if user has manually edited the time inputs\n const userHasEditedTimeRef = useRef(false)\n\n // Track previous prop values to detect external changes\n const prevFromUtcRef = useRef(fromUtc)\n const prevToUtcRef = useRef(toUtc)\n\n // Debounce timer ref\n const debounceTimerRef = useRef<NodeJS.Timeout | null>(null)\n\n // Popover open states\n const [startDateOpen, setStartDateOpen] = useState(false)\n const [endDateOpen, setEndDateOpen] = useState(false)\n\n // Parse initial values\n const initialFrom = parseDateTimeParts(utcStringToZonedDate(fromUtc, timezone))\n const initialTo = parseDateTimeParts(utcStringToZonedDate(toUtc, timezone))\n\n // Local state for date and time (in user's timezone)\n const [startDate, setStartDate] = useState<Date>(initialFrom.date)\n const [startTime, setStartTime] = useState<string>(initialFrom.time)\n const [endDate, setEndDate] = useState<Date>(initialTo.date)\n const [endTime, setEndTime] = useState<string>(initialTo.time)\n\n // Cleanup debounce timer on unmount\n useEffect(() => {\n return () => {\n if (debounceTimerRef.current) {\n clearTimeout(debounceTimerRef.current)\n }\n }\n }, [])\n\n // Update local state when UTC props change (from external source like preset selection)\n useEffect(() => {\n const fromChanged = fromUtc !== prevFromUtcRef.current\n const toChanged = toUtc !== prevToUtcRef.current\n\n if (fromChanged) {\n try {\n const parsed = parseDateTimeParts(utcStringToZonedDate(fromUtc, timezone))\n setStartDate(parsed.date)\n setStartTime(parsed.time)\n userHasEditedTimeRef.current = false\n }\n catch {\n // Ignore invalid dates\n }\n prevFromUtcRef.current = fromUtc\n }\n\n if (toChanged) {\n try {\n const parsed = parseDateTimeParts(utcStringToZonedDate(toUtc, timezone))\n setEndDate(parsed.date)\n setEndTime(parsed.time)\n userHasEditedTimeRef.current = false\n }\n catch {\n // Ignore invalid dates\n }\n prevToUtcRef.current = toUtc\n }\n }, [fromUtc, toUtc, timezone])\n\n // Notify parent when values change (immediate, no debounce)\n const notifyChangeImmediate = useCallback(\n (newStartDate: Date, newStartTime: string, newEndDate: Date, newEndTime: string) => {\n if (!isValidTime(newStartTime) || !isValidTime(newEndTime))\n return\n\n const startCombined = combineDateAndTime(newStartDate, newStartTime)\n const endCombined = combineDateAndTime(newEndDate, newEndTime)\n\n // Validate: start must be before end\n if (startCombined >= endCombined)\n return\n\n const newFromUtc = zonedDateToUtcString(startCombined, timezone)\n const newToUtc = zonedDateToUtcString(endCombined, timezone)\n\n // Only call if actually changed\n if (newFromUtc !== fromUtc || newToUtc !== toUtc) {\n onRangeChange(newFromUtc, newToUtc)\n }\n },\n [timezone, fromUtc, toUtc, onRangeChange],\n )\n\n // Notify parent when values change (debounced for time inputs)\n const notifyChangeDebounced = useCallback(\n (newStartDate: Date, newStartTime: string, newEndDate: Date, newEndTime: string) => {\n // Clear existing timer\n if (debounceTimerRef.current) {\n clearTimeout(debounceTimerRef.current)\n }\n\n // Set new debounced timer\n debounceTimerRef.current = setTimeout(() => {\n notifyChangeImmediate(newStartDate, newStartTime, newEndDate, newEndTime)\n }, debounceMs)\n },\n [notifyChangeImmediate, debounceMs],\n )\n\n // Handlers for start date (immediate)\n const handleStartDateSelect = useCallback(\n (date: Date | undefined) => {\n if (!date)\n return\n setStartDate(date)\n setStartDateOpen(false)\n notifyChangeImmediate(date, startTime, endDate, endTime)\n },\n [startTime, endDate, endTime, notifyChangeImmediate],\n )\n\n // Handlers for start time (debounced)\n const handleStartTimeChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newTime = e.target.value\n userHasEditedTimeRef.current = true\n setStartTime(newTime)\n if (isValidTime(newTime)) {\n notifyChangeDebounced(startDate, newTime, endDate, endTime)\n }\n },\n [startDate, endDate, endTime, notifyChangeDebounced],\n )\n\n // Handlers for end date (immediate)\n const handleEndDateSelect = useCallback(\n (date: Date | undefined) => {\n if (!date)\n return\n setEndDate(date)\n setEndDateOpen(false)\n notifyChangeImmediate(startDate, startTime, date, endTime)\n },\n [startDate, startTime, endTime, notifyChangeImmediate],\n )\n\n // Handlers for end time (debounced)\n const handleEndTimeChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newTime = e.target.value\n userHasEditedTimeRef.current = true\n setEndTime(newTime)\n if (isValidTime(newTime)) {\n notifyChangeDebounced(startDate, startTime, endDate, newTime)\n }\n },\n [startDate, startTime, endDate, notifyChangeDebounced],\n )\n\n // Effective max date for calendar\n // const effectiveMaxDate = disableFuture ? new Date() : undefined;\n\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n <p className=\"text-muted-foreground text-xs font-medium\">Custom Range</p>\n\n {/* Inline layout: Start — End */}\n <div className=\"flex items-center gap-2\">\n {/* Start Date + Time */}\n <div className=\"flex items-center gap-1.5\">\n <Popover open={startDateOpen} onOpenChange={setStartDateOpen}>\n <PopoverTrigger asChild>\n <Button\n type=\"quaternary\"\n theme=\"outline\"\n id={startDateId}\n className=\"h-8 w-full justify-start gap-1.5 px-2 text-xs font-normal\"\n >\n <CalendarIcon className=\"h-3.5 w-3.5 shrink-0 opacity-50\" />\n <span className=\"truncate\">{format(startDate, 'MMM d, yyyy')}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={startDate}\n onSelect={handleStartDateSelect}\n disabled={disableFuture ? date => date > new Date() : undefined}\n initialFocus\n />\n </PopoverContent>\n </Popover>\n\n <Input\n type=\"time\"\n id={startTimeId}\n value={startTime}\n onChange={handleStartTimeChange}\n className={cn(\n 'h-8 w-[80px] px-2 text-xs md:text-xs',\n 'appearance-none bg-transparent',\n '[&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none',\n )}\n />\n </div>\n\n {/* Separator */}\n <span className=\"text-muted-foreground text-sm\">—</span>\n\n {/* End Date + Time */}\n <div className=\"flex items-center gap-1.5\">\n <Popover open={endDateOpen} onOpenChange={setEndDateOpen}>\n <PopoverTrigger asChild>\n <Button\n type=\"quaternary\"\n theme=\"outline\"\n id={endDateId}\n className=\"h-8 w-full justify-start gap-1.5 px-2 text-xs font-normal\"\n >\n <CalendarIcon className=\"h-3.5 w-3.5 shrink-0 opacity-50\" />\n <span className=\"truncate\">{format(endDate, 'MMM d, yyyy')}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={endDate}\n onSelect={handleEndDateSelect}\n disabled={\n disableFuture\n ? date => date > new Date() || date < startDate\n : date => date < startDate\n }\n initialFocus\n />\n </PopoverContent>\n </Popover>\n\n <Input\n type=\"time\"\n id={endTimeId}\n value={endTime}\n onChange={handleEndTimeChange}\n className={cn(\n 'h-8 w-[80px] px-2 text-xs md:text-xs',\n 'appearance-none bg-transparent',\n '[&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none',\n )}\n />\n </div>\n </div>\n </div>\n )\n}\n\n// Keep the old name for backward compatibility during refactor\nexport { CustomRangePanel as AbsoluteRangePanel }\n","// app/modules/datum-ui/components/time-range-picker/components/quick-ranges-panel.tsx\nimport type { PresetConfig, TimeRangeValue } from '../types'\nimport { cn } from '@repo/shadcn/lib/utils'\n\ninterface QuickRangesPanelProps {\n presets: PresetConfig[]\n value: TimeRangeValue | null\n onPresetSelect: (preset: PresetConfig) => void\n className?: string\n}\n\nexport function QuickRangesPanel({\n presets,\n value,\n onPresetSelect,\n className,\n}: QuickRangesPanelProps) {\n const selectedPreset = value?.type === 'preset' ? value.preset : undefined\n\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n <p className=\"text-muted-foreground px-3 text-xs font-medium\">Presets</p>\n <div className=\"grid gap-1\">\n {presets.map((preset) => {\n const isSelected = selectedPreset === preset.key\n return (\n <button\n key={preset.key}\n type=\"button\"\n onClick={() => onPresetSelect(preset)}\n className={cn(\n 'flex items-center justify-between gap-2 rounded-lg px-3 py-1.5 text-xs transition-colors',\n 'hover:bg-accent hover:text-accent-foreground',\n isSelected\n ? 'bg-accent text-primary border-border border font-medium'\n : 'border border-transparent',\n )}\n >\n <span>{preset.label}</span>\n <kbd\n className={cn(\n 'bg-muted pointer-events-none hidden h-5 items-center gap-1 rounded border px-1.5 font-mono text-[10px] font-medium select-none sm:flex',\n isSelected ? 'border-primary' : 'bg-muted/50 border-transparent',\n )}\n >\n {preset.shortcut}\n </kbd>\n </button>\n )\n })}\n </div>\n </div>\n )\n}\n","// app/modules/datum-ui/components/time-range-picker/components/timezone-selector.tsx\nimport type { TimezoneOption } from '../types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Globe } from 'lucide-react'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../../..'\n\ninterface TimezoneSelectorProps {\n value: string\n onChange: (value: string) => void\n options: TimezoneOption[]\n className?: string\n}\n\nexport function TimezoneSelector({ value, onChange, options, className }: TimezoneSelectorProps) {\n const selectedOption = options.find(opt => opt.value === value)\n\n return (\n <div className={cn('flex items-center gap-2', className)}>\n <Globe className=\"text-muted-foreground h-4 w-4 shrink-0\" />\n <Select value={value} onValueChange={onChange}>\n <SelectTrigger className=\"hover:bg-accent h-8 min-w-[180px] border-0 bg-transparent px-2 text-xs shadow-none\">\n <SelectValue placeholder=\"Select timezone\">{selectedOption?.label ?? value}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {options.map(option => (\n <SelectItem key={option.value} value={option.value} className=\"text-xs\">\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )\n}\n","// app/modules/datum-ui/components/time-range-picker/presets.ts\nimport type { DateRange, PresetConfig } from './types'\nimport { subDays, subHours, subMinutes } from 'date-fns'\nimport { fromZonedTime, toZonedTime } from 'date-fns-tz'\n\n/**\n * Get start of day in a specific timezone\n */\nfunction startOfDayInTimezone(date: Date, timezone: string): Date {\n // Convert to timezone, set to start of day, convert back\n const zonedDate = toZonedTime(date, timezone)\n zonedDate.setHours(0, 0, 0, 0)\n return fromZonedTime(zonedDate, timezone)\n}\n\n/**\n * Get end of day in a specific timezone\n */\nfunction endOfDayInTimezone(date: Date, timezone: string): Date {\n // Convert to timezone, set to end of day, convert back\n const zonedDate = toZonedTime(date, timezone)\n zonedDate.setHours(23, 59, 59, 999)\n return fromZonedTime(zonedDate, timezone)\n}\n\n/**\n * Default time range presets with timezone-aware range calculation\n * Note: All presets use \"now\" as end time to avoid future timestamps\n * (API rejects future times for historical audit logs)\n *\n * API constraint: Maximum time range is 720 hours (30 days)\n */\nexport const DEFAULT_PRESETS: PresetConfig[] = [\n {\n key: '15m',\n label: 'Last 15 minutes',\n shortcut: '1',\n getRange: (_timezone: string): DateRange => {\n const now = new Date()\n return {\n from: subMinutes(now, 15),\n to: now,\n }\n },\n },\n {\n key: '30m',\n label: 'Last 30 minutes',\n shortcut: '3',\n getRange: (_timezone: string): DateRange => {\n const now = new Date()\n return {\n from: subMinutes(now, 30),\n to: now,\n }\n },\n },\n {\n key: '1h',\n label: 'Last hour',\n shortcut: 'H',\n getRange: (_timezone: string): DateRange => {\n const now = new Date()\n return {\n from: subHours(now, 1),\n to: now,\n }\n },\n },\n {\n key: 'today',\n label: 'Today',\n shortcut: 'D',\n getRange: (timezone: string): DateRange => {\n const now = new Date()\n return {\n from: startOfDayInTimezone(now, timezone),\n to: now, // Use now, not end of day (which would be in the future)\n }\n },\n },\n {\n key: 'yesterday',\n label: 'Yesterday',\n shortcut: 'Y',\n getRange: (timezone: string): DateRange => {\n const yesterday = subDays(new Date(), 1)\n return {\n from: startOfDayInTimezone(yesterday, timezone),\n to: endOfDayInTimezone(yesterday, timezone), // Yesterday's end is always in the past\n }\n },\n },\n {\n key: '7d',\n label: 'Last 7 days',\n shortcut: 'W',\n getRange: (_timezone: string): DateRange => {\n const now = new Date()\n return {\n from: subDays(now, 7), // Exactly 7 days ago (168 hours)\n to: now,\n }\n },\n },\n {\n key: '30d',\n label: 'Last 30 days',\n shortcut: 'M',\n getRange: (_timezone: string): DateRange => {\n const now = new Date()\n // Use exactly 30 days (720 hours) to stay within API limit\n return {\n from: subDays(now, 30),\n to: now,\n }\n },\n },\n]\n\n/**\n * Get a preset by key\n */\nexport function getPresetByKey(\n key: string,\n presets: PresetConfig[] = DEFAULT_PRESETS,\n): PresetConfig | undefined {\n return presets.find(p => p.key === key)\n}\n\n/**\n * Get a preset by keyboard shortcut\n */\nexport function getPresetByShortcut(\n shortcut: string,\n presets: PresetConfig[] = DEFAULT_PRESETS,\n): PresetConfig | undefined {\n return presets.find(p => p.shortcut.toLowerCase() === shortcut.toLowerCase())\n}\n\n/**\n * Get the default preset (last 7 days)\n */\nexport function getDefaultPreset(presets: PresetConfig[] = DEFAULT_PRESETS): PresetConfig {\n return getPresetByKey('today', presets) ?? presets[0]!\n}\n\n/**\n * Calculate preset range and return UTC ISO strings\n */\nexport function getPresetRange(\n preset: PresetConfig,\n timezone: string,\n): { from: string, to: string } {\n const range = preset.getRange(timezone)\n return {\n from: range.from.toISOString(),\n to: range.to.toISOString(),\n }\n}\n","// app/modules/datum-ui/components/time-range-picker/utils/format-display.ts\nimport type { TimeRangeValue } from '../types'\nimport { format, isSameDay, isSameYear } from 'date-fns'\nimport { formatUtcForDisplay, utcStringToZonedDate, utcToLocalInputString } from './timezone'\n\n/**\n * Format a TimeRangeValue for display in the trigger button\n * Always shows the actual date/time range, not preset labels\n * Converts UTC timestamps to user's timezone for display\n */\nexport function formatTimeRangeDisplay(value: TimeRangeValue | null, timezone: string): string {\n if (!value || !value.from || !value.to) {\n return 'Select time range'\n }\n\n return formatDateRangeDisplay(value.from, value.to, timezone)\n}\n\n/**\n * Format a date range for display\n * Smart formatting based on whether dates are same day/year\n */\nfunction formatDateRangeDisplay(fromUtc: string, toUtc: string, timezone: string): string {\n try {\n const fromDate = utcStringToZonedDate(fromUtc, timezone)\n const toDate = utcStringToZonedDate(toUtc, timezone)\n const now = new Date()\n\n // Same day: \"Jan 16, 00:00 - 14:30\"\n if (isSameDay(fromDate, toDate)) {\n const dateStr = isSameYear(fromDate, now)\n ? format(fromDate, 'MMM d')\n : format(fromDate, 'MMM d, yyyy')\n const fromTime = format(fromDate, 'HH:mm')\n const toTime = format(toDate, 'HH:mm')\n return `${dateStr}, ${fromTime} - ${toTime}`\n }\n\n // Same year as current: \"Jan 10, 00:00 - Jan 16, 14:30\"\n if (isSameYear(fromDate, now) && isSameYear(toDate, now)) {\n const fromStr = format(fromDate, 'MMM d, HH:mm')\n const toStr = format(toDate, 'MMM d, HH:mm')\n return `${fromStr} - ${toStr}`\n }\n\n // Different years: \"Dec 17, 2025 - Jan 16, 2026\"\n const fromStr = format(fromDate, 'MMM d, yyyy')\n const toStr = format(toDate, 'MMM d, yyyy')\n return `${fromStr} - ${toStr}`\n }\n catch {\n // Fallback to simple format\n const fromDisplay = formatUtcForDisplay(fromUtc, timezone, 'MMM d, HH:mm')\n const toDisplay = formatUtcForDisplay(toUtc, timezone, 'MMM d, HH:mm')\n return `${fromDisplay} - ${toDisplay}`\n }\n}\n\n/**\n * Format a UTC ISO string for display in user's timezone\n */\nexport function formatSingleTimeDisplay(utcString: string, timezone: string): string {\n try {\n return formatUtcForDisplay(utcString, timezone, 'MMM d, yyyy HH:mm')\n }\n catch {\n return utcString\n }\n}\n\n/**\n * Format a Date object for the datetime-local input field\n */\nexport function formatDateForInput(date: Date): string {\n return format(date, 'yyyy-MM-dd\\'T\\'HH:mm')\n}\n\n/**\n * Format UTC string for datetime-local input in user's timezone\n */\nexport function formatUtcForInput(utcString: string, timezone: string): string {\n try {\n const date = new Date(utcString)\n return utcToLocalInputString(date, timezone)\n }\n catch {\n return ''\n }\n}\n","import type { DateRange as DayPickerDateRange } from 'react-day-picker'\nimport type { PresetConfig, TimeRangeValue } from './types'\nimport { cn } from '@repo/shadcn/lib/utils'\nimport { Popover, PopoverContent, PopoverTrigger } from '@repo/shadcn/ui/popover'\nimport { Separator } from '@repo/shadcn/ui/separator'\nimport { Calendar as CalendarIcon, Globe, X } from 'lucide-react'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { Button, Calendar, Icon } from '../..'\n// app/modules/datum-ui/components/time-range-picker/time-range-picker.tsx\nimport { CustomRangePanel } from './components/absolute-range-panel'\nimport { QuickRangesPanel } from './components/quick-ranges-panel'\nimport { DEFAULT_PRESETS, getDefaultPreset, getPresetByShortcut, getPresetRange } from './presets'\nimport { formatTimeRangeDisplay } from './utils/format-display'\nimport {\n formatTimezoneLabel,\n getBrowserTimezone,\n utcStringToZonedDate,\n zonedDateToUtcString,\n} from './utils/timezone'\n\nexport interface TimeRangePickerProps {\n /** Current value (controlled) - stores UTC timestamps */\n value: TimeRangeValue | null\n /** Called when value changes */\n onChange: (value: TimeRangeValue) => void\n /** Called when clear button is clicked - clears URL params and resets to default */\n onClear?: () => void\n\n /** User's timezone (for display conversion) */\n timezone?: string\n\n /** Preset configurations */\n presets?: PresetConfig[]\n\n /** Disable future dates */\n disableFuture?: boolean\n /** Maximum selectable date */\n maxDate?: Date\n /** Minimum selectable date */\n minDate?: Date\n\n /** Custom class name */\n className?: string\n /** Whether the picker is disabled */\n disabled?: boolean\n /** Placeholder text */\n placeholder?: string\n /** Popover alignment */\n align?: 'start' | 'center' | 'end'\n /** Popover side */\n side?: 'top' | 'bottom'\n}\n\nexport function TimeRangePicker({\n value,\n onChange,\n onClear,\n timezone: timezoneProp,\n presets = DEFAULT_PRESETS,\n disableFuture = false,\n maxDate,\n minDate,\n className,\n disabled = false,\n placeholder = 'Select time range',\n align = 'start',\n side = 'bottom',\n}: TimeRangePickerProps) {\n const [open, setOpen] = useState(false)\n\n // Effective timezone\n const timezone = timezoneProp ?? getBrowserTimezone()\n\n // Get default range for initial state - memoized to prevent recalculation on every render\n const defaultPreset = getDefaultPreset(presets)\n const defaultRange = useMemo(\n () => getPresetRange(defaultPreset, timezone),\n [defaultPreset, timezone],\n )\n\n // Current UTC values (from value or default)\n const currentFromUtc = value?.from ?? defaultRange.from\n const currentToUtc = value?.to ?? defaultRange.to\n\n // Convert UTC to zoned dates for calendar display\n const calendarRange = useMemo<DayPickerDateRange | undefined>(() => {\n try {\n return {\n from: utcStringToZonedDate(currentFromUtc, timezone),\n to: utcStringToZonedDate(currentToUtc, timezone),\n }\n }\n catch {\n return undefined\n }\n }, [currentFromUtc, currentToUtc, timezone])\n\n // Effective value (use default if no value provided)\n const effectiveValue = useMemo<TimeRangeValue>(() => {\n // If we have a preset key but missing timestamps (from URL deserialization),\n // recalculate the timestamps from the preset\n if (value?.type === 'preset' && value?.preset && (!value?.from || !value?.to)) {\n const preset = presets.find(p => p.key === value.preset) ?? defaultPreset\n const range = getPresetRange(preset, timezone)\n return {\n type: 'preset',\n preset: preset.key,\n from: range.from,\n to: range.to,\n }\n }\n\n if (value?.from && value?.to) {\n return value\n }\n // Return default preset value\n return {\n type: 'preset',\n preset: defaultPreset.key,\n from: defaultRange.from,\n to: defaultRange.to,\n }\n }, [value, defaultPreset, defaultRange.from, defaultRange.to, presets, timezone])\n\n // Display text for trigger button\n const displayText = useMemo(\n () => formatTimeRangeDisplay(effectiveValue, timezone) || placeholder,\n [effectiveValue, timezone, placeholder],\n )\n\n // Handle preset selection (instant apply)\n const handlePresetSelect = useCallback(\n (preset: PresetConfig) => {\n const range = getPresetRange(preset, timezone)\n onChange({\n type: 'preset',\n preset: preset.key,\n from: range.from,\n to: range.to,\n })\n setOpen(false)\n },\n [onChange, timezone],\n )\n\n // Track if user has interacted with calendar (via day click)\n const userClickedCalendarRef = useRef(false)\n\n // Handle calendar day click - fires BEFORE onSelect\n const handleDayClick = useCallback(() => {\n userClickedCalendarRef.current = true\n }, [])\n\n // Handle calendar range selection\n // Only triggers onChange when user actually clicks on calendar dates\n const handleCalendarSelect = useCallback(\n (range: DayPickerDateRange | undefined) => {\n // Ignore if this isn't a user-initiated selection\n // onDayClick sets the ref to true just before onSelect fires\n if (!userClickedCalendarRef.current)\n return\n\n // Reset the flag after processing\n userClickedCalendarRef.current = false\n\n if (range?.from && range?.to) {\n const now = new Date()\n\n // Calendar returns dates at 00:00:00 (start of day)\n // For 'from': use start of day (00:00:00)\n const fromStart = new Date(range.from)\n fromStart.setHours(0, 0, 0, 0)\n\n // For 'to': use end of day, but cap at 'now' if it's today (to avoid future times)\n const toEnd = new Date(range.to)\n toEnd.setHours(23, 59, 59, 999)\n\n // If toEnd is in the future, use now instead\n const effectiveToEnd = toEnd > now ? now : toEnd\n\n // Convert zoned dates to UTC\n const fromUtc = zonedDateToUtcString(fromStart, timezone)\n const toUtc = zonedDateToUtcString(effectiveToEnd, timezone)\n\n onChange({\n type: 'custom',\n from: fromUtc,\n to: toUtc,\n })\n }\n else if (range?.from) {\n const now = new Date()\n\n // Single date selected - use full day range\n const fromStart = new Date(range.from)\n fromStart.setHours(0, 0, 0, 0)\n\n const toEnd = new Date(range.from)\n toEnd.setHours(23, 59, 59, 999)\n\n // If toEnd is in the future, use now instead\n const effectiveToEnd = toEnd > now ? now : toEnd\n\n const fromUtc = zonedDateToUtcString(fromStart, timezone)\n const toUtc = zonedDateToUtcString(effectiveToEnd, timezone)\n\n onChange({\n type: 'custom',\n from: fromUtc,\n to: toUtc,\n })\n }\n },\n [onChange, timezone],\n )\n\n // Handle custom range input changes\n const handleCustomRangeChange = useCallback(\n (fromUtc: string, toUtc: string) => {\n onChange({\n type: 'custom',\n from: fromUtc,\n to: toUtc,\n })\n },\n [onChange],\n )\n\n // Keyboard shortcuts\n useEffect(() => {\n if (!open)\n return\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const preset = getPresetByShortcut(e.key, presets)\n if (preset) {\n e.preventDefault()\n handlePresetSelect(preset)\n }\n }\n\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [open, presets, handlePresetSelect])\n\n // Effective max date\n const effectiveMaxDate = disableFuture ? new Date() : maxDate\n\n // Handle clear button click\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation() // Prevent popover from opening\n onClear?.()\n },\n [onClear],\n )\n\n // Show clear button only when there's a value and onClear is provided\n const showClearButton = value && onClear\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <div className=\"relative inline-flex\">\n <PopoverTrigger asChild>\n <Button\n type=\"quaternary\"\n theme=\"outline\"\n disabled={disabled}\n className={cn(\n 'text-foreground min-w-[200px] items-center justify-between gap-2 px-3 font-normal',\n className,\n )}\n >\n <div className=\"flex flex-1 items-center gap-2\">\n <Icon icon={CalendarIcon} size={16} />\n <span className=\"truncate text-xs\">{displayText}</span>\n </div>\n\n {showClearButton && (\n <div\n onClick={(e) => {\n e.stopPropagation()\n e.preventDefault()\n handleClear(e)\n }}\n className={cn(\n 'size-[14px] shrink-0 p-0 hover:bg-transparent',\n 'hover:text-destructive text-icon-quaternary hover:bg-transparent dark:text-white',\n 'focus:ring-ring focus:ring-2 focus:ring-offset-1 focus:outline-none',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'transition-colors',\n )}\n aria-label=\"Clear time range\"\n >\n <Icon icon={X} size={14} />\n </div>\n )}\n </Button>\n </PopoverTrigger>\n </div>\n\n <PopoverContent className=\"w-auto rounded-xl p-0\" align={align} side={side} sideOffset={4}>\n {/* Main content: Calendar (left) + Presets (right) */}\n <div className=\"divide-border flex flex-col divide-x sm:flex-row\">\n {/* Calendar */}\n <div className=\"flex-1 px-0\">\n <Calendar\n className=\"w-full\"\n mode=\"range\"\n defaultMonth={calendarRange?.from}\n selected={calendarRange}\n onSelect={handleCalendarSelect}\n onDayClick={handleDayClick}\n numberOfMonths={1}\n disabled={(date) => {\n if (effectiveMaxDate && date > effectiveMaxDate)\n return true\n if (minDate && date < minDate)\n return true\n return false\n }}\n initialFocus\n />\n </div>\n\n {/* Separator */}\n {/* <Separator orientation=\"vertical\" className=\"hidden h-auto sm:block\" />\n <Separator orientation=\"horizontal\" className=\"sm:hidden\" /> */}\n\n {/* Presets */}\n <div className=\"p-3\">\n <QuickRangesPanel\n presets={presets}\n value={effectiveValue}\n onPresetSelect={handlePresetSelect}\n />\n </div>\n </div>\n\n <Separator />\n\n {/* Custom range inputs */}\n <div className=\"p-3\">\n <CustomRangePanel\n fromUtc={currentFromUtc}\n toUtc={currentToUtc}\n timezone={timezone}\n onRangeChange={handleCustomRangeChange}\n disableFuture={disableFuture}\n />\n </div>\n\n <Separator />\n\n {/* Timezone indicator */}\n <div className=\"text-muted-foreground bg-muted/30 flex items-center gap-2 px-3 py-2 text-xs\">\n <Globe className=\"h-3.5 w-3.5\" />\n <span>\n Your timezone:\n {formatTimezoneLabel(timezone)}\n </span>\n </div>\n </PopoverContent>\n </Popover>\n )\n}\n","import type { ApiTimeRange, PresetConfig, TimeRangeValue } from '../types'\n// app/modules/datum-ui/components/time-range-picker/utils/to-api-format.ts\nimport { DEFAULT_PRESETS, getDefaultPreset, getPresetRange } from '../presets'\nimport { getBrowserTimezone } from './timezone'\n\n/**\n * Convert a TimeRangeValue to API format (startTime/endTime)\n *\n * Since TimeRangeValue now always stores UTC timestamps,\n * this is a simple passthrough.\n *\n * @param value - The time range value (stores UTC timestamps)\n * @param timezone - User's timezone (used only if value needs recalculation)\n * @param presets - Preset configurations\n */\nexport function toApiTimeRange(\n value: TimeRangeValue | null,\n timezone?: string,\n presets: PresetConfig[] = DEFAULT_PRESETS,\n): ApiTimeRange {\n const tz = timezone ?? getBrowserTimezone()\n\n // Default fallback - use first preset\n if (!value) {\n const defaultPreset = getDefaultPreset()\n const range = getPresetRange(defaultPreset, tz)\n return { startTime: range.from, endTime: range.to }\n }\n\n // Value has from/to - use them directly (they're already UTC)\n if (value.from && value.to) {\n return {\n startTime: value.from,\n endTime: value.to,\n }\n }\n\n // Fallback for malformed value - recalculate from preset\n if (value.type === 'preset' && value.preset) {\n const preset = presets.find(p => p.key === value.preset)\n if (preset) {\n const range = getPresetRange(preset, tz)\n return { startTime: range.from, endTime: range.to }\n }\n }\n\n // Ultimate fallback\n const defaultPreset = getDefaultPreset(presets)\n const range = getPresetRange(defaultPreset, tz)\n return { startTime: range.from, endTime: range.to }\n}\n","import * as React from 'react'\n\ninterface ClientOnlyProps {\n children: React.ReactNode\n fallback?: React.ReactNode\n}\n\nexport function ClientOnly({ children, fallback = null }: ClientOnlyProps) {\n const [hasMounted, setHasMounted] = React.useState(false)\n\n React.useEffect(() => {\n setHasMounted(true)\n }, [])\n\n if (!hasMounted) {\n return <>{fallback}</>\n }\n\n return <>{children}</>\n}\n","export function script(attribute: string | string[], storageKey: string, defaultTheme: string, forcedTheme: string | undefined, themes: string[], value: Record<string, string> | undefined, enableSystem: boolean, enableColorScheme: boolean) {\n // Don't run on server\n if (typeof window === 'undefined')\n return\n const el = document.documentElement\n const systemThemes = ['light', 'dark']\n\n function updateDOM(theme: string) {\n const attributes = Array.isArray(attribute) ? attribute : [attribute]\n\n attributes.forEach((attr) => {\n const isClass = attr === 'class'\n const classes = isClass && value ? themes.map(t => value[t] || t) : themes\n if (isClass) {\n el.classList.remove(...classes)\n el.classList.add(value && value[theme] ? value[theme] : theme)\n }\n else {\n el.setAttribute(attr, theme)\n }\n })\n\n setColorScheme(theme)\n }\n\n function setColorScheme(theme: string) {\n if (enableColorScheme && systemThemes.includes(theme)) {\n el.style.colorScheme = theme\n }\n }\n\n function getSystemTheme() {\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n }\n\n if (forcedTheme) {\n updateDOM(forcedTheme)\n }\n else {\n try {\n const themeName = localStorage.getItem(storageKey) || defaultTheme\n const isSystem = enableSystem && themeName === 'system'\n const theme = isSystem ? getSystemTheme() : themeName\n updateDOM(theme)\n }\n catch {\n // Ignore\n }\n }\n}\n","import * as React from 'react'\nimport { script } from './script'\n\ninterface ThemeScriptProps {\n forcedTheme?: string\n storageKey?: string\n attribute?: string | string[]\n enableSystem?: boolean\n enableColorScheme?: boolean\n defaultTheme?: string\n value?: Record<string, string>\n themes?: string[]\n nonce?: string\n scriptProps?: {\n [key: string]: any\n }\n}\n\nexport const ThemeScript = React.memo(({\n forcedTheme,\n storageKey = 'theme',\n attribute = 'data-theme',\n enableSystem = true,\n enableColorScheme = true,\n defaultTheme = 'system',\n value,\n themes = ['light', 'dark'],\n nonce,\n scriptProps,\n}: ThemeScriptProps) => {\n const scriptArgs = JSON.stringify([\n attribute,\n storageKey,\n defaultTheme,\n forcedTheme,\n themes,\n value,\n enableSystem,\n enableColorScheme,\n ]).slice(1, -1)\n\n return (\n <script\n {...scriptProps}\n suppressHydrationWarning\n nonce={nonce}\n dangerouslySetInnerHTML={{ __html: `(${script.toString()})(${scriptArgs})` }}\n />\n )\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,MAAM,qBAAqB;CACzB,SAAS;EACP,SAAS;EACT,kBAAkB;EACnB;CACD,WAAW;EACT,SAAS;EACT,kBAAkB;EACnB;CACD,SAAS;EACP,SAAS;EACT,kBAAkB;EACnB;CACD,aAAa;EACX,SACE;EACF,kBAAkB;EACnB;CACD,SAAS;EACP,SAAS;EACT,kBAAkB;EACnB;CACD,MAAM;EACJ,SAAS;EACT,kBAAkB;EACnB;CACD,SAAS;EACP,SAAS;EACT,kBAAkB;EACnB;CACF;AAED,MAAM,gBAAgB,IACpB,6JACA;CACE,UAAU,EACR,SAAS;EACP,SAAS,mBAAmB,QAAQ;EACpC,WAAW,mBAAmB,UAAU;EACxC,SAAS,mBAAmB,QAAQ;EACpC,aAAa,mBAAmB,YAAY;EAC5C,SAAS,mBAAmB,QAAQ;EACpC,MAAM,mBAAmB,KAAK;EAC9B,SAAS,mBAAmB,QAAQ;EACrC,EACF;CACD,iBAAiB,EACf,SAAS,WACV;CACF,CACF;AAeD,SAAS,MAAM,EAAE,WAAW,SAAS,WAAW,OAAO,SAAS,GAAG,SAAqB;CACtF,MAAM,CAAC,WAAW,gBAAgBA,QAAM,SAAS,KAAK;CAEtD,MAAM,oBAAoB;AACxB,MAAI,QACF,UAAS;MAGT,cAAa,MAAM;;AAIvB,KAAI,CAAC,UACH,QAAO;AAGT,QACE,qBAAC;EACC,MAAK;EACL,WAAW,GAAG,cAAc,EAAE,SAAS,CAAC,EAAE,YAAY,SAAS,UAAU;EACzE,GAAI;aAEH,MAAM,UACN,YACC,oBAAC;GACC,SAAS;GACT,MAAK;GACL,UAAU;GACV,YAAY,MAAM;AAChB,QAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,OAAE,gBAAgB;AAClB,kBAAa;;;GAGjB,WAAU;GACV,cAAW;aAEX,oBAAC,eACC,WAAW,GAAG,UAAU,WAAW,mBAAmB,UAAU,iBAAiB,GACjF;IACG;GAEL;;AAIV,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;AACxE,QACE,oBAAC;EACC,WAAW,GAAG,+DAA+D,UAAU;EACvF,GAAI;GACJ;;AAIN,SAAS,iBAAiB,EAAE,WAAW,GAAG,SAAsC;AAC9E,QACE,oBAAC;EACC,WAAW,GACT,kGACA,UACD;EACD,GAAI;GACJ;;;;;;;;;;;AChIN,MAAM,gBAAgB,IACpB,uKACA;CACE,UAAU;EACR,MAAM;GACJ,SAAS;GACT,WAAW;GACX,UAAU;GACV,YAAY;GACZ,MAAM;GACN,SAAS;GACT,QAAQ;GACR,SAAS;GACT,OAAO;GACR;EACD,OAAO;GACL,OAAO;GACP,SAAS;GACT,OAAO;GACR;EACF;CACD,kBAAkB;EAEhB;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACF;CACD,iBAAiB;EACf,MAAM;EACN,OAAO;EACR;CACF,CACF;AAKD,SAAS,MAAM,EAAE,WAAW,MAAM,OAAO,GAAG,SAAqB;AAC/D,QAAO,oBAAC;EAAI,WAAW,GAAG,cAAc;GAAE;GAAM;GAAO,CAAC,EAAE,UAAU;EAAE,GAAI;GAAS;;;;;AC3NrF,MAAMC,mBAAiB,IACrB,gNACA;CACE,UAAU;EACR,MAAM;GACJ,SAAS;GACT,WAAW;GACX,UAAU;GACV,YAAY;GACZ,SAAS;GACT,QAAQ;GACR,SAAS;GACV;EACD,OAAO;GACL,OAAO;GACP,OAAO;GACP,SAAS;GACT,YAAY;GACZ,MAAM;GACP;EACD,MAAM;GACJ,IAAI;GACJ,OAAO;GACP,SAAS;GACT,OAAO;GACP,MAAM;GACN,MAAM;GACP;EACD,OAAO;GACL,MAAM;GACN,OAAO;GACR;EACF;CACD,kBAAkB;EAEhB;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,iJACA,uBACD;GACF;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,yMACA,+GACD;GACF;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,sHACA,uBACD;GACF;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,qJACA,uBACD;GACF;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,qNACA,+GACD;GACF;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,0HACA,uBACD;GACF;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,mJACA,uBACD;GACF;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,+MACA,+GACD;GACF;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,wHACA,uBACD;GACF;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,qLACA,uBACD;GACF;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,yPACA,+GACD;GACF;EACD;GACE,MAAM;GACN,OAAO;GACP,WAAW,GACT,0JACA,uBACD;GACF;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EAGD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACD;GACE,MAAM;GACN,OAAO;GACP,WACE;GACH;EACF;CACD,iBAAiB;EACf,MAAM;EACN,OAAO;EACP,MAAM;EACN,OAAO;EACR;CACF,CACF;AAcD,SAASC,SAAO,EAAE,KAAK,WAAW,MAAM,OAAO,MAAM,OAAO,UAAU,OAAO,UAAU,MAAM,eAAe,QAAQ,aAAa,WAAW,UAAU,UAAU,GAAG,SAA4E;CAC7O,MAAM,aAAa,YAAY;CAG/B,MAAM,cAAc,QAAQ,YAAY,CAAC;CAGzC,MAAM,WAAW,CAAC,WAAW;CAC7B,MAAM,uBAAuB;AAC3B,SACE,eACE,oBAAC;GACC,MAAM,SAAS,UAAU,OAAO,SAAS,UAAU,OAAO;GAC1D,eAAY;IACZ;;CAIR,MAAM,kB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"}