@thangnqdev/ui 0.1.1 → 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 (231) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -65
  3. package/dist/bento/index.cjs.map +1 -1
  4. package/dist/bento/index.js +2 -2
  5. package/dist/bento/styles.css +2 -46
  6. package/dist/buttons/index.cjs +111 -18
  7. package/dist/buttons/index.cjs.map +1 -1
  8. package/dist/buttons/index.d.cts +1 -1
  9. package/dist/buttons/index.d.ts +1 -1
  10. package/dist/buttons/index.js +3 -3
  11. package/dist/buttons/styles.css +2 -6
  12. package/dist/{chunk-4S6L5V7X.js → chunk-2YJBW4E2.js} +2 -2
  13. package/dist/chunk-2YJBW4E2.js.map +1 -0
  14. package/dist/{chunk-F5Q7BTMH.js → chunk-4CRFNALF.js} +1011 -556
  15. package/dist/chunk-4CRFNALF.js.map +1 -0
  16. package/dist/{chunk-LWFRUJRU.js → chunk-4MS6ZHFQ.js} +225 -41
  17. package/dist/chunk-4MS6ZHFQ.js.map +1 -0
  18. package/dist/{chunk-2OXZK6IP.js → chunk-77KTYOMQ.js} +3 -3
  19. package/dist/chunk-77KTYOMQ.js.map +1 -0
  20. package/dist/{chunk-IABPUCAQ.js → chunk-ADO3SVUA.js} +2 -2
  21. package/dist/chunk-ADO3SVUA.js.map +1 -0
  22. package/dist/{chunk-GXI2H5XA.js → chunk-D7FB3TCA.js} +3 -3
  23. package/dist/chunk-D7FB3TCA.js.map +1 -0
  24. package/dist/chunk-DSEL7ELZ.js +314 -0
  25. package/dist/chunk-DSEL7ELZ.js.map +1 -0
  26. package/dist/{chunk-KJRBRTQE.js → chunk-EXFR2BFJ.js} +37 -28
  27. package/dist/chunk-EXFR2BFJ.js.map +1 -0
  28. package/dist/{chunk-PF4ZHGVW.js → chunk-GXWB6BSY.js} +116 -23
  29. package/dist/chunk-GXWB6BSY.js.map +1 -0
  30. package/dist/{chunk-66VWUJEI.js → chunk-I2FQBMVW.js} +3 -3
  31. package/dist/chunk-I2FQBMVW.js.map +1 -0
  32. package/dist/{chunk-EU2LPUYP.js → chunk-I5O2WCGF.js} +3 -3
  33. package/dist/chunk-I5O2WCGF.js.map +1 -0
  34. package/dist/{chunk-ATYGDTMK.js → chunk-ME4XILG5.js} +5 -5
  35. package/dist/chunk-ME4XILG5.js.map +1 -0
  36. package/dist/{chunk-5FZ6ZFII.js → chunk-PC5SZFZC.js} +373 -150
  37. package/dist/chunk-PC5SZFZC.js.map +1 -0
  38. package/dist/{chunk-C4SUXMI3.js → chunk-S6XJMYME.js} +3 -3
  39. package/dist/chunk-S6XJMYME.js.map +1 -0
  40. package/dist/{chunk-A7P3O5Z5.js → chunk-V52JOSDF.js} +3 -3
  41. package/dist/chunk-V52JOSDF.js.map +1 -0
  42. package/dist/{chunk-NFVONJUK.js → chunk-W5WNWTQC.js} +455 -211
  43. package/dist/chunk-W5WNWTQC.js.map +1 -0
  44. package/dist/{chunk-WAFHC4DQ.js → chunk-YJ64RI7J.js} +3 -3
  45. package/dist/chunk-YJ64RI7J.js.map +1 -0
  46. package/dist/chunk-YOCGBORV.js +155 -0
  47. package/dist/chunk-YOCGBORV.js.map +1 -0
  48. package/dist/chunk-ZEDXARXW.js +96 -0
  49. package/dist/chunk-ZEDXARXW.js.map +1 -0
  50. package/dist/components.css +2 -0
  51. package/dist/core/index.cjs +33 -24
  52. package/dist/core/index.cjs.map +1 -1
  53. package/dist/core/index.js +2 -2
  54. package/dist/core/styles.css +2 -130
  55. package/dist/data-display/index.cjs +770 -247
  56. package/dist/data-display/index.cjs.map +1 -1
  57. package/dist/data-display/index.d.cts +1 -1
  58. package/dist/data-display/index.d.ts +1 -1
  59. package/dist/data-display/index.js +5 -4
  60. package/dist/data-display/styles.css +2 -4
  61. package/dist/feedback/index.cjs.map +1 -1
  62. package/dist/feedback/index.js +2 -2
  63. package/dist/feedback/styles.css +2 -4
  64. package/dist/forms/index.cjs +1211 -459
  65. package/dist/forms/index.cjs.map +1 -1
  66. package/dist/forms/index.d.cts +1 -1
  67. package/dist/forms/index.d.ts +1 -1
  68. package/dist/forms/index.js +8 -8
  69. package/dist/forms/styles.css +2 -6
  70. package/dist/glass/index.cjs.map +1 -1
  71. package/dist/glass/index.js +2 -2
  72. package/dist/glass/styles.css +2 -81
  73. package/dist/{index-D6fE7w-b.d.cts → index-BGt_hecO.d.cts} +1 -0
  74. package/dist/{index-D6fE7w-b.d.ts → index-BGt_hecO.d.ts} +1 -0
  75. package/dist/{index-DzcWh1Hs.d.cts → index-BtDvpZCf.d.cts} +7 -0
  76. package/dist/{index-DzcWh1Hs.d.ts → index-BtDvpZCf.d.ts} +7 -0
  77. package/dist/{index-Cle6QzQl.d.ts → index-COX1sBUN.d.ts} +27 -3
  78. package/dist/{index-BkRqGNG1.d.ts → index-Cg8MuP7u.d.cts} +40 -13
  79. package/dist/{index-BkRqGNG1.d.cts → index-Cg8MuP7u.d.ts} +40 -13
  80. package/dist/{index-CenuF_P2.d.ts → index-DHkPRTvE.d.cts} +39 -8
  81. package/dist/{index-CenuF_P2.d.cts → index-DHkPRTvE.d.ts} +39 -8
  82. package/dist/{index-TyK-Ldpy.d.cts → index-Du_oht9k.d.cts} +27 -3
  83. package/dist/index.cjs +2481 -917
  84. package/dist/index.cjs.map +1 -1
  85. package/dist/index.d.cts +5 -5
  86. package/dist/index.d.ts +5 -5
  87. package/dist/index.js +19 -19
  88. package/dist/layout/index.cjs.map +1 -1
  89. package/dist/layout/index.js +2 -2
  90. package/dist/layout/styles.css +2 -8
  91. package/dist/navigation/index.cjs +288 -48
  92. package/dist/navigation/index.cjs.map +1 -1
  93. package/dist/navigation/index.d.cts +1 -1
  94. package/dist/navigation/index.d.ts +1 -1
  95. package/dist/navigation/index.js +6 -6
  96. package/dist/navigation/styles.css +2 -4
  97. package/dist/overlays/index.cjs +566 -229
  98. package/dist/overlays/index.cjs.map +1 -1
  99. package/dist/overlays/index.d.cts +1 -1
  100. package/dist/overlays/index.d.ts +1 -1
  101. package/dist/overlays/index.js +7 -7
  102. package/dist/overlays/styles.css +2 -8
  103. package/dist/reset.css +45 -0
  104. package/dist/styles.css +1 -1
  105. package/dist/tokens.css +11 -0
  106. package/dist/typography/index.cjs.map +1 -1
  107. package/dist/typography/index.js +4 -4
  108. package/dist/typography/styles.css +2 -5
  109. package/llms.txt +211 -113
  110. package/package.json +160 -116
  111. package/src/bento/BentoCard.tsx +140 -140
  112. package/src/bento/BentoGrid.tsx +50 -50
  113. package/src/bento/index.ts +2 -2
  114. package/src/bento/tokens.css +46 -46
  115. package/src/buttons/Button.tsx +104 -104
  116. package/src/buttons/ButtonGroup.tsx +43 -43
  117. package/src/buttons/IconButton.tsx +79 -79
  118. package/src/buttons/SplitButton.tsx +186 -86
  119. package/src/buttons/ToggleButton.tsx +157 -157
  120. package/src/buttons/index.ts +5 -5
  121. package/src/buttons/tokens.css +6 -6
  122. package/src/core/ThemeProvider.tsx +135 -123
  123. package/src/core/index.ts +2 -2
  124. package/src/core/tokens.css +134 -130
  125. package/src/data-display/Accordion.tsx +147 -147
  126. package/src/data-display/Avatar.tsx +134 -134
  127. package/src/data-display/Card.tsx +112 -112
  128. package/src/data-display/Chip.tsx +74 -74
  129. package/src/data-display/DataTablePro.tsx +299 -121
  130. package/src/data-display/StatCard.tsx +60 -60
  131. package/src/data-display/Table.tsx +74 -74
  132. package/src/data-display/Timeline.tsx +62 -62
  133. package/src/data-display/TreeView.tsx +243 -104
  134. package/src/data-display/tokens.css +4 -4
  135. package/src/feedback/Alert.tsx +80 -80
  136. package/src/feedback/EmptyState.tsx +45 -45
  137. package/src/feedback/Skeleton.tsx +66 -66
  138. package/src/feedback/Spinner.tsx +65 -65
  139. package/src/feedback/index.ts +5 -5
  140. package/src/feedback/tokens.css +4 -4
  141. package/src/forms/Checkbox.tsx +149 -69
  142. package/src/forms/CheckboxGroup.tsx +76 -29
  143. package/src/forms/Combobox.tsx +172 -28
  144. package/src/forms/DatePicker.tsx +385 -81
  145. package/src/forms/FileUpload.tsx +51 -7
  146. package/src/forms/FormField.tsx +115 -115
  147. package/src/forms/Input.tsx +151 -151
  148. package/src/forms/NumberInput.tsx +34 -20
  149. package/src/forms/PasswordInput.tsx +35 -35
  150. package/src/forms/PinInput.tsx +139 -125
  151. package/src/forms/Radio.tsx +142 -142
  152. package/src/forms/RangeSlider.tsx +237 -111
  153. package/src/forms/SearchInput.tsx +34 -34
  154. package/src/forms/Select.tsx +103 -103
  155. package/src/forms/Slider.tsx +85 -85
  156. package/src/forms/Textarea.tsx +114 -114
  157. package/src/forms/tokens.css +6 -6
  158. package/src/glass/GlassButton.tsx +59 -59
  159. package/src/glass/GlassCard.tsx +71 -71
  160. package/src/glass/index.ts +3 -3
  161. package/src/glass/tokens.css +81 -81
  162. package/src/index.ts +26 -26
  163. package/src/layout/AspectRatio.tsx +39 -39
  164. package/src/layout/Container.tsx +53 -53
  165. package/src/layout/Divider.tsx +61 -61
  166. package/src/layout/Flex.tsx +79 -79
  167. package/src/layout/Grid.tsx +124 -124
  168. package/src/layout/PageLayout.tsx +59 -59
  169. package/src/layout/Section.tsx +47 -47
  170. package/src/layout/Spacer.tsx +30 -30
  171. package/src/layout/Stack.tsx +88 -88
  172. package/src/layout/tokens.css +8 -8
  173. package/src/navigation/Breadcrumb.tsx +73 -73
  174. package/src/navigation/CommandPalette.tsx +142 -142
  175. package/src/navigation/DropdownMenu.tsx +244 -160
  176. package/src/navigation/Pagination.tsx +114 -114
  177. package/src/navigation/Stepper.tsx +93 -93
  178. package/src/navigation/Tabs.tsx +265 -133
  179. package/src/navigation/index.ts +6 -6
  180. package/src/navigation/tokens.css +4 -4
  181. package/src/overlays/AlertDialog.tsx +63 -54
  182. package/src/overlays/BottomSheet.tsx +30 -10
  183. package/src/overlays/ContextMenu.tsx +51 -9
  184. package/src/overlays/Drawer.tsx +160 -145
  185. package/src/overlays/FocusTrap.tsx +122 -49
  186. package/src/overlays/Modal.tsx +296 -219
  187. package/src/overlays/Popover.tsx +55 -25
  188. package/src/overlays/Portal.tsx +23 -23
  189. package/src/overlays/Toast.tsx +175 -137
  190. package/src/overlays/Tooltip.tsx +125 -100
  191. package/src/overlays/tokens.css +8 -8
  192. package/src/registry/components.ts +1368 -0
  193. package/src/styles/components.css +39 -0
  194. package/src/styles/index.css +2 -93
  195. package/src/styles/reset.css +45 -0
  196. package/src/styles/tokens.css +11 -2
  197. package/src/typography/Blockquote.tsx +32 -32
  198. package/src/typography/Code.tsx +89 -89
  199. package/src/typography/Heading.tsx +56 -56
  200. package/src/typography/Kbd.tsx +25 -25
  201. package/src/typography/Label.tsx +47 -47
  202. package/src/typography/Link.tsx +56 -56
  203. package/src/typography/Text.tsx +62 -62
  204. package/src/typography/index.ts +7 -7
  205. package/src/typography/tokens.css +5 -5
  206. package/src/utils/cn.ts +6 -6
  207. package/src/utils/scroll-lock.ts +19 -0
  208. package/src/utils/useControllableState.ts +54 -0
  209. package/ui-contract.json +192 -35
  210. package/dist/chunk-2OXZK6IP.js.map +0 -1
  211. package/dist/chunk-4S6L5V7X.js.map +0 -1
  212. package/dist/chunk-5FZ6ZFII.js.map +0 -1
  213. package/dist/chunk-66VWUJEI.js.map +0 -1
  214. package/dist/chunk-A7P3O5Z5.js.map +0 -1
  215. package/dist/chunk-ATYGDTMK.js.map +0 -1
  216. package/dist/chunk-C4SUXMI3.js.map +0 -1
  217. package/dist/chunk-EU2LPUYP.js.map +0 -1
  218. package/dist/chunk-F5Q7BTMH.js.map +0 -1
  219. package/dist/chunk-GXI2H5XA.js.map +0 -1
  220. package/dist/chunk-H3LCNPMC.js +0 -101
  221. package/dist/chunk-H3LCNPMC.js.map +0 -1
  222. package/dist/chunk-IABPUCAQ.js.map +0 -1
  223. package/dist/chunk-KJRBRTQE.js.map +0 -1
  224. package/dist/chunk-LBUBXUYQ.js +0 -40
  225. package/dist/chunk-LBUBXUYQ.js.map +0 -1
  226. package/dist/chunk-LWFRUJRU.js.map +0 -1
  227. package/dist/chunk-NFVONJUK.js.map +0 -1
  228. package/dist/chunk-PF4ZHGVW.js.map +0 -1
  229. package/dist/chunk-WAFHC4DQ.js.map +0 -1
  230. package/dist/chunk-X76KBH4Y.js +0 -71
  231. package/dist/chunk-X76KBH4Y.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { cn } from './chunk-4S6L5V7X.js';
1
+ import { cn } from './chunk-2YJBW4E2.js';
2
2
  import { forwardRef } from 'react';
3
3
  import { cva } from 'class-variance-authority';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -42,5 +42,5 @@ var Label = forwardRef(
42
42
  Label.displayName = "Label";
43
43
 
44
44
  export { Label, labelVariants };
45
- //# sourceMappingURL=chunk-GXI2H5XA.js.map
46
- //# sourceMappingURL=chunk-GXI2H5XA.js.map
45
+ //# sourceMappingURL=chunk-D7FB3TCA.js.map
46
+ //# sourceMappingURL=chunk-D7FB3TCA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/typography/Label.tsx"],"names":[],"mappings":";;;;;AAIO,IAAM,aAAA,GAAgB,GAAA;AAAA,EAC3B,qKAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,IAAA,EAAM;AAAA,QACJ,EAAA,EAAI,SAAA;AAAA,QACJ,EAAA,EAAI,SAAA;AAAA,QACJ,EAAA,EAAI;AAAA,OACN;AAAA,MACA,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,wBAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,IAAA,EAAM,IAAA;AAAA,MACN,KAAA,EAAO;AAAA;AACT;AAEJ;AAQO,IAAM,KAAA,GAAQ,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,UAAU,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACjE,IAAA,uBACE,IAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,GAAG,aAAA,CAAc,EAAE,MAAM,KAAA,EAAO,GAAG,SAAS,CAAA;AAAA,QACtD,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,QAAA;AAAA,UACA,4BAAY,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,+BAAA,EAAgC,aAAA,EAAY,QAAO,QAAA,EAAA,GAAA,EAAC;AAAA;AAAA;AAAA,KACnF;AAAA,EAEJ;AACF;AAEA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-D7FB3TCA.js","sourcesContent":["import React, { forwardRef } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../utils/cn';\n\nexport const labelVariants = cva(\n 'text-sm font-medium leading-none select-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-[var(--ui-text-primary)] inline-flex items-center gap-1',\n {\n variants: {\n size: {\n sm: 'text-xs',\n md: 'text-sm',\n lg: 'text-base',\n },\n error: {\n true: 'text-[var(--ui-error)]',\n false: '',\n },\n },\n defaultVariants: {\n size: 'md',\n error: false,\n },\n }\n);\n\nexport interface LabelProps\n extends React.LabelHTMLAttributes<HTMLLabelElement>,\n VariantProps<typeof labelVariants> {\n required?: boolean;\n}\n\nexport const Label = forwardRef<HTMLLabelElement, LabelProps>(\n ({ className, size, error, required, children, ...props }, ref) => {\n return (\n <label\n ref={ref}\n className={cn(labelVariants({ size, error }), className)}\n {...props}\n >\n {children}\n {required && <span className=\"text-[var(--ui-error)] ml-0.5\" aria-hidden=\"true\">*</span>}\n </label>\n );\n }\n);\n\nLabel.displayName = 'Label';\n"]}
@@ -0,0 +1,314 @@
1
+ import { Label } from './chunk-D7FB3TCA.js';
2
+ import { cn } from './chunk-2YJBW4E2.js';
3
+ import { createContext, forwardRef, useId, useState, useRef, useImperativeHandle, useEffect, useContext } from 'react';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+ import { Minus, Check, X } from 'lucide-react';
6
+ import { cva } from 'class-variance-authority';
7
+
8
+ var FormFieldContext = createContext(null);
9
+ function useFormField() {
10
+ const context = useContext(FormFieldContext);
11
+ return context;
12
+ }
13
+ var FormField = forwardRef(
14
+ ({ className, isRequired, isInvalid, isDisabled, children, ...props }, ref) => {
15
+ const generatedId = useId();
16
+ const id = props.id || generatedId;
17
+ const labelId = `${id}-label`;
18
+ const descriptionId = `${id}-description`;
19
+ const errorId = `${id}-error`;
20
+ return /* @__PURE__ */ jsx(
21
+ FormFieldContext.Provider,
22
+ {
23
+ value: {
24
+ id,
25
+ labelId,
26
+ descriptionId,
27
+ errorId,
28
+ isRequired,
29
+ isInvalid,
30
+ isDisabled
31
+ },
32
+ children: /* @__PURE__ */ jsx("div", { ref, className: cn("space-y-1.5 w-full", className), ...props, children })
33
+ }
34
+ );
35
+ }
36
+ );
37
+ FormField.displayName = "FormField";
38
+ var FormLabel = forwardRef(
39
+ ({ className, required, children, ...props }, ref) => {
40
+ const context = useFormField();
41
+ const isRequired = required ?? context?.isRequired;
42
+ const isError = context?.isInvalid;
43
+ return /* @__PURE__ */ jsx(
44
+ Label,
45
+ {
46
+ ref,
47
+ id: context?.labelId,
48
+ htmlFor: context?.id,
49
+ required: isRequired,
50
+ error: isError,
51
+ className,
52
+ ...props,
53
+ children
54
+ }
55
+ );
56
+ }
57
+ );
58
+ FormLabel.displayName = "FormLabel";
59
+ var FormHelperText = forwardRef(
60
+ ({ className, children, ...props }, ref) => {
61
+ const context = useFormField();
62
+ return /* @__PURE__ */ jsx(
63
+ "p",
64
+ {
65
+ ref,
66
+ id: context?.descriptionId,
67
+ className: cn("text-xs text-[var(--ui-text-muted)]", className),
68
+ ...props,
69
+ children
70
+ }
71
+ );
72
+ }
73
+ );
74
+ FormHelperText.displayName = "FormHelperText";
75
+ var FormErrorMessage = forwardRef(
76
+ ({ className, children, ...props }, ref) => {
77
+ const context = useFormField();
78
+ if (!context?.isInvalid && !children) return null;
79
+ return /* @__PURE__ */ jsx(
80
+ "p",
81
+ {
82
+ ref,
83
+ id: context?.errorId,
84
+ role: "alert",
85
+ className: cn("text-xs font-medium text-[var(--ui-error)]", className),
86
+ ...props,
87
+ children
88
+ }
89
+ );
90
+ }
91
+ );
92
+ FormErrorMessage.displayName = "FormErrorMessage";
93
+ var CheckboxGroupContext = createContext(null);
94
+ var useCheckboxGroup = () => useContext(CheckboxGroupContext);
95
+ var CheckboxGroup = forwardRef(
96
+ ({
97
+ className,
98
+ orientation = "vertical",
99
+ children,
100
+ value: controlledValue,
101
+ defaultValue = [],
102
+ onChange,
103
+ disabled,
104
+ name,
105
+ ...props
106
+ }, ref) => {
107
+ const [internalValue, setInternalValue] = useState(defaultValue);
108
+ const isControlled = controlledValue !== void 0;
109
+ const value = isControlled ? controlledValue : internalValue;
110
+ const handleValueChange = (nextValue) => {
111
+ if (!isControlled) {
112
+ setInternalValue(nextValue);
113
+ }
114
+ onChange?.(nextValue);
115
+ };
116
+ return /* @__PURE__ */ jsx(
117
+ CheckboxGroupContext.Provider,
118
+ {
119
+ value: {
120
+ value,
121
+ onChange: handleValueChange,
122
+ disabled,
123
+ name
124
+ },
125
+ children: /* @__PURE__ */ jsx(
126
+ "div",
127
+ {
128
+ ref,
129
+ role: "group",
130
+ className: cn(
131
+ "flex gap-2",
132
+ orientation === "vertical" ? "flex-col" : "flex-row flex-wrap items-center",
133
+ className
134
+ ),
135
+ ...props,
136
+ children
137
+ }
138
+ )
139
+ }
140
+ );
141
+ }
142
+ );
143
+ CheckboxGroup.displayName = "CheckboxGroup";
144
+ var checkboxVariants = cva(
145
+ "peer shrink-0 rounded-[var(--ui-radius-sm)] border border-[var(--ui-border-default)] bg-[var(--ui-bg-surface)] transition-all flex items-center justify-center text-[var(--ui-primary-fg)] peer-focus-visible:ring-2 peer-focus-visible:ring-[var(--ui-primary)] peer-focus-visible:ring-offset-2",
146
+ {
147
+ variants: {
148
+ size: {
149
+ sm: "w-4 h-4 text-xs",
150
+ md: "w-5 h-5 text-sm",
151
+ lg: "w-6 h-6 text-base"
152
+ }
153
+ },
154
+ defaultVariants: {
155
+ size: "md"
156
+ }
157
+ }
158
+ );
159
+ var Checkbox = forwardRef(
160
+ ({
161
+ className,
162
+ size,
163
+ indeterminate = false,
164
+ label,
165
+ checked,
166
+ defaultChecked = false,
167
+ disabled,
168
+ id,
169
+ name,
170
+ value: propValue,
171
+ onChange,
172
+ onCheckedChange,
173
+ ...props
174
+ }, ref) => {
175
+ const formField = useFormField();
176
+ const group = useCheckboxGroup();
177
+ const isGroupMember = group !== null && propValue !== void 0;
178
+ const isDisabled = disabled ?? group?.disabled ?? formField?.isDisabled ?? false;
179
+ const checkboxId = id || formField?.id;
180
+ const checkboxName = name || group?.name;
181
+ const isControlled = checked !== void 0;
182
+ const [internalChecked, setInternalChecked] = useState(defaultChecked);
183
+ const isChecked = isGroupMember ? group.value.includes(String(propValue)) : isControlled ? Boolean(checked) : internalChecked;
184
+ const innerRef = useRef(null);
185
+ useImperativeHandle(ref, () => innerRef.current);
186
+ useEffect(() => {
187
+ if (innerRef.current) {
188
+ innerRef.current.indeterminate = Boolean(indeterminate);
189
+ }
190
+ }, [indeterminate]);
191
+ const handleChange = (e) => {
192
+ if (isDisabled) return;
193
+ const newChecked = e.target.checked;
194
+ if (!isControlled && !isGroupMember) {
195
+ setInternalChecked(newChecked);
196
+ }
197
+ if (isGroupMember && group) {
198
+ const val = String(propValue);
199
+ const next = newChecked ? [...group.value, val] : group.value.filter((v) => v !== val);
200
+ group.onChange(next);
201
+ }
202
+ onChange?.(e);
203
+ onCheckedChange?.(newChecked);
204
+ };
205
+ const isVisualActive = isChecked || indeterminate;
206
+ return /* @__PURE__ */ jsxs(
207
+ "label",
208
+ {
209
+ className: cn(
210
+ "inline-flex items-center gap-2 select-none cursor-pointer group",
211
+ isDisabled && "cursor-not-allowed opacity-50"
212
+ ),
213
+ children: [
214
+ /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
215
+ /* @__PURE__ */ jsx(
216
+ "input",
217
+ {
218
+ ref: innerRef,
219
+ type: "checkbox",
220
+ id: checkboxId,
221
+ name: checkboxName,
222
+ value: propValue,
223
+ disabled: isDisabled,
224
+ checked: isChecked,
225
+ onChange: handleChange,
226
+ "aria-checked": indeterminate ? "mixed" : isChecked,
227
+ className: "sr-only peer",
228
+ ...props
229
+ }
230
+ ),
231
+ /* @__PURE__ */ jsx(
232
+ "div",
233
+ {
234
+ className: cn(
235
+ checkboxVariants({ size }),
236
+ isVisualActive ? "bg-[var(--ui-primary)] border-[var(--ui-primary)] text-white" : "hover:border-[var(--ui-border-strong)]",
237
+ className
238
+ ),
239
+ children: indeterminate ? /* @__PURE__ */ jsx(Minus, { className: "w-3.5 h-3.5 stroke-[3]" }) : isChecked && /* @__PURE__ */ jsx(Check, { className: "w-3.5 h-3.5 stroke-[3]" })
240
+ }
241
+ )
242
+ ] }),
243
+ label && /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-[var(--ui-text-primary)]", children: label })
244
+ ]
245
+ }
246
+ );
247
+ }
248
+ );
249
+ Checkbox.displayName = "Checkbox";
250
+ var chipVariants = cva(
251
+ "inline-flex items-center gap-1.5 rounded-full font-medium transition-colors select-none",
252
+ {
253
+ variants: {
254
+ variant: {
255
+ default: "bg-[var(--ui-bg-tertiary)] text-[var(--ui-text-primary)] border border-[var(--ui-border-default)]",
256
+ primary: "bg-[var(--ui-primary)]/15 text-[var(--ui-primary)] border border-[var(--ui-primary)]/30",
257
+ secondary: "bg-[var(--ui-secondary)]/15 text-[var(--ui-secondary)] border border-[var(--ui-secondary)]/30",
258
+ success: "bg-[var(--ui-success-subtle)] text-[var(--ui-success)] border border-[var(--ui-success)]/30",
259
+ warning: "bg-[var(--ui-warning-subtle)] text-[var(--ui-warning)] border border-[var(--ui-warning)]/30",
260
+ error: "bg-[var(--ui-error-subtle)] text-[var(--ui-error)] border border-[var(--ui-error)]/30"
261
+ },
262
+ size: {
263
+ sm: "h-6 px-2.5 text-xs",
264
+ md: "h-7 px-3 text-xs",
265
+ lg: "h-8 px-3.5 text-sm"
266
+ },
267
+ clickable: {
268
+ true: "cursor-pointer hover:opacity-80 active:scale-95",
269
+ false: ""
270
+ }
271
+ },
272
+ defaultVariants: {
273
+ variant: "default",
274
+ size: "md",
275
+ clickable: false
276
+ }
277
+ }
278
+ );
279
+ var Chip = forwardRef(
280
+ ({ className, variant, size, clickable, onRemove, icon, children, onClick, ...props }, ref) => {
281
+ const isClickable = Boolean(clickable || onClick);
282
+ return /* @__PURE__ */ jsxs(
283
+ "div",
284
+ {
285
+ ref,
286
+ onClick,
287
+ className: cn(chipVariants({ variant, size, clickable: isClickable }), className),
288
+ ...props,
289
+ children: [
290
+ icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: icon }),
291
+ /* @__PURE__ */ jsx("span", { children }),
292
+ onRemove && /* @__PURE__ */ jsx(
293
+ "button",
294
+ {
295
+ type: "button",
296
+ onClick: (e) => {
297
+ e.stopPropagation();
298
+ onRemove();
299
+ },
300
+ "aria-label": "Remove chip",
301
+ className: "p-0.5 rounded-full hover:bg-black/10 dark:hover:bg-white/10 transition-colors -mr-1",
302
+ children: /* @__PURE__ */ jsx(X, { className: "w-3 h-3" })
303
+ }
304
+ )
305
+ ]
306
+ }
307
+ );
308
+ }
309
+ );
310
+ Chip.displayName = "Chip";
311
+
312
+ export { Checkbox, CheckboxGroup, CheckboxGroupContext, Chip, FormErrorMessage, FormField, FormHelperText, FormLabel, checkboxVariants, chipVariants, useCheckboxGroup, useFormField };
313
+ //# sourceMappingURL=chunk-DSEL7ELZ.js.map
314
+ //# sourceMappingURL=chunk-DSEL7ELZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/forms/FormField.tsx","../src/forms/CheckboxGroup.tsx","../src/forms/Checkbox.tsx","../src/data-display/Chip.tsx"],"names":["createContext","useContext","forwardRef","jsx","useState","cva","jsxs"],"mappings":"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","file":"chunk-DSEL7ELZ.js","sourcesContent":["import React, { createContext, useContext, useId, forwardRef } from 'react';\nimport { cn } from '../utils/cn';\nimport { Label, LabelProps } from '../typography/Label';\n\ninterface FormFieldContextValue {\n id: string;\n labelId: string;\n descriptionId: string;\n errorId: string;\n isRequired?: boolean;\n isInvalid?: boolean;\n isDisabled?: boolean;\n}\n\nconst FormFieldContext = createContext<FormFieldContextValue | null>(null);\n\nexport function useFormField() {\n const context = useContext(FormFieldContext);\n return context;\n}\n\nexport interface FormFieldProps extends React.HTMLAttributes<HTMLDivElement> {\n isRequired?: boolean;\n isInvalid?: boolean;\n isDisabled?: boolean;\n}\n\nexport const FormField = forwardRef<HTMLDivElement, FormFieldProps>(\n ({ className, isRequired, isInvalid, isDisabled, children, ...props }, ref) => {\n const generatedId = useId();\n const id = props.id || generatedId;\n const labelId = `${id}-label`;\n const descriptionId = `${id}-description`;\n const errorId = `${id}-error`;\n\n return (\n <FormFieldContext.Provider\n value={{\n id,\n labelId,\n descriptionId,\n errorId,\n isRequired,\n isInvalid,\n isDisabled,\n }}\n >\n <div ref={ref} className={cn('space-y-1.5 w-full', className)} {...props}>\n {children}\n </div>\n </FormFieldContext.Provider>\n );\n }\n);\nFormField.displayName = 'FormField';\n\nexport const FormLabel = forwardRef<HTMLLabelElement, LabelProps>(\n ({ className, required, children, ...props }, ref) => {\n const context = useFormField();\n const isRequired = required ?? context?.isRequired;\n const isError = context?.isInvalid;\n\n return (\n <Label\n ref={ref}\n id={context?.labelId}\n htmlFor={context?.id}\n required={isRequired}\n error={isError}\n className={className}\n {...props}\n >\n {children}\n </Label>\n );\n }\n);\nFormLabel.displayName = 'FormLabel';\n\nexport const FormHelperText = forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n ({ className, children, ...props }, ref) => {\n const context = useFormField();\n return (\n <p\n ref={ref}\n id={context?.descriptionId}\n className={cn('text-xs text-[var(--ui-text-muted)]', className)}\n {...props}\n >\n {children}\n </p>\n );\n }\n);\nFormHelperText.displayName = 'FormHelperText';\n\nexport const FormErrorMessage = forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n ({ className, children, ...props }, ref) => {\n const context = useFormField();\n if (!context?.isInvalid && !children) return null;\n\n return (\n <p\n ref={ref}\n id={context?.errorId}\n role=\"alert\"\n className={cn('text-xs font-medium text-[var(--ui-error)]', className)}\n {...props}\n >\n {children}\n </p>\n );\n }\n);\nFormErrorMessage.displayName = 'FormErrorMessage';\n","import React, { forwardRef, useState, createContext, useContext } from 'react';\nimport { cn } from '../utils/cn';\n\nexport interface CheckboxGroupContextValue {\n value: string[];\n onChange: (value: string[]) => void;\n disabled?: boolean;\n name?: string;\n}\n\nexport const CheckboxGroupContext = createContext<CheckboxGroupContextValue | null>(null);\n\nexport const useCheckboxGroup = () => useContext(CheckboxGroupContext);\n\nexport interface CheckboxGroupProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n orientation?: 'horizontal' | 'vertical';\n value?: string[];\n defaultValue?: string[];\n onChange?: (value: string[]) => void;\n disabled?: boolean;\n name?: string;\n}\n\nexport const CheckboxGroup = forwardRef<HTMLDivElement, CheckboxGroupProps>(\n (\n {\n className,\n orientation = 'vertical',\n children,\n value: controlledValue,\n defaultValue = [],\n onChange,\n disabled,\n name,\n ...props\n },\n ref\n ) => {\n const [internalValue, setInternalValue] = useState<string[]>(defaultValue);\n const isControlled = controlledValue !== undefined;\n const value = isControlled ? controlledValue : internalValue;\n\n const handleValueChange = (nextValue: string[]) => {\n if (!isControlled) {\n setInternalValue(nextValue);\n }\n onChange?.(nextValue);\n };\n\n return (\n <CheckboxGroupContext.Provider\n value={{\n value,\n onChange: handleValueChange,\n disabled,\n name,\n }}\n >\n <div\n ref={ref}\n role=\"group\"\n className={cn(\n 'flex gap-2',\n orientation === 'vertical' ? 'flex-col' : 'flex-row flex-wrap items-center',\n className\n )}\n {...props}\n >\n {children}\n </div>\n </CheckboxGroupContext.Provider>\n );\n }\n);\n\nCheckboxGroup.displayName = 'CheckboxGroup';\n","import React, { forwardRef, useState, useEffect, useRef, useImperativeHandle } from 'react';\nimport { Check, Minus } from 'lucide-react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useFormField } from './FormField';\nimport { useCheckboxGroup } from './CheckboxGroup';\nimport { cn } from '../utils/cn';\n\nexport const checkboxVariants = cva(\n 'peer shrink-0 rounded-[var(--ui-radius-sm)] border border-[var(--ui-border-default)] bg-[var(--ui-bg-surface)] transition-all flex items-center justify-center text-[var(--ui-primary-fg)] peer-focus-visible:ring-2 peer-focus-visible:ring-[var(--ui-primary)] peer-focus-visible:ring-offset-2',\n {\n variants: {\n size: {\n sm: 'w-4 h-4 text-xs',\n md: 'w-5 h-5 text-sm',\n lg: 'w-6 h-6 text-base',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n }\n);\n\nexport interface CheckboxProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'onChange'>,\n VariantProps<typeof checkboxVariants> {\n indeterminate?: boolean;\n label?: React.ReactNode;\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n onChange?: React.ChangeEventHandler<HTMLInputElement>;\n}\n\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(\n (\n {\n className,\n size,\n indeterminate = false,\n label,\n checked,\n defaultChecked = false,\n disabled,\n id,\n name,\n value: propValue,\n onChange,\n onCheckedChange,\n ...props\n },\n ref\n ) => {\n const formField = useFormField();\n const group = useCheckboxGroup();\n\n const isGroupMember = group !== null && propValue !== undefined;\n const isDisabled = disabled ?? group?.disabled ?? formField?.isDisabled ?? false;\n const checkboxId = id || formField?.id;\n const checkboxName = name || group?.name;\n\n const isControlled = checked !== undefined;\n const [internalChecked, setInternalChecked] = useState<boolean>(defaultChecked);\n\n const isChecked = isGroupMember\n ? group.value.includes(String(propValue))\n : isControlled\n ? Boolean(checked)\n : internalChecked;\n\n const innerRef = useRef<HTMLInputElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLInputElement);\n\n useEffect(() => {\n if (innerRef.current) {\n innerRef.current.indeterminate = Boolean(indeterminate);\n }\n }, [indeterminate]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (isDisabled) return;\n const newChecked = e.target.checked;\n\n if (!isControlled && !isGroupMember) {\n setInternalChecked(newChecked);\n }\n\n if (isGroupMember && group) {\n const val = String(propValue);\n const next = newChecked\n ? [...group.value, val]\n : group.value.filter((v) => v !== val);\n group.onChange(next);\n }\n\n onChange?.(e);\n onCheckedChange?.(newChecked);\n };\n\n const isVisualActive = isChecked || indeterminate;\n\n return (\n <label\n className={cn(\n 'inline-flex items-center gap-2 select-none cursor-pointer group',\n isDisabled && 'cursor-not-allowed opacity-50'\n )}\n >\n <div className=\"relative flex items-center justify-center\">\n <input\n ref={innerRef}\n type=\"checkbox\"\n id={checkboxId}\n name={checkboxName}\n value={propValue}\n disabled={isDisabled}\n checked={isChecked}\n onChange={handleChange}\n aria-checked={indeterminate ? 'mixed' : isChecked}\n className=\"sr-only peer\"\n {...props}\n />\n <div\n className={cn(\n checkboxVariants({ size }),\n isVisualActive\n ? 'bg-[var(--ui-primary)] border-[var(--ui-primary)] text-white'\n : 'hover:border-[var(--ui-border-strong)]',\n className\n )}\n >\n {indeterminate ? (\n <Minus className=\"w-3.5 h-3.5 stroke-[3]\" />\n ) : (\n isChecked && <Check className=\"w-3.5 h-3.5 stroke-[3]\" />\n )}\n </div>\n </div>\n {label && (\n <span className=\"text-sm font-medium text-[var(--ui-text-primary)]\">\n {label}\n </span>\n )}\n </label>\n );\n }\n);\n\nCheckbox.displayName = 'Checkbox';\n","import React, { forwardRef } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { X } from 'lucide-react';\nimport { cn } from '../utils/cn';\n\nexport const chipVariants = cva(\n 'inline-flex items-center gap-1.5 rounded-full font-medium transition-colors select-none',\n {\n variants: {\n variant: {\n default: 'bg-[var(--ui-bg-tertiary)] text-[var(--ui-text-primary)] border border-[var(--ui-border-default)]',\n primary: 'bg-[var(--ui-primary)]/15 text-[var(--ui-primary)] border border-[var(--ui-primary)]/30',\n secondary: 'bg-[var(--ui-secondary)]/15 text-[var(--ui-secondary)] border border-[var(--ui-secondary)]/30',\n success: 'bg-[var(--ui-success-subtle)] text-[var(--ui-success)] border border-[var(--ui-success)]/30',\n warning: 'bg-[var(--ui-warning-subtle)] text-[var(--ui-warning)] border border-[var(--ui-warning)]/30',\n error: 'bg-[var(--ui-error-subtle)] text-[var(--ui-error)] border border-[var(--ui-error)]/30',\n },\n size: {\n sm: 'h-6 px-2.5 text-xs',\n md: 'h-7 px-3 text-xs',\n lg: 'h-8 px-3.5 text-sm',\n },\n clickable: {\n true: 'cursor-pointer hover:opacity-80 active:scale-95',\n false: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n clickable: false,\n },\n }\n);\n\nexport interface ChipProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof chipVariants> {\n onRemove?: () => void;\n icon?: React.ReactNode;\n}\n\nexport const Chip = forwardRef<HTMLDivElement, ChipProps>(\n ({ className, variant, size, clickable, onRemove, icon, children, onClick, ...props }, ref) => {\n const isClickable = Boolean(clickable || onClick);\n\n return (\n <div\n ref={ref}\n onClick={onClick}\n className={cn(chipVariants({ variant, size, clickable: isClickable }), className)}\n {...props}\n >\n {icon && <span className=\"flex-shrink-0\">{icon}</span>}\n <span>{children}</span>\n {onRemove && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onRemove();\n }}\n aria-label=\"Remove chip\"\n className=\"p-0.5 rounded-full hover:bg-black/10 dark:hover:bg-white/10 transition-colors -mr-1\"\n >\n <X className=\"w-3 h-3\" />\n </button>\n )}\n </div>\n );\n }\n);\n\nChip.displayName = 'Chip';\n"]}
@@ -1,5 +1,5 @@
1
- import { __export, cn } from './chunk-4S6L5V7X.js';
2
- import { createContext, useState, useEffect, useMemo, useContext } from 'react';
1
+ import { __export, cn } from './chunk-2YJBW4E2.js';
2
+ import { createContext, useState, useCallback, useEffect, useMemo, useContext } from 'react';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
 
5
5
  // src/core/index.ts
@@ -17,25 +17,32 @@ function ThemeProvider({
17
17
  attribute = "data-theme",
18
18
  enableSystem = true
19
19
  }) {
20
- const [theme, setThemeState] = useState(() => {
21
- if (typeof window !== "undefined" && typeof window.localStorage !== "undefined") {
22
- try {
23
- const stored = window.localStorage.getItem(storageKey);
24
- if (stored) return stored;
25
- } catch {
26
- }
27
- }
28
- return defaultTheme;
29
- });
30
- const [resolvedTheme, setResolvedTheme] = useState("dark");
31
- useEffect(() => {
32
- const root = document.documentElement;
33
- const computeResolved = (t) => {
20
+ const [theme, setThemeState] = useState(defaultTheme);
21
+ const [resolvedTheme, setResolvedTheme] = useState(
22
+ defaultTheme === "light" ? "light" : "dark"
23
+ );
24
+ const computeResolved = useCallback(
25
+ (t) => {
34
26
  if (t === "system" && enableSystem && typeof window !== "undefined" && window.matchMedia) {
35
27
  return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
36
28
  }
37
29
  return t === "dark" ? "dark" : "light";
38
- };
30
+ },
31
+ [enableSystem]
32
+ );
33
+ useEffect(() => {
34
+ if (typeof window === "undefined") return;
35
+ try {
36
+ const stored = window.localStorage?.getItem(storageKey);
37
+ if (stored && stored !== theme) {
38
+ setThemeState(stored);
39
+ }
40
+ } catch {
41
+ }
42
+ }, [storageKey, theme]);
43
+ useEffect(() => {
44
+ if (typeof document === "undefined") return;
45
+ const root = document.documentElement;
39
46
  const currentResolved = computeResolved(theme);
40
47
  setResolvedTheme(currentResolved);
41
48
  root.setAttribute(attribute, currentResolved);
@@ -52,20 +59,22 @@ function ThemeProvider({
52
59
  } catch {
53
60
  }
54
61
  }
55
- }, [theme, attribute, enableSystem, storageKey]);
62
+ }, [theme, attribute, computeResolved, storageKey]);
56
63
  useEffect(() => {
57
- if (theme !== "system" || !enableSystem) return;
64
+ if (theme !== "system" || !enableSystem || typeof window === "undefined" || !window.matchMedia) return;
58
65
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
59
66
  const handleChange = () => {
60
67
  const newResolved = mediaQuery.matches ? "dark" : "light";
61
68
  setResolvedTheme(newResolved);
62
- document.documentElement.setAttribute(attribute, newResolved);
63
- if (newResolved === "dark") {
64
- document.documentElement.classList.add("dark");
65
- document.documentElement.classList.remove("light");
66
- } else {
67
- document.documentElement.classList.add("light");
68
- document.documentElement.classList.remove("dark");
69
+ if (typeof document !== "undefined") {
70
+ document.documentElement.setAttribute(attribute, newResolved);
71
+ if (newResolved === "dark") {
72
+ document.documentElement.classList.add("dark");
73
+ document.documentElement.classList.remove("light");
74
+ } else {
75
+ document.documentElement.classList.add("light");
76
+ document.documentElement.classList.remove("dark");
77
+ }
69
78
  }
70
79
  };
71
80
  mediaQuery.addEventListener("change", handleChange);
@@ -97,5 +106,5 @@ function useTheme() {
97
106
  }
98
107
 
99
108
  export { ThemeProvider, core_exports, useTheme };
100
- //# sourceMappingURL=chunk-KJRBRTQE.js.map
101
- //# sourceMappingURL=chunk-KJRBRTQE.js.map
109
+ //# sourceMappingURL=chunk-EXFR2BFJ.js.map
110
+ //# sourceMappingURL=chunk-EXFR2BFJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/index.ts","../src/core/ThemeProvider.tsx"],"names":[],"mappings":";;;;;AAAA,IAAA,YAAA,GAAA;AAAA,QAAA,CAAA,YAAA,EAAA;AAAA,EAAA,aAAA,EAAA,MAAA,aAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,QAAA,EAAA,MAAA;AAAA,CAAA,CAAA;ACmBA,IAAM,YAAA,GAAe,cAA4C,MAAS,CAAA;AAEnE,SAAS,aAAA,CAAc;AAAA,EAC5B,QAAA;AAAA,EACA,YAAA,GAAe,MAAA;AAAA,EACf,UAAA,GAAa,UAAA;AAAA,EACb,SAAA,GAAY,YAAA;AAAA,EACZ,YAAA,GAAe;AACjB,CAAA,EAAuB;AAErB,EAAA,MAAM,CAAC,KAAA,EAAO,aAAa,CAAA,GAAI,SAAgB,YAAY,CAAA;AAC3D,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,QAAA;AAAA,IACxC,YAAA,KAAiB,UAAU,OAAA,GAAU;AAAA,GACvC;AAEA,EAAA,MAAM,eAAA,GAAkB,WAAA;AAAA,IACtB,CAAC,CAAA,KAA+B;AAC9B,MAAA,IAAI,MAAM,QAAA,IAAY,YAAA,IAAgB,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,UAAA,EAAY;AACxF,QAAA,OAAO,MAAA,CAAO,UAAA,CAAW,8BAA8B,CAAA,CAAE,UAAU,MAAA,GAAS,OAAA;AAAA,MAC9E;AACA,MAAA,OAAO,CAAA,KAAM,SAAS,MAAA,GAAS,OAAA;AAAA,IACjC,CAAA;AAAA,IACA,CAAC,YAAY;AAAA,GACf;AAGA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAEnC,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,YAAA,EAAc,OAAA,CAAQ,UAAU,CAAA;AACtD,MAAA,IAAI,MAAA,IAAU,WAAW,KAAA,EAAO;AAC9B,QAAA,aAAA,CAAc,MAAM,CAAA;AAAA,MACtB;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA,EAAG,CAAC,UAAA,EAAY,KAAK,CAAC,CAAA;AAGtB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AAErC,IAAA,MAAM,OAAO,QAAA,CAAS,eAAA;AACtB,IAAA,MAAM,eAAA,GAAkB,gBAAgB,KAAK,CAAA;AAC7C,IAAA,gBAAA,CAAiB,eAAe,CAAA;AAEhC,IAAA,IAAA,CAAK,YAAA,CAAa,WAAW,eAAe,CAAA;AAC5C,IAAA,IAAI,oBAAoB,MAAA,EAAQ;AAC9B,MAAA,IAAA,CAAK,SAAA,CAAU,IAAI,MAAM,CAAA;AACzB,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,OAAO,CAAA;AAAA,IAC/B,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,SAAA,CAAU,IAAI,OAAO,CAAA;AAC1B,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,MAAM,CAAA;AAAA,IAC9B;AAEA,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,MAAA,CAAO,iBAAiB,WAAA,EAAa;AAC/E,MAAA,IAAI;AACF,QAAA,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,UAAA,EAAY,KAAK,CAAA;AAAA,MAC/C,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,GAAG,CAAC,KAAA,EAAO,SAAA,EAAW,eAAA,EAAiB,UAAU,CAAC,CAAA;AAGlD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAA,KAAU,YAAY,CAAC,YAAA,IAAgB,OAAO,MAAA,KAAW,WAAA,IAAe,CAAC,MAAA,CAAO,UAAA,EAAY;AAEhG,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,UAAA,CAAW,8BAA8B,CAAA;AACnE,IAAA,MAAM,eAAe,MAAM;AACzB,MAAA,MAAM,WAAA,GAAc,UAAA,CAAW,OAAA,GAAU,MAAA,GAAS,OAAA;AAClD,MAAA,gBAAA,CAAiB,WAAW,CAAA;AAC5B,MAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACnC,QAAA,QAAA,CAAS,eAAA,CAAgB,YAAA,CAAa,SAAA,EAAW,WAAW,CAAA;AAC5D,QAAA,IAAI,gBAAgB,MAAA,EAAQ;AAC1B,UAAA,QAAA,CAAS,eAAA,CAAgB,SAAA,CAAU,GAAA,CAAI,MAAM,CAAA;AAC7C,UAAA,QAAA,CAAS,eAAA,CAAgB,SAAA,CAAU,MAAA,CAAO,OAAO,CAAA;AAAA,QACnD,CAAA,MAAO;AACL,UAAA,QAAA,CAAS,eAAA,CAAgB,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAC9C,UAAA,QAAA,CAAS,eAAA,CAAgB,SAAA,CAAU,MAAA,CAAO,MAAM,CAAA;AAAA,QAClD;AAAA,MACF;AAAA,IACF,CAAA;AAEA,IAAA,UAAA,CAAW,gBAAA,CAAiB,UAAU,YAAY,CAAA;AAClD,IAAA,OAAO,MAAM,UAAA,CAAW,mBAAA,CAAoB,QAAA,EAAU,YAAY,CAAA;AAAA,EACpE,CAAA,EAAG,CAAC,KAAA,EAAO,YAAA,EAAc,SAAS,CAAC,CAAA;AAEnC,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,aAAA,CAAc,CAAC,IAAA,KAAS;AACtB,MAAA,IAAI,IAAA,KAAS,QAAQ,OAAO,OAAA;AAC5B,MAAA,OAAO,MAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,OAAA;AAAA,IACZ,OAAO;AAAA,MACL,KAAA;AAAA,MACA,aAAA;AAAA,MACA,QAAA,EAAU,aAAA;AAAA,MACV;AAAA,KACF,CAAA;AAAA,IACA,CAAC,OAAO,aAAa;AAAA,GACvB;AAEA,EAAA,uBAAO,GAAA,CAAC,YAAA,CAAa,QAAA,EAAb,EAAsB,OAAe,QAAA,EAAS,CAAA;AACxD;AAEO,SAAS,QAAA,GAA6B;AAC3C,EAAA,MAAM,OAAA,GAAU,WAAW,YAAY,CAAA;AACvC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,8CAA8C,CAAA;AAAA,EAChE;AACA,EAAA,OAAO,OAAA;AACT","file":"chunk-EXFR2BFJ.js","sourcesContent":["export * from './ThemeProvider';\nexport * from '../utils/cn';\n","import React, { createContext, useContext, useEffect, useState, useMemo, useCallback } from 'react';\n\nexport type Theme = 'dark' | 'light' | 'system';\n\nexport interface ThemeProviderProps {\n children: React.ReactNode;\n defaultTheme?: Theme;\n storageKey?: string;\n attribute?: string;\n enableSystem?: boolean;\n}\n\ninterface ThemeContextType {\n theme: Theme;\n resolvedTheme: 'dark' | 'light';\n setTheme: (theme: Theme) => void;\n toggleTheme: () => void;\n}\n\nconst ThemeContext = createContext<ThemeContextType | undefined>(undefined);\n\nexport function ThemeProvider({\n children,\n defaultTheme = 'dark',\n storageKey = 'ui-theme',\n attribute = 'data-theme',\n enableSystem = true,\n}: ThemeProviderProps) {\n // Always initialize identically on SSR and initial client pass to avoid hydration mismatches\n const [theme, setThemeState] = useState<Theme>(defaultTheme);\n const [resolvedTheme, setResolvedTheme] = useState<'dark' | 'light'>(\n defaultTheme === 'light' ? 'light' : 'dark'\n );\n\n const computeResolved = useCallback(\n (t: Theme): 'dark' | 'light' => {\n if (t === 'system' && enableSystem && typeof window !== 'undefined' && window.matchMedia) {\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n return t === 'dark' ? 'dark' : 'light';\n },\n [enableSystem]\n );\n\n // Client-side initialization: read storage once mounted\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n try {\n const stored = window.localStorage?.getItem(storageKey) as Theme | null;\n if (stored && stored !== theme) {\n setThemeState(stored);\n }\n } catch {\n // Ignore storage access errors in restricted iframe/incognito environments\n }\n }, [storageKey, theme]);\n\n // Sync theme changes to DOM and storage\n useEffect(() => {\n if (typeof document === 'undefined') return;\n\n const root = document.documentElement;\n const currentResolved = computeResolved(theme);\n setResolvedTheme(currentResolved);\n\n root.setAttribute(attribute, currentResolved);\n if (currentResolved === 'dark') {\n root.classList.add('dark');\n root.classList.remove('light');\n } else {\n root.classList.add('light');\n root.classList.remove('dark');\n }\n\n if (typeof window !== 'undefined' && typeof window.localStorage !== 'undefined') {\n try {\n window.localStorage.setItem(storageKey, theme);\n } catch {\n // Ignore storage access errors\n }\n }\n }, [theme, attribute, computeResolved, storageKey]);\n\n // System media query listener\n useEffect(() => {\n if (theme !== 'system' || !enableSystem || typeof window === 'undefined' || !window.matchMedia) return;\n\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const handleChange = () => {\n const newResolved = mediaQuery.matches ? 'dark' : 'light';\n setResolvedTheme(newResolved);\n if (typeof document !== 'undefined') {\n document.documentElement.setAttribute(attribute, newResolved);\n if (newResolved === 'dark') {\n document.documentElement.classList.add('dark');\n document.documentElement.classList.remove('light');\n } else {\n document.documentElement.classList.add('light');\n document.documentElement.classList.remove('dark');\n }\n }\n };\n\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, [theme, enableSystem, attribute]);\n\n const toggleTheme = () => {\n setThemeState((prev) => {\n if (prev === 'dark') return 'light';\n return 'dark';\n });\n };\n\n const value = useMemo(\n () => ({\n theme,\n resolvedTheme,\n setTheme: setThemeState,\n toggleTheme,\n }),\n [theme, resolvedTheme]\n );\n\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;\n}\n\nexport function useTheme(): ThemeContextType {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider');\n }\n return context;\n}\n"]}