@marktiderman/genesis-ui 1.1.1 → 1.3.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 (65) hide show
  1. package/dist/{chunk-DGRHPJ3M.js → chunk-44TULYGG.js} +3 -3
  2. package/dist/{chunk-DGRHPJ3M.js.map → chunk-44TULYGG.js.map} +1 -1
  3. package/dist/{chunk-AI6CCNWK.js → chunk-6NPEMLBA.js} +2 -2
  4. package/dist/chunk-6NPEMLBA.js.map +1 -0
  5. package/dist/{chunk-UKSBLFEK.js → chunk-6VVVGYKS.js} +4 -4
  6. package/dist/{chunk-UKSBLFEK.js.map → chunk-6VVVGYKS.js.map} +1 -1
  7. package/dist/chunk-A2OXCNNY.js +65 -0
  8. package/dist/chunk-A2OXCNNY.js.map +1 -0
  9. package/dist/{chunk-O4B5ALO7.js → chunk-AUECDWP2.js} +3 -3
  10. package/dist/{chunk-O4B5ALO7.js.map → chunk-AUECDWP2.js.map} +1 -1
  11. package/dist/{chunk-FCGFG4RV.js → chunk-D4JTQYP5.js} +3 -3
  12. package/dist/{chunk-FCGFG4RV.js.map → chunk-D4JTQYP5.js.map} +1 -1
  13. package/dist/chunk-GCQFVMPI.js +56 -0
  14. package/dist/chunk-GCQFVMPI.js.map +1 -0
  15. package/dist/{chunk-X7KMF6NH.js → chunk-IP6TMT3D.js} +3 -3
  16. package/dist/{chunk-X7KMF6NH.js.map → chunk-IP6TMT3D.js.map} +1 -1
  17. package/dist/{chunk-LDPPIBIJ.js → chunk-KB5T5LWM.js} +3 -3
  18. package/dist/{chunk-LDPPIBIJ.js.map → chunk-KB5T5LWM.js.map} +1 -1
  19. package/dist/{chunk-MUQLZFUR.js → chunk-NPNADZHM.js} +11 -5
  20. package/dist/chunk-NPNADZHM.js.map +1 -0
  21. package/dist/{chunk-6V4GJUE3.js → chunk-QSXVL5UB.js} +4 -3
  22. package/dist/chunk-QSXVL5UB.js.map +1 -0
  23. package/dist/{chunk-AIODTBWP.js → chunk-T5VX5DYO.js} +3 -2
  24. package/dist/chunk-T5VX5DYO.js.map +1 -0
  25. package/dist/chunk-YETMISCE.js +23 -0
  26. package/dist/chunk-YETMISCE.js.map +1 -0
  27. package/dist/{chunk-I6JQHP6D.js → chunk-ZJFSZFPI.js} +4 -2
  28. package/dist/chunk-ZJFSZFPI.js.map +1 -0
  29. package/dist/components/data/index.d.ts +186 -20
  30. package/dist/components/data/index.js +1165 -181
  31. package/dist/components/data/index.js.map +1 -1
  32. package/dist/components/ui/badge.js +1 -1
  33. package/dist/components/ui/button.d.ts +3 -1
  34. package/dist/components/ui/button.js +1 -1
  35. package/dist/components/ui/calendar.js +2 -2
  36. package/dist/components/ui/carousel.js +2 -2
  37. package/dist/components/ui/command-palette.d.ts +30 -0
  38. package/dist/components/ui/command-palette.js +6 -0
  39. package/dist/components/ui/command-palette.js.map +1 -0
  40. package/dist/components/ui/date-picker.js +3 -3
  41. package/dist/components/ui/form-field.js +2 -2
  42. package/dist/components/ui/input.js +1 -1
  43. package/dist/components/ui/label.js +1 -1
  44. package/dist/components/ui/pagination.js +2 -2
  45. package/dist/components/ui/textarea.js +1 -1
  46. package/dist/hooks/index.d.ts +4 -2
  47. package/dist/hooks/index.js +8 -3
  48. package/dist/hooks/use-data-filters.d.ts +1 -1
  49. package/dist/hooks/use-data-filters.js +2 -2
  50. package/dist/hooks/use-resource-page.d.ts +2 -1
  51. package/dist/hooks/use-saved-views.d.ts +28 -0
  52. package/dist/hooks/use-saved-views.js +3 -0
  53. package/dist/hooks/use-saved-views.js.map +1 -0
  54. package/dist/index.d.ts +2 -1
  55. package/dist/index.js +24 -23
  56. package/dist/{navigation-qI86Ldug.d.ts → navigation-CpOEyUSb.d.ts} +4 -0
  57. package/dist/{use-resource-page-B-CFcikK.d.ts → use-resource-page-BXBv_Xah.d.ts} +9 -1
  58. package/package.json +5 -1
  59. package/dist/chunk-6V4GJUE3.js.map +0 -1
  60. package/dist/chunk-AI6CCNWK.js.map +0 -1
  61. package/dist/chunk-AIODTBWP.js.map +0 -1
  62. package/dist/chunk-I6JQHP6D.js.map +0 -1
  63. package/dist/chunk-MUQLZFUR.js.map +0 -1
  64. package/dist/chunk-W64GERJW.js +0 -22
  65. package/dist/chunk-W64GERJW.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { buttonVariants, Button } from './chunk-I6JQHP6D.js';
2
+ import { buttonVariants, Button } from './chunk-ZJFSZFPI.js';
3
3
  import { cn } from './chunk-NZ5WBA4R.js';
4
4
  import * as React from 'react';
5
5
  import { ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon } from 'lucide-react';
@@ -201,5 +201,5 @@ function CalendarDayButton({
201
201
  }
202
202
 
203
203
  export { Calendar, CalendarDayButton };
204
- //# sourceMappingURL=chunk-DGRHPJ3M.js.map
205
- //# sourceMappingURL=chunk-DGRHPJ3M.js.map
204
+ //# sourceMappingURL=chunk-44TULYGG.js.map
205
+ //# sourceMappingURL=chunk-44TULYGG.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ui/calendar.tsx"],"names":[],"mappings":"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","file":"chunk-DGRHPJ3M.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n} from \"lucide-react\";\nimport {\n DayPicker,\n getDefaultClassNames,\n type DayButton,\n} from \"react-day-picker\";\n\nimport { cn } from \"../../utils\";\nimport { Button, buttonVariants } from \"./button\";\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 \"group/calendar bg-background 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) =>\n date.toLocaleString(\"default\", { month: \"short\" }),\n ...formatters,\n }}\n classNames={{\n root: cn(\"w-fit\", defaultClassNames.root),\n months: cn(\n \"relative flex flex-col gap-4 md:flex-row\",\n defaultClassNames.months,\n ),\n month: cn(\"flex w-full flex-col gap-4\", defaultClassNames.month),\n nav: cn(\n \"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1\",\n defaultClassNames.nav,\n ),\n button_previous: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n defaultClassNames.button_previous,\n ),\n button_next: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n defaultClassNames.button_next,\n ),\n month_caption: cn(\n \"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)\",\n defaultClassNames.month_caption,\n ),\n dropdowns: cn(\n \"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium\",\n defaultClassNames.dropdowns,\n ),\n dropdown_root: cn(\n \"relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50\",\n defaultClassNames.dropdown_root,\n ),\n dropdown: cn(\n \"absolute inset-0 bg-popover opacity-0\",\n defaultClassNames.dropdown,\n ),\n caption_label: cn(\n \"font-medium select-none\",\n captionLayout === \"label\"\n ? \"text-sm\"\n : \"flex h-8 items-center gap-1 rounded-md pr-1 pl-2 text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground\",\n defaultClassNames.caption_label,\n ),\n table: \"w-full border-collapse\",\n weekdays: cn(\"flex\", defaultClassNames.weekdays),\n weekday: cn(\n \"flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none\",\n defaultClassNames.weekday,\n ),\n week: cn(\"mt-2 flex w-full\", defaultClassNames.week),\n week_number_header: cn(\n \"w-(--cell-size) select-none\",\n defaultClassNames.week_number_header,\n ),\n week_number: cn(\n \"text-[0.8rem] text-muted-foreground select-none\",\n defaultClassNames.week_number,\n ),\n day: cn(\n \"group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-md\",\n props.showWeekNumber\n ? \"[&:nth-child(2)[data-selected=true]_button]:rounded-l-md\"\n : \"[&:first-child[data-selected=true]_button]:rounded-l-md\",\n defaultClassNames.day,\n ),\n range_start: cn(\n \"rounded-l-md bg-accent\",\n defaultClassNames.range_start,\n ),\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 \"rounded-md bg-accent text-accent-foreground 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(\n \"text-muted-foreground opacity-50\",\n defaultClassNames.disabled,\n ),\n hidden: cn(\"invisible\", defaultClassNames.hidden),\n ...classNames,\n }}\n components={{\n Root: ({ className: rootClassName, rootRef, ...rootProps }) => {\n return (\n <div\n data-slot=\"calendar\"\n ref={rootRef}\n className={cn(rootClassName)}\n {...rootProps}\n />\n );\n },\n Chevron: ({\n className: chevronClassName,\n orientation,\n ...chevronProps\n }) => {\n if (orientation === \"left\") {\n return (\n <ChevronLeftIcon\n className={cn(\"size-4\", chevronClassName)}\n {...chevronProps}\n />\n );\n }\n\n if (orientation === \"right\") {\n return (\n <ChevronRightIcon\n className={cn(\"size-4\", chevronClassName)}\n {...chevronProps}\n />\n );\n }\n\n return (\n <ChevronDownIcon\n className={cn(\"size-4\", chevronClassName)}\n {...chevronProps}\n />\n );\n },\n DayButton: CalendarDayButton,\n WeekNumber: ({ children, ...weekNumberProps }) => {\n return (\n <td {...weekNumberProps}>\n <div className=\"flex size-(--cell-size) items-center justify-center text-center\">\n {children}\n </div>\n </td>\n );\n },\n ...components,\n }}\n {...props}\n />\n );\n}\n\nfunction CalendarDayButton({\n className: dayClassName,\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) 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 \"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:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-accent-foreground [&>span]:text-xs [&>span]:opacity-70\",\n defaultClassNames.day,\n dayClassName,\n )}\n {...props}\n />\n );\n}\n\nexport { Calendar, CalendarDayButton };\n"]}
1
+ {"version":3,"sources":["../src/components/ui/calendar.tsx"],"names":[],"mappings":"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","file":"chunk-44TULYGG.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n} from \"lucide-react\";\nimport {\n DayPicker,\n getDefaultClassNames,\n type DayButton,\n} from \"react-day-picker\";\n\nimport { cn } from \"../../utils\";\nimport { Button, buttonVariants } from \"./button\";\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 \"group/calendar bg-background 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) =>\n date.toLocaleString(\"default\", { month: \"short\" }),\n ...formatters,\n }}\n classNames={{\n root: cn(\"w-fit\", defaultClassNames.root),\n months: cn(\n \"relative flex flex-col gap-4 md:flex-row\",\n defaultClassNames.months,\n ),\n month: cn(\"flex w-full flex-col gap-4\", defaultClassNames.month),\n nav: cn(\n \"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1\",\n defaultClassNames.nav,\n ),\n button_previous: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n defaultClassNames.button_previous,\n ),\n button_next: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n defaultClassNames.button_next,\n ),\n month_caption: cn(\n \"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)\",\n defaultClassNames.month_caption,\n ),\n dropdowns: cn(\n \"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium\",\n defaultClassNames.dropdowns,\n ),\n dropdown_root: cn(\n \"relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50\",\n defaultClassNames.dropdown_root,\n ),\n dropdown: cn(\n \"absolute inset-0 bg-popover opacity-0\",\n defaultClassNames.dropdown,\n ),\n caption_label: cn(\n \"font-medium select-none\",\n captionLayout === \"label\"\n ? \"text-sm\"\n : \"flex h-8 items-center gap-1 rounded-md pr-1 pl-2 text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground\",\n defaultClassNames.caption_label,\n ),\n table: \"w-full border-collapse\",\n weekdays: cn(\"flex\", defaultClassNames.weekdays),\n weekday: cn(\n \"flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none\",\n defaultClassNames.weekday,\n ),\n week: cn(\"mt-2 flex w-full\", defaultClassNames.week),\n week_number_header: cn(\n \"w-(--cell-size) select-none\",\n defaultClassNames.week_number_header,\n ),\n week_number: cn(\n \"text-[0.8rem] text-muted-foreground select-none\",\n defaultClassNames.week_number,\n ),\n day: cn(\n \"group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-md\",\n props.showWeekNumber\n ? \"[&:nth-child(2)[data-selected=true]_button]:rounded-l-md\"\n : \"[&:first-child[data-selected=true]_button]:rounded-l-md\",\n defaultClassNames.day,\n ),\n range_start: cn(\n \"rounded-l-md bg-accent\",\n defaultClassNames.range_start,\n ),\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 \"rounded-md bg-accent text-accent-foreground 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(\n \"text-muted-foreground opacity-50\",\n defaultClassNames.disabled,\n ),\n hidden: cn(\"invisible\", defaultClassNames.hidden),\n ...classNames,\n }}\n components={{\n Root: ({ className: rootClassName, rootRef, ...rootProps }) => {\n return (\n <div\n data-slot=\"calendar\"\n ref={rootRef}\n className={cn(rootClassName)}\n {...rootProps}\n />\n );\n },\n Chevron: ({\n className: chevronClassName,\n orientation,\n ...chevronProps\n }) => {\n if (orientation === \"left\") {\n return (\n <ChevronLeftIcon\n className={cn(\"size-4\", chevronClassName)}\n {...chevronProps}\n />\n );\n }\n\n if (orientation === \"right\") {\n return (\n <ChevronRightIcon\n className={cn(\"size-4\", chevronClassName)}\n {...chevronProps}\n />\n );\n }\n\n return (\n <ChevronDownIcon\n className={cn(\"size-4\", chevronClassName)}\n {...chevronProps}\n />\n );\n },\n DayButton: CalendarDayButton,\n WeekNumber: ({ children, ...weekNumberProps }) => {\n return (\n <td {...weekNumberProps}>\n <div className=\"flex size-(--cell-size) items-center justify-center text-center\">\n {children}\n </div>\n </td>\n );\n },\n ...components,\n }}\n {...props}\n />\n );\n}\n\nfunction CalendarDayButton({\n className: dayClassName,\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) 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 \"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:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-accent-foreground [&>span]:text-xs [&>span]:opacity-70\",\n defaultClassNames.day,\n dayClassName,\n )}\n {...props}\n />\n );\n}\n\nexport { Calendar, CalendarDayButton };\n"]}
@@ -47,5 +47,5 @@ function useBrowserSearchParams() {
47
47
  }
48
48
 
49
49
  export { DefaultLink, defaultNavigate, isPathActive, useBrowserSearchParams };
50
- //# sourceMappingURL=chunk-AI6CCNWK.js.map
51
- //# sourceMappingURL=chunk-AI6CCNWK.js.map
50
+ //# sourceMappingURL=chunk-6NPEMLBA.js.map
51
+ //# sourceMappingURL=chunk-6NPEMLBA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/navigation.tsx"],"names":[],"mappings":";;;;AAgEO,IAAM,cAA6B,CAAC;AAAA,EACzC,IAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAG;AACL,CAAA,yBACG,GAAA,EAAA,EAAE,IAAA,EAAY,eAAa,MAAA,EAAS,GAAG,MACrC,QAAA,EACH;AAUK,SAAS,YAAA,CAAa,IAAY,UAAA,EAA8B;AACrE,EAAA,IAAI,UAAA,IAAc,MAAM,OAAO,KAAA;AAC/B,EAAA,IAAI,EAAA,KAAO,YAAY,OAAO,IAAA;AAC9B,EAAA,IAAI,OAAO,GAAA,IAAO,UAAA,CAAW,WAAW,EAAA,GAAK,GAAG,GAAG,OAAO,IAAA;AAC1D,EAAA,OAAO,KAAA;AACT;AAkBO,IAAM,eAAA,GAA8B,CAAC,IAAA,KAAS;AACnD,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,MAAA,CAAO,QAAA,CAAS,OAAO,IAAI,CAAA;AAChE;AA4BO,SAAS,sBAAA,GAA8C;AAC5D,EAAA,MAAM,IAAA,GAAO,MACX,IAAI,eAAA;AAAA,IACF,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS;AAAA,GAC3D;AAEF,EAAA,MAAM,CAAC,YAAA,EAAc,QAAQ,CAAA,GAAI,SAA0B,IAAI,CAAA;AAE/D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,IAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAM,CAAA;AACnC,IAAA,MAAA,CAAO,gBAAA,CAAiB,YAAY,KAAK,CAAA;AACzC,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,UAAA,EAAY,KAAK,CAAA;AAAA,EAC3D,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,eAAA,GAAkB,WAAA;AAAA,IACtB,CAAC,MAAM,OAAA,KAAY;AACjB,MAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,MAAA,MAAM,EAAA,GAAK,KAAK,QAAA,EAAS;AACzB,MAAA,MAAM,GAAA,GACJ,MAAA,CAAO,QAAA,CAAS,QAAA,IAAY,EAAA,GAAK,IAAI,EAAE,CAAA,CAAA,GAAK,EAAA,CAAA,GAAM,MAAA,CAAO,QAAA,CAAS,IAAA;AACpE,MAAA,IAAI,SAAS,OAAA,EAAS;AACpB,QAAA,MAAA,CAAO,QAAQ,YAAA,CAAa,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAO,IAAI,GAAG,CAAA;AAAA,MAC3D,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,QAAQ,SAAA,CAAU,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAO,IAAI,GAAG,CAAA;AAAA,MACxD;AACA,MAAA,QAAA,CAAS,IAAI,eAAA,CAAgB,IAAI,CAAC,CAAA;AAAA,IACpC,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,OAAO,EAAE,cAAc,eAAA,EAAgB;AACzC","file":"chunk-6NPEMLBA.js","sourcesContent":["\"use client\";\n\n/**\n * Router-agnostic navigation primitives.\n *\n * genesis-ui does NOT depend on any router. Components that need to render a\n * link or navigate imperatively accept an injectable abstraction defined here,\n * and default to plain browser behavior (`<a>` / `window.location`). Consumers\n * on React Router or Next.js inject a thin adapter that maps these props to\n * their own `<Link>` / router.\n */\nimport {\n useCallback,\n useEffect,\n useState,\n type AnchorHTMLAttributes,\n type ComponentType,\n type ReactNode,\n} from \"react\";\n\n// ---------------------------------------------------------------------------\n// Link abstraction\n// ---------------------------------------------------------------------------\n\n/**\n * Props passed to an injectable link component. The contract is a plain anchor\n * (`href`), so the default works with NO router. A React Router consumer maps\n * `href` → `to`; a Next.js consumer passes `next/link` directly (it already\n * accepts `href`, `className`, `children`).\n *\n * @stability Beta\n */\nexport interface GenesisLinkProps {\n /** Destination path or URL. */\n href: string;\n className?: string;\n onClick?: () => void;\n children?: ReactNode;\n /** Set to \"page\" when the link points at the active route. */\n \"aria-current\"?: AnchorHTMLAttributes<HTMLAnchorElement>[\"aria-current\"];\n /** Accessible name — useful when the visible label is hidden (icon rail). */\n \"aria-label\"?: string;\n /** Native tooltip / title attribute. */\n title?: string;\n /**\n * Stable test/automation selector. {@link DefaultLink} renders it as\n * `data-testid`; injected router adapters (`next/link`, RR `Link`) forward it\n * to the underlying `<a>` too.\n */\n testID?: string;\n}\n\n/**\n * A component that renders a navigable link from {@link GenesisLinkProps}.\n *\n * @stability Beta\n */\nexport type LinkComponent = ComponentType<GenesisLinkProps>;\n\n/**\n * Default link — a plain `<a>`. No router required.\n *\n * @stability Beta\n */\nexport const DefaultLink: LinkComponent = ({\n href,\n children,\n testID,\n ...rest\n}) => (\n <a href={href} data-testid={testID} {...rest}>\n {children}\n </a>\n);\n\n/**\n * Default active-path matcher, mirroring React Router's `NavLink` (prefix\n * match, with `/` treated as exact). Consumers can override via an `isActive`\n * prop where components accept one.\n *\n * @stability Beta\n */\nexport function isPathActive(to: string, activePath?: string): boolean {\n if (activePath == null) return false;\n if (to === activePath) return true;\n if (to !== \"/\" && activePath.startsWith(to + \"/\")) return true;\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Imperative navigation abstraction\n// ---------------------------------------------------------------------------\n\n/**\n * Injectable imperative navigation callback.\n *\n * @stability Beta\n */\nexport type NavigateFn = (path: string) => void;\n\n/**\n * Default navigate — a full-page navigation. No router required.\n *\n * @stability Beta\n */\nexport const defaultNavigate: NavigateFn = (path) => {\n if (typeof window !== \"undefined\") window.location.assign(path);\n};\n\n// ---------------------------------------------------------------------------\n// Search-params abstraction (for URL-synced hooks)\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal, router-agnostic replacement for React Router's `useSearchParams`\n * return shape. Consumers may inject their router's implementation for full\n * SPA integration; otherwise the browser History API is used.\n *\n * @stability Beta\n */\nexport interface SearchParamsAdapter {\n searchParams: URLSearchParams;\n setSearchParams: (\n next: URLSearchParams,\n options?: { replace?: boolean },\n ) => void;\n}\n\n/**\n * Browser-native {@link SearchParamsAdapter} built on the History API. Reads\n * the current query string and writes updates via `pushState`/`replaceState`,\n * staying reactive to `popstate` events. No router required.\n *\n * @stability Beta\n */\nexport function useBrowserSearchParams(): SearchParamsAdapter {\n const read = () =>\n new URLSearchParams(\n typeof window !== \"undefined\" ? window.location.search : \"\",\n );\n\n const [searchParams, setLocal] = useState<URLSearchParams>(read);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onPop = () => setLocal(read());\n window.addEventListener(\"popstate\", onPop);\n return () => window.removeEventListener(\"popstate\", onPop);\n }, []);\n\n const setSearchParams = useCallback<SearchParamsAdapter[\"setSearchParams\"]>(\n (next, options) => {\n if (typeof window === \"undefined\") return;\n const qs = next.toString();\n const url =\n window.location.pathname + (qs ? `?${qs}` : \"\") + window.location.hash;\n if (options?.replace) {\n window.history.replaceState(window.history.state, \"\", url);\n } else {\n window.history.pushState(window.history.state, \"\", url);\n }\n setLocal(new URLSearchParams(next));\n },\n [],\n );\n\n return { searchParams, setSearchParams };\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { Calendar } from './chunk-DGRHPJ3M.js';
2
+ import { Calendar } from './chunk-44TULYGG.js';
3
3
  import { Popover, PopoverTrigger, PopoverContent } from './chunk-NJMO3VPA.js';
4
- import { Button } from './chunk-I6JQHP6D.js';
4
+ import { Button } from './chunk-ZJFSZFPI.js';
5
5
  import { cn } from './chunk-NZ5WBA4R.js';
6
6
  import { CalendarIcon } from 'lucide-react';
7
7
  import { format } from 'date-fns';
@@ -36,5 +36,5 @@ function DatePicker({
36
36
  }
37
37
 
38
38
  export { DatePicker };
39
- //# sourceMappingURL=chunk-UKSBLFEK.js.map
40
- //# sourceMappingURL=chunk-UKSBLFEK.js.map
39
+ //# sourceMappingURL=chunk-6VVVGYKS.js.map
40
+ //# sourceMappingURL=chunk-6VVVGYKS.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ui/date-picker.tsx"],"names":[],"mappings":";;;;;;;;AAmBA,SAAS,UAAA,CAAW;AAAA,EAClB,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,aAAA;AAAA,EACd,SAAA;AAAA,EACA;AACF,CAAA,EAAoB;AAClB,EAAA,4BACG,OAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,SAAO,IAAA,EACrB,QAAA,kBAAA,IAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,SAAA;AAAA,QACR,QAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,+CAAA;AAAA,UACA,CAAC,KAAA,IAAS,uBAAA;AAAA,UACV;AAAA,SACF;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,YAAA,EAAA,EAAa,WAAU,cAAA,EAAe,CAAA;AAAA,UACtC,KAAA,GAAQ,MAAA,CAAO,KAAA,EAAO,KAAK,CAAA,GAAI;AAAA;AAAA;AAAA,KAClC,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,cAAA,EAAA,EAAe,SAAA,EAAU,YAAA,EAAa,OAAM,OAAA,EAC3C,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,IAAA,EAAK,QAAA,EAAS,QAAA,EAAU,KAAA,EAAO,QAAA,EAAU,UAAU,CAAA,EAC/D;AAAA,GAAA,EACF,CAAA;AAEJ","file":"chunk-UKSBLFEK.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { CalendarIcon } from \"lucide-react\";\nimport { format } from \"date-fns\";\n\nimport { cn } from \"../../utils\";\nimport { Button } from \"./button\";\nimport { Calendar } from \"./calendar\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\n\ninterface DatePickerProps {\n value?: Date;\n onChange?: (date: Date | undefined) => void;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n}\n\nfunction DatePicker({\n value,\n onChange,\n placeholder = \"Pick a date\",\n className,\n disabled,\n}: DatePickerProps) {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n disabled={disabled}\n className={cn(\n \"w-[240px] justify-start text-left font-normal\",\n !value && \"text-muted-foreground\",\n className,\n )}\n >\n <CalendarIcon className=\"mr-2 h-4 w-4\" />\n {value ? format(value, \"PPP\") : placeholder}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar mode=\"single\" selected={value} onSelect={onChange} />\n </PopoverContent>\n </Popover>\n );\n}\n\nexport { DatePicker, type DatePickerProps };\n"]}
1
+ {"version":3,"sources":["../src/components/ui/date-picker.tsx"],"names":[],"mappings":";;;;;;;;AAmBA,SAAS,UAAA,CAAW;AAAA,EAClB,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,aAAA;AAAA,EACd,SAAA;AAAA,EACA;AACF,CAAA,EAAoB;AAClB,EAAA,4BACG,OAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,SAAO,IAAA,EACrB,QAAA,kBAAA,IAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,SAAA;AAAA,QACR,QAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,+CAAA;AAAA,UACA,CAAC,KAAA,IAAS,uBAAA;AAAA,UACV;AAAA,SACF;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,YAAA,EAAA,EAAa,WAAU,cAAA,EAAe,CAAA;AAAA,UACtC,KAAA,GAAQ,MAAA,CAAO,KAAA,EAAO,KAAK,CAAA,GAAI;AAAA;AAAA;AAAA,KAClC,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,cAAA,EAAA,EAAe,SAAA,EAAU,YAAA,EAAa,OAAM,OAAA,EAC3C,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,IAAA,EAAK,QAAA,EAAS,QAAA,EAAU,KAAA,EAAO,QAAA,EAAU,UAAU,CAAA,EAC/D;AAAA,GAAA,EACF,CAAA;AAEJ","file":"chunk-6VVVGYKS.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { CalendarIcon } from \"lucide-react\";\nimport { format } from \"date-fns\";\n\nimport { cn } from \"../../utils\";\nimport { Button } from \"./button\";\nimport { Calendar } from \"./calendar\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\n\ninterface DatePickerProps {\n value?: Date;\n onChange?: (date: Date | undefined) => void;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n}\n\nfunction DatePicker({\n value,\n onChange,\n placeholder = \"Pick a date\",\n className,\n disabled,\n}: DatePickerProps) {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n disabled={disabled}\n className={cn(\n \"w-[240px] justify-start text-left font-normal\",\n !value && \"text-muted-foreground\",\n className,\n )}\n >\n <CalendarIcon className=\"mr-2 h-4 w-4\" />\n {value ? format(value, \"PPP\") : placeholder}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar mode=\"single\" selected={value} onSelect={onChange} />\n </PopoverContent>\n </Popover>\n );\n}\n\nexport { DatePicker, type DatePickerProps };\n"]}
@@ -0,0 +1,65 @@
1
+ "use client";
2
+ import { CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut } from './chunk-7OBL3H5P.js';
3
+ import * as React from 'react';
4
+ import { useState, useEffect } from 'react';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ function CommandPalette({
8
+ open,
9
+ onOpenChange,
10
+ commands,
11
+ placeholder = "Type a command or search\u2026",
12
+ emptyMessage = "No results found.",
13
+ title = "Command palette"
14
+ }) {
15
+ const groups = React.useMemo(() => {
16
+ const map = /* @__PURE__ */ new Map();
17
+ for (const cmd of commands) {
18
+ const key = cmd.group ?? "Actions";
19
+ const list = map.get(key) ?? [];
20
+ list.push(cmd);
21
+ map.set(key, list);
22
+ }
23
+ return map;
24
+ }, [commands]);
25
+ return /* @__PURE__ */ jsxs(CommandDialog, { open, onOpenChange, children: [
26
+ /* @__PURE__ */ jsx(CommandInput, { placeholder, "aria-label": title }),
27
+ /* @__PURE__ */ jsxs(CommandList, { children: [
28
+ /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
29
+ Array.from(groups.entries()).map(([group, items]) => /* @__PURE__ */ jsx(CommandGroup, { heading: group, children: items.map((cmd) => /* @__PURE__ */ jsxs(
30
+ CommandItem,
31
+ {
32
+ value: `${cmd.id} ${cmd.label}`,
33
+ onSelect: () => {
34
+ onOpenChange(false);
35
+ cmd.onSelect();
36
+ },
37
+ children: [
38
+ cmd.label,
39
+ cmd.shortcut ? /* @__PURE__ */ jsx(CommandShortcut, { children: cmd.shortcut }) : null
40
+ ]
41
+ },
42
+ cmd.id
43
+ )) }, group))
44
+ ] })
45
+ ] });
46
+ }
47
+ function useCommandPaletteHotkey(enabled = true) {
48
+ const [open, setOpen] = useState(false);
49
+ useEffect(() => {
50
+ if (!enabled) return;
51
+ const onKeyDown = (e) => {
52
+ if (e.key.toLowerCase() !== "k") return;
53
+ if (!(e.metaKey || e.ctrlKey)) return;
54
+ e.preventDefault();
55
+ setOpen((prev) => !prev);
56
+ };
57
+ window.addEventListener("keydown", onKeyDown);
58
+ return () => window.removeEventListener("keydown", onKeyDown);
59
+ }, [enabled]);
60
+ return [open, setOpen];
61
+ }
62
+
63
+ export { CommandPalette, useCommandPaletteHotkey };
64
+ //# sourceMappingURL=chunk-A2OXCNNY.js.map
65
+ //# sourceMappingURL=chunk-A2OXCNNY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/command-palette.tsx"],"names":[],"mappings":";;;;;AAmCO,SAAS,cAAA,CAAe;AAAA,EAC7B,IAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,gCAAA;AAAA,EACd,YAAA,GAAe,mBAAA;AAAA,EACf,KAAA,GAAQ;AACV,CAAA,EAAwB;AACtB,EAAA,MAAM,MAAA,GAAe,cAAQ,MAAM;AACjC,IAAA,MAAM,GAAA,uBAAU,GAAA,EAAkC;AAClD,IAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,MAAA,MAAM,GAAA,GAAM,IAAI,KAAA,IAAS,SAAA;AACzB,MAAA,MAAM,IAAA,GAAO,GAAA,CAAI,GAAA,CAAI,GAAG,KAAK,EAAC;AAC9B,MAAA,IAAA,CAAK,KAAK,GAAG,CAAA;AACb,MAAA,GAAA,CAAI,GAAA,CAAI,KAAK,IAAI,CAAA;AAAA,IACnB;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,uBACE,IAAA,CAAC,aAAA,EAAA,EAAc,IAAA,EAAY,YAAA,EACzB,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,WAAA,EAA0B,YAAA,EAAY,KAAA,EAAO,CAAA;AAAA,yBAC1D,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,gBAAc,QAAA,EAAA,YAAA,EAAa,CAAA;AAAA,MAC3B,MAAM,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA,CAAE,IAAI,CAAC,CAAC,OAAO,KAAK,CAAA,yBAC7C,YAAA,EAAA,EAAyB,OAAA,EAAS,OAChC,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,GAAA,qBACV,IAAA;AAAA,QAAC,WAAA;AAAA,QAAA;AAAA,UAEC,OAAO,CAAA,EAAG,GAAA,CAAI,EAAE,CAAA,CAAA,EAAI,IAAI,KAAK,CAAA,CAAA;AAAA,UAC7B,UAAU,MAAM;AACd,YAAA,YAAA,CAAa,KAAK,CAAA;AAClB,YAAA,GAAA,CAAI,QAAA,EAAS;AAAA,UACf,CAAA;AAAA,UAEC,QAAA,EAAA;AAAA,YAAA,GAAA,CAAI,KAAA;AAAA,YACJ,IAAI,QAAA,mBACH,GAAA,CAAC,eAAA,EAAA,EAAiB,QAAA,EAAA,GAAA,CAAI,UAAS,CAAA,GAC7B;AAAA;AAAA,SAAA;AAAA,QAVC,GAAA,CAAI;AAAA,OAYZ,CAAA,EAAA,EAfgB,KAgBnB,CACD;AAAA,KAAA,EACH;AAAA,GAAA,EACF,CAAA;AAEJ;AAMO,SAAS,uBAAA,CACd,UAAU,IAAA,EACgD;AAC1D,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,KAAK,CAAA;AAEtC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAqB;AACtC,MAAA,IAAI,CAAA,CAAE,GAAA,CAAI,WAAA,EAAY,KAAM,GAAA,EAAK;AACjC,MAAA,IAAI,EAAE,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,CAAA,EAAU;AAC/B,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,OAAA,CAAQ,CAAC,IAAA,KAAS,CAAC,IAAI,CAAA;AAAA,IACzB,CAAA;AACA,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC5C,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,SAAS,CAAA;AAAA,EAC9D,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,OAAO,CAAC,MAAM,OAAO,CAAA;AACvB","file":"chunk-A2OXCNNY.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { useEffect, useState } from \"react\";\nimport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandShortcut,\n} from \"./command\";\n\nexport interface CommandPaletteItem {\n id: string;\n label: string;\n shortcut?: string;\n group?: string;\n onSelect: () => void;\n}\n\nexport interface CommandPaletteProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n commands: CommandPaletteItem[];\n placeholder?: string;\n emptyMessage?: string;\n title?: string;\n}\n\n/**\n * Thin action registry over `CommandDialog` / cmdk.\n * Consumers register flat commands; optional `group` buckets them.\n */\nexport function CommandPalette({\n open,\n onOpenChange,\n commands,\n placeholder = \"Type a command or search…\",\n emptyMessage = \"No results found.\",\n title = \"Command palette\",\n}: CommandPaletteProps) {\n const groups = React.useMemo(() => {\n const map = new Map<string, CommandPaletteItem[]>();\n for (const cmd of commands) {\n const key = cmd.group ?? \"Actions\";\n const list = map.get(key) ?? [];\n list.push(cmd);\n map.set(key, list);\n }\n return map;\n }, [commands]);\n\n return (\n <CommandDialog open={open} onOpenChange={onOpenChange}>\n <CommandInput placeholder={placeholder} aria-label={title} />\n <CommandList>\n <CommandEmpty>{emptyMessage}</CommandEmpty>\n {Array.from(groups.entries()).map(([group, items]) => (\n <CommandGroup key={group} heading={group}>\n {items.map((cmd) => (\n <CommandItem\n key={cmd.id}\n value={`${cmd.id} ${cmd.label}`}\n onSelect={() => {\n onOpenChange(false);\n cmd.onSelect();\n }}\n >\n {cmd.label}\n {cmd.shortcut ? (\n <CommandShortcut>{cmd.shortcut}</CommandShortcut>\n ) : null}\n </CommandItem>\n ))}\n </CommandGroup>\n ))}\n </CommandList>\n </CommandDialog>\n );\n}\n\n/**\n * Toggle a command palette with Cmd/Ctrl+K.\n * Returns `[open, setOpen]` — pass into `<CommandPalette open onOpenChange />`.\n */\nexport function useCommandPaletteHotkey(\n enabled = true,\n): [boolean, React.Dispatch<React.SetStateAction<boolean>>] {\n const [open, setOpen] = useState(false);\n\n useEffect(() => {\n if (!enabled) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key.toLowerCase() !== \"k\") return;\n if (!(e.metaKey || e.ctrlKey)) return;\n e.preventDefault();\n setOpen((prev) => !prev);\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [enabled]);\n\n return [open, setOpen];\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { Button } from './chunk-I6JQHP6D.js';
2
+ import { Button } from './chunk-ZJFSZFPI.js';
3
3
  import { cn } from './chunk-NZ5WBA4R.js';
4
4
  import * as React from 'react';
5
5
  import useEmblaCarousel from 'embla-carousel-react';
@@ -195,5 +195,5 @@ function CarouselNext({
195
195
  }
196
196
 
197
197
  export { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious };
198
- //# sourceMappingURL=chunk-O4B5ALO7.js.map
199
- //# sourceMappingURL=chunk-O4B5ALO7.js.map
198
+ //# sourceMappingURL=chunk-AUECDWP2.js.map
199
+ //# sourceMappingURL=chunk-AUECDWP2.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ui/carousel.tsx"],"names":["api"],"mappings":"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","file":"chunk-O4B5ALO7.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport useEmblaCarousel, {\n type UseEmblaCarouselType,\n} from \"embla-carousel-react\";\nimport { ArrowLeft, ArrowRight } from \"lucide-react\";\n\nimport { cn } from \"../../utils\";\nimport { Button } from \"./button\";\n\ntype CarouselApi = UseEmblaCarouselType[1];\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\ntype CarouselOptions = UseCarouselParameters[0];\ntype CarouselPlugin = UseCarouselParameters[1];\n\ntype CarouselProps = {\n opts?: CarouselOptions;\n plugins?: CarouselPlugin;\n orientation?: \"horizontal\" | \"vertical\";\n setApi?: (api: CarouselApi) => void;\n};\n\ntype CarouselContextProps = {\n carouselRef: ReturnType<typeof useEmblaCarousel>[0];\n api: ReturnType<typeof useEmblaCarousel>[1];\n scrollPrev: () => void;\n scrollNext: () => void;\n canScrollPrev: boolean;\n canScrollNext: boolean;\n} & CarouselProps;\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null);\n\nfunction useCarousel() {\n const context = React.useContext(CarouselContext);\n\n if (!context) {\n throw new Error(\"useCarousel must be used within a <Carousel />\");\n }\n\n return context;\n}\n\nconst Carousel = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & CarouselProps\n>(\n (\n {\n orientation = \"horizontal\",\n opts,\n setApi,\n plugins,\n className,\n children,\n ...props\n },\n ref\n ) => {\n const [carouselRef, api] = useEmblaCarousel(\n {\n ...opts,\n axis: orientation === \"horizontal\" ? \"x\" : \"y\",\n },\n plugins\n );\n const [canScrollPrev, setCanScrollPrev] = React.useState(false);\n const [canScrollNext, setCanScrollNext] = React.useState(false);\n\n const onSelect = React.useCallback((api: CarouselApi) => {\n if (!api) {\n return;\n }\n\n setCanScrollPrev(api.canScrollPrev());\n setCanScrollNext(api.canScrollNext());\n }, []);\n\n const scrollPrev = React.useCallback(() => {\n api?.scrollPrev();\n }, [api]);\n\n const scrollNext = React.useCallback(() => {\n api?.scrollNext();\n }, [api]);\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n scrollPrev();\n } else if (event.key === \"ArrowRight\") {\n event.preventDefault();\n scrollNext();\n }\n },\n [scrollPrev, scrollNext]\n );\n\n React.useEffect(() => {\n if (!api || !setApi) {\n return;\n }\n\n setApi(api);\n }, [api, setApi]);\n\n React.useEffect(() => {\n if (!api) {\n return;\n }\n\n onSelect(api);\n api.on(\"reInit\", onSelect);\n api.on(\"select\", onSelect);\n\n return () => {\n api?.off(\"select\", onSelect);\n };\n }, [api, onSelect]);\n\n return (\n <CarouselContext.Provider\n value={{\n carouselRef,\n api: api,\n opts,\n orientation:\n orientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\n scrollPrev,\n scrollNext,\n canScrollPrev,\n canScrollNext,\n }}\n >\n <div\n ref={ref}\n onKeyDownCapture={handleKeyDown}\n className={cn(\"relative\", className)}\n role=\"region\"\n aria-roledescription=\"carousel\"\n {...props}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n );\n }\n);\nCarousel.displayName = \"Carousel\";\n\nconst CarouselContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => {\n const { carouselRef, orientation } = useCarousel();\n\n return (\n <div ref={carouselRef} className=\"overflow-hidden\">\n <div\n ref={ref}\n className={cn(\n \"flex\",\n orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\",\n className\n )}\n {...props}\n />\n </div>\n );\n});\nCarouselContent.displayName = \"CarouselContent\";\n\nconst CarouselItem = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => {\n const { orientation } = useCarousel();\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-roledescription=\"slide\"\n className={cn(\n \"min-w-0 shrink-0 grow-0 basis-full\",\n orientation === \"horizontal\" ? \"pl-4\" : \"pt-4\",\n className\n )}\n {...props}\n />\n );\n});\nCarouselItem.displayName = \"CarouselItem\";\n\nfunction CarouselPrevious({\n className,\n variant = \"outline\",\n size = \"icon\",\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { orientation, scrollPrev, canScrollPrev } = useCarousel();\n\n return (\n <Button\n variant={variant}\n size={size}\n className={cn(\n \"absolute h-8 w-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"-left-12 top-1/2 -translate-y-1/2\"\n : \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollPrev}\n onClick={scrollPrev}\n {...props}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n <span className=\"sr-only\">Previous slide</span>\n </Button>\n );\n}\n\nfunction CarouselNext({\n className,\n variant = \"outline\",\n size = \"icon\",\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { orientation, scrollNext, canScrollNext } = useCarousel();\n\n return (\n <Button\n variant={variant}\n size={size}\n className={cn(\n \"absolute h-8 w-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"-right-12 top-1/2 -translate-y-1/2\"\n : \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollNext}\n onClick={scrollNext}\n {...props}\n >\n <ArrowRight className=\"h-4 w-4\" />\n <span className=\"sr-only\">Next slide</span>\n </Button>\n );\n}\n\nexport {\n type CarouselApi,\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselPrevious,\n CarouselNext,\n};\n"]}
1
+ {"version":3,"sources":["../src/components/ui/carousel.tsx"],"names":["api"],"mappings":"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","file":"chunk-AUECDWP2.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport useEmblaCarousel, {\n type UseEmblaCarouselType,\n} from \"embla-carousel-react\";\nimport { ArrowLeft, ArrowRight } from \"lucide-react\";\n\nimport { cn } from \"../../utils\";\nimport { Button } from \"./button\";\n\ntype CarouselApi = UseEmblaCarouselType[1];\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\ntype CarouselOptions = UseCarouselParameters[0];\ntype CarouselPlugin = UseCarouselParameters[1];\n\ntype CarouselProps = {\n opts?: CarouselOptions;\n plugins?: CarouselPlugin;\n orientation?: \"horizontal\" | \"vertical\";\n setApi?: (api: CarouselApi) => void;\n};\n\ntype CarouselContextProps = {\n carouselRef: ReturnType<typeof useEmblaCarousel>[0];\n api: ReturnType<typeof useEmblaCarousel>[1];\n scrollPrev: () => void;\n scrollNext: () => void;\n canScrollPrev: boolean;\n canScrollNext: boolean;\n} & CarouselProps;\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null);\n\nfunction useCarousel() {\n const context = React.useContext(CarouselContext);\n\n if (!context) {\n throw new Error(\"useCarousel must be used within a <Carousel />\");\n }\n\n return context;\n}\n\nconst Carousel = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & CarouselProps\n>(\n (\n {\n orientation = \"horizontal\",\n opts,\n setApi,\n plugins,\n className,\n children,\n ...props\n },\n ref\n ) => {\n const [carouselRef, api] = useEmblaCarousel(\n {\n ...opts,\n axis: orientation === \"horizontal\" ? \"x\" : \"y\",\n },\n plugins\n );\n const [canScrollPrev, setCanScrollPrev] = React.useState(false);\n const [canScrollNext, setCanScrollNext] = React.useState(false);\n\n const onSelect = React.useCallback((api: CarouselApi) => {\n if (!api) {\n return;\n }\n\n setCanScrollPrev(api.canScrollPrev());\n setCanScrollNext(api.canScrollNext());\n }, []);\n\n const scrollPrev = React.useCallback(() => {\n api?.scrollPrev();\n }, [api]);\n\n const scrollNext = React.useCallback(() => {\n api?.scrollNext();\n }, [api]);\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n scrollPrev();\n } else if (event.key === \"ArrowRight\") {\n event.preventDefault();\n scrollNext();\n }\n },\n [scrollPrev, scrollNext]\n );\n\n React.useEffect(() => {\n if (!api || !setApi) {\n return;\n }\n\n setApi(api);\n }, [api, setApi]);\n\n React.useEffect(() => {\n if (!api) {\n return;\n }\n\n onSelect(api);\n api.on(\"reInit\", onSelect);\n api.on(\"select\", onSelect);\n\n return () => {\n api?.off(\"select\", onSelect);\n };\n }, [api, onSelect]);\n\n return (\n <CarouselContext.Provider\n value={{\n carouselRef,\n api: api,\n opts,\n orientation:\n orientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\n scrollPrev,\n scrollNext,\n canScrollPrev,\n canScrollNext,\n }}\n >\n <div\n ref={ref}\n onKeyDownCapture={handleKeyDown}\n className={cn(\"relative\", className)}\n role=\"region\"\n aria-roledescription=\"carousel\"\n {...props}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n );\n }\n);\nCarousel.displayName = \"Carousel\";\n\nconst CarouselContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => {\n const { carouselRef, orientation } = useCarousel();\n\n return (\n <div ref={carouselRef} className=\"overflow-hidden\">\n <div\n ref={ref}\n className={cn(\n \"flex\",\n orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\",\n className\n )}\n {...props}\n />\n </div>\n );\n});\nCarouselContent.displayName = \"CarouselContent\";\n\nconst CarouselItem = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => {\n const { orientation } = useCarousel();\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-roledescription=\"slide\"\n className={cn(\n \"min-w-0 shrink-0 grow-0 basis-full\",\n orientation === \"horizontal\" ? \"pl-4\" : \"pt-4\",\n className\n )}\n {...props}\n />\n );\n});\nCarouselItem.displayName = \"CarouselItem\";\n\nfunction CarouselPrevious({\n className,\n variant = \"outline\",\n size = \"icon\",\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { orientation, scrollPrev, canScrollPrev } = useCarousel();\n\n return (\n <Button\n variant={variant}\n size={size}\n className={cn(\n \"absolute h-8 w-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"-left-12 top-1/2 -translate-y-1/2\"\n : \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollPrev}\n onClick={scrollPrev}\n {...props}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n <span className=\"sr-only\">Previous slide</span>\n </Button>\n );\n}\n\nfunction CarouselNext({\n className,\n variant = \"outline\",\n size = \"icon\",\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { orientation, scrollNext, canScrollNext } = useCarousel();\n\n return (\n <Button\n variant={variant}\n size={size}\n className={cn(\n \"absolute h-8 w-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"-right-12 top-1/2 -translate-y-1/2\"\n : \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollNext}\n onClick={scrollNext}\n {...props}\n >\n <ArrowRight className=\"h-4 w-4\" />\n <span className=\"sr-only\">Next slide</span>\n </Button>\n );\n}\n\nexport {\n type CarouselApi,\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselPrevious,\n CarouselNext,\n};\n"]}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { useBrowserSearchParams } from './chunk-AI6CCNWK.js';
2
+ import { useBrowserSearchParams } from './chunk-6NPEMLBA.js';
3
3
  import { useRef, useCallback, useState, useEffect } from 'react';
4
4
  import { useStorage } from '@marktiderman/genesis-core';
5
5
 
@@ -116,5 +116,5 @@ function useDataFilters(storageKey, defs, options) {
116
116
  }
117
117
 
118
118
  export { useDataFilters };
119
- //# sourceMappingURL=chunk-FCGFG4RV.js.map
120
- //# sourceMappingURL=chunk-FCGFG4RV.js.map
119
+ //# sourceMappingURL=chunk-D4JTQYP5.js.map
120
+ //# sourceMappingURL=chunk-D4JTQYP5.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/use-data-filters.ts"],"names":[],"mappings":"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","file":"chunk-FCGFG4RV.js","sourcesContent":["\"use client\";\n\nimport { useState, useCallback, useEffect, useRef } from \"react\";\nimport { useStorage } from \"@marktiderman/genesis-core\";\nimport {\n useBrowserSearchParams,\n type SearchParamsAdapter,\n} from \"../navigation\";\n\ntype FilterType = \"string\" | \"multi\";\n\nexport interface FilterDef {\n type: FilterType;\n default: string | string[];\n}\n\nexport type FilterDefs = Record<string, FilterDef>;\n\nexport type FilterValues<T extends FilterDefs> = {\n [K in keyof T]: T[K][\"type\"] extends \"multi\" ? string[] : string;\n};\n\nfunction parseArray(val: string | null): string[] {\n if (!val) return [];\n return val.split(\",\").filter(Boolean);\n}\n\n/**\n * @stability Beta\n */\nexport interface UseDataFiltersOptions {\n /**\n * Injectable URL search-params adapter. Defaults to a browser History-API\n * implementation (no router). Router consumers may pass their own — e.g.\n * React Router's `useSearchParams()` result — for full SPA integration.\n */\n searchParams?: SearchParamsAdapter;\n}\n\nexport function useDataFilters<T extends FilterDefs>(\n storageKey: string,\n defs: T,\n options?: UseDataFiltersOptions\n) {\n // Always call the default hook (rules-of-hooks); use the override if provided.\n const browserAdapter = useBrowserSearchParams();\n const { searchParams, setSearchParams } =\n options?.searchParams ?? browserAdapter;\n const storage = useStorage();\n const initialized = useRef(false);\n\n // Build initial state from URL -> storage -> defaults\n const getInitial = useCallback((): FilterValues<T> => {\n const result = {} as Record<string, unknown>;\n const localKey = `${storageKey}-filters`;\n let stored: Record<string, unknown> = {};\n\n try {\n const raw = storage.getItem(localKey);\n if (raw) stored = JSON.parse(raw);\n } catch {\n /* ignore */\n }\n\n // Check if URL has any of our params\n const hasUrlParams = Object.keys(defs).some((k) => searchParams.has(k));\n\n for (const [key, def] of Object.entries(defs)) {\n if (def.type === \"multi\") {\n const urlVal = hasUrlParams ? searchParams.get(key) : null;\n if (urlVal !== null) {\n result[key] = parseArray(urlVal);\n } else if (Array.isArray(stored[key])) {\n result[key] = stored[key];\n } else {\n result[key] = def.default;\n }\n } else {\n const urlVal = hasUrlParams ? searchParams.get(key) : null;\n if (urlVal !== null) {\n result[key] = urlVal;\n } else if (typeof stored[key] === \"string\") {\n result[key] = stored[key];\n } else {\n result[key] = def.default;\n }\n }\n }\n\n return result as FilterValues<T>;\n }, [defs, searchParams, storageKey, storage]);\n\n const [filters, setFilters] = useState<FilterValues<T>>(() => getInitial());\n\n // Mark as initialized after first render\n useEffect(() => {\n if (!initialized.current) {\n initialized.current = true;\n }\n }, []);\n\n // Persist to storage + URL whenever filters change\n useEffect(() => {\n if (!initialized.current) return;\n\n const localKey = `${storageKey}-filters`;\n storage.setItem(localKey, JSON.stringify(filters));\n\n // Update URL params. When using the DEFAULT browser adapter, seed from the\n // LIVE URL (not the adapter's possibly stale snapshot) so a second\n // useDataFilters instance on the same page can't merge against an old query\n // string and drop params another instance just wrote. When a caller\n // explicitly injects a SearchParamsAdapter (custom router / test double\n // whose URL state may not be synced to the DOM), trust ITS snapshot instead\n // of reading the real DOM location. Also falls back to the adapter snapshot\n // in non-browser envs.\n const newParams = new URLSearchParams(\n !options?.searchParams && typeof window !== \"undefined\"\n ? window.location.search\n : searchParams.toString(),\n );\n for (const [key, def] of Object.entries(defs)) {\n const val = (filters as Record<string, unknown>)[key];\n const isDefault =\n def.type === \"multi\"\n ? (val as string[]).length === 0\n : val === def.default;\n\n if (isDefault) {\n newParams.delete(key);\n } else if (def.type === \"multi\") {\n newParams.set(key, (val as string[]).join(\",\"));\n } else {\n newParams.set(key, val as string);\n }\n }\n setSearchParams(newParams, { replace: true });\n }, [filters, defs, storageKey, storage]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const setFilter = useCallback(\n <K extends keyof T>(\n key: K,\n value: T[K][\"type\"] extends \"multi\" ? string[] : string\n ) => {\n setFilters((prev) => ({ ...prev, [key]: value }));\n },\n []\n );\n\n const resetFilters = useCallback(() => {\n const result = {} as Record<string, unknown>;\n for (const [key, def] of Object.entries(defs)) {\n result[key] = def.default;\n }\n setFilters(result as FilterValues<T>);\n }, [defs]);\n\n const loadView = useCallback(\n (viewFilters: Record<string, unknown>) => {\n const result = {} as Record<string, unknown>;\n for (const [key, def] of Object.entries(defs)) {\n const v = viewFilters[key];\n if (def.type === \"multi\" && Array.isArray(v)) {\n result[key] = v;\n } else if (def.type === \"string\" && typeof v === \"string\") {\n result[key] = v;\n } else {\n result[key] = def.default;\n }\n }\n setFilters(result as FilterValues<T>);\n },\n [defs]\n );\n\n const hasActiveFilters = Object.entries(defs).some(([key, def]) => {\n const val = (filters as Record<string, unknown>)[key];\n if (def.type === \"multi\") return (val as string[]).length > 0;\n return val !== def.default;\n });\n\n return {\n filters,\n setFilter,\n resetFilters,\n loadView,\n hasActiveFilters,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/use-data-filters.ts"],"names":[],"mappings":"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","file":"chunk-D4JTQYP5.js","sourcesContent":["\"use client\";\n\nimport { useState, useCallback, useEffect, useRef } from \"react\";\nimport { useStorage } from \"@marktiderman/genesis-core\";\nimport {\n useBrowserSearchParams,\n type SearchParamsAdapter,\n} from \"../navigation\";\n\ntype FilterType = \"string\" | \"multi\";\n\nexport interface FilterDef {\n type: FilterType;\n default: string | string[];\n}\n\nexport type FilterDefs = Record<string, FilterDef>;\n\nexport type FilterValues<T extends FilterDefs> = {\n [K in keyof T]: T[K][\"type\"] extends \"multi\" ? string[] : string;\n};\n\nfunction parseArray(val: string | null): string[] {\n if (!val) return [];\n return val.split(\",\").filter(Boolean);\n}\n\n/**\n * @stability Beta\n */\nexport interface UseDataFiltersOptions {\n /**\n * Injectable URL search-params adapter. Defaults to a browser History-API\n * implementation (no router). Router consumers may pass their own — e.g.\n * React Router's `useSearchParams()` result — for full SPA integration.\n */\n searchParams?: SearchParamsAdapter;\n}\n\nexport function useDataFilters<T extends FilterDefs>(\n storageKey: string,\n defs: T,\n options?: UseDataFiltersOptions\n) {\n // Always call the default hook (rules-of-hooks); use the override if provided.\n const browserAdapter = useBrowserSearchParams();\n const { searchParams, setSearchParams } =\n options?.searchParams ?? browserAdapter;\n const storage = useStorage();\n const initialized = useRef(false);\n\n // Build initial state from URL -> storage -> defaults\n const getInitial = useCallback((): FilterValues<T> => {\n const result = {} as Record<string, unknown>;\n const localKey = `${storageKey}-filters`;\n let stored: Record<string, unknown> = {};\n\n try {\n const raw = storage.getItem(localKey);\n if (raw) stored = JSON.parse(raw);\n } catch {\n /* ignore */\n }\n\n // Check if URL has any of our params\n const hasUrlParams = Object.keys(defs).some((k) => searchParams.has(k));\n\n for (const [key, def] of Object.entries(defs)) {\n if (def.type === \"multi\") {\n const urlVal = hasUrlParams ? searchParams.get(key) : null;\n if (urlVal !== null) {\n result[key] = parseArray(urlVal);\n } else if (Array.isArray(stored[key])) {\n result[key] = stored[key];\n } else {\n result[key] = def.default;\n }\n } else {\n const urlVal = hasUrlParams ? searchParams.get(key) : null;\n if (urlVal !== null) {\n result[key] = urlVal;\n } else if (typeof stored[key] === \"string\") {\n result[key] = stored[key];\n } else {\n result[key] = def.default;\n }\n }\n }\n\n return result as FilterValues<T>;\n }, [defs, searchParams, storageKey, storage]);\n\n const [filters, setFilters] = useState<FilterValues<T>>(() => getInitial());\n\n // Mark as initialized after first render\n useEffect(() => {\n if (!initialized.current) {\n initialized.current = true;\n }\n }, []);\n\n // Persist to storage + URL whenever filters change\n useEffect(() => {\n if (!initialized.current) return;\n\n const localKey = `${storageKey}-filters`;\n storage.setItem(localKey, JSON.stringify(filters));\n\n // Update URL params. When using the DEFAULT browser adapter, seed from the\n // LIVE URL (not the adapter's possibly stale snapshot) so a second\n // useDataFilters instance on the same page can't merge against an old query\n // string and drop params another instance just wrote. When a caller\n // explicitly injects a SearchParamsAdapter (custom router / test double\n // whose URL state may not be synced to the DOM), trust ITS snapshot instead\n // of reading the real DOM location. Also falls back to the adapter snapshot\n // in non-browser envs.\n const newParams = new URLSearchParams(\n !options?.searchParams && typeof window !== \"undefined\"\n ? window.location.search\n : searchParams.toString(),\n );\n for (const [key, def] of Object.entries(defs)) {\n const val = (filters as Record<string, unknown>)[key];\n const isDefault =\n def.type === \"multi\"\n ? (val as string[]).length === 0\n : val === def.default;\n\n if (isDefault) {\n newParams.delete(key);\n } else if (def.type === \"multi\") {\n newParams.set(key, (val as string[]).join(\",\"));\n } else {\n newParams.set(key, val as string);\n }\n }\n setSearchParams(newParams, { replace: true });\n }, [filters, defs, storageKey, storage]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const setFilter = useCallback(\n <K extends keyof T>(\n key: K,\n value: T[K][\"type\"] extends \"multi\" ? string[] : string\n ) => {\n setFilters((prev) => ({ ...prev, [key]: value }));\n },\n []\n );\n\n const resetFilters = useCallback(() => {\n const result = {} as Record<string, unknown>;\n for (const [key, def] of Object.entries(defs)) {\n result[key] = def.default;\n }\n setFilters(result as FilterValues<T>);\n }, [defs]);\n\n const loadView = useCallback(\n (viewFilters: Record<string, unknown>) => {\n const result = {} as Record<string, unknown>;\n for (const [key, def] of Object.entries(defs)) {\n const v = viewFilters[key];\n if (def.type === \"multi\" && Array.isArray(v)) {\n result[key] = v;\n } else if (def.type === \"string\" && typeof v === \"string\") {\n result[key] = v;\n } else {\n result[key] = def.default;\n }\n }\n setFilters(result as FilterValues<T>);\n },\n [defs]\n );\n\n const hasActiveFilters = Object.entries(defs).some(([key, def]) => {\n const val = (filters as Record<string, unknown>)[key];\n if (def.type === \"multi\") return (val as string[]).length > 0;\n return val !== def.default;\n });\n\n return {\n filters,\n setFilter,\n resetFilters,\n loadView,\n hasActiveFilters,\n };\n}\n"]}
@@ -0,0 +1,56 @@
1
+ "use client";
2
+ import { useState, useEffect, useCallback } from 'react';
3
+
4
+ // src/hooks/use-saved-views.ts
5
+ function readViews(storageKey) {
6
+ if (typeof window === "undefined") return [];
7
+ try {
8
+ const raw = localStorage.getItem(storageKey);
9
+ if (!raw) return [];
10
+ const parsed = JSON.parse(raw);
11
+ if (!Array.isArray(parsed)) return [];
12
+ return parsed.filter(
13
+ (v) => !!v && typeof v === "object" && typeof v.id === "string" && typeof v.name === "string" && typeof v.filters === "object"
14
+ );
15
+ } catch {
16
+ return [];
17
+ }
18
+ }
19
+ function writeViews(storageKey, views) {
20
+ if (typeof window === "undefined") return;
21
+ try {
22
+ localStorage.setItem(storageKey, JSON.stringify(views));
23
+ } catch {
24
+ }
25
+ }
26
+ function useSavedViews(storageKey) {
27
+ const [savedViews, setSavedViews] = useState([]);
28
+ const [hydrated, setHydrated] = useState(false);
29
+ useEffect(() => {
30
+ setSavedViews(readViews(storageKey));
31
+ setHydrated(true);
32
+ }, [storageKey]);
33
+ useEffect(() => {
34
+ if (!hydrated) return;
35
+ writeViews(storageKey, savedViews);
36
+ }, [savedViews, storageKey, hydrated]);
37
+ const saveView = useCallback((name, filters) => {
38
+ const id = `view-${Date.now().toString(36)}`;
39
+ setSavedViews((prev) => [...prev, { id, name, filters }]);
40
+ }, []);
41
+ const deleteView = useCallback((id) => {
42
+ setSavedViews((prev) => prev.filter((v) => v.id !== id));
43
+ }, []);
44
+ const loadViewFilters = useCallback(
45
+ (id) => {
46
+ const view = savedViews.find((v) => v.id === id);
47
+ return view?.filters ?? null;
48
+ },
49
+ [savedViews]
50
+ );
51
+ return { savedViews, saveView, deleteView, loadViewFilters };
52
+ }
53
+
54
+ export { useSavedViews };
55
+ //# sourceMappingURL=chunk-GCQFVMPI.js.map
56
+ //# sourceMappingURL=chunk-GCQFVMPI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/use-saved-views.ts"],"names":[],"mappings":";;;AAWA,SAAS,UAAU,UAAA,EAAqC;AACtD,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,EAAC;AAC3C,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,OAAA,CAAQ,UAAU,CAAA;AAC3C,IAAA,IAAI,CAAC,GAAA,EAAK,OAAO,EAAC;AAClB,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,SAAU,EAAC;AACpC,IAAA,OAAO,MAAA,CAAO,MAAA;AAAA,MACZ,CAAC,CAAA,KACC,CAAC,CAAC,CAAA,IACF,OAAO,MAAM,QAAA,IACb,OAAQ,CAAA,CAAoB,EAAA,KAAO,YACnC,OAAQ,CAAA,CAAoB,SAAS,QAAA,IACrC,OAAQ,EAAoB,OAAA,KAAY;AAAA,KAC5C;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAC;AAAA,EACV;AACF;AAEA,SAAS,UAAA,CAAW,YAAoB,KAAA,EAAwB;AAC9D,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,EAAA,IAAI;AACF,IAAA,YAAA,CAAa,OAAA,CAAQ,UAAA,EAAY,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,EACxD,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAsBO,SAAS,cAAc,UAAA,EAAyC;AACrE,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,QAAA,CAA0B,EAAE,CAAA;AAChE,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAE9C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,aAAA,CAAc,SAAA,CAAU,UAAU,CAAC,CAAA;AACnC,IAAA,WAAA,CAAY,IAAI,CAAA;AAAA,EAClB,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,QAAA,EAAU;AACf,IAAA,UAAA,CAAW,YAAY,UAAU,CAAA;AAAA,EACnC,CAAA,EAAG,CAAC,UAAA,EAAY,UAAA,EAAY,QAAQ,CAAC,CAAA;AAErC,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,CAAC,IAAA,EAAc,OAAA,KAAqC;AAC/E,IAAA,MAAM,KAAK,CAAA,KAAA,EAAQ,IAAA,CAAK,KAAI,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA;AAC1C,IAAA,aAAA,CAAc,CAAC,IAAA,KAAS,CAAC,GAAG,IAAA,EAAM,EAAE,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,CAAC,CAAA;AAAA,EAC1D,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,CAAC,EAAA,KAAe;AAC7C,IAAA,aAAA,CAAc,CAAC,SAAS,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,EAAE,CAAC,CAAA;AAAA,EACzD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,eAAA,GAAkB,WAAA;AAAA,IACtB,CAAC,EAAA,KAAe;AACd,MAAA,MAAM,OAAO,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AAC/C,MAAA,OAAO,MAAM,OAAA,IAAW,IAAA;AAAA,IAC1B,CAAA;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AAEA,EAAA,OAAO,EAAE,UAAA,EAAY,QAAA,EAAU,UAAA,EAAY,eAAA,EAAgB;AAC7D","file":"chunk-GCQFVMPI.js","sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\n\n/** Same shape as `DataFilters` `savedViews` items — kept local to avoid cycles. */\nexport interface SavedViewItem {\n id: string;\n name: string;\n filters: Record<string, unknown>;\n}\n\nfunction readViews(storageKey: string): SavedViewItem[] {\n if (typeof window === \"undefined\") return [];\n try {\n const raw = localStorage.getItem(storageKey);\n if (!raw) return [];\n const parsed = JSON.parse(raw) as unknown;\n if (!Array.isArray(parsed)) return [];\n return parsed.filter(\n (v): v is SavedViewItem =>\n !!v &&\n typeof v === \"object\" &&\n typeof (v as SavedViewItem).id === \"string\" &&\n typeof (v as SavedViewItem).name === \"string\" &&\n typeof (v as SavedViewItem).filters === \"object\",\n );\n } catch {\n return [];\n }\n}\n\nfunction writeViews(storageKey: string, views: SavedViewItem[]) {\n if (typeof window === \"undefined\") return;\n try {\n localStorage.setItem(storageKey, JSON.stringify(views));\n } catch {\n // quota / private mode — ignore\n }\n}\n\nexport interface UseSavedViewsReturn {\n savedViews: SavedViewItem[];\n saveView: (name: string, filters: Record<string, unknown>) => void;\n deleteView: (id: string) => void;\n loadViewFilters: (id: string) => Record<string, unknown> | null;\n}\n\n/**\n * Persist `DataFilters` saved-view shape in localStorage.\n *\n * @example\n * const { savedViews, saveView, deleteView } = useSavedViews(\"genesis-map-views\");\n * <DataFilters\n * savedViews={savedViews}\n * canSaveViews\n * onSaveView={(name) => saveView(name, currentFilters)}\n * onLoadView={(filters) => applyFilters(filters)}\n * onDeleteView={deleteView}\n * />\n */\nexport function useSavedViews(storageKey: string): UseSavedViewsReturn {\n const [savedViews, setSavedViews] = useState<SavedViewItem[]>([]);\n const [hydrated, setHydrated] = useState(false);\n\n useEffect(() => {\n setSavedViews(readViews(storageKey));\n setHydrated(true);\n }, [storageKey]);\n\n useEffect(() => {\n if (!hydrated) return;\n writeViews(storageKey, savedViews);\n }, [savedViews, storageKey, hydrated]);\n\n const saveView = useCallback((name: string, filters: Record<string, unknown>) => {\n const id = `view-${Date.now().toString(36)}`;\n setSavedViews((prev) => [...prev, { id, name, filters }]);\n }, []);\n\n const deleteView = useCallback((id: string) => {\n setSavedViews((prev) => prev.filter((v) => v.id !== id));\n }, []);\n\n const loadViewFilters = useCallback(\n (id: string) => {\n const view = savedViews.find((v) => v.id === id);\n return view?.filters ?? null;\n },\n [savedViews],\n );\n\n return { savedViews, saveView, deleteView, loadViewFilters };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Label } from './chunk-AIODTBWP.js';
1
+ import { Label } from './chunk-T5VX5DYO.js';
2
2
  import { cn } from './chunk-NZ5WBA4R.js';
3
3
  import * as React from 'react';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -55,5 +55,5 @@ function FormDescription({
55
55
  }
56
56
 
57
57
  export { FormDescription, FormError, FormField, FormLabel };
58
- //# sourceMappingURL=chunk-X7KMF6NH.js.map
59
- //# sourceMappingURL=chunk-X7KMF6NH.js.map
58
+ //# sourceMappingURL=chunk-IP6TMT3D.js.map
59
+ //# sourceMappingURL=chunk-IP6TMT3D.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ui/form-field.tsx"],"names":[],"mappings":";;;;;AAQA,SAAS,SAAA,CAAU;AAAA,EACjB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAyC;AACvC,EAAA,uBACE,GAAA,CAAC,SAAI,SAAA,EAAW,EAAA,CAAG,aAAa,SAAS,CAAA,EAAI,GAAG,KAAA,EAC7C,QAAA,EACH,CAAA;AAEJ;AAWA,IAAM,SAAA,GAAkB,KAAA,CAAA,UAAA,CAGtB,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,QAAA,EAAU,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,qBACrD,IAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,KAAA,IAAS,kBAAA,EAAoB,SAAS,CAAA;AAAA,IACnD,GAAG,KAAA;AAAA,IAEH,QAAA,EAAA;AAAA,MAAA,QAAA;AAAA,MACA,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAwB,QAAA,EAAA,GAAA,EAAC;AAAA;AAAA;AACxD,CACD;AACD,SAAA,CAAU,WAAA,GAAc,WAAA;AAMxB,SAAS,SAAA,CAAU;AAAA,EACjB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA+C;AAC7C,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AACtB,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,sCAAA,EAAwC,SAAS,CAAA;AAAA,MAC9D,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAMA,SAAS,eAAA,CAAgB;AAAA,EACvB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA+C;AAC7C,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AACtB,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS,CAAA;AAAA,MACvD,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ","file":"chunk-X7KMF6NH.js","sourcesContent":["import * as React from \"react\";\nimport { Label } from \"./label\";\nimport { cn } from \"../../utils\";\n\n// ---------------------------------------------------------------------------\n// FormField — wrapper div for consistent form field layout\n// ---------------------------------------------------------------------------\n\nfunction FormField({\n className,\n children,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div className={cn(\"space-y-2\", className)} {...props}>\n {children}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// FormLabel — label with error styling support\n// ---------------------------------------------------------------------------\n\ninterface FormLabelProps extends React.ComponentPropsWithoutRef<typeof Label> {\n error?: boolean;\n required?: boolean;\n}\n\nconst FormLabel = React.forwardRef<\n React.ComponentRef<typeof Label>,\n FormLabelProps\n>(({ className, error, required, children, ...props }, ref) => (\n <Label\n ref={ref}\n className={cn(error && \"text-destructive\", className)}\n {...props}\n >\n {children}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </Label>\n));\nFormLabel.displayName = \"FormLabel\";\n\n// ---------------------------------------------------------------------------\n// FormError — error message display\n// ---------------------------------------------------------------------------\n\nfunction FormError({\n className,\n children,\n ...props\n}: React.HTMLAttributes<HTMLParagraphElement>) {\n if (!children) return null;\n return (\n <p\n className={cn(\"text-sm font-medium text-destructive\", className)}\n {...props}\n >\n {children}\n </p>\n );\n}\n\n// ---------------------------------------------------------------------------\n// FormDescription — help text\n// ---------------------------------------------------------------------------\n\nfunction FormDescription({\n className,\n children,\n ...props\n}: React.HTMLAttributes<HTMLParagraphElement>) {\n if (!children) return null;\n return (\n <p\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n >\n {children}\n </p>\n );\n}\n\nexport { FormField, FormLabel, FormError, FormDescription };\n"]}
1
+ {"version":3,"sources":["../src/components/ui/form-field.tsx"],"names":[],"mappings":";;;;;AAQA,SAAS,SAAA,CAAU;AAAA,EACjB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAyC;AACvC,EAAA,uBACE,GAAA,CAAC,SAAI,SAAA,EAAW,EAAA,CAAG,aAAa,SAAS,CAAA,EAAI,GAAG,KAAA,EAC7C,QAAA,EACH,CAAA;AAEJ;AAWA,IAAM,SAAA,GAAkB,KAAA,CAAA,UAAA,CAGtB,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,QAAA,EAAU,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,qBACrD,IAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,KAAA,IAAS,kBAAA,EAAoB,SAAS,CAAA;AAAA,IACnD,GAAG,KAAA;AAAA,IAEH,QAAA,EAAA;AAAA,MAAA,QAAA;AAAA,MACA,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAwB,QAAA,EAAA,GAAA,EAAC;AAAA;AAAA;AACxD,CACD;AACD,SAAA,CAAU,WAAA,GAAc,WAAA;AAMxB,SAAS,SAAA,CAAU;AAAA,EACjB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA+C;AAC7C,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AACtB,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,sCAAA,EAAwC,SAAS,CAAA;AAAA,MAC9D,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAMA,SAAS,eAAA,CAAgB;AAAA,EACvB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA+C;AAC7C,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AACtB,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS,CAAA;AAAA,MACvD,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ","file":"chunk-IP6TMT3D.js","sourcesContent":["import * as React from \"react\";\nimport { Label } from \"./label\";\nimport { cn } from \"../../utils\";\n\n// ---------------------------------------------------------------------------\n// FormField — wrapper div for consistent form field layout\n// ---------------------------------------------------------------------------\n\nfunction FormField({\n className,\n children,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div className={cn(\"space-y-2\", className)} {...props}>\n {children}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// FormLabel — label with error styling support\n// ---------------------------------------------------------------------------\n\ninterface FormLabelProps extends React.ComponentPropsWithoutRef<typeof Label> {\n error?: boolean;\n required?: boolean;\n}\n\nconst FormLabel = React.forwardRef<\n React.ComponentRef<typeof Label>,\n FormLabelProps\n>(({ className, error, required, children, ...props }, ref) => (\n <Label\n ref={ref}\n className={cn(error && \"text-destructive\", className)}\n {...props}\n >\n {children}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </Label>\n));\nFormLabel.displayName = \"FormLabel\";\n\n// ---------------------------------------------------------------------------\n// FormError — error message display\n// ---------------------------------------------------------------------------\n\nfunction FormError({\n className,\n children,\n ...props\n}: React.HTMLAttributes<HTMLParagraphElement>) {\n if (!children) return null;\n return (\n <p\n className={cn(\"text-sm font-medium text-destructive\", className)}\n {...props}\n >\n {children}\n </p>\n );\n}\n\n// ---------------------------------------------------------------------------\n// FormDescription — help text\n// ---------------------------------------------------------------------------\n\nfunction FormDescription({\n className,\n children,\n ...props\n}: React.HTMLAttributes<HTMLParagraphElement>) {\n if (!children) return null;\n return (\n <p\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n >\n {children}\n </p>\n );\n}\n\nexport { FormField, FormLabel, FormError, FormDescription };\n"]}
@@ -1,4 +1,4 @@
1
- import { buttonVariants } from './chunk-I6JQHP6D.js';
1
+ import { buttonVariants } from './chunk-ZJFSZFPI.js';
2
2
  import { cn } from './chunk-NZ5WBA4R.js';
3
3
  import * as React from 'react';
4
4
  import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';
@@ -97,5 +97,5 @@ var PaginationEllipsis = ({
97
97
  PaginationEllipsis.displayName = "PaginationEllipsis";
98
98
 
99
99
  export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious };
100
- //# sourceMappingURL=chunk-LDPPIBIJ.js.map
101
- //# sourceMappingURL=chunk-LDPPIBIJ.js.map
100
+ //# sourceMappingURL=chunk-KB5T5LWM.js.map
101
+ //# sourceMappingURL=chunk-KB5T5LWM.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ui/pagination.tsx"],"names":[],"mappings":";;;;;;AAKA,IAAM,aAAa,CAAC,EAAE,SAAA,EAAW,GAAG,OAAM,qBACxC,GAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,IAAA,EAAK,YAAA;AAAA,IACL,YAAA,EAAW,YAAA;AAAA,IACX,SAAA,EAAW,EAAA,CAAG,oCAAA,EAAsC,SAAS,CAAA;AAAA,IAC5D,GAAG;AAAA;AACN;AAEF,UAAA,CAAW,WAAA,GAAc,YAAA;AAEzB,IAAM,iBAAA,GAA0B,iBAG9B,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC1B,GAAA;AAAA,EAAC,IAAA;AAAA,EAAA;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,kCAAA,EAAoC,SAAS,CAAA;AAAA,IAC1D,GAAG;AAAA;AACN,CACD;AACD,iBAAA,CAAkB,WAAA,GAAc,mBAAA;AAEhC,IAAM,iBAAuB,KAAA,CAAA,UAAA,CAG3B,CAAC,EAAE,SAAA,EAAW,GAAG,OAAM,EAAG,GAAA,yBACzB,IAAA,EAAA,EAAG,GAAA,EAAU,WAAW,EAAA,CAAG,EAAA,EAAI,SAAS,CAAA,EAAI,GAAG,OAAO,CACxD;AACD,cAAA,CAAe,WAAA,GAAc,gBAAA;AAO7B,IAAM,iBAAiB,CAAC;AAAA,EACtB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA,GAAO,MAAA;AAAA,EACP,GAAG;AACL,CAAA,qBACE,GAAA;AAAA,EAAC,GAAA;AAAA,EAAA;AAAA,IACC,cAAA,EAAc,WAAW,MAAA,GAAS,MAAA;AAAA,IAClC,SAAA,EAAW,EAAA;AAAA,MACT,cAAA,CAAe;AAAA,QACb,OAAA,EAAS,WAAW,SAAA,GAAY,OAAA;AAAA,QAChC;AAAA,OACD,CAAA;AAAA,MACD;AAAA,KACF;AAAA,IACC,GAAG;AAAA;AACN;AAEF,cAAA,CAAe,WAAA,GAAc,gBAAA;AAE7B,IAAM,qBAAqB,CAAC;AAAA,EAC1B,SAAA;AAAA,EACA,GAAG;AACL,CAAA,qBACE,IAAA;AAAA,EAAC,cAAA;AAAA,EAAA;AAAA,IACC,YAAA,EAAW,qBAAA;AAAA,IACX,IAAA,EAAK,SAAA;AAAA,IACL,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA;AAAA,IACtC,GAAG,KAAA;AAAA,IAEJ,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,WAAU,SAAA,EAAU,CAAA;AAAA,sBACjC,GAAA,CAAC,UAAK,QAAA,EAAA,UAAA,EAAQ;AAAA;AAAA;AAChB;AAEF,kBAAA,CAAmB,WAAA,GAAc,oBAAA;AAEjC,IAAM,iBAAiB,CAAC;AAAA,EACtB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,qBACE,IAAA;AAAA,EAAC,cAAA;AAAA,EAAA;AAAA,IACC,YAAA,EAAW,iBAAA;AAAA,IACX,IAAA,EAAK,SAAA;AAAA,IACL,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA;AAAA,IACtC,GAAG,KAAA;AAAA,IAEJ,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,UAAK,QAAA,EAAA,MAAA,EAAI,CAAA;AAAA,sBACV,GAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA;AACpC;AAEF,cAAA,CAAe,WAAA,GAAc,gBAAA;AAE7B,IAAM,qBAAqB,CAAC;AAAA,EAC1B,SAAA;AAAA,EACA,GAAG;AACL,CAAA,qBACE,IAAA;AAAA,EAAC,MAAA;AAAA,EAAA;AAAA,IACC,aAAA,EAAW,IAAA;AAAA,IACX,SAAA,EAAW,EAAA,CAAG,0CAAA,EAA4C,SAAS,CAAA;AAAA,IAClE,GAAG,KAAA;AAAA,IAEJ,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,WAAU,SAAA,EAAU,CAAA;AAAA,sBACpC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAU,QAAA,EAAA,YAAA,EAAU;AAAA;AAAA;AACtC;AAEF,kBAAA,CAAmB,WAAA,GAAc,oBAAA","file":"chunk-LDPPIBIJ.js","sourcesContent":["import * as React from \"react\";\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport { type ButtonProps, buttonVariants } from \"./button\";\n\nconst Pagination = ({ className, ...props }: React.ComponentProps<\"nav\">) => (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n);\nPagination.displayName = \"Pagination\";\n\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n React.ComponentProps<\"ul\">\n>(({ className, ...props }, ref) => (\n <ul\n ref={ref}\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n));\nPaginationContent.displayName = \"PaginationContent\";\n\nconst PaginationItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentProps<\"li\">\n>(({ className, ...props }, ref) => (\n <li ref={ref} className={cn(\"\", className)} {...props} />\n));\nPaginationItem.displayName = \"PaginationItem\";\n\ntype PaginationLinkProps = {\n isActive?: boolean;\n} & Pick<ButtonProps, \"size\"> &\n React.ComponentProps<\"a\">;\n\nconst PaginationLink = ({\n className,\n isActive,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) => (\n <a\n aria-current={isActive ? \"page\" : undefined}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n className,\n )}\n {...props}\n />\n);\nPaginationLink.displayName = \"PaginationLink\";\n\nconst PaginationPrevious = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"gap-1 pl-2.5\", className)}\n {...props}\n >\n <ChevronLeft className=\"h-4 w-4\" />\n <span>Previous</span>\n </PaginationLink>\n);\nPaginationPrevious.displayName = \"PaginationPrevious\";\n\nconst PaginationNext = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"gap-1 pr-2.5\", className)}\n {...props}\n >\n <span>Next</span>\n <ChevronRight className=\"h-4 w-4\" />\n </PaginationLink>\n);\nPaginationNext.displayName = \"PaginationNext\";\n\nconst PaginationEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n <span\n aria-hidden\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n);\nPaginationEllipsis.displayName = \"PaginationEllipsis\";\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n};\n"]}
1
+ {"version":3,"sources":["../src/components/ui/pagination.tsx"],"names":[],"mappings":"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","file":"chunk-KB5T5LWM.js","sourcesContent":["import * as React from \"react\";\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport { type ButtonProps, buttonVariants } from \"./button\";\n\nconst Pagination = ({ className, ...props }: React.ComponentProps<\"nav\">) => (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n);\nPagination.displayName = \"Pagination\";\n\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n React.ComponentProps<\"ul\">\n>(({ className, ...props }, ref) => (\n <ul\n ref={ref}\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n));\nPaginationContent.displayName = \"PaginationContent\";\n\nconst PaginationItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentProps<\"li\">\n>(({ className, ...props }, ref) => (\n <li ref={ref} className={cn(\"\", className)} {...props} />\n));\nPaginationItem.displayName = \"PaginationItem\";\n\ntype PaginationLinkProps = {\n isActive?: boolean;\n} & Pick<ButtonProps, \"size\"> &\n React.ComponentProps<\"a\">;\n\nconst PaginationLink = ({\n className,\n isActive,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) => (\n <a\n aria-current={isActive ? \"page\" : undefined}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n className,\n )}\n {...props}\n />\n);\nPaginationLink.displayName = \"PaginationLink\";\n\nconst PaginationPrevious = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"gap-1 pl-2.5\", className)}\n {...props}\n >\n <ChevronLeft className=\"h-4 w-4\" />\n <span>Previous</span>\n </PaginationLink>\n);\nPaginationPrevious.displayName = \"PaginationPrevious\";\n\nconst PaginationNext = ({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) => (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"gap-1 pr-2.5\", className)}\n {...props}\n >\n <span>Next</span>\n <ChevronRight className=\"h-4 w-4\" />\n </PaginationLink>\n);\nPaginationNext.displayName = \"PaginationNext\";\n\nconst PaginationEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n <span\n aria-hidden\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n);\nPaginationEllipsis.displayName = \"PaginationEllipsis\";\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n};\n"]}
@@ -11,9 +11,15 @@ var badgeVariants = cva(
11
11
  secondary: "border-transparent bg-secondary text-secondary-foreground",
12
12
  destructive: "border-transparent bg-destructive text-destructive-foreground",
13
13
  outline: "text-foreground",
14
- success: "border-transparent bg-success/15 text-success dark:bg-success/20",
15
- warning: "border-transparent bg-warning/15 text-warning dark:bg-warning/20",
16
- info: "border-transparent bg-info/15 text-info dark:bg-info/20",
14
+ // AA-safe status text on the tinted chip. Same-hue status text
15
+ // (text-success ~2.2:1) fails WCAG AA, so text uses the semantic
16
+ // Tailwind ramp (same hues as the Genesis status tokens). Measured
17
+ // over the light /15 tint: emerald-700 4.76:1, amber-800 6.33:1,
18
+ // blue-700 5.64:1 (amber-700 was 4.48:1 — under the 4.5:1 floor).
19
+ // Dark mode uses the 200/300 stops over the /20 tint: 8.8–11.5:1.
20
+ success: "border-transparent bg-success/15 text-emerald-700 dark:bg-success/20 dark:text-emerald-300",
21
+ warning: "border-transparent bg-warning/15 text-amber-800 dark:bg-warning/20 dark:text-amber-200",
22
+ info: "border-transparent bg-info/15 text-blue-700 dark:bg-info/20 dark:text-blue-300",
17
23
  muted: "border-transparent bg-muted text-muted-foreground"
18
24
  }
19
25
  },
@@ -27,5 +33,5 @@ function Badge({ className, variant, ...props }) {
27
33
  }
28
34
 
29
35
  export { Badge, badgeVariants };
30
- //# sourceMappingURL=chunk-MUQLZFUR.js.map
31
- //# sourceMappingURL=chunk-MUQLZFUR.js.map
36
+ //# sourceMappingURL=chunk-NPNADZHM.js.map
37
+ //# sourceMappingURL=chunk-NPNADZHM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/badge.tsx"],"names":[],"mappings":";;;;AAIA,IAAM,aAAA,GAAgB,GAAA;AAAA,EACpB,8LAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EACE,uDAAA;AAAA,QACF,SAAA,EACE,2DAAA;AAAA,QACF,WAAA,EACE,+DAAA;AAAA,QACF,OAAA,EAAS,iBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOT,OAAA,EACE,4FAAA;AAAA,QACF,OAAA,EACE,wFAAA;AAAA,QACF,IAAA,EAAM,gFAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ;AAMA,SAAS,MAAM,EAAE,SAAA,EAAW,OAAA,EAAS,GAAG,OAAM,EAAe;AAC3D,EAAA,uBACE,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,aAAA,CAAc,EAAE,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO,CAAA;AAE3E","file":"chunk-NPNADZHM.js","sourcesContent":["import * as React from \"react\";\nimport { type VariantProps, cva } from \"class-variance-authority\";\nimport { cn } from \"../../utils\";\n\nconst badgeVariants = cva(\n \"inline-flex w-fit items-center whitespace-nowrap rounded-full border px-2.5 py-0.5 text-xs font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",\n {\n variants: {\n variant: {\n default:\n \"border-transparent bg-primary text-primary-foreground\",\n secondary:\n \"border-transparent bg-secondary text-secondary-foreground\",\n destructive:\n \"border-transparent bg-destructive text-destructive-foreground\",\n outline: \"text-foreground\",\n // AA-safe status text on the tinted chip. Same-hue status text\n // (text-success ~2.2:1) fails WCAG AA, so text uses the semantic\n // Tailwind ramp (same hues as the Genesis status tokens). Measured\n // over the light /15 tint: emerald-700 4.76:1, amber-800 6.33:1,\n // blue-700 5.64:1 (amber-700 was 4.48:1 — under the 4.5:1 floor).\n // Dark mode uses the 200/300 stops over the /20 tint: 8.8–11.5:1.\n success:\n \"border-transparent bg-success/15 text-emerald-700 dark:bg-success/20 dark:text-emerald-300\",\n warning:\n \"border-transparent bg-warning/15 text-amber-800 dark:bg-warning/20 dark:text-amber-200\",\n info: \"border-transparent bg-info/15 text-blue-700 dark:bg-info/20 dark:text-blue-300\",\n muted: \"border-transparent bg-muted text-muted-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLSpanElement>,\n VariantProps<typeof badgeVariants> {}\n\nfunction Badge({ className, variant, ...props }: BadgeProps) {\n return (\n <span className={cn(badgeVariants({ variant }), className)} {...props} />\n );\n}\n\nexport { Badge, badgeVariants };\n"]}
@@ -8,8 +8,9 @@ var Input = React.forwardRef(
8
8
  "input",
9
9
  {
10
10
  type,
11
+ "data-slot": "input",
11
12
  className: cn(
12
- "flex h-10 w-full min-w-0 rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
13
+ "flex h-10 w-full min-w-0 rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm aria-invalid:border-destructive aria-invalid:ring-destructive/20",
13
14
  className
14
15
  ),
15
16
  ref,
@@ -21,5 +22,5 @@ var Input = React.forwardRef(
21
22
  Input.displayName = "Input";
22
23
 
23
24
  export { Input };
24
- //# sourceMappingURL=chunk-6V4GJUE3.js.map
25
- //# sourceMappingURL=chunk-6V4GJUE3.js.map
25
+ //# sourceMappingURL=chunk-QSXVL5UB.js.map
26
+ //# sourceMappingURL=chunk-QSXVL5UB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/input.tsx"],"names":[],"mappings":";;;;AAIA,IAAM,KAAA,GAAc,KAAA,CAAA,UAAA;AAAA,EAClB,CAAC,EAAE,SAAA,EAAW,MAAM,GAAG,KAAA,IAAS,GAAA,KAAQ;AACtC,IAAA,uBACE,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,WAAA,EAAU,OAAA;AAAA,QACV,SAAA,EAAW,EAAA;AAAA,UACT,ycAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-QSXVL5UB.js","sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"../../utils\";\n\nconst Input = React.forwardRef<HTMLInputElement, React.ComponentProps<\"input\">>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"flex h-10 w-full min-w-0 rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm aria-invalid:border-destructive aria-invalid:ring-destructive/20\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n },\n);\nInput.displayName = \"Input\";\n\nexport { Input };\n"]}
@@ -12,6 +12,7 @@ var Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ j
12
12
  LabelPrimitive.Root,
13
13
  {
14
14
  ref,
15
+ "data-slot": "label",
15
16
  className: cn(labelVariants(), className),
16
17
  ...props
17
18
  }
@@ -19,5 +20,5 @@ var Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ j
19
20
  Label.displayName = LabelPrimitive.Root.displayName;
20
21
 
21
22
  export { Label };
22
- //# sourceMappingURL=chunk-AIODTBWP.js.map
23
- //# sourceMappingURL=chunk-AIODTBWP.js.map
23
+ //# sourceMappingURL=chunk-T5VX5DYO.js.map
24
+ //# sourceMappingURL=chunk-T5VX5DYO.js.map