@omnifyjp/ui 0.1.7 → 0.2.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 (93) hide show
  1. package/dist/{chunk-BEZF6UWZ.js → chunk-2C2HRGM7.js} +3 -3
  2. package/dist/{chunk-BEZF6UWZ.js.map → chunk-2C2HRGM7.js.map} +1 -1
  3. package/dist/{chunk-TX42RKQU.js → chunk-2TUWDXAC.js} +3 -3
  4. package/dist/{chunk-TX42RKQU.js.map → chunk-2TUWDXAC.js.map} +1 -1
  5. package/dist/{chunk-HY4FVDA4.js → chunk-35U6QG4P.js} +5 -5
  6. package/dist/{chunk-HY4FVDA4.js.map → chunk-35U6QG4P.js.map} +1 -1
  7. package/dist/{chunk-YT3W2URB.js → chunk-36YYHIJU.js} +3 -3
  8. package/dist/{chunk-YT3W2URB.js.map → chunk-36YYHIJU.js.map} +1 -1
  9. package/dist/{chunk-33DTBAFF.js → chunk-4MHIUUAW.js} +3 -3
  10. package/dist/{chunk-33DTBAFF.js.map → chunk-4MHIUUAW.js.map} +1 -1
  11. package/dist/chunk-55E7D2HR.js +99 -0
  12. package/dist/chunk-55E7D2HR.js.map +1 -0
  13. package/dist/{chunk-4MD7BIEK.js → chunk-6DIDQ4TB.js} +8 -8
  14. package/dist/{chunk-4MD7BIEK.js.map → chunk-6DIDQ4TB.js.map} +1 -1
  15. package/dist/{chunk-ZHP73HKU.js → chunk-7IRLBU2I.js} +3 -3
  16. package/dist/{chunk-ZHP73HKU.js.map → chunk-7IRLBU2I.js.map} +1 -1
  17. package/dist/chunk-A3BB5ZOC.js +77 -0
  18. package/dist/chunk-A3BB5ZOC.js.map +1 -0
  19. package/dist/{chunk-EIY5FVSV.js → chunk-BAQWGQJG.js} +3 -3
  20. package/dist/{chunk-EIY5FVSV.js.map → chunk-BAQWGQJG.js.map} +1 -1
  21. package/dist/{chunk-UAX7UJIJ.js → chunk-G7HTZBUR.js} +13 -13
  22. package/dist/{chunk-UAX7UJIJ.js.map → chunk-G7HTZBUR.js.map} +1 -1
  23. package/dist/{chunk-V4ZOPVXV.js → chunk-JAJMM32I.js} +3 -3
  24. package/dist/{chunk-V4ZOPVXV.js.map → chunk-JAJMM32I.js.map} +1 -1
  25. package/dist/{chunk-4SMVBJFU.js → chunk-LMT327XH.js} +4 -4
  26. package/dist/chunk-LMT327XH.js.map +1 -0
  27. package/dist/{chunk-YE7EHQ6P.js → chunk-LTTNCAAA.js} +3 -3
  28. package/dist/{chunk-YE7EHQ6P.js.map → chunk-LTTNCAAA.js.map} +1 -1
  29. package/dist/{chunk-C6EAO7IA.js → chunk-MJLFJPUG.js} +8 -8
  30. package/dist/{chunk-C6EAO7IA.js.map → chunk-MJLFJPUG.js.map} +1 -1
  31. package/dist/{chunk-QX56UQ2I.js → chunk-MZ2P566X.js} +3 -3
  32. package/dist/{chunk-QX56UQ2I.js.map → chunk-MZ2P566X.js.map} +1 -1
  33. package/dist/{chunk-C7LPAIU6.js → chunk-N47H4MHX.js} +3 -3
  34. package/dist/{chunk-C7LPAIU6.js.map → chunk-N47H4MHX.js.map} +1 -1
  35. package/dist/{chunk-UVOH3VSV.js → chunk-NPL2R5LD.js} +3 -3
  36. package/dist/{chunk-UVOH3VSV.js.map → chunk-NPL2R5LD.js.map} +1 -1
  37. package/dist/chunk-TGYQ3AKH.js +95 -0
  38. package/dist/chunk-TGYQ3AKH.js.map +1 -0
  39. package/dist/{chunk-WNKEQCXM.js → chunk-THQUH6WX.js} +4 -4
  40. package/dist/{chunk-WNKEQCXM.js.map → chunk-THQUH6WX.js.map} +1 -1
  41. package/dist/{chunk-ZB2FWKHF.js → chunk-VVYSAGB3.js} +6 -6
  42. package/dist/{chunk-ZB2FWKHF.js.map → chunk-VVYSAGB3.js.map} +1 -1
  43. package/dist/{chunk-JBQT2H4K.js → chunk-XUVLD65E.js} +3 -3
  44. package/dist/{chunk-JBQT2H4K.js.map → chunk-XUVLD65E.js.map} +1 -1
  45. package/dist/{chunk-ZYSFPIGY.js → chunk-YS3PMGYC.js} +4 -4
  46. package/dist/{chunk-ZYSFPIGY.js.map → chunk-YS3PMGYC.js.map} +1 -1
  47. package/dist/{chunk-DZ7752H3.js → chunk-ZHEKDP5X.js} +3 -3
  48. package/dist/{chunk-DZ7752H3.js.map → chunk-ZHEKDP5X.js.map} +1 -1
  49. package/dist/{chunk-BOMDCV63.js → chunk-ZYEGBF7G.js} +3 -3
  50. package/dist/{chunk-BOMDCV63.js.map → chunk-ZYEGBF7G.js.map} +1 -1
  51. package/dist/components/alert-dialog.js +2 -2
  52. package/dist/components/alert.d.ts +38 -12
  53. package/dist/components/alert.js +1 -1
  54. package/dist/components/badge.d.ts +31 -8
  55. package/dist/components/badge.js +1 -1
  56. package/dist/components/button.d.ts +43 -19
  57. package/dist/components/button.js +1 -1
  58. package/dist/components/calendar-category-badge.js +2 -2
  59. package/dist/components/calendar-event-sheet.js +4 -4
  60. package/dist/components/calendar-toolbar.js +2 -2
  61. package/dist/components/calendar.js +2 -2
  62. package/dist/components/carousel.d.ts +1 -0
  63. package/dist/components/carousel.js +2 -2
  64. package/dist/components/color-picker.js +2 -2
  65. package/dist/components/combobox.js +2 -2
  66. package/dist/components/date-picker.js +3 -3
  67. package/dist/components/file-upload.js +2 -2
  68. package/dist/components/pagination.d.ts +1 -0
  69. package/dist/components/pagination.js +2 -2
  70. package/dist/components/rating.js +1 -1
  71. package/dist/components/scope-tree.js +2 -2
  72. package/dist/components/scope-type-badge.js +2 -2
  73. package/dist/components/sidebar.d.ts +1 -0
  74. package/dist/components/sidebar.js +2 -2
  75. package/dist/components/stage-type-badge.js +2 -2
  76. package/dist/components/tag-input.js +2 -2
  77. package/dist/components/time-picker.js +2 -2
  78. package/dist/components/workflow-category-badge.js +2 -2
  79. package/dist/components/workflow-diagram.js +1 -1
  80. package/dist/components/workflow-status-badge.js +2 -2
  81. package/dist/components/workflow-stepper.js +1 -1
  82. package/dist/index.d.ts +1 -0
  83. package/dist/index.js +25 -25
  84. package/dist/types-CBVkScfB.d.ts +84 -0
  85. package/package.json +23 -13
  86. package/src/styles/theme.css +10 -0
  87. package/dist/chunk-4SMVBJFU.js.map +0 -1
  88. package/dist/chunk-L6K7UH3O.js +0 -66
  89. package/dist/chunk-L6K7UH3O.js.map +0 -1
  90. package/dist/chunk-OBZQTY3H.js +0 -41
  91. package/dist/chunk-OBZQTY3H.js.map +0 -1
  92. package/dist/chunk-Y65FNGEE.js +0 -52
  93. package/dist/chunk-Y65FNGEE.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { Badge } from './chunk-OBZQTY3H.js';
1
+ import { Badge } from './chunk-A3BB5ZOC.js';
2
2
  import { cn } from './chunk-DGPY4WP3.js';
3
3
  import { MoreHorizontal, FileText, FileSignature, ShoppingCart, Receipt, Calendar } from 'lucide-react';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -47,5 +47,5 @@ function WorkflowCategoryBadge({ category, label, className }) {
47
47
  }
48
48
 
49
49
  export { WorkflowCategoryBadge };
50
- //# sourceMappingURL=chunk-BEZF6UWZ.js.map
51
- //# sourceMappingURL=chunk-BEZF6UWZ.js.map
50
+ //# sourceMappingURL=chunk-2C2HRGM7.js.map
51
+ //# sourceMappingURL=chunk-2C2HRGM7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/workflow-category-badge.tsx"],"names":[],"mappings":";;;;;AA6BA,IAAM,cAAA,GAAqF;AAAA,EACzF,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,YAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,aAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,cAAA;AAAA,IACN,KAAA,EAAO;AAAA;AAEX,CAAA;AAEA,IAAM,aAAA,GAAkD;AAAA,EACtD,KAAA,EAAO,OAAA;AAAA,EACP,OAAA,EAAS,SAAA;AAAA,EACT,QAAA,EAAU,UAAA;AAAA,EACV,QAAA,EAAU,UAAA;AAAA,EACV,QAAA,EAAU,UAAA;AAAA,EACV,KAAA,EAAO;AACT,CAAA;AAmBO,SAAS,qBAAA,CAAsB,EAAE,QAAA,EAAU,KAAA,EAAO,WAAU,EAA+B;AAChG,EAAA,MAAM,MAAA,GAAS,eAAe,QAAQ,CAAA;AACtC,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AAEpB,EAAA,uBACE,IAAA,CAAC,SAAM,OAAA,EAAQ,SAAA,EAAU,WAAW,EAAA,CAAG,MAAA,CAAO,KAAA,EAAO,SAAS,CAAA,EAC5D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,cAAA,EAAe,CAAA;AAAA,IAC9B,KAAA,IAAS,cAAc,QAAQ;AAAA,GAAA,EAClC,CAAA;AAEJ","file":"chunk-BEZF6UWZ.js","sourcesContent":["import {\n Calendar,\n Receipt,\n ShoppingCart,\n FileSignature,\n FileText,\n MoreHorizontal,\n} from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport { Badge } from './badge';\n\n/** Supported workflow categories with built-in icon and color mappings. */\nexport type WorkflowCategory =\n | 'leave'\n | 'expense'\n | 'purchase'\n | 'contract'\n | 'document'\n | 'other';\n\nexport interface WorkflowCategoryBadgeProps {\n /** The category key. Determines the icon and color. */\n category: WorkflowCategory;\n /** The displayed label text. Defaults to a capitalized version of the category. */\n label?: string;\n /** Optional additional className. */\n className?: string;\n}\n\nconst categoryConfig: Record<WorkflowCategory, { icon: typeof Calendar; style: string }> = {\n leave: {\n icon: Calendar,\n style:\n 'bg-blue-50 dark:bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-200 dark:border-blue-500/30',\n },\n expense: {\n icon: Receipt,\n style:\n 'bg-green-50 dark:bg-green-500/15 text-green-600 dark:text-green-400 border-green-200 dark:border-green-500/30',\n },\n purchase: {\n icon: ShoppingCart,\n style:\n 'bg-amber-50 dark:bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-500/30',\n },\n contract: {\n icon: FileSignature,\n style:\n 'bg-purple-50 dark:bg-purple-500/15 text-purple-600 dark:text-purple-400 border-purple-200 dark:border-purple-500/30',\n },\n document: {\n icon: FileText,\n style:\n 'bg-cyan-50 dark:bg-cyan-500/15 text-cyan-600 dark:text-cyan-400 border-cyan-200 dark:border-cyan-500/30',\n },\n other: {\n icon: MoreHorizontal,\n style: 'bg-muted text-muted-foreground',\n },\n};\n\nconst defaultLabels: Record<WorkflowCategory, string> = {\n leave: 'Leave',\n expense: 'Expense',\n purchase: 'Purchase',\n contract: 'Contract',\n document: 'Document',\n other: 'Other',\n};\n\n/**\n * WorkflowCategoryBadge renders a badge with an icon and color for a workflow category.\n *\n * Each category has a dedicated icon and color scheme:\n * - leave: Calendar (blue)\n * - expense: Receipt (green)\n * - purchase: ShoppingCart (amber)\n * - contract: FileSignature (purple)\n * - document: FileText (cyan)\n * - other: MoreHorizontal (muted)\n *\n * @example\n * ```tsx\n * <WorkflowCategoryBadge category=\"expense\" />\n * <WorkflowCategoryBadge category=\"leave\" label=\"Annual Leave\" />\n * ```\n */\nexport function WorkflowCategoryBadge({ category, label, className }: WorkflowCategoryBadgeProps) {\n const config = categoryConfig[category];\n const Icon = config.icon;\n\n return (\n <Badge variant=\"outline\" className={cn(config.style, className)}>\n <Icon className=\"w-3 h-3 mr-1\" />\n {label ?? defaultLabels[category]}\n </Badge>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/workflow-category-badge.tsx"],"names":[],"mappings":";;;;;AA6BA,IAAM,cAAA,GAAqF;AAAA,EACzF,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,YAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,aAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,cAAA;AAAA,IACN,KAAA,EAAO;AAAA;AAEX,CAAA;AAEA,IAAM,aAAA,GAAkD;AAAA,EACtD,KAAA,EAAO,OAAA;AAAA,EACP,OAAA,EAAS,SAAA;AAAA,EACT,QAAA,EAAU,UAAA;AAAA,EACV,QAAA,EAAU,UAAA;AAAA,EACV,QAAA,EAAU,UAAA;AAAA,EACV,KAAA,EAAO;AACT,CAAA;AAmBO,SAAS,qBAAA,CAAsB,EAAE,QAAA,EAAU,KAAA,EAAO,WAAU,EAA+B;AAChG,EAAA,MAAM,MAAA,GAAS,eAAe,QAAQ,CAAA;AACtC,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AAEpB,EAAA,uBACE,IAAA,CAAC,SAAM,OAAA,EAAQ,SAAA,EAAU,WAAW,EAAA,CAAG,MAAA,CAAO,KAAA,EAAO,SAAS,CAAA,EAC5D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,cAAA,EAAe,CAAA;AAAA,IAC9B,KAAA,IAAS,cAAc,QAAQ;AAAA,GAAA,EAClC,CAAA;AAEJ","file":"chunk-2C2HRGM7.js","sourcesContent":["import {\n Calendar,\n Receipt,\n ShoppingCart,\n FileSignature,\n FileText,\n MoreHorizontal,\n} from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport { Badge } from './badge';\n\n/** Supported workflow categories with built-in icon and color mappings. */\nexport type WorkflowCategory =\n | 'leave'\n | 'expense'\n | 'purchase'\n | 'contract'\n | 'document'\n | 'other';\n\nexport interface WorkflowCategoryBadgeProps {\n /** The category key. Determines the icon and color. */\n category: WorkflowCategory;\n /** The displayed label text. Defaults to a capitalized version of the category. */\n label?: string;\n /** Optional additional className. */\n className?: string;\n}\n\nconst categoryConfig: Record<WorkflowCategory, { icon: typeof Calendar; style: string }> = {\n leave: {\n icon: Calendar,\n style:\n 'bg-blue-50 dark:bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-200 dark:border-blue-500/30',\n },\n expense: {\n icon: Receipt,\n style:\n 'bg-green-50 dark:bg-green-500/15 text-green-600 dark:text-green-400 border-green-200 dark:border-green-500/30',\n },\n purchase: {\n icon: ShoppingCart,\n style:\n 'bg-amber-50 dark:bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-500/30',\n },\n contract: {\n icon: FileSignature,\n style:\n 'bg-purple-50 dark:bg-purple-500/15 text-purple-600 dark:text-purple-400 border-purple-200 dark:border-purple-500/30',\n },\n document: {\n icon: FileText,\n style:\n 'bg-cyan-50 dark:bg-cyan-500/15 text-cyan-600 dark:text-cyan-400 border-cyan-200 dark:border-cyan-500/30',\n },\n other: {\n icon: MoreHorizontal,\n style: 'bg-muted text-muted-foreground',\n },\n};\n\nconst defaultLabels: Record<WorkflowCategory, string> = {\n leave: 'Leave',\n expense: 'Expense',\n purchase: 'Purchase',\n contract: 'Contract',\n document: 'Document',\n other: 'Other',\n};\n\n/**\n * WorkflowCategoryBadge renders a badge with an icon and color for a workflow category.\n *\n * Each category has a dedicated icon and color scheme:\n * - leave: Calendar (blue)\n * - expense: Receipt (green)\n * - purchase: ShoppingCart (amber)\n * - contract: FileSignature (purple)\n * - document: FileText (cyan)\n * - other: MoreHorizontal (muted)\n *\n * @example\n * ```tsx\n * <WorkflowCategoryBadge category=\"expense\" />\n * <WorkflowCategoryBadge category=\"leave\" label=\"Annual Leave\" />\n * ```\n */\nexport function WorkflowCategoryBadge({ category, label, className }: WorkflowCategoryBadgeProps) {\n const config = categoryConfig[category];\n const Icon = config.icon;\n\n return (\n <Badge variant=\"outline\" className={cn(config.style, className)}>\n <Icon className=\"w-3 h-3 mr-1\" />\n {label ?? defaultLabels[category]}\n </Badge>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Button } from './chunk-Y65FNGEE.js';
1
+ import { Button } from './chunk-55E7D2HR.js';
2
2
  import { cn } from './chunk-DGPY4WP3.js';
3
3
  import * as React from 'react';
4
4
  import useEmblaCarousel from 'embla-carousel-react';
@@ -192,5 +192,5 @@ function CarouselNext({
192
192
  }
193
193
 
194
194
  export { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious };
195
- //# sourceMappingURL=chunk-TX42RKQU.js.map
196
- //# sourceMappingURL=chunk-TX42RKQU.js.map
195
+ //# sourceMappingURL=chunk-2TUWDXAC.js.map
196
+ //# sourceMappingURL=chunk-2TUWDXAC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/carousel.tsx"],"names":["api"],"mappings":";;;;;;;AAgCA,IAAM,eAAA,GAAwB,oBAA2C,IAAI,CAAA;AAG7E,SAAS,WAAA,GAAc;AACrB,EAAA,MAAM,OAAA,GAAgB,iBAAW,eAAe,CAAA;AAEhD,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,EAClE;AAEA,EAAA,OAAO,OAAA;AACT;AAsBA,SAAS,QAAA,CAAS;AAAA,EAChB,WAAA,GAAc,YAAA;AAAA,EACd,IAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAgD;AAC9C,EAAA,MAAM,CAAC,WAAA,EAAa,GAAG,CAAA,GAAI,gBAAA;AAAA,IACzB;AAAA,MACE,GAAG,IAAA;AAAA,MACH,IAAA,EAAM,WAAA,KAAgB,YAAA,GAAe,GAAA,GAAM;AAAA,KAC7C;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAU,eAAS,KAAK,CAAA;AAC9D,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAU,eAAS,KAAK,CAAA;AAE9D,EAAA,MAAM,QAAA,GAAiB,KAAA,CAAA,WAAA,CAAY,CAACA,IAAAA,KAAqB;AACvD,IAAA,IAAI,CAACA,IAAAA,EAAK;AACV,IAAA,gBAAA,CAAiBA,IAAAA,CAAI,eAAe,CAAA;AACpC,IAAA,gBAAA,CAAiBA,IAAAA,CAAI,eAAe,CAAA;AAAA,EACtC,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,UAAA,GAAmB,kBAAY,MAAM;AACzC,IAAA,GAAA,EAAK,UAAA,EAAW;AAAA,EAClB,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,MAAM,UAAA,GAAmB,kBAAY,MAAM;AACzC,IAAA,GAAA,EAAK,UAAA,EAAW;AAAA,EAClB,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,MAAM,aAAA,GAAsB,KAAA,CAAA,WAAA;AAAA,IAC1B,CAAC,KAAA,KAA+C;AAC9C,MAAA,IAAI,KAAA,CAAM,QAAQ,WAAA,EAAa;AAC7B,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,UAAA,EAAW;AAAA,MACb,CAAA,MAAA,IAAW,KAAA,CAAM,GAAA,KAAQ,YAAA,EAAc;AACrC,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,UAAA,EAAW;AAAA,MACb;AAAA,IACF,CAAA;AAAA,IACA,CAAC,YAAY,UAAU;AAAA,GACzB;AAEA,EAAM,gBAAU,MAAM;AACpB,IAAA,IAAI,CAAC,GAAA,IAAO,CAAC,MAAA,EAAQ;AACrB,IAAA,MAAA,CAAO,GAAG,CAAA;AAAA,EACZ,CAAA,EAAG,CAAC,GAAA,EAAK,MAAM,CAAC,CAAA;AAEhB,EAAM,gBAAU,MAAM;AACpB,IAAA,IAAI,CAAC,GAAA,EAAK;AACV,IAAA,QAAA,CAAS,GAAG,CAAA;AACZ,IAAA,GAAA,CAAI,EAAA,CAAG,UAAU,QAAQ,CAAA;AACzB,IAAA,GAAA,CAAI,EAAA,CAAG,UAAU,QAAQ,CAAA;AAEzB,IAAA,OAAO,MAAM;AACX,MAAA,GAAA,EAAK,GAAA,CAAI,UAAU,QAAQ,CAAA;AAAA,IAC7B,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,QAAQ,CAAC,CAAA;AAElB,EAAA,uBACE,GAAA;AAAA,IAAC,eAAA,CAAgB,QAAA;AAAA,IAAhB;AAAA,MACC,KAAA,EAAO;AAAA,QACL,WAAA;AAAA,QACA,GAAA;AAAA,QACA,IAAA;AAAA,QACA,WAAA,EACE,WAAA,KAAgB,IAAA,EAAM,IAAA,KAAS,MAAM,UAAA,GAAa,YAAA,CAAA;AAAA,QACpD,UAAA;AAAA,QACA,UAAA;AAAA,QACA,aAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,gBAAA,EAAkB,aAAA;AAAA,UAClB,SAAA,EAAW,EAAA,CAAG,UAAA,EAAY,SAAS,CAAA;AAAA,UACnC,IAAA,EAAK,QAAA;AAAA,UACL,sBAAA,EAAqB,UAAA;AAAA,UACrB,WAAA,EAAU,UAAA;AAAA,UACT,GAAG,KAAA;AAAA,UAEH;AAAA;AAAA;AACH;AAAA,GACF;AAEJ;AAGA,SAAS,eAAA,CAAgB,EAAE,SAAA,EAAW,GAAG,OAAM,EAAgC;AAC7E,EAAA,MAAM,EAAE,WAAA,EAAa,WAAA,EAAY,GAAI,WAAA,EAAY;AAEjD,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,WAAA;AAAA,MACL,SAAA,EAAU,iBAAA;AAAA,MACV,WAAA,EAAU,kBAAA;AAAA,MAEV,QAAA,kBAAA,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,EAAA;AAAA,YACT,MAAA;AAAA,YACA,WAAA,KAAgB,eAAe,OAAA,GAAU,gBAAA;AAAA,YACzC;AAAA,WACF;AAAA,UACC,GAAG;AAAA;AAAA;AACN;AAAA,GACF;AAEJ;AAGA,SAAS,YAAA,CAAa,EAAE,SAAA,EAAW,GAAG,OAAM,EAAgC;AAC1E,EAAA,MAAM,EAAE,WAAA,EAAY,GAAI,WAAA,EAAY;AAEpC,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,OAAA;AAAA,MACL,sBAAA,EAAqB,OAAA;AAAA,MACrB,WAAA,EAAU,eAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,oCAAA;AAAA,QACA,WAAA,KAAgB,eAAe,MAAA,GAAS,MAAA;AAAA,QACxC;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAGA,SAAS,gBAAA,CAAiB;AAAA,EACxB,SAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,MAAA;AAAA,EACP,GAAG;AACL,CAAA,EAAwC;AACtC,EAAA,MAAM,EAAE,WAAA,EAAa,UAAA,EAAY,aAAA,KAAkB,WAAA,EAAY;AAE/D,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,mBAAA;AAAA,MACV,OAAA;AAAA,MACA,IAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,8BAAA;AAAA,QACA,WAAA,KAAgB,eACZ,mCAAA,GACA,6CAAA;AAAA,QACJ;AAAA,OACF;AAAA,MACA,UAAU,CAAC,aAAA;AAAA,MACX,OAAA,EAAS,UAAA;AAAA,MACR,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,SAAA,EAAA,EAAU,CAAA;AAAA,wBACX,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAU,QAAA,EAAA,gBAAA,EAAc;AAAA;AAAA;AAAA,GAC1C;AAEJ;AAGA,SAAS,YAAA,CAAa;AAAA,EACpB,SAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,MAAA;AAAA,EACP,GAAG;AACL,CAAA,EAAwC;AACtC,EAAA,MAAM,EAAE,WAAA,EAAa,UAAA,EAAY,aAAA,KAAkB,WAAA,EAAY;AAE/D,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,eAAA;AAAA,MACV,OAAA;AAAA,MACA,IAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,8BAAA;AAAA,QACA,WAAA,KAAgB,eACZ,oCAAA,GACA,gDAAA;AAAA,QACJ;AAAA,OACF;AAAA,MACA,UAAU,CAAC,aAAA;AAAA,MACX,OAAA,EAAS,UAAA;AAAA,MACR,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,CAAA;AAAA,wBACZ,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAU,QAAA,EAAA,YAAA,EAAU;AAAA;AAAA;AAAA,GACtC;AAEJ","file":"chunk-TX42RKQU.js","sourcesContent":["import * as React from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport { ArrowLeft, ArrowRight } from \"lucide-react\";\n\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\n\ntype CarouselApi = ReturnType<typeof useEmblaCarousel>[1];\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\ntype CarouselOptions = UseCarouselParameters[0];\ntype CarouselPlugin = UseCarouselParameters[1];\n\ntype CarouselProps = {\n /** Embla Carousel options (e.g., `{ loop: true, align: \"start\" }`). */\n opts?: CarouselOptions;\n /** Embla Carousel plugins (e.g., Autoplay, ClassNames). */\n plugins?: CarouselPlugin;\n /** Scroll axis direction. Defaults to `\"horizontal\"`. */\n orientation?: \"horizontal\" | \"vertical\";\n /** Callback to receive the Embla API instance for external control. */\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\n/** Returns the carousel context. Must be called within a `<Carousel>` provider. */\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\n/**\n * Carousel/slider component powered by Embla Carousel.\n *\n * Provides a context for child components (`CarouselContent`, `CarouselItem`,\n * `CarouselPrevious`, `CarouselNext`). Supports horizontal/vertical orientation,\n * keyboard navigation (arrow keys), and plugin extensibility.\n *\n * @example\n * ```tsx\n * <Carousel opts={{ loop: true }}>\n * <CarouselContent>\n * <CarouselItem>Slide 1</CarouselItem>\n * <CarouselItem>Slide 2</CarouselItem>\n * <CarouselItem>Slide 3</CarouselItem>\n * </CarouselContent>\n * <CarouselPrevious />\n * <CarouselNext />\n * </Carousel>\n * ```\n */\nfunction Carousel({\n orientation = \"horizontal\",\n opts,\n setApi,\n plugins,\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & CarouselProps) {\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) return;\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) return;\n setApi(api);\n }, [api, setApi]);\n\n React.useEffect(() => {\n if (!api) return;\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 onKeyDownCapture={handleKeyDown}\n className={cn(\"relative\", className)}\n role=\"region\"\n aria-roledescription=\"carousel\"\n data-slot=\"carousel\"\n {...props}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n );\n}\n\n/** Scrollable container for `CarouselItem` elements. Manages the overflow viewport. */\nfunction CarouselContent({ className, ...props }: React.ComponentProps<\"div\">) {\n const { carouselRef, orientation } = useCarousel();\n\n return (\n <div\n ref={carouselRef}\n className=\"overflow-hidden\"\n data-slot=\"carousel-content\"\n >\n <div\n className={cn(\n \"flex\",\n orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\",\n className,\n )}\n {...props}\n />\n </div>\n );\n}\n\n/** Individual slide within the carousel. Defaults to full-width (`basis-full`). */\nfunction CarouselItem({ className, ...props }: React.ComponentProps<\"div\">) {\n const { orientation } = useCarousel();\n\n return (\n <div\n role=\"group\"\n aria-roledescription=\"slide\"\n data-slot=\"carousel-item\"\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}\n\n/** Navigation button to scroll to the previous slide. Automatically disabled when at the beginning. */\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 data-slot=\"carousel-previous\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -left-12 -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 />\n <span className=\"sr-only\">Previous slide</span>\n </Button>\n );\n}\n\n/** Navigation button to scroll to the next slide. Automatically disabled when at the end. */\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 data-slot=\"carousel-next\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -right-12 -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 />\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/carousel.tsx"],"names":["api"],"mappings":"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","file":"chunk-2TUWDXAC.js","sourcesContent":["import * as React from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport { ArrowLeft, ArrowRight } from \"lucide-react\";\n\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\n\ntype CarouselApi = ReturnType<typeof useEmblaCarousel>[1];\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\ntype CarouselOptions = UseCarouselParameters[0];\ntype CarouselPlugin = UseCarouselParameters[1];\n\ntype CarouselProps = {\n /** Embla Carousel options (e.g., `{ loop: true, align: \"start\" }`). */\n opts?: CarouselOptions;\n /** Embla Carousel plugins (e.g., Autoplay, ClassNames). */\n plugins?: CarouselPlugin;\n /** Scroll axis direction. Defaults to `\"horizontal\"`. */\n orientation?: \"horizontal\" | \"vertical\";\n /** Callback to receive the Embla API instance for external control. */\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\n/** Returns the carousel context. Must be called within a `<Carousel>` provider. */\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\n/**\n * Carousel/slider component powered by Embla Carousel.\n *\n * Provides a context for child components (`CarouselContent`, `CarouselItem`,\n * `CarouselPrevious`, `CarouselNext`). Supports horizontal/vertical orientation,\n * keyboard navigation (arrow keys), and plugin extensibility.\n *\n * @example\n * ```tsx\n * <Carousel opts={{ loop: true }}>\n * <CarouselContent>\n * <CarouselItem>Slide 1</CarouselItem>\n * <CarouselItem>Slide 2</CarouselItem>\n * <CarouselItem>Slide 3</CarouselItem>\n * </CarouselContent>\n * <CarouselPrevious />\n * <CarouselNext />\n * </Carousel>\n * ```\n */\nfunction Carousel({\n orientation = \"horizontal\",\n opts,\n setApi,\n plugins,\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & CarouselProps) {\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) return;\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) return;\n setApi(api);\n }, [api, setApi]);\n\n React.useEffect(() => {\n if (!api) return;\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 onKeyDownCapture={handleKeyDown}\n className={cn(\"relative\", className)}\n role=\"region\"\n aria-roledescription=\"carousel\"\n data-slot=\"carousel\"\n {...props}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n );\n}\n\n/** Scrollable container for `CarouselItem` elements. Manages the overflow viewport. */\nfunction CarouselContent({ className, ...props }: React.ComponentProps<\"div\">) {\n const { carouselRef, orientation } = useCarousel();\n\n return (\n <div\n ref={carouselRef}\n className=\"overflow-hidden\"\n data-slot=\"carousel-content\"\n >\n <div\n className={cn(\n \"flex\",\n orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\",\n className,\n )}\n {...props}\n />\n </div>\n );\n}\n\n/** Individual slide within the carousel. Defaults to full-width (`basis-full`). */\nfunction CarouselItem({ className, ...props }: React.ComponentProps<\"div\">) {\n const { orientation } = useCarousel();\n\n return (\n <div\n role=\"group\"\n aria-roledescription=\"slide\"\n data-slot=\"carousel-item\"\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}\n\n/** Navigation button to scroll to the previous slide. Automatically disabled when at the beginning. */\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 data-slot=\"carousel-previous\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -left-12 -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 />\n <span className=\"sr-only\">Previous slide</span>\n </Button>\n );\n}\n\n/** Navigation button to scroll to the next slide. Automatically disabled when at the end. */\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 data-slot=\"carousel-next\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -right-12 -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 />\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"]}
@@ -81,7 +81,7 @@ function Rating({
81
81
  {
82
82
  className: cn(
83
83
  sizeClasses[size],
84
- "text-gray-300"
84
+ "text-muted-foreground/40"
85
85
  )
86
86
  }
87
87
  ),
@@ -99,7 +99,7 @@ function Rating({
99
99
  {
100
100
  className: cn(
101
101
  sizeClasses[size],
102
- fill === "full" ? "text-yellow-400 fill-yellow-400" : "text-gray-300"
102
+ fill === "full" ? "text-yellow-400 fill-yellow-400" : "text-muted-foreground/40"
103
103
  )
104
104
  }
105
105
  )
@@ -107,10 +107,10 @@ function Rating({
107
107
  index
108
108
  );
109
109
  }),
110
- value > 0 && /* @__PURE__ */ jsx("span", { className: "ml-2 text-sm text-gray-600", children: value.toFixed(allowHalf ? 1 : 0) })
110
+ value > 0 && /* @__PURE__ */ jsx("span", { className: "ml-2 text-sm text-muted-foreground", children: value.toFixed(allowHalf ? 1 : 0) })
111
111
  ] });
112
112
  }
113
113
 
114
114
  export { Rating };
115
- //# sourceMappingURL=chunk-HY4FVDA4.js.map
116
- //# sourceMappingURL=chunk-HY4FVDA4.js.map
115
+ //# sourceMappingURL=chunk-35U6QG4P.js.map
116
+ //# sourceMappingURL=chunk-35U6QG4P.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/rating.tsx"],"names":[],"mappings":"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","file":"chunk-HY4FVDA4.js","sourcesContent":["import * as React from \"react\";\nimport { Star } from \"lucide-react\";\nimport { cn } from \"../lib/utils\";\n\ninterface RatingProps {\n /** Current rating value (e.g., `3` or `3.5` with half stars). */\n value?: number;\n /** Callback fired when the user clicks a star. Receives the new rating number. */\n onChange?: (value: number) => void;\n /** Maximum number of stars. Defaults to `5`. */\n max?: number;\n /** Size of the star icons. Defaults to `\"md\"`. */\n size?: \"sm\" | \"md\" | \"lg\";\n /** Whether the rating is display-only (non-interactive). Defaults to `false`. */\n readonly?: boolean;\n /** Whether half-star ratings are enabled. Defaults to `false`. */\n allowHalf?: boolean;\n /** Additional CSS class for the outer container. */\n className?: string;\n}\n\n/**\n * Star rating component with hover preview and optional half-star support.\n * Shows filled/empty/half star icons and displays the numeric value beside the stars.\n *\n * @example\n * ```tsx\n * const [rating, setRating] = useState(0);\n *\n * <Rating value={rating} onChange={setRating} max={5} />\n *\n * // Read-only display with half stars:\n * <Rating value={3.5} readonly allowHalf />\n * ```\n */\nexport function Rating({\n value = 0,\n onChange,\n max = 5,\n size = \"md\",\n readonly = false,\n allowHalf = false,\n className,\n}: RatingProps) {\n const [hoverValue, setHoverValue] = React.useState<number | null>(null);\n\n const sizeClasses = {\n sm: \"w-4 h-4\",\n md: \"w-5 h-5\",\n lg: \"w-6 h-6\",\n };\n\n const handleClick = (index: number, isHalf: boolean) => {\n if (readonly) return;\n const newValue = isHalf ? index + 0.5 : index + 1;\n onChange?.(newValue);\n };\n\n const handleMouseMove = (index: number, e: React.MouseEvent<HTMLButtonElement>) => {\n if (readonly || !allowHalf) return;\n\n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const isHalf = x < rect.width / 2;\n\n setHoverValue(isHalf ? index + 0.5 : index + 1);\n };\n\n const handleMouseEnter = (index: number) => {\n if (readonly) return;\n if (!allowHalf) {\n setHoverValue(index + 1);\n }\n };\n\n const handleMouseLeave = () => {\n setHoverValue(null);\n };\n\n const getStarFill = (index: number) => {\n const currentValue = hoverValue !== null ? hoverValue : value;\n\n if (currentValue >= index + 1) {\n return \"full\";\n } else if (allowHalf && currentValue >= index + 0.5) {\n return \"half\";\n } else {\n return \"empty\";\n }\n };\n\n return (\n <div className={cn(\"flex items-center gap-1\", className)}>\n {Array.from({ length: max }).map((_, index) => {\n const fill = getStarFill(index);\n\n return (\n <button\n key={index}\n type=\"button\"\n onClick={(e) => {\n if (!allowHalf) {\n handleClick(index, false);\n return;\n }\n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const isHalf = x < rect.width / 2;\n handleClick(index, isHalf);\n }}\n onMouseMove={(e) => handleMouseMove(index, e)}\n onMouseEnter={() => handleMouseEnter(index)}\n onMouseLeave={handleMouseLeave}\n disabled={readonly}\n className={cn(\n \"relative transition-transform hover:scale-110\",\n !readonly && \"cursor-pointer\",\n readonly && \"cursor-default\"\n )}\n >\n {fill === \"half\" ? (\n <div className=\"relative\">\n <Star\n className={cn(\n sizeClasses[size],\n \"text-gray-300\"\n )}\n />\n <div className=\"absolute inset-0 overflow-hidden w-1/2\">\n <Star\n className={cn(\n sizeClasses[size],\n \"text-yellow-400 fill-yellow-400\"\n )}\n />\n </div>\n </div>\n ) : (\n <Star\n className={cn(\n sizeClasses[size],\n fill === \"full\"\n ? \"text-yellow-400 fill-yellow-400\"\n : \"text-gray-300\"\n )}\n />\n )}\n </button>\n );\n })}\n\n {value > 0 && (\n <span className=\"ml-2 text-sm text-gray-600\">\n {value.toFixed(allowHalf ? 1 : 0)}\n </span>\n )}\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/rating.tsx"],"names":[],"mappings":"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","file":"chunk-35U6QG4P.js","sourcesContent":["import * as React from \"react\";\nimport { Star } from \"lucide-react\";\nimport { cn } from \"../lib/utils\";\n\ninterface RatingProps {\n /** Current rating value (e.g., `3` or `3.5` with half stars). */\n value?: number;\n /** Callback fired when the user clicks a star. Receives the new rating number. */\n onChange?: (value: number) => void;\n /** Maximum number of stars. Defaults to `5`. */\n max?: number;\n /** Size of the star icons. Defaults to `\"md\"`. */\n size?: \"sm\" | \"md\" | \"lg\";\n /** Whether the rating is display-only (non-interactive). Defaults to `false`. */\n readonly?: boolean;\n /** Whether half-star ratings are enabled. Defaults to `false`. */\n allowHalf?: boolean;\n /** Additional CSS class for the outer container. */\n className?: string;\n}\n\n/**\n * Star rating component with hover preview and optional half-star support.\n * Shows filled/empty/half star icons and displays the numeric value beside the stars.\n *\n * @example\n * ```tsx\n * const [rating, setRating] = useState(0);\n *\n * <Rating value={rating} onChange={setRating} max={5} />\n *\n * // Read-only display with half stars:\n * <Rating value={3.5} readonly allowHalf />\n * ```\n */\nexport function Rating({\n value = 0,\n onChange,\n max = 5,\n size = \"md\",\n readonly = false,\n allowHalf = false,\n className,\n}: RatingProps) {\n const [hoverValue, setHoverValue] = React.useState<number | null>(null);\n\n const sizeClasses = {\n sm: \"w-4 h-4\",\n md: \"w-5 h-5\",\n lg: \"w-6 h-6\",\n };\n\n const handleClick = (index: number, isHalf: boolean) => {\n if (readonly) return;\n const newValue = isHalf ? index + 0.5 : index + 1;\n onChange?.(newValue);\n };\n\n const handleMouseMove = (index: number, e: React.MouseEvent<HTMLButtonElement>) => {\n if (readonly || !allowHalf) return;\n\n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const isHalf = x < rect.width / 2;\n\n setHoverValue(isHalf ? index + 0.5 : index + 1);\n };\n\n const handleMouseEnter = (index: number) => {\n if (readonly) return;\n if (!allowHalf) {\n setHoverValue(index + 1);\n }\n };\n\n const handleMouseLeave = () => {\n setHoverValue(null);\n };\n\n const getStarFill = (index: number) => {\n const currentValue = hoverValue !== null ? hoverValue : value;\n\n if (currentValue >= index + 1) {\n return \"full\";\n } else if (allowHalf && currentValue >= index + 0.5) {\n return \"half\";\n } else {\n return \"empty\";\n }\n };\n\n return (\n <div className={cn(\"flex items-center gap-1\", className)}>\n {Array.from({ length: max }).map((_, index) => {\n const fill = getStarFill(index);\n\n return (\n <button\n key={index}\n type=\"button\"\n onClick={(e) => {\n if (!allowHalf) {\n handleClick(index, false);\n return;\n }\n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const isHalf = x < rect.width / 2;\n handleClick(index, isHalf);\n }}\n onMouseMove={(e) => handleMouseMove(index, e)}\n onMouseEnter={() => handleMouseEnter(index)}\n onMouseLeave={handleMouseLeave}\n disabled={readonly}\n className={cn(\n \"relative transition-transform hover:scale-110\",\n !readonly && \"cursor-pointer\",\n readonly && \"cursor-default\"\n )}\n >\n {fill === \"half\" ? (\n <div className=\"relative\">\n <Star\n className={cn(\n sizeClasses[size],\n \"text-muted-foreground/40\"\n )}\n />\n <div className=\"absolute inset-0 overflow-hidden w-1/2\">\n <Star\n className={cn(\n sizeClasses[size],\n \"text-yellow-400 fill-yellow-400\"\n )}\n />\n </div>\n </div>\n ) : (\n <Star\n className={cn(\n sizeClasses[size],\n fill === \"full\"\n ? \"text-yellow-400 fill-yellow-400\"\n : \"text-muted-foreground/40\"\n )}\n />\n )}\n </button>\n );\n })}\n\n {value > 0 && (\n <span className=\"ml-2 text-sm text-muted-foreground\">\n {value.toFixed(allowHalf ? 1 : 0)}\n </span>\n )}\n </div>\n );\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { ToggleGroup, ToggleGroupItem } from './chunk-ZPMXRW2A.js';
2
- import { Button } from './chunk-Y65FNGEE.js';
2
+ import { Button } from './chunk-55E7D2HR.js';
3
3
  import { format } from 'date-fns';
4
4
  import { ChevronLeft, ChevronRight, Plus } from 'lucide-react';
5
5
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -48,5 +48,5 @@ function CalendarToolbar({
48
48
  }
49
49
 
50
50
  export { CalendarToolbar };
51
- //# sourceMappingURL=chunk-YT3W2URB.js.map
52
- //# sourceMappingURL=chunk-YT3W2URB.js.map
51
+ //# sourceMappingURL=chunk-36YYHIJU.js.map
52
+ //# sourceMappingURL=chunk-36YYHIJU.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/calendar-toolbar.tsx"],"names":[],"mappings":";;;;;;AAsBA,IAAM,aAAA,GAAiD;AAAA,EACrD,KAAA,EAAO,OAAA;AAAA,EACP,KAAA,EAAO,OAAA;AAAA,EACP,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,WAAA,EAAa;AACf,CAAA;AAyCO,SAAS,eAAA,CAAgB;AAAA,EAC9B,WAAA;AAAA,EACA,IAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA;AAAA,EACA,MAAA,EAAQ,UAAA;AAAA,EACR,WAAA,EAAa;AACf,CAAA,EAAyB;AACvB,EAAA,MAAM,MAAA,GAAS,EAAE,GAAG,aAAA,EAAe,GAAG,UAAA,EAAW;AAEjD,EAAA,MAAM,WAAA,GAAc,eAAA,KAAoB,IAAA,KAAS,KAAA,GAC7C,oBAAA,GACA,WAAA,CAAA;AAEJ,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mDAAA,EACb,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EACb,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,SAAQ,SAAA,EAAU,IAAA,EAAK,MAAK,OAAA,EAAS,OAAA,EAC1C,iBAAO,KAAA,EACV,CAAA;AAAA,sBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mBAAA,EACb,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,OAAA,EAAQ,IAAA,EAAK,MAAA,EAAO,SAAA,EAAU,SAAA,EAAU,OAAA,EAAS,MAAA,EAC/D,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAU,WAAU,CAAA,EACnC,CAAA;AAAA,wBACA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,OAAA,EAAQ,MAAK,MAAA,EAAO,SAAA,EAAU,SAAA,EAAU,OAAA,EAAS,MAAA,EAC/D,QAAA,kBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAU,WAAU,CAAA,EACpC;AAAA,OAAA,EACF,CAAA;AAAA,0BACC,IAAA,EAAA,EAAG,SAAA,EAAU,yBAAyB,QAAA,EAAA,MAAA,CAAO,WAAA,EAAa,WAAW,CAAA,EAAE;AAAA,KAAA,EAC1E,CAAA;AAAA,oBAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,WAAA,EAAA,EAAY,IAAA,EAAK,QAAA,EAAS,KAAA,EAAO,IAAA,EAAM,eAAe,CAAA,GAAA,KAAO,GAAA,IAAO,YAAA,CAAa,GAAmB,CAAA,EACnG,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,mBAAgB,KAAA,EAAM,OAAA,EAAQ,IAAA,EAAK,IAAA,EAAM,iBAAO,KAAA,EAAM,CAAA;AAAA,4BACtD,eAAA,EAAA,EAAgB,KAAA,EAAM,QAAO,IAAA,EAAK,IAAA,EAAM,iBAAO,IAAA,EAAK,CAAA;AAAA,4BACpD,eAAA,EAAA,EAAgB,KAAA,EAAM,OAAM,IAAA,EAAK,IAAA,EAAM,iBAAO,GAAA,EAAI;AAAA,OAAA,EACrD,CAAA;AAAA,MACC,iCACC,IAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAK,IAAA,EAAK,SAAS,aAAA,EACzB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,SAAA,EAAU,CAAA;AAAA,QACzB,MAAA,CAAO;AAAA,OAAA,EACV;AAAA,KAAA,EAEJ;AAAA,GAAA,EACF,CAAA;AAEJ","file":"chunk-YT3W2URB.js","sourcesContent":["import { format } from 'date-fns';\nimport { ChevronLeft, ChevronRight, Plus } from 'lucide-react';\nimport { Button } from './button';\nimport { ToggleGroup, ToggleGroupItem } from './toggle-group';\n\n/** Supported calendar view modes. */\nexport type CalendarView = 'month' | 'week' | 'day';\n\n/** Localizable labels for the calendar toolbar. All have English defaults. */\nexport interface CalendarToolbarLabels {\n /** Label for the \"Today\" button. */\n today?: string;\n /** Label for the \"Month\" view toggle. */\n month?: string;\n /** Label for the \"Week\" view toggle. */\n week?: string;\n /** Label for the \"Day\" view toggle. */\n day?: string;\n /** Label for the \"Create Event\" button. */\n createEvent?: string;\n}\n\nconst defaultLabels: Required<CalendarToolbarLabels> = {\n today: 'Today',\n month: 'Month',\n week: 'Week',\n day: 'Day',\n createEvent: 'Create Event',\n};\n\nexport interface CalendarToolbarProps {\n /** The date currently being viewed. Used for the title display. */\n currentDate: Date;\n /** The active calendar view mode. */\n view: CalendarView;\n /** Callback when the user switches between month/week/day views. */\n onViewChange: (view: CalendarView) => void;\n /** Navigate to the previous period. */\n onPrev: () => void;\n /** Navigate to the next period. */\n onNext: () => void;\n /** Navigate to today. */\n onToday: () => void;\n /** Optional callback for the \"Create Event\" button. Button is hidden when omitted. */\n onCreateEvent?: () => void;\n /** Localizable UI labels with English defaults. */\n labels?: CalendarToolbarLabels;\n /** date-fns format string for the title. Defaults to `\"MMMM yyyy\"` or `\"EEEE, MMMM d, yyyy\"` for day view. */\n titleFormat?: string;\n}\n\n/**\n * Toolbar for calendar views with navigation controls (prev/next/today),\n * view mode toggle (month/week/day), and an optional \"Create Event\" button.\n * Locale-agnostic via the `labels` prop.\n *\n * @example\n * ```tsx\n * <CalendarToolbar\n * currentDate={currentDate}\n * view=\"month\"\n * onViewChange={setView}\n * onPrev={handlePrev}\n * onNext={handleNext}\n * onToday={handleToday}\n * onCreateEvent={() => setDialogOpen(true)}\n * />\n * ```\n */\nexport function CalendarToolbar({\n currentDate,\n view,\n onViewChange,\n onPrev,\n onNext,\n onToday,\n onCreateEvent,\n labels: labelsProp,\n titleFormat: titleFormatProp,\n}: CalendarToolbarProps) {\n const labels = { ...defaultLabels, ...labelsProp };\n\n const titleFormat = titleFormatProp ?? (view === 'day'\n ? 'EEEE, MMMM d, yyyy'\n : 'MMMM yyyy');\n\n return (\n <div className=\"flex items-center justify-between gap-4 flex-wrap\">\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={onToday}>\n {labels.today}\n </Button>\n <div className=\"flex items-center\">\n <Button variant=\"ghost\" size=\"icon\" className=\"w-8 h-8\" onClick={onPrev}>\n <ChevronLeft className=\"w-4 h-4\" />\n </Button>\n <Button variant=\"ghost\" size=\"icon\" className=\"w-8 h-8\" onClick={onNext}>\n <ChevronRight className=\"w-4 h-4\" />\n </Button>\n </div>\n <h2 className=\"text-lg font-semibold\">{format(currentDate, titleFormat)}</h2>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <ToggleGroup type=\"single\" value={view} onValueChange={val => val && onViewChange(val as CalendarView)}>\n <ToggleGroupItem value=\"month\" size=\"sm\">{labels.month}</ToggleGroupItem>\n <ToggleGroupItem value=\"week\" size=\"sm\">{labels.week}</ToggleGroupItem>\n <ToggleGroupItem value=\"day\" size=\"sm\">{labels.day}</ToggleGroupItem>\n </ToggleGroup>\n {onCreateEvent && (\n <Button size=\"sm\" onClick={onCreateEvent}>\n <Plus className=\"w-4 h-4\" />\n {labels.createEvent}\n </Button>\n )}\n </div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/calendar-toolbar.tsx"],"names":[],"mappings":";;;;;;AAsBA,IAAM,aAAA,GAAiD;AAAA,EACrD,KAAA,EAAO,OAAA;AAAA,EACP,KAAA,EAAO,OAAA;AAAA,EACP,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,WAAA,EAAa;AACf,CAAA;AAyCO,SAAS,eAAA,CAAgB;AAAA,EAC9B,WAAA;AAAA,EACA,IAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA;AAAA,EACA,MAAA,EAAQ,UAAA;AAAA,EACR,WAAA,EAAa;AACf,CAAA,EAAyB;AACvB,EAAA,MAAM,MAAA,GAAS,EAAE,GAAG,aAAA,EAAe,GAAG,UAAA,EAAW;AAEjD,EAAA,MAAM,WAAA,GAAc,eAAA,KAAoB,IAAA,KAAS,KAAA,GAC7C,oBAAA,GACA,WAAA,CAAA;AAEJ,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mDAAA,EACb,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EACb,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,SAAQ,SAAA,EAAU,IAAA,EAAK,MAAK,OAAA,EAAS,OAAA,EAC1C,iBAAO,KAAA,EACV,CAAA;AAAA,sBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mBAAA,EACb,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,OAAA,EAAQ,IAAA,EAAK,MAAA,EAAO,SAAA,EAAU,SAAA,EAAU,OAAA,EAAS,MAAA,EAC/D,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAU,WAAU,CAAA,EACnC,CAAA;AAAA,wBACA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,OAAA,EAAQ,MAAK,MAAA,EAAO,SAAA,EAAU,SAAA,EAAU,OAAA,EAAS,MAAA,EAC/D,QAAA,kBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAU,WAAU,CAAA,EACpC;AAAA,OAAA,EACF,CAAA;AAAA,0BACC,IAAA,EAAA,EAAG,SAAA,EAAU,yBAAyB,QAAA,EAAA,MAAA,CAAO,WAAA,EAAa,WAAW,CAAA,EAAE;AAAA,KAAA,EAC1E,CAAA;AAAA,oBAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,WAAA,EAAA,EAAY,IAAA,EAAK,QAAA,EAAS,KAAA,EAAO,IAAA,EAAM,eAAe,CAAA,GAAA,KAAO,GAAA,IAAO,YAAA,CAAa,GAAmB,CAAA,EACnG,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,mBAAgB,KAAA,EAAM,OAAA,EAAQ,IAAA,EAAK,IAAA,EAAM,iBAAO,KAAA,EAAM,CAAA;AAAA,4BACtD,eAAA,EAAA,EAAgB,KAAA,EAAM,QAAO,IAAA,EAAK,IAAA,EAAM,iBAAO,IAAA,EAAK,CAAA;AAAA,4BACpD,eAAA,EAAA,EAAgB,KAAA,EAAM,OAAM,IAAA,EAAK,IAAA,EAAM,iBAAO,GAAA,EAAI;AAAA,OAAA,EACrD,CAAA;AAAA,MACC,iCACC,IAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAK,IAAA,EAAK,SAAS,aAAA,EACzB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,SAAA,EAAU,CAAA;AAAA,QACzB,MAAA,CAAO;AAAA,OAAA,EACV;AAAA,KAAA,EAEJ;AAAA,GAAA,EACF,CAAA;AAEJ","file":"chunk-36YYHIJU.js","sourcesContent":["import { format } from 'date-fns';\nimport { ChevronLeft, ChevronRight, Plus } from 'lucide-react';\nimport { Button } from './button';\nimport { ToggleGroup, ToggleGroupItem } from './toggle-group';\n\n/** Supported calendar view modes. */\nexport type CalendarView = 'month' | 'week' | 'day';\n\n/** Localizable labels for the calendar toolbar. All have English defaults. */\nexport interface CalendarToolbarLabels {\n /** Label for the \"Today\" button. */\n today?: string;\n /** Label for the \"Month\" view toggle. */\n month?: string;\n /** Label for the \"Week\" view toggle. */\n week?: string;\n /** Label for the \"Day\" view toggle. */\n day?: string;\n /** Label for the \"Create Event\" button. */\n createEvent?: string;\n}\n\nconst defaultLabels: Required<CalendarToolbarLabels> = {\n today: 'Today',\n month: 'Month',\n week: 'Week',\n day: 'Day',\n createEvent: 'Create Event',\n};\n\nexport interface CalendarToolbarProps {\n /** The date currently being viewed. Used for the title display. */\n currentDate: Date;\n /** The active calendar view mode. */\n view: CalendarView;\n /** Callback when the user switches between month/week/day views. */\n onViewChange: (view: CalendarView) => void;\n /** Navigate to the previous period. */\n onPrev: () => void;\n /** Navigate to the next period. */\n onNext: () => void;\n /** Navigate to today. */\n onToday: () => void;\n /** Optional callback for the \"Create Event\" button. Button is hidden when omitted. */\n onCreateEvent?: () => void;\n /** Localizable UI labels with English defaults. */\n labels?: CalendarToolbarLabels;\n /** date-fns format string for the title. Defaults to `\"MMMM yyyy\"` or `\"EEEE, MMMM d, yyyy\"` for day view. */\n titleFormat?: string;\n}\n\n/**\n * Toolbar for calendar views with navigation controls (prev/next/today),\n * view mode toggle (month/week/day), and an optional \"Create Event\" button.\n * Locale-agnostic via the `labels` prop.\n *\n * @example\n * ```tsx\n * <CalendarToolbar\n * currentDate={currentDate}\n * view=\"month\"\n * onViewChange={setView}\n * onPrev={handlePrev}\n * onNext={handleNext}\n * onToday={handleToday}\n * onCreateEvent={() => setDialogOpen(true)}\n * />\n * ```\n */\nexport function CalendarToolbar({\n currentDate,\n view,\n onViewChange,\n onPrev,\n onNext,\n onToday,\n onCreateEvent,\n labels: labelsProp,\n titleFormat: titleFormatProp,\n}: CalendarToolbarProps) {\n const labels = { ...defaultLabels, ...labelsProp };\n\n const titleFormat = titleFormatProp ?? (view === 'day'\n ? 'EEEE, MMMM d, yyyy'\n : 'MMMM yyyy');\n\n return (\n <div className=\"flex items-center justify-between gap-4 flex-wrap\">\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={onToday}>\n {labels.today}\n </Button>\n <div className=\"flex items-center\">\n <Button variant=\"ghost\" size=\"icon\" className=\"w-8 h-8\" onClick={onPrev}>\n <ChevronLeft className=\"w-4 h-4\" />\n </Button>\n <Button variant=\"ghost\" size=\"icon\" className=\"w-8 h-8\" onClick={onNext}>\n <ChevronRight className=\"w-4 h-4\" />\n </Button>\n </div>\n <h2 className=\"text-lg font-semibold\">{format(currentDate, titleFormat)}</h2>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <ToggleGroup type=\"single\" value={view} onValueChange={val => val && onViewChange(val as CalendarView)}>\n <ToggleGroupItem value=\"month\" size=\"sm\">{labels.month}</ToggleGroupItem>\n <ToggleGroupItem value=\"week\" size=\"sm\">{labels.week}</ToggleGroupItem>\n <ToggleGroupItem value=\"day\" size=\"sm\">{labels.day}</ToggleGroupItem>\n </ToggleGroup>\n {onCreateEvent && (\n <Button size=\"sm\" onClick={onCreateEvent}>\n <Plus className=\"w-4 h-4\" />\n {labels.createEvent}\n </Button>\n )}\n </div>\n </div>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { buttonVariants } from './chunk-Y65FNGEE.js';
1
+ import { buttonVariants } from './chunk-55E7D2HR.js';
2
2
  import { cn } from './chunk-DGPY4WP3.js';
3
3
  import { ChevronRightIcon, ChevronLeftIcon } from 'lucide-react';
4
4
  import { DayPicker } from 'react-day-picker';
@@ -59,5 +59,5 @@ function Calendar({
59
59
  }
60
60
 
61
61
  export { Calendar };
62
- //# sourceMappingURL=chunk-33DTBAFF.js.map
63
- //# sourceMappingURL=chunk-33DTBAFF.js.map
62
+ //# sourceMappingURL=chunk-4MHIUUAW.js.map
63
+ //# sourceMappingURL=chunk-4MHIUUAW.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/calendar.tsx"],"names":["className","props"],"mappings":";;;;;;AAmBA,SAAS,QAAA,CAAS;AAAA,EAChB,SAAA;AAAA,EACA,UAAA;AAAA,EACA,eAAA,GAAkB,IAAA;AAAA,EAClB,GAAG;AACL,CAAA,EAA2C;AACzC,EAAA,uBACE,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,eAAA;AAAA,MACA,SAAA,EAAW,EAAA,CAAG,KAAA,EAAO,SAAS,CAAA;AAAA,MAC9B,UAAA,EAAY;AAAA,QACV,MAAA,EAAQ,iCAAA;AAAA,QACR,KAAA,EAAO,qBAAA;AAAA,QACP,OAAA,EAAS,uDAAA;AAAA,QACT,aAAA,EAAe,qBAAA;AAAA,QACf,GAAA,EAAK,yBAAA;AAAA,QACL,UAAA,EAAY,EAAA;AAAA,UACV,cAAA,CAAe,EAAE,OAAA,EAAS,SAAA,EAAW,CAAA;AAAA,UACrC;AAAA,SACF;AAAA,QACA,mBAAA,EAAqB,iBAAA;AAAA,QACrB,eAAA,EAAiB,kBAAA;AAAA,QACjB,KAAA,EAAO,kCAAA;AAAA,QACP,QAAA,EAAU,MAAA;AAAA,QACV,SAAA,EACE,gEAAA;AAAA,QACF,GAAA,EAAK,kBAAA;AAAA,QACL,IAAA,EAAM,EAAA;AAAA,UACJ,iKAAA;AAAA,UACA,KAAA,CAAM,IAAA,KAAS,OAAA,GACX,sKAAA,GACA;AAAA,SACN;AAAA,QACA,GAAA,EAAK,EAAA;AAAA,UACH,cAAA,CAAe,EAAE,OAAA,EAAS,OAAA,EAAS,CAAA;AAAA,UACnC;AAAA,SACF;AAAA,QACA,eAAA,EACE,gFAAA;AAAA,QACF,aAAA,EACE,8EAAA;AAAA,QACF,YAAA,EACE,kIAAA;AAAA,QACF,SAAA,EAAW,kCAAA;AAAA,QACX,WAAA,EACE,uEAAA;AAAA,QACF,YAAA,EAAc,kCAAA;AAAA,QACd,gBAAA,EACE,8DAAA;AAAA,QACF,UAAA,EAAY,WAAA;AAAA,QACZ,GAAG;AAAA,OACL;AAAA,MACA,UAAA,EAAY;AAAA,QACV,UAAU,CAAC,EAAE,SAAA,EAAAA,UAAAA,EAAW,GAAGC,MAAAA,EAAM,qBAC/B,GAAA,CAAC,eAAA,EAAA,EAAgB,WAAW,EAAA,CAAG,QAAA,EAAUD,UAAS,CAAA,EAAI,GAAGC,MAAAA,EAAO,CAAA;AAAA,QAElE,WAAW,CAAC,EAAE,SAAA,EAAAD,UAAAA,EAAW,GAAGC,MAAAA,EAAM,qBAChC,GAAA,CAAC,gBAAA,EAAA,EAAiB,WAAW,EAAA,CAAG,QAAA,EAAUD,UAAS,CAAA,EAAI,GAAGC,MAAAA,EAAO;AAAA,OAErE;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-33DTBAFF.js","sourcesContent":["import * as React from \"react\";\nimport { ChevronLeftIcon, ChevronRightIcon } from \"lucide-react\";\nimport { DayPicker } from \"react-day-picker\";\n\nimport { cn } from \"../lib/utils\";\nimport { buttonVariants } from \"./button\";\n\n/**\n * Date picker calendar built on `react-day-picker`. Supports single, multiple,\n * and range selection modes. Styled with Shadcn UI conventions.\n *\n * @param showOutsideDays - Whether to show days from adjacent months. Defaults to `true`.\n *\n * @example\n * ```tsx\n * const [date, setDate] = useState<Date | undefined>();\n * <Calendar mode=\"single\" selected={date} onSelect={setDate} />\n * ```\n */\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: React.ComponentProps<typeof DayPicker>) {\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\"p-3\", className)}\n classNames={{\n months: \"flex flex-col sm:flex-row gap-2\",\n month: \"flex flex-col gap-4\",\n caption: \"flex justify-center pt-1 relative items-center w-full\",\n caption_label: \"text-sm font-medium\",\n nav: \"flex items-center gap-1\",\n nav_button: cn(\n buttonVariants({ variant: \"outline\" }),\n \"size-7 bg-transparent p-0 opacity-50 hover:opacity-100\",\n ),\n nav_button_previous: \"absolute left-1\",\n nav_button_next: \"absolute right-1\",\n table: \"w-full border-collapse space-x-1\",\n head_row: \"flex\",\n head_cell:\n \"text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]\",\n row: \"flex w-full mt-2\",\n cell: cn(\n \"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-range-end)]:rounded-r-md\",\n props.mode === \"range\"\n ? \"[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md\"\n : \"[&:has([aria-selected])]:rounded-md\",\n ),\n day: cn(\n buttonVariants({ variant: \"ghost\" }),\n \"size-8 p-0 font-normal aria-selected:opacity-100\",\n ),\n day_range_start:\n \"day-range-start aria-selected:bg-primary aria-selected:text-primary-foreground\",\n day_range_end:\n \"day-range-end aria-selected:bg-primary aria-selected:text-primary-foreground\",\n day_selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground\",\n day_today: \"bg-accent text-accent-foreground\",\n day_outside:\n \"day-outside text-muted-foreground aria-selected:text-muted-foreground\",\n day_disabled: \"text-muted-foreground opacity-50\",\n day_range_middle:\n \"aria-selected:bg-accent aria-selected:text-accent-foreground\",\n day_hidden: \"invisible\",\n ...classNames,\n }}\n components={{\n IconLeft: ({ className, ...props }) => (\n <ChevronLeftIcon className={cn(\"size-4\", className)} {...props} />\n ),\n IconRight: ({ className, ...props }) => (\n <ChevronRightIcon className={cn(\"size-4\", className)} {...props} />\n ),\n }}\n {...props}\n />\n );\n}\n\nexport { Calendar };"]}
1
+ {"version":3,"sources":["../src/components/calendar.tsx"],"names":["className","props"],"mappings":";;;;;;AAmBA,SAAS,QAAA,CAAS;AAAA,EAChB,SAAA;AAAA,EACA,UAAA;AAAA,EACA,eAAA,GAAkB,IAAA;AAAA,EAClB,GAAG;AACL,CAAA,EAA2C;AACzC,EAAA,uBACE,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,eAAA;AAAA,MACA,SAAA,EAAW,EAAA,CAAG,KAAA,EAAO,SAAS,CAAA;AAAA,MAC9B,UAAA,EAAY;AAAA,QACV,MAAA,EAAQ,iCAAA;AAAA,QACR,KAAA,EAAO,qBAAA;AAAA,QACP,OAAA,EAAS,uDAAA;AAAA,QACT,aAAA,EAAe,qBAAA;AAAA,QACf,GAAA,EAAK,yBAAA;AAAA,QACL,UAAA,EAAY,EAAA;AAAA,UACV,cAAA,CAAe,EAAE,OAAA,EAAS,SAAA,EAAW,CAAA;AAAA,UACrC;AAAA,SACF;AAAA,QACA,mBAAA,EAAqB,iBAAA;AAAA,QACrB,eAAA,EAAiB,kBAAA;AAAA,QACjB,KAAA,EAAO,kCAAA;AAAA,QACP,QAAA,EAAU,MAAA;AAAA,QACV,SAAA,EACE,gEAAA;AAAA,QACF,GAAA,EAAK,kBAAA;AAAA,QACL,IAAA,EAAM,EAAA;AAAA,UACJ,iKAAA;AAAA,UACA,KAAA,CAAM,IAAA,KAAS,OAAA,GACX,sKAAA,GACA;AAAA,SACN;AAAA,QACA,GAAA,EAAK,EAAA;AAAA,UACH,cAAA,CAAe,EAAE,OAAA,EAAS,OAAA,EAAS,CAAA;AAAA,UACnC;AAAA,SACF;AAAA,QACA,eAAA,EACE,gFAAA;AAAA,QACF,aAAA,EACE,8EAAA;AAAA,QACF,YAAA,EACE,kIAAA;AAAA,QACF,SAAA,EAAW,kCAAA;AAAA,QACX,WAAA,EACE,uEAAA;AAAA,QACF,YAAA,EAAc,kCAAA;AAAA,QACd,gBAAA,EACE,8DAAA;AAAA,QACF,UAAA,EAAY,WAAA;AAAA,QACZ,GAAG;AAAA,OACL;AAAA,MACA,UAAA,EAAY;AAAA,QACV,UAAU,CAAC,EAAE,SAAA,EAAAA,UAAAA,EAAW,GAAGC,MAAAA,EAAM,qBAC/B,GAAA,CAAC,eAAA,EAAA,EAAgB,WAAW,EAAA,CAAG,QAAA,EAAUD,UAAS,CAAA,EAAI,GAAGC,MAAAA,EAAO,CAAA;AAAA,QAElE,WAAW,CAAC,EAAE,SAAA,EAAAD,UAAAA,EAAW,GAAGC,MAAAA,EAAM,qBAChC,GAAA,CAAC,gBAAA,EAAA,EAAiB,WAAW,EAAA,CAAG,QAAA,EAAUD,UAAS,CAAA,EAAI,GAAGC,MAAAA,EAAO;AAAA,OAErE;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-4MHIUUAW.js","sourcesContent":["import * as React from \"react\";\nimport { ChevronLeftIcon, ChevronRightIcon } from \"lucide-react\";\nimport { DayPicker } from \"react-day-picker\";\n\nimport { cn } from \"../lib/utils\";\nimport { buttonVariants } from \"./button\";\n\n/**\n * Date picker calendar built on `react-day-picker`. Supports single, multiple,\n * and range selection modes. Styled with Shadcn UI conventions.\n *\n * @param showOutsideDays - Whether to show days from adjacent months. Defaults to `true`.\n *\n * @example\n * ```tsx\n * const [date, setDate] = useState<Date | undefined>();\n * <Calendar mode=\"single\" selected={date} onSelect={setDate} />\n * ```\n */\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: React.ComponentProps<typeof DayPicker>) {\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\"p-3\", className)}\n classNames={{\n months: \"flex flex-col sm:flex-row gap-2\",\n month: \"flex flex-col gap-4\",\n caption: \"flex justify-center pt-1 relative items-center w-full\",\n caption_label: \"text-sm font-medium\",\n nav: \"flex items-center gap-1\",\n nav_button: cn(\n buttonVariants({ variant: \"outline\" }),\n \"size-7 bg-transparent p-0 opacity-50 hover:opacity-100\",\n ),\n nav_button_previous: \"absolute left-1\",\n nav_button_next: \"absolute right-1\",\n table: \"w-full border-collapse space-x-1\",\n head_row: \"flex\",\n head_cell:\n \"text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]\",\n row: \"flex w-full mt-2\",\n cell: cn(\n \"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-range-end)]:rounded-r-md\",\n props.mode === \"range\"\n ? \"[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md\"\n : \"[&:has([aria-selected])]:rounded-md\",\n ),\n day: cn(\n buttonVariants({ variant: \"ghost\" }),\n \"size-8 p-0 font-normal aria-selected:opacity-100\",\n ),\n day_range_start:\n \"day-range-start aria-selected:bg-primary aria-selected:text-primary-foreground\",\n day_range_end:\n \"day-range-end aria-selected:bg-primary aria-selected:text-primary-foreground\",\n day_selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground\",\n day_today: \"bg-accent text-accent-foreground\",\n day_outside:\n \"day-outside text-muted-foreground aria-selected:text-muted-foreground\",\n day_disabled: \"text-muted-foreground opacity-50\",\n day_range_middle:\n \"aria-selected:bg-accent aria-selected:text-accent-foreground\",\n day_hidden: \"invisible\",\n ...classNames,\n }}\n components={{\n IconLeft: ({ className, ...props }) => (\n <ChevronLeftIcon className={cn(\"size-4\", className)} {...props} />\n ),\n IconRight: ({ className, ...props }) => (\n <ChevronRightIcon className={cn(\"size-4\", className)} {...props} />\n ),\n }}\n {...props}\n />\n );\n}\n\nexport { Calendar };"]}
@@ -0,0 +1,99 @@
1
+ import { cn } from './chunk-DGPY4WP3.js';
2
+ import * as React from 'react';
3
+ import { Slot } from '@radix-ui/react-slot';
4
+ import { cva } from 'class-variance-authority';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ var buttonVariants = cva(
8
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ // Solid — color applied via compoundVariants
13
+ default: "",
14
+ // Legacy — maps to solid + destructive color (backward compatible)
15
+ destructive: "",
16
+ // Color-independent
17
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
18
+ // Color-aware — applied via compoundVariants
19
+ outline: "",
20
+ soft: "",
21
+ ghost: "",
22
+ link: ""
23
+ },
24
+ color: {
25
+ primary: "",
26
+ destructive: "",
27
+ success: "",
28
+ warning: "",
29
+ info: ""
30
+ },
31
+ size: {
32
+ xs: "h-element-xs rounded-md gap-1 px-2 text-xs has-[>svg]:px-1.5",
33
+ sm: "h-element-sm rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
34
+ default: "h-element px-4 py-2 has-[>svg]:px-3",
35
+ lg: "h-element-lg rounded-md px-6 has-[>svg]:px-4",
36
+ xl: "h-element-xl rounded-md px-8 text-base font-semibold has-[>svg]:px-5",
37
+ icon: "size-element rounded-md"
38
+ }
39
+ },
40
+ compoundVariants: [
41
+ // ── Solid (default variant) × color ──
42
+ { variant: "default", color: "primary", className: "bg-primary text-primary-foreground hover:bg-primary/90" },
43
+ { variant: "default", color: "destructive", className: "bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40" },
44
+ { variant: "default", color: "success", className: "bg-success text-success-foreground hover:bg-success/90 focus-visible:ring-success/20 dark:focus-visible:ring-success/40" },
45
+ { variant: "default", color: "warning", className: "bg-warning text-warning-foreground hover:bg-warning/90 focus-visible:ring-warning/20 dark:focus-visible:ring-warning/40" },
46
+ { variant: "default", color: "info", className: "bg-info text-info-foreground hover:bg-info/90 focus-visible:ring-info/20 dark:focus-visible:ring-info/40" },
47
+ // ── Legacy destructive variant (backward compat) ──
48
+ { variant: "destructive", className: "bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40" },
49
+ // ── Outline × color ──
50
+ { variant: "outline", color: "primary", className: "border border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50" },
51
+ { variant: "outline", color: "destructive", className: "border border-destructive/50 text-destructive bg-background hover:bg-destructive/10 focus-visible:ring-destructive/20" },
52
+ { variant: "outline", color: "success", className: "border border-success/50 text-success bg-background hover:bg-success/10 focus-visible:ring-success/20" },
53
+ { variant: "outline", color: "warning", className: "border border-warning/50 text-warning bg-background hover:bg-warning/10 focus-visible:ring-warning/20" },
54
+ { variant: "outline", color: "info", className: "border border-info/50 text-info bg-background hover:bg-info/10 focus-visible:ring-info/20" },
55
+ // ── Soft × color ──
56
+ { variant: "soft", color: "primary", className: "bg-primary/10 text-primary hover:bg-primary/20" },
57
+ { variant: "soft", color: "destructive", className: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:ring-destructive/20" },
58
+ { variant: "soft", color: "success", className: "bg-success/10 text-success hover:bg-success/20 focus-visible:ring-success/20" },
59
+ { variant: "soft", color: "warning", className: "bg-warning/10 text-warning hover:bg-warning/20 focus-visible:ring-warning/20" },
60
+ { variant: "soft", color: "info", className: "bg-info/10 text-info hover:bg-info/20 focus-visible:ring-info/20" },
61
+ // ── Ghost × color ──
62
+ { variant: "ghost", color: "primary", className: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50" },
63
+ { variant: "ghost", color: "destructive", className: "text-destructive hover:bg-destructive/10" },
64
+ { variant: "ghost", color: "success", className: "text-success hover:bg-success/10" },
65
+ { variant: "ghost", color: "warning", className: "text-warning hover:bg-warning/10" },
66
+ { variant: "ghost", color: "info", className: "text-info hover:bg-info/10" },
67
+ // ── Link × color ──
68
+ { variant: "link", color: "primary", className: "text-primary underline-offset-4 hover:underline" },
69
+ { variant: "link", color: "destructive", className: "text-destructive underline-offset-4 hover:underline" },
70
+ { variant: "link", color: "success", className: "text-success underline-offset-4 hover:underline" },
71
+ { variant: "link", color: "warning", className: "text-warning underline-offset-4 hover:underline" },
72
+ { variant: "link", color: "info", className: "text-info underline-offset-4 hover:underline" }
73
+ ],
74
+ defaultVariants: {
75
+ variant: "default",
76
+ color: "primary",
77
+ size: "default"
78
+ }
79
+ }
80
+ );
81
+ var Button = React.forwardRef(
82
+ ({ className, variant, color, size, asChild = false, block = false, ...props }, ref) => {
83
+ const Comp = asChild ? Slot : "button";
84
+ return /* @__PURE__ */ jsx(
85
+ Comp,
86
+ {
87
+ ref,
88
+ "data-slot": "button",
89
+ className: cn(buttonVariants({ variant, color, size }), block && "w-full", className),
90
+ ...props
91
+ }
92
+ );
93
+ }
94
+ );
95
+ Button.displayName = "Button";
96
+
97
+ export { Button, buttonVariants };
98
+ //# sourceMappingURL=chunk-55E7D2HR.js.map
99
+ //# sourceMappingURL=chunk-55E7D2HR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/button.tsx"],"names":[],"mappings":"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","file":"chunk-55E7D2HR.js","sourcesContent":["import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../lib/utils\";\nimport type { UIColor } from \"../lib/types\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n // Solid — color applied via compoundVariants\n default: \"\",\n // Legacy — maps to solid + destructive color (backward compatible)\n destructive: \"\",\n // Color-independent\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n // Color-aware — applied via compoundVariants\n outline: \"\",\n soft: \"\",\n ghost: \"\",\n link: \"\",\n },\n color: {\n primary: \"\",\n destructive: \"\",\n success: \"\",\n warning: \"\",\n info: \"\",\n },\n size: {\n xs: \"h-element-xs rounded-md gap-1 px-2 text-xs has-[>svg]:px-1.5\",\n sm: \"h-element-sm rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n default: \"h-element px-4 py-2 has-[>svg]:px-3\",\n lg: \"h-element-lg rounded-md px-6 has-[>svg]:px-4\",\n xl: \"h-element-xl rounded-md px-8 text-base font-semibold has-[>svg]:px-5\",\n icon: \"size-element rounded-md\",\n },\n },\n compoundVariants: [\n // ── Solid (default variant) × color ──\n { variant: \"default\", color: \"primary\", className: \"bg-primary text-primary-foreground hover:bg-primary/90\" },\n { variant: \"default\", color: \"destructive\", className: \"bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40\" },\n { variant: \"default\", color: \"success\", className: \"bg-success text-success-foreground hover:bg-success/90 focus-visible:ring-success/20 dark:focus-visible:ring-success/40\" },\n { variant: \"default\", color: \"warning\", className: \"bg-warning text-warning-foreground hover:bg-warning/90 focus-visible:ring-warning/20 dark:focus-visible:ring-warning/40\" },\n { variant: \"default\", color: \"info\", className: \"bg-info text-info-foreground hover:bg-info/90 focus-visible:ring-info/20 dark:focus-visible:ring-info/40\" },\n\n // ── Legacy destructive variant (backward compat) ──\n { variant: \"destructive\", className: \"bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40\" },\n\n // ── Outline × color ──\n { variant: \"outline\", color: \"primary\", className: \"border border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\" },\n { variant: \"outline\", color: \"destructive\", className: \"border border-destructive/50 text-destructive bg-background hover:bg-destructive/10 focus-visible:ring-destructive/20\" },\n { variant: \"outline\", color: \"success\", className: \"border border-success/50 text-success bg-background hover:bg-success/10 focus-visible:ring-success/20\" },\n { variant: \"outline\", color: \"warning\", className: \"border border-warning/50 text-warning bg-background hover:bg-warning/10 focus-visible:ring-warning/20\" },\n { variant: \"outline\", color: \"info\", className: \"border border-info/50 text-info bg-background hover:bg-info/10 focus-visible:ring-info/20\" },\n\n // ── Soft × color ──\n { variant: \"soft\", color: \"primary\", className: \"bg-primary/10 text-primary hover:bg-primary/20\" },\n { variant: \"soft\", color: \"destructive\", className: \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:ring-destructive/20\" },\n { variant: \"soft\", color: \"success\", className: \"bg-success/10 text-success hover:bg-success/20 focus-visible:ring-success/20\" },\n { variant: \"soft\", color: \"warning\", className: \"bg-warning/10 text-warning hover:bg-warning/20 focus-visible:ring-warning/20\" },\n { variant: \"soft\", color: \"info\", className: \"bg-info/10 text-info hover:bg-info/20 focus-visible:ring-info/20\" },\n\n // ── Ghost × color ──\n { variant: \"ghost\", color: \"primary\", className: \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\" },\n { variant: \"ghost\", color: \"destructive\", className: \"text-destructive hover:bg-destructive/10\" },\n { variant: \"ghost\", color: \"success\", className: \"text-success hover:bg-success/10\" },\n { variant: \"ghost\", color: \"warning\", className: \"text-warning hover:bg-warning/10\" },\n { variant: \"ghost\", color: \"info\", className: \"text-info hover:bg-info/10\" },\n\n // ── Link × color ──\n { variant: \"link\", color: \"primary\", className: \"text-primary underline-offset-4 hover:underline\" },\n { variant: \"link\", color: \"destructive\", className: \"text-destructive underline-offset-4 hover:underline\" },\n { variant: \"link\", color: \"success\", className: \"text-success underline-offset-4 hover:underline\" },\n { variant: \"link\", color: \"warning\", className: \"text-warning underline-offset-4 hover:underline\" },\n { variant: \"link\", color: \"info\", className: \"text-info underline-offset-4 hover:underline\" },\n ],\n defaultVariants: {\n variant: \"default\",\n color: \"primary\",\n size: \"default\",\n },\n },\n);\n\ninterface ButtonProps\n extends React.ComponentProps<\"button\">,\n Omit<VariantProps<typeof buttonVariants>, \"color\"> {\n /**\n * Semantic color intent. Works with `variant` to produce the final appearance.\n *\n * | Color | Use for |\n * |-------|---------|\n * | `primary` | Main actions (default) |\n * | `destructive` | Delete, errors |\n * | `success` | Approve, confirm |\n * | `warning` | Caution, attention |\n * | `info` | Informational |\n *\n * @default \"primary\"\n * @example\n * ```tsx\n * <Button color=\"success\">Approve</Button>\n * <Button variant=\"outline\" color=\"destructive\">Reject</Button>\n * <Button variant=\"soft\" color=\"warning\">Review</Button>\n * ```\n */\n color?: UIColor;\n /**\n * Render as a child component using Radix Slot.\n * When `true`, the button merges its props onto its single child element.\n * @default false\n */\n asChild?: boolean;\n /**\n * Make the button take the full width of its container.\n * @default false\n * @example\n * ```tsx\n * <Button block>Full Width</Button>\n * <Button size=\"xl\" block>Sign In</Button>\n * ```\n */\n block?: boolean;\n}\n\n/**\n * Button component with semantic colors, visual variants, and standard sizes.\n *\n * Combines `variant` (how it looks) with `color` (what it means) for full flexibility.\n * All existing `variant=\"destructive\"` usage continues to work unchanged.\n *\n * @example\n * ```tsx\n * // Default (solid primary)\n * <Button>Save</Button>\n *\n * // Semantic colors\n * <Button color=\"success\">Approve</Button>\n * <Button color=\"destructive\">Delete</Button>\n * <Button color=\"warning\">Proceed with caution</Button>\n *\n * // Variant × Color combinations\n * <Button variant=\"outline\" color=\"destructive\">Reject</Button>\n * <Button variant=\"soft\" color=\"success\">Approved</Button>\n * <Button variant=\"ghost\" color=\"info\">Learn more</Button>\n *\n * // Legacy (still works)\n * <Button variant=\"destructive\">Delete</Button>\n *\n * // Sizes: xs (24px) | sm (28px) | default (32px) | lg (36px) | xl (44px) | icon (32x32)\n * <Button size=\"xs\">Tiny</Button>\n * <Button size=\"xl\" block>Sign In</Button>\n * <Button size=\"icon\"><PlusIcon /></Button>\n * ```\n */\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, color, size, asChild = false, block = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n ref={ref}\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, color, size }), block && \"w-full\", className)}\n {...props}\n />\n );\n },\n);\n\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\nexport type { ButtonProps };\n"]}
@@ -1,7 +1,7 @@
1
1
  import { ScrollArea } from './chunk-JJSVA3TH.js';
2
2
  import { Input } from './chunk-3VU56V66.js';
3
3
  import { Popover, PopoverTrigger, PopoverContent } from './chunk-C34KSTWA.js';
4
- import { Button } from './chunk-Y65FNGEE.js';
4
+ import { Button } from './chunk-55E7D2HR.js';
5
5
  import { cn } from './chunk-DGPY4WP3.js';
6
6
  import * as React from 'react';
7
7
  import { Clock } from 'lucide-react';
@@ -55,8 +55,8 @@ function TimePicker({
55
55
  type: "button",
56
56
  onClick: () => handleHourSelect(hour),
57
57
  className: cn(
58
- "w-full px-3 py-2 text-sm rounded hover:bg-gray-100 transition-colors text-center",
59
- selectedHour === hour && "bg-blue-100 text-blue-700 font-semibold"
58
+ "w-full px-3 py-2 text-sm rounded hover:bg-accent transition-colors text-center",
59
+ selectedHour === hour && "bg-primary/10 text-primary font-semibold"
60
60
  ),
61
61
  children: hour
62
62
  },
@@ -68,8 +68,8 @@ function TimePicker({
68
68
  type: "button",
69
69
  onClick: () => handleMinuteSelect(minute),
70
70
  className: cn(
71
- "w-full px-3 py-2 text-sm rounded hover:bg-gray-100 transition-colors text-center",
72
- selectedMinute === minute && "bg-blue-100 text-blue-700 font-semibold"
71
+ "w-full px-3 py-2 text-sm rounded hover:bg-accent transition-colors text-center",
72
+ selectedMinute === minute && "bg-primary/10 text-primary font-semibold"
73
73
  ),
74
74
  children: minute
75
75
  },
@@ -122,10 +122,10 @@ function TimeInput({
122
122
  className: cn("pr-10", className)
123
123
  }
124
124
  ),
125
- /* @__PURE__ */ jsx(Clock, { className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" })
125
+ /* @__PURE__ */ jsx(Clock, { className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" })
126
126
  ] });
127
127
  }
128
128
 
129
129
  export { TimeInput, TimePicker };
130
- //# sourceMappingURL=chunk-4MD7BIEK.js.map
131
- //# sourceMappingURL=chunk-4MD7BIEK.js.map
130
+ //# sourceMappingURL=chunk-6DIDQ4TB.js.map
131
+ //# sourceMappingURL=chunk-6DIDQ4TB.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/time-picker.tsx"],"names":[],"mappings":"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","file":"chunk-4MD7BIEK.js","sourcesContent":["import * as React from \"react\";\nimport { Clock } from \"lucide-react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\nimport { ScrollArea } from \"./scroll-area\";\n\ninterface TimePickerProps {\n /** Currently selected time in `\"HH:mm\"` format (e.g., `\"14:30\"`). */\n value?: string;\n /** Callback fired when a time is selected. Receives a `\"HH:mm\"` string. */\n onChange?: (time: string) => void;\n /** Placeholder text shown when no time is selected. */\n placeholder?: string;\n /** Additional CSS class for the trigger button. */\n className?: string;\n /** Whether the time picker is disabled. */\n disabled?: boolean;\n /** Use 24-hour format (0-23). When false, shows 12-hour (1-12). Defaults to `true`. */\n format24h?: boolean;\n}\n\n/**\n * Time picker with a scrollable hour/minute popover.\n * Opens a two-column dropdown for selecting hours and minutes.\n *\n * @example\n * ```tsx\n * const [time, setTime] = useState<string>();\n *\n * <TimePicker\n * value={time}\n * onChange={setTime}\n * placeholder=\"Select time\"\n * format24h\n * />\n * ```\n */\nexport function TimePicker({\n value,\n onChange,\n placeholder = \"Chọn giờ\",\n className,\n disabled,\n format24h = true,\n}: TimePickerProps) {\n const [open, setOpen] = React.useState(false);\n\n const hours = format24h\n ? Array.from({ length: 24 }, (_, i) => i.toString().padStart(2, \"0\"))\n : Array.from({ length: 12 }, (_, i) => (i + 1).toString().padStart(2, \"0\"));\n\n const minutes = Array.from({ length: 60 }, (_, i) =>\n i.toString().padStart(2, \"0\")\n );\n\n const [selectedHour, selectedMinute] = value?.split(\":\") || [\"\", \"\"];\n\n const handleHourSelect = (hour: string) => {\n const newTime = `${hour}:${selectedMinute || \"00\"}`;\n onChange?.(newTime);\n };\n\n const handleMinuteSelect = (minute: string) => {\n const newTime = `${selectedHour || \"00\"}:${minute}`;\n onChange?.(newTime);\n setOpen(false);\n };\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n disabled={disabled}\n className={cn(\n \"w-full justify-start\",\n !value && \"text-muted-foreground\",\n className\n )}\n >\n <Clock className=\"mr-2 h-4 w-4\" />\n {value || placeholder}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <div className=\"flex\">\n {/* Hours */}\n <ScrollArea className=\"h-60 w-20 border-r\">\n <div className=\"p-1\">\n {hours.map((hour) => (\n <button\n key={hour}\n type=\"button\"\n onClick={() => handleHourSelect(hour)}\n className={cn(\n \"w-full px-3 py-2 text-sm rounded hover:bg-gray-100 transition-colors text-center\",\n selectedHour === hour && \"bg-blue-100 text-blue-700 font-semibold\"\n )}\n >\n {hour}\n </button>\n ))}\n </div>\n </ScrollArea>\n\n {/* Minutes */}\n <ScrollArea className=\"h-60 w-20\">\n <div className=\"p-1\">\n {minutes.map((minute) => (\n <button\n key={minute}\n type=\"button\"\n onClick={() => handleMinuteSelect(minute)}\n className={cn(\n \"w-full px-3 py-2 text-sm rounded hover:bg-gray-100 transition-colors text-center\",\n selectedMinute === minute && \"bg-blue-100 text-blue-700 font-semibold\"\n )}\n >\n {minute}\n </button>\n ))}\n </div>\n </ScrollArea>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\ninterface TimeInputProps {\n /** Current time value in `\"HH:mm\"` format. */\n value?: string;\n /** Callback fired on blur with a valid `\"HH:mm\"` string. */\n onChange?: (time: string) => void;\n /** Additional CSS class for the input wrapper. */\n className?: string;\n /** Whether the input is disabled. */\n disabled?: boolean;\n}\n\n/**\n * Inline text input for typing a time value directly.\n * Automatically formats input as `HH:mm` and validates on blur.\n *\n * @example\n * ```tsx\n * const [time, setTime] = useState(\"09:00\");\n *\n * <TimeInput value={time} onChange={setTime} />\n * ```\n */\nexport function TimeInput({\n value = \"\",\n onChange,\n className,\n disabled,\n}: TimeInputProps) {\n const [localValue, setLocalValue] = React.useState(value);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n let input = e.target.value.replace(/\\D/g, \"\"); // Remove non-digits\n\n if (input.length >= 2) {\n const hours = parseInt(input.substring(0, 2));\n if (hours > 23) input = \"23\" + input.substring(2);\n }\n\n if (input.length >= 4) {\n const minutes = parseInt(input.substring(2, 4));\n if (minutes > 59) input = input.substring(0, 2) + \"59\";\n }\n\n // Format as HH:mm\n if (input.length >= 2) {\n input = input.substring(0, 2) + \":\" + input.substring(2, 4);\n }\n\n setLocalValue(input);\n };\n\n const handleBlur = () => {\n // Validate and format\n const parts = localValue.split(\":\");\n if (parts.length === 2 && parts[0].length === 2 && parts[1].length === 2) {\n onChange?.(localValue);\n } else {\n setLocalValue(value);\n }\n };\n\n return (\n <div className=\"relative\">\n <Input\n type=\"text\"\n value={localValue}\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder=\"00:00\"\n maxLength={5}\n disabled={disabled}\n className={cn(\"pr-10\", className)}\n />\n <Clock className=\"absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400\" />\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/time-picker.tsx"],"names":[],"mappings":"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","file":"chunk-6DIDQ4TB.js","sourcesContent":["import * as React from \"react\";\nimport { Clock } from \"lucide-react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\nimport { ScrollArea } from \"./scroll-area\";\n\ninterface TimePickerProps {\n /** Currently selected time in `\"HH:mm\"` format (e.g., `\"14:30\"`). */\n value?: string;\n /** Callback fired when a time is selected. Receives a `\"HH:mm\"` string. */\n onChange?: (time: string) => void;\n /** Placeholder text shown when no time is selected. */\n placeholder?: string;\n /** Additional CSS class for the trigger button. */\n className?: string;\n /** Whether the time picker is disabled. */\n disabled?: boolean;\n /** Use 24-hour format (0-23). When false, shows 12-hour (1-12). Defaults to `true`. */\n format24h?: boolean;\n}\n\n/**\n * Time picker with a scrollable hour/minute popover.\n * Opens a two-column dropdown for selecting hours and minutes.\n *\n * @example\n * ```tsx\n * const [time, setTime] = useState<string>();\n *\n * <TimePicker\n * value={time}\n * onChange={setTime}\n * placeholder=\"Select time\"\n * format24h\n * />\n * ```\n */\nexport function TimePicker({\n value,\n onChange,\n placeholder = \"Chọn giờ\",\n className,\n disabled,\n format24h = true,\n}: TimePickerProps) {\n const [open, setOpen] = React.useState(false);\n\n const hours = format24h\n ? Array.from({ length: 24 }, (_, i) => i.toString().padStart(2, \"0\"))\n : Array.from({ length: 12 }, (_, i) => (i + 1).toString().padStart(2, \"0\"));\n\n const minutes = Array.from({ length: 60 }, (_, i) =>\n i.toString().padStart(2, \"0\")\n );\n\n const [selectedHour, selectedMinute] = value?.split(\":\") || [\"\", \"\"];\n\n const handleHourSelect = (hour: string) => {\n const newTime = `${hour}:${selectedMinute || \"00\"}`;\n onChange?.(newTime);\n };\n\n const handleMinuteSelect = (minute: string) => {\n const newTime = `${selectedHour || \"00\"}:${minute}`;\n onChange?.(newTime);\n setOpen(false);\n };\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n disabled={disabled}\n className={cn(\n \"w-full justify-start\",\n !value && \"text-muted-foreground\",\n className\n )}\n >\n <Clock className=\"mr-2 h-4 w-4\" />\n {value || placeholder}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <div className=\"flex\">\n {/* Hours */}\n <ScrollArea className=\"h-60 w-20 border-r\">\n <div className=\"p-1\">\n {hours.map((hour) => (\n <button\n key={hour}\n type=\"button\"\n onClick={() => handleHourSelect(hour)}\n className={cn(\n \"w-full px-3 py-2 text-sm rounded hover:bg-accent transition-colors text-center\",\n selectedHour === hour && \"bg-primary/10 text-primary font-semibold\"\n )}\n >\n {hour}\n </button>\n ))}\n </div>\n </ScrollArea>\n\n {/* Minutes */}\n <ScrollArea className=\"h-60 w-20\">\n <div className=\"p-1\">\n {minutes.map((minute) => (\n <button\n key={minute}\n type=\"button\"\n onClick={() => handleMinuteSelect(minute)}\n className={cn(\n \"w-full px-3 py-2 text-sm rounded hover:bg-accent transition-colors text-center\",\n selectedMinute === minute && \"bg-primary/10 text-primary font-semibold\"\n )}\n >\n {minute}\n </button>\n ))}\n </div>\n </ScrollArea>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\ninterface TimeInputProps {\n /** Current time value in `\"HH:mm\"` format. */\n value?: string;\n /** Callback fired on blur with a valid `\"HH:mm\"` string. */\n onChange?: (time: string) => void;\n /** Additional CSS class for the input wrapper. */\n className?: string;\n /** Whether the input is disabled. */\n disabled?: boolean;\n}\n\n/**\n * Inline text input for typing a time value directly.\n * Automatically formats input as `HH:mm` and validates on blur.\n *\n * @example\n * ```tsx\n * const [time, setTime] = useState(\"09:00\");\n *\n * <TimeInput value={time} onChange={setTime} />\n * ```\n */\nexport function TimeInput({\n value = \"\",\n onChange,\n className,\n disabled,\n}: TimeInputProps) {\n const [localValue, setLocalValue] = React.useState(value);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n let input = e.target.value.replace(/\\D/g, \"\"); // Remove non-digits\n\n if (input.length >= 2) {\n const hours = parseInt(input.substring(0, 2));\n if (hours > 23) input = \"23\" + input.substring(2);\n }\n\n if (input.length >= 4) {\n const minutes = parseInt(input.substring(2, 4));\n if (minutes > 59) input = input.substring(0, 2) + \"59\";\n }\n\n // Format as HH:mm\n if (input.length >= 2) {\n input = input.substring(0, 2) + \":\" + input.substring(2, 4);\n }\n\n setLocalValue(input);\n };\n\n const handleBlur = () => {\n // Validate and format\n const parts = localValue.split(\":\");\n if (parts.length === 2 && parts[0].length === 2 && parts[1].length === 2) {\n onChange?.(localValue);\n } else {\n setLocalValue(value);\n }\n };\n\n return (\n <div className=\"relative\">\n <Input\n type=\"text\"\n value={localValue}\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder=\"00:00\"\n maxLength={5}\n disabled={disabled}\n className={cn(\"pr-10\", className)}\n />\n <Clock className=\"absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground\" />\n </div>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { buttonVariants } from './chunk-Y65FNGEE.js';
1
+ import { buttonVariants } from './chunk-55E7D2HR.js';
2
2
  import { cn } from './chunk-DGPY4WP3.js';
3
3
  import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from 'lucide-react';
4
4
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -110,5 +110,5 @@ function PaginationEllipsis({
110
110
  }
111
111
 
112
112
  export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious };
113
- //# sourceMappingURL=chunk-ZHP73HKU.js.map
114
- //# sourceMappingURL=chunk-ZHP73HKU.js.map
113
+ //# sourceMappingURL=chunk-7IRLBU2I.js.map
114
+ //# sourceMappingURL=chunk-7IRLBU2I.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/pagination.tsx"],"names":[],"mappings":"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","file":"chunk-ZHP73HKU.js","sourcesContent":["import * as React from \"react\";\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n MoreHorizontalIcon,\n} from \"lucide-react\";\n\nimport { cn } from \"../lib/utils\";\nimport { Button, buttonVariants } from \"./button\";\n\n/**\n * Page navigation component with numbered links, previous/next buttons, and ellipsis indicators.\n *\n * Renders as a `<nav>` with `aria-label=\"pagination\"` for accessibility.\n * Compose with `PaginationContent`, `PaginationItem`, `PaginationLink`,\n * `PaginationPrevious`, `PaginationNext`, and `PaginationEllipsis`.\n *\n * @example\n * ```tsx\n * <Pagination>\n * <PaginationContent>\n * <PaginationItem>\n * <PaginationPrevious href=\"#\" />\n * </PaginationItem>\n * <PaginationItem>\n * <PaginationLink href=\"#\" isActive>1</PaginationLink>\n * </PaginationItem>\n * <PaginationItem>\n * <PaginationLink href=\"#\">2</PaginationLink>\n * </PaginationItem>\n * <PaginationItem>\n * <PaginationEllipsis />\n * </PaginationItem>\n * <PaginationItem>\n * <PaginationLink href=\"#\">10</PaginationLink>\n * </PaginationItem>\n * <PaginationItem>\n * <PaginationNext href=\"#\" />\n * </PaginationItem>\n * </PaginationContent>\n * </Pagination>\n * ```\n */\nfunction Pagination({ className, ...props }: React.ComponentProps<\"nav\">) {\n return (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n data-slot=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n );\n}\n\n/** Flex container for pagination items. Renders as a `<ul>`. */\nfunction PaginationContent({\n className,\n ...props\n}: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"pagination-content\"\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n );\n}\n\n/** List item wrapper for a single pagination element. */\nfunction PaginationItem({ ...props }: React.ComponentProps<\"li\">) {\n return <li data-slot=\"pagination-item\" {...props} />;\n}\n\ntype PaginationLinkProps = {\n /** When true, renders the link with an `outline` variant and `aria-current=\"page\"`. */\n isActive?: boolean;\n} & Pick<React.ComponentProps<typeof Button>, \"size\"> &\n React.ComponentProps<\"a\">;\n\n/** Styled pagination link using button variants. Supports `isActive` for the current page. */\nfunction PaginationLink({\n className,\n isActive,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) {\n return (\n <a\n aria-current={isActive ? \"page\" : undefined}\n data-slot=\"pagination-link\"\n data-active={isActive}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n className,\n )}\n {...props}\n />\n );\n}\n\n/** \"Previous\" pagination link with a left chevron icon. */\nfunction PaginationPrevious({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) {\n return (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"gap-1 px-2.5 sm:pl-2.5\", className)}\n {...props}\n >\n <ChevronLeftIcon />\n <span className=\"hidden sm:block\">Previous</span>\n </PaginationLink>\n );\n}\n\n/** \"Next\" pagination link with a right chevron icon. */\nfunction PaginationNext({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) {\n return (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"gap-1 px-2.5 sm:pr-2.5\", className)}\n {...props}\n >\n <span className=\"hidden sm:block\">Next</span>\n <ChevronRightIcon />\n </PaginationLink>\n );\n}\n\n/** Ellipsis indicator for omitted page numbers. Renders a `MoreHorizontal` icon with screen-reader text. */\nfunction PaginationEllipsis({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n aria-hidden\n data-slot=\"pagination-ellipsis\"\n className={cn(\"flex size-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontalIcon className=\"size-4\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n );\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n};\n"]}
1
+ {"version":3,"sources":["../src/components/pagination.tsx"],"names":[],"mappings":"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","file":"chunk-7IRLBU2I.js","sourcesContent":["import * as React from \"react\";\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n MoreHorizontalIcon,\n} from \"lucide-react\";\n\nimport { cn } from \"../lib/utils\";\nimport { Button, buttonVariants } from \"./button\";\n\n/**\n * Page navigation component with numbered links, previous/next buttons, and ellipsis indicators.\n *\n * Renders as a `<nav>` with `aria-label=\"pagination\"` for accessibility.\n * Compose with `PaginationContent`, `PaginationItem`, `PaginationLink`,\n * `PaginationPrevious`, `PaginationNext`, and `PaginationEllipsis`.\n *\n * @example\n * ```tsx\n * <Pagination>\n * <PaginationContent>\n * <PaginationItem>\n * <PaginationPrevious href=\"#\" />\n * </PaginationItem>\n * <PaginationItem>\n * <PaginationLink href=\"#\" isActive>1</PaginationLink>\n * </PaginationItem>\n * <PaginationItem>\n * <PaginationLink href=\"#\">2</PaginationLink>\n * </PaginationItem>\n * <PaginationItem>\n * <PaginationEllipsis />\n * </PaginationItem>\n * <PaginationItem>\n * <PaginationLink href=\"#\">10</PaginationLink>\n * </PaginationItem>\n * <PaginationItem>\n * <PaginationNext href=\"#\" />\n * </PaginationItem>\n * </PaginationContent>\n * </Pagination>\n * ```\n */\nfunction Pagination({ className, ...props }: React.ComponentProps<\"nav\">) {\n return (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n data-slot=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n );\n}\n\n/** Flex container for pagination items. Renders as a `<ul>`. */\nfunction PaginationContent({\n className,\n ...props\n}: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"pagination-content\"\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n );\n}\n\n/** List item wrapper for a single pagination element. */\nfunction PaginationItem({ ...props }: React.ComponentProps<\"li\">) {\n return <li data-slot=\"pagination-item\" {...props} />;\n}\n\ntype PaginationLinkProps = {\n /** When true, renders the link with an `outline` variant and `aria-current=\"page\"`. */\n isActive?: boolean;\n} & Pick<React.ComponentProps<typeof Button>, \"size\"> &\n React.ComponentProps<\"a\">;\n\n/** Styled pagination link using button variants. Supports `isActive` for the current page. */\nfunction PaginationLink({\n className,\n isActive,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) {\n return (\n <a\n aria-current={isActive ? \"page\" : undefined}\n data-slot=\"pagination-link\"\n data-active={isActive}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n className,\n )}\n {...props}\n />\n );\n}\n\n/** \"Previous\" pagination link with a left chevron icon. */\nfunction PaginationPrevious({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) {\n return (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"gap-1 px-2.5 sm:pl-2.5\", className)}\n {...props}\n >\n <ChevronLeftIcon />\n <span className=\"hidden sm:block\">Previous</span>\n </PaginationLink>\n );\n}\n\n/** \"Next\" pagination link with a right chevron icon. */\nfunction PaginationNext({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) {\n return (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"gap-1 px-2.5 sm:pr-2.5\", className)}\n {...props}\n >\n <span className=\"hidden sm:block\">Next</span>\n <ChevronRightIcon />\n </PaginationLink>\n );\n}\n\n/** Ellipsis indicator for omitted page numbers. Renders a `MoreHorizontal` icon with screen-reader text. */\nfunction PaginationEllipsis({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n aria-hidden\n data-slot=\"pagination-ellipsis\"\n className={cn(\"flex size-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontalIcon className=\"size-4\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n );\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n};\n"]}