@thangnqdev/ui 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +144 -142
  3. package/bin/cli.js +125 -125
  4. package/dist/bento/index.cjs.map +1 -1
  5. package/dist/bento/index.js +2 -2
  6. package/dist/buttons/index.cjs.map +1 -1
  7. package/dist/buttons/index.js +3 -3
  8. package/dist/{chunk-77KTYOMQ.js → chunk-2OXZK6IP.js} +3 -3
  9. package/dist/chunk-2OXZK6IP.js.map +1 -0
  10. package/dist/{chunk-4CRFNALF.js → chunk-4GNFT2ZJ.js} +7 -7
  11. package/dist/chunk-4GNFT2ZJ.js.map +1 -0
  12. package/dist/{chunk-2YJBW4E2.js → chunk-4S6L5V7X.js} +2 -2
  13. package/dist/chunk-4S6L5V7X.js.map +1 -0
  14. package/dist/{chunk-I2FQBMVW.js → chunk-66VWUJEI.js} +3 -3
  15. package/dist/chunk-66VWUJEI.js.map +1 -0
  16. package/dist/{chunk-YOCGBORV.js → chunk-7NMB2Y64.js} +4 -4
  17. package/dist/chunk-7NMB2Y64.js.map +1 -0
  18. package/dist/{chunk-V52JOSDF.js → chunk-A7P3O5Z5.js} +3 -3
  19. package/dist/chunk-A7P3O5Z5.js.map +1 -0
  20. package/dist/{chunk-ME4XILG5.js → chunk-ATYGDTMK.js} +5 -5
  21. package/dist/chunk-ATYGDTMK.js.map +1 -0
  22. package/dist/{chunk-S6XJMYME.js → chunk-C4SUXMI3.js} +3 -3
  23. package/dist/chunk-C4SUXMI3.js.map +1 -0
  24. package/dist/{chunk-EXFR2BFJ.js → chunk-DUPPPGXY.js} +7 -7
  25. package/dist/chunk-DUPPPGXY.js.map +1 -0
  26. package/dist/{chunk-I5O2WCGF.js → chunk-EU2LPUYP.js} +3 -3
  27. package/dist/chunk-EU2LPUYP.js.map +1 -0
  28. package/dist/{chunk-D7FB3TCA.js → chunk-GXI2H5XA.js} +3 -3
  29. package/dist/chunk-GXI2H5XA.js.map +1 -0
  30. package/dist/{chunk-ADO3SVUA.js → chunk-IABPUCAQ.js} +2 -2
  31. package/dist/chunk-IABPUCAQ.js.map +1 -0
  32. package/dist/{chunk-PC5SZFZC.js → chunk-JOKEKOP3.js} +8 -8
  33. package/dist/chunk-JOKEKOP3.js.map +1 -0
  34. package/dist/{chunk-GXWB6BSY.js → chunk-KUQWUTZA.js} +4 -4
  35. package/dist/chunk-KUQWUTZA.js.map +1 -0
  36. package/dist/{chunk-ZEDXARXW.js → chunk-U3J4UPV3.js} +2 -2
  37. package/dist/chunk-U3J4UPV3.js.map +1 -0
  38. package/dist/{chunk-DSEL7ELZ.js → chunk-VE2PNSDQ.js} +4 -4
  39. package/dist/chunk-VE2PNSDQ.js.map +1 -0
  40. package/dist/{chunk-YJ64RI7J.js → chunk-WAFHC4DQ.js} +3 -3
  41. package/dist/chunk-WAFHC4DQ.js.map +1 -0
  42. package/dist/{chunk-W5WNWTQC.js → chunk-YJ67WYVW.js} +5 -5
  43. package/dist/chunk-YJ67WYVW.js.map +1 -0
  44. package/dist/{chunk-4MS6ZHFQ.js → chunk-Z427NPMU.js} +7 -7
  45. package/dist/chunk-Z427NPMU.js.map +1 -0
  46. package/dist/core/index.cjs +4 -4
  47. package/dist/core/index.cjs.map +1 -1
  48. package/dist/core/index.js +2 -2
  49. package/dist/data-display/index.cjs.map +1 -1
  50. package/dist/data-display/index.js +5 -5
  51. package/dist/feedback/index.cjs.map +1 -1
  52. package/dist/feedback/index.js +2 -2
  53. package/dist/forms/index.cjs.map +1 -1
  54. package/dist/forms/index.js +8 -8
  55. package/dist/glass/index.cjs.map +1 -1
  56. package/dist/glass/index.js +2 -2
  57. package/dist/index.cjs +4 -4
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.js +19 -19
  60. package/dist/layout/index.cjs.map +1 -1
  61. package/dist/layout/index.js +2 -2
  62. package/dist/navigation/index.cjs.map +1 -1
  63. package/dist/navigation/index.js +6 -6
  64. package/dist/overlays/index.cjs.map +1 -1
  65. package/dist/overlays/index.js +7 -7
  66. package/dist/reset.css +45 -45
  67. package/dist/tokens.css +11 -11
  68. package/dist/typography/index.cjs.map +1 -1
  69. package/dist/typography/index.js +4 -4
  70. package/llms.txt +3 -3
  71. package/package.json +165 -165
  72. package/scripts/postinstall.js +125 -125
  73. package/src/bento/BentoCard.tsx +140 -140
  74. package/src/bento/BentoGrid.tsx +50 -50
  75. package/src/bento/index.ts +2 -2
  76. package/src/bento/tokens.css +46 -46
  77. package/src/buttons/Button.tsx +104 -104
  78. package/src/buttons/ButtonGroup.tsx +43 -43
  79. package/src/buttons/IconButton.tsx +79 -79
  80. package/src/buttons/SplitButton.tsx +186 -186
  81. package/src/buttons/ToggleButton.tsx +157 -157
  82. package/src/buttons/index.ts +5 -5
  83. package/src/buttons/tokens.css +6 -6
  84. package/src/core/ThemeProvider.tsx +133 -133
  85. package/src/core/index.ts +2 -2
  86. package/src/core/tokens.css +134 -134
  87. package/src/data-display/Accordion.tsx +147 -147
  88. package/src/data-display/Avatar.tsx +134 -134
  89. package/src/data-display/Card.tsx +112 -112
  90. package/src/data-display/Chip.tsx +74 -74
  91. package/src/data-display/DataTablePro.tsx +534 -534
  92. package/src/data-display/StatCard.tsx +60 -60
  93. package/src/data-display/Table.tsx +74 -74
  94. package/src/data-display/Timeline.tsx +62 -62
  95. package/src/data-display/TreeView.tsx +279 -279
  96. package/src/data-display/tokens.css +4 -4
  97. package/src/feedback/Alert.tsx +80 -80
  98. package/src/feedback/EmptyState.tsx +45 -45
  99. package/src/feedback/Skeleton.tsx +66 -66
  100. package/src/feedback/Spinner.tsx +65 -65
  101. package/src/feedback/index.ts +5 -5
  102. package/src/feedback/tokens.css +4 -4
  103. package/src/forms/Checkbox.tsx +149 -149
  104. package/src/forms/CheckboxGroup.tsx +76 -76
  105. package/src/forms/Combobox.tsx +512 -512
  106. package/src/forms/DatePicker.tsx +784 -784
  107. package/src/forms/FileUpload.tsx +266 -266
  108. package/src/forms/FormField.tsx +115 -115
  109. package/src/forms/Input.tsx +151 -151
  110. package/src/forms/NumberInput.tsx +262 -262
  111. package/src/forms/PasswordInput.tsx +35 -35
  112. package/src/forms/PinInput.tsx +139 -139
  113. package/src/forms/Radio.tsx +142 -142
  114. package/src/forms/RangeSlider.tsx +237 -237
  115. package/src/forms/SearchInput.tsx +34 -34
  116. package/src/forms/Select.tsx +103 -103
  117. package/src/forms/Slider.tsx +85 -85
  118. package/src/forms/Textarea.tsx +114 -114
  119. package/src/forms/tokens.css +6 -6
  120. package/src/glass/GlassButton.tsx +59 -59
  121. package/src/glass/GlassCard.tsx +71 -71
  122. package/src/glass/index.ts +3 -3
  123. package/src/glass/tokens.css +81 -81
  124. package/src/index.ts +26 -26
  125. package/src/layout/AspectRatio.tsx +39 -39
  126. package/src/layout/Container.tsx +53 -53
  127. package/src/layout/Divider.tsx +61 -61
  128. package/src/layout/Flex.tsx +79 -79
  129. package/src/layout/Grid.tsx +124 -124
  130. package/src/layout/PageLayout.tsx +59 -59
  131. package/src/layout/Section.tsx +47 -47
  132. package/src/layout/Spacer.tsx +30 -30
  133. package/src/layout/Stack.tsx +88 -88
  134. package/src/layout/tokens.css +8 -8
  135. package/src/navigation/Breadcrumb.tsx +73 -73
  136. package/src/navigation/CommandPalette.tsx +142 -142
  137. package/src/navigation/DropdownMenu.tsx +244 -244
  138. package/src/navigation/Pagination.tsx +114 -114
  139. package/src/navigation/Stepper.tsx +93 -93
  140. package/src/navigation/Tabs.tsx +265 -265
  141. package/src/navigation/index.ts +6 -6
  142. package/src/navigation/tokens.css +4 -4
  143. package/src/overlays/AlertDialog.tsx +63 -63
  144. package/src/overlays/BottomSheet.tsx +143 -143
  145. package/src/overlays/ContextMenu.tsx +161 -161
  146. package/src/overlays/Drawer.tsx +160 -160
  147. package/src/overlays/FocusTrap.tsx +122 -122
  148. package/src/overlays/Modal.tsx +296 -296
  149. package/src/overlays/Popover.tsx +156 -156
  150. package/src/overlays/Portal.tsx +23 -23
  151. package/src/overlays/Toast.tsx +175 -175
  152. package/src/overlays/Tooltip.tsx +125 -125
  153. package/src/overlays/tokens.css +8 -8
  154. package/src/registry/components.ts +1368 -1368
  155. package/src/styles/components.css +39 -39
  156. package/src/styles/index.css +5 -5
  157. package/src/styles/reset.css +45 -45
  158. package/src/styles/tokens.css +11 -11
  159. package/src/typography/Blockquote.tsx +32 -32
  160. package/src/typography/Code.tsx +89 -89
  161. package/src/typography/Heading.tsx +56 -56
  162. package/src/typography/Kbd.tsx +25 -25
  163. package/src/typography/Label.tsx +47 -47
  164. package/src/typography/Link.tsx +56 -56
  165. package/src/typography/Text.tsx +62 -62
  166. package/src/typography/index.ts +7 -7
  167. package/src/typography/tokens.css +5 -5
  168. package/src/utils/cn.ts +6 -6
  169. package/src/utils/scroll-lock.ts +19 -19
  170. package/src/utils/useControllableState.ts +54 -54
  171. package/ui-contract.json +1 -1
  172. package/dist/chunk-2YJBW4E2.js.map +0 -1
  173. package/dist/chunk-4CRFNALF.js.map +0 -1
  174. package/dist/chunk-4MS6ZHFQ.js.map +0 -1
  175. package/dist/chunk-77KTYOMQ.js.map +0 -1
  176. package/dist/chunk-ADO3SVUA.js.map +0 -1
  177. package/dist/chunk-D7FB3TCA.js.map +0 -1
  178. package/dist/chunk-DSEL7ELZ.js.map +0 -1
  179. package/dist/chunk-EXFR2BFJ.js.map +0 -1
  180. package/dist/chunk-GXWB6BSY.js.map +0 -1
  181. package/dist/chunk-I2FQBMVW.js.map +0 -1
  182. package/dist/chunk-I5O2WCGF.js.map +0 -1
  183. package/dist/chunk-ME4XILG5.js.map +0 -1
  184. package/dist/chunk-PC5SZFZC.js.map +0 -1
  185. package/dist/chunk-S6XJMYME.js.map +0 -1
  186. package/dist/chunk-V52JOSDF.js.map +0 -1
  187. package/dist/chunk-W5WNWTQC.js.map +0 -1
  188. package/dist/chunk-YJ64RI7J.js.map +0 -1
  189. package/dist/chunk-YOCGBORV.js.map +0 -1
  190. package/dist/chunk-ZEDXARXW.js.map +0 -1
@@ -1,134 +1,134 @@
1
- :root {
2
- /* ==========================================================================
3
- APPLE DESIGN SYSTEM TOKENS — LIGHT MODE (ALABASTER & FROSTED GLASS)
4
- ========================================================================== */
5
- --ui-bg-primary: #f5f5f7;
6
- --ui-bg-page: #f5f5f7;
7
- --ui-bg-secondary: #ffffff;
8
- --ui-bg-tertiary: #e8e8ed;
9
- --ui-bg-surface: rgba(255, 255, 255, 0.75);
10
- --ui-bg-overlay: rgba(0, 0, 0, 0.28);
11
-
12
- --ui-border-subtle: rgba(0, 0, 0, 0.06);
13
- --ui-border-default: rgba(0, 0, 0, 0.10);
14
- --ui-border-strong: rgba(0, 0, 0, 0.20);
15
-
16
- --ui-text-primary: #1d1d1f;
17
- --ui-text-secondary: #515154;
18
- --ui-text-muted: #86868b;
19
- --ui-text-inverse: #ffffff;
20
-
21
- /* Typography Fonts */
22
- --ui-font-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', Inter, sans-serif;
23
- --ui-font-mono: 'SF Mono', ui-monospace, Menlo, Monaco, Consolas, monospace;
24
-
25
- /* Apple System Colors */
26
- --ui-primary: #0071e3;
27
- --ui-primary-hover: #0077ed;
28
- --ui-primary-fg: #ffffff;
29
- --ui-primary-glow: rgba(0, 113, 227, 0.25);
30
-
31
- --ui-secondary: #06c;
32
- --ui-secondary-hover: #0071e3;
33
- --ui-secondary-fg: #ffffff;
34
- --ui-secondary-glow: rgba(0, 102, 204, 0.25);
35
-
36
- --ui-accent: #af52de;
37
- --ui-accent-hover: #bf5af2;
38
- --ui-accent-fg: #ffffff;
39
-
40
- /* Apple Semantic Feedback */
41
- --ui-success: #34c759;
42
- --ui-success-subtle: rgba(52, 199, 89, 0.12);
43
- --ui-success-fg: #ffffff;
44
-
45
- --ui-warning: #ff9500;
46
- --ui-warning-subtle: rgba(255, 149, 0, 0.12);
47
- --ui-warning-fg: #ffffff;
48
-
49
- --ui-error: #ff3b30;
50
- --ui-error-subtle: rgba(255, 59, 48, 0.12);
51
- --ui-error-fg: #ffffff;
52
-
53
- --ui-info: #0071e3;
54
- --ui-info-subtle: rgba(0, 113, 227, 0.12);
55
- --ui-info-fg: #ffffff;
56
-
57
- /* Apple Shadows & Translucency */
58
- --ui-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
59
- --ui-shadow-md: 0 4px 14px rgba(0, 0, 0, 0.06), 0 0 1px rgba(0, 0, 0, 0.12);
60
- --ui-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.08), 0 0 1px rgba(0, 0, 0, 0.16);
61
- --ui-shadow-xl: 0 24px 64px rgba(0, 0, 0, 0.12), 0 0 1px rgba(0, 0, 0, 0.2);
62
- --ui-focus-ring: 0 0 0 4px rgba(0, 113, 227, 0.35);
63
-
64
- /* Radii (Apple Continuous Corners) */
65
- --ui-radius-sm: 0.5rem;
66
- --ui-radius-md: 0.75rem;
67
- --ui-radius-lg: 1.125rem;
68
- --ui-radius-xl: 1.5rem;
69
- --ui-radius-2xl: 2rem;
70
- --ui-radius-full: 9999px;
71
-
72
- /* Transitions (Apple Spring Curves) */
73
- --ui-transition-fast: 160ms cubic-bezier(0.25, 1, 0.5, 1);
74
- --ui-transition-normal: 280ms cubic-bezier(0.25, 1, 0.5, 1);
75
- --ui-transition-slow: 420ms cubic-bezier(0.25, 1, 0.5, 1);
76
- }
77
-
78
- .dark, [data-theme="dark"] {
79
- /* ==========================================================================
80
- APPLE DESIGN SYSTEM TOKENS — DARK MODE (VISIONOS OBSIDIAN & LIQUID GLASS)
81
- ========================================================================== */
82
- --ui-bg-primary: #000000;
83
- --ui-bg-page: #000000;
84
- --ui-bg-secondary: #161618;
85
- --ui-bg-tertiary: #242426;
86
- --ui-bg-surface: rgba(30, 30, 34, 0.72);
87
- --ui-bg-overlay: rgba(0, 0, 0, 0.75);
88
-
89
- --ui-border-subtle: rgba(255, 255, 255, 0.08);
90
- --ui-border-default: rgba(255, 255, 255, 0.14);
91
- --ui-border-strong: rgba(255, 255, 255, 0.25);
92
-
93
- --ui-text-primary: #f5f5f7;
94
- --ui-text-secondary: #a1a1a6;
95
- --ui-text-muted: #6e6e73;
96
- --ui-text-inverse: #000000;
97
-
98
- /* Apple Vision Dark System Colors */
99
- --ui-primary: #2997ff;
100
- --ui-primary-hover: #47a6ff;
101
- --ui-primary-fg: #ffffff;
102
- --ui-primary-glow: rgba(41, 151, 255, 0.35);
103
-
104
- --ui-secondary: #64d2ff;
105
- --ui-secondary-hover: #7dd9ff;
106
- --ui-secondary-fg: #000000;
107
- --ui-secondary-glow: rgba(100, 210, 255, 0.35);
108
-
109
- --ui-accent: #bf5af2;
110
- --ui-accent-hover: #d27fff;
111
- --ui-accent-fg: #ffffff;
112
-
113
- --ui-success: #30d158;
114
- --ui-success-subtle: rgba(48, 209, 88, 0.15);
115
- --ui-success-fg: #ffffff;
116
-
117
- --ui-warning: #ffd60a;
118
- --ui-warning-subtle: rgba(255, 214, 10, 0.15);
119
- --ui-warning-fg: #000000;
120
-
121
- --ui-error: #ff453a;
122
- --ui-error-subtle: rgba(255, 69, 58, 0.15);
123
- --ui-error-fg: #ffffff;
124
-
125
- --ui-info: #0a84ff;
126
- --ui-info-subtle: rgba(10, 132, 255, 0.15);
127
- --ui-info-fg: #ffffff;
128
-
129
- --ui-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.6);
130
- --ui-shadow-md: 0 8px 24px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.12);
131
- --ui-shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.16);
132
- --ui-shadow-xl: 0 28px 72px rgba(0, 0, 0, 0.85), inset 0 1px 0 rgba(255, 255, 255, 0.22);
133
- --ui-focus-ring: 0 0 0 4px rgba(41, 151, 255, 0.4);
134
- }
1
+ :root {
2
+ /* ==========================================================================
3
+ APPLE DESIGN SYSTEM TOKENS — LIGHT MODE (ALABASTER & FROSTED GLASS)
4
+ ========================================================================== */
5
+ --ui-bg-primary: #f5f5f7;
6
+ --ui-bg-page: #f5f5f7;
7
+ --ui-bg-secondary: #ffffff;
8
+ --ui-bg-tertiary: #e8e8ed;
9
+ --ui-bg-surface: rgba(255, 255, 255, 0.75);
10
+ --ui-bg-overlay: rgba(0, 0, 0, 0.28);
11
+
12
+ --ui-border-subtle: rgba(0, 0, 0, 0.06);
13
+ --ui-border-default: rgba(0, 0, 0, 0.10);
14
+ --ui-border-strong: rgba(0, 0, 0, 0.20);
15
+
16
+ --ui-text-primary: #1d1d1f;
17
+ --ui-text-secondary: #515154;
18
+ --ui-text-muted: #86868b;
19
+ --ui-text-inverse: #ffffff;
20
+
21
+ /* Typography Fonts */
22
+ --ui-font-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', Inter, sans-serif;
23
+ --ui-font-mono: 'SF Mono', ui-monospace, Menlo, Monaco, Consolas, monospace;
24
+
25
+ /* Apple System Colors */
26
+ --ui-primary: #0071e3;
27
+ --ui-primary-hover: #0077ed;
28
+ --ui-primary-fg: #ffffff;
29
+ --ui-primary-glow: rgba(0, 113, 227, 0.25);
30
+
31
+ --ui-secondary: #06c;
32
+ --ui-secondary-hover: #0071e3;
33
+ --ui-secondary-fg: #ffffff;
34
+ --ui-secondary-glow: rgba(0, 102, 204, 0.25);
35
+
36
+ --ui-accent: #af52de;
37
+ --ui-accent-hover: #bf5af2;
38
+ --ui-accent-fg: #ffffff;
39
+
40
+ /* Apple Semantic Feedback */
41
+ --ui-success: #34c759;
42
+ --ui-success-subtle: rgba(52, 199, 89, 0.12);
43
+ --ui-success-fg: #ffffff;
44
+
45
+ --ui-warning: #ff9500;
46
+ --ui-warning-subtle: rgba(255, 149, 0, 0.12);
47
+ --ui-warning-fg: #ffffff;
48
+
49
+ --ui-error: #ff3b30;
50
+ --ui-error-subtle: rgba(255, 59, 48, 0.12);
51
+ --ui-error-fg: #ffffff;
52
+
53
+ --ui-info: #0071e3;
54
+ --ui-info-subtle: rgba(0, 113, 227, 0.12);
55
+ --ui-info-fg: #ffffff;
56
+
57
+ /* Apple Shadows & Translucency */
58
+ --ui-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
59
+ --ui-shadow-md: 0 4px 14px rgba(0, 0, 0, 0.06), 0 0 1px rgba(0, 0, 0, 0.12);
60
+ --ui-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.08), 0 0 1px rgba(0, 0, 0, 0.16);
61
+ --ui-shadow-xl: 0 24px 64px rgba(0, 0, 0, 0.12), 0 0 1px rgba(0, 0, 0, 0.2);
62
+ --ui-focus-ring: 0 0 0 4px rgba(0, 113, 227, 0.35);
63
+
64
+ /* Radii (Apple Continuous Corners) */
65
+ --ui-radius-sm: 0.5rem;
66
+ --ui-radius-md: 0.75rem;
67
+ --ui-radius-lg: 1.125rem;
68
+ --ui-radius-xl: 1.5rem;
69
+ --ui-radius-2xl: 2rem;
70
+ --ui-radius-full: 9999px;
71
+
72
+ /* Transitions (Apple Spring Curves) */
73
+ --ui-transition-fast: 160ms cubic-bezier(0.25, 1, 0.5, 1);
74
+ --ui-transition-normal: 280ms cubic-bezier(0.25, 1, 0.5, 1);
75
+ --ui-transition-slow: 420ms cubic-bezier(0.25, 1, 0.5, 1);
76
+ }
77
+
78
+ .dark, [data-theme="dark"] {
79
+ /* ==========================================================================
80
+ APPLE DESIGN SYSTEM TOKENS — DARK MODE (VISIONOS OBSIDIAN & LIQUID GLASS)
81
+ ========================================================================== */
82
+ --ui-bg-primary: #000000;
83
+ --ui-bg-page: #000000;
84
+ --ui-bg-secondary: #161618;
85
+ --ui-bg-tertiary: #242426;
86
+ --ui-bg-surface: rgba(30, 30, 34, 0.72);
87
+ --ui-bg-overlay: rgba(0, 0, 0, 0.75);
88
+
89
+ --ui-border-subtle: rgba(255, 255, 255, 0.08);
90
+ --ui-border-default: rgba(255, 255, 255, 0.14);
91
+ --ui-border-strong: rgba(255, 255, 255, 0.25);
92
+
93
+ --ui-text-primary: #f5f5f7;
94
+ --ui-text-secondary: #a1a1a6;
95
+ --ui-text-muted: #6e6e73;
96
+ --ui-text-inverse: #000000;
97
+
98
+ /* Apple Vision Dark System Colors */
99
+ --ui-primary: #2997ff;
100
+ --ui-primary-hover: #47a6ff;
101
+ --ui-primary-fg: #ffffff;
102
+ --ui-primary-glow: rgba(41, 151, 255, 0.35);
103
+
104
+ --ui-secondary: #64d2ff;
105
+ --ui-secondary-hover: #7dd9ff;
106
+ --ui-secondary-fg: #000000;
107
+ --ui-secondary-glow: rgba(100, 210, 255, 0.35);
108
+
109
+ --ui-accent: #bf5af2;
110
+ --ui-accent-hover: #d27fff;
111
+ --ui-accent-fg: #ffffff;
112
+
113
+ --ui-success: #30d158;
114
+ --ui-success-subtle: rgba(48, 209, 88, 0.15);
115
+ --ui-success-fg: #ffffff;
116
+
117
+ --ui-warning: #ffd60a;
118
+ --ui-warning-subtle: rgba(255, 214, 10, 0.15);
119
+ --ui-warning-fg: #000000;
120
+
121
+ --ui-error: #ff453a;
122
+ --ui-error-subtle: rgba(255, 69, 58, 0.15);
123
+ --ui-error-fg: #ffffff;
124
+
125
+ --ui-info: #0a84ff;
126
+ --ui-info-subtle: rgba(10, 132, 255, 0.15);
127
+ --ui-info-fg: #ffffff;
128
+
129
+ --ui-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.6);
130
+ --ui-shadow-md: 0 8px 24px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.12);
131
+ --ui-shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.16);
132
+ --ui-shadow-xl: 0 28px 72px rgba(0, 0, 0, 0.85), inset 0 1px 0 rgba(255, 255, 255, 0.22);
133
+ --ui-focus-ring: 0 0 0 4px rgba(41, 151, 255, 0.4);
134
+ }
@@ -1,147 +1,147 @@
1
- import React, { createContext, useContext, useState, forwardRef } from 'react';
2
- import { ChevronDown } from 'lucide-react';
3
- import { cn } from '../utils/cn';
4
-
5
- interface AccordionContextType {
6
- openItems: string[];
7
- toggleItem: (id: string) => void;
8
- }
9
-
10
- const AccordionContext = createContext<AccordionContextType | null>(null);
11
-
12
- export function useAccordion() {
13
- const context = useContext(AccordionContext);
14
- if (!context) throw new Error('AccordionItem components must be used within <Accordion />');
15
- return context;
16
- }
17
-
18
- export interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {
19
- type?: 'single' | 'multiple';
20
- defaultValue?: string | string[];
21
- value?: string | string[];
22
- onValueChange?: (val: any) => void;
23
- }
24
-
25
- export const Accordion = forwardRef<HTMLDivElement, AccordionProps>(
26
- (
27
- {
28
- className,
29
- type = 'single',
30
- defaultValue,
31
- value: controlledValue,
32
- onValueChange,
33
- children,
34
- ...props
35
- },
36
- ref
37
- ) => {
38
- const [internalOpen, setInternalOpen] = useState<string[]>(() => {
39
- if (Array.isArray(defaultValue)) return defaultValue;
40
- if (typeof defaultValue === 'string') return [defaultValue];
41
- return [];
42
- });
43
-
44
- const openItems =
45
- controlledValue !== undefined
46
- ? Array.isArray(controlledValue)
47
- ? controlledValue
48
- : [controlledValue]
49
- : internalOpen;
50
-
51
- const toggleItem = (id: string) => {
52
- let next: string[];
53
- if (type === 'single') {
54
- next = openItems.includes(id) ? [] : [id];
55
- } else {
56
- next = openItems.includes(id) ? openItems.filter((i) => i !== id) : [...openItems, id];
57
- }
58
-
59
- setInternalOpen(next);
60
- onValueChange?.(type === 'single' ? next[0] || '' : next);
61
- };
62
-
63
- return (
64
- <AccordionContext.Provider value={{ openItems, toggleItem }}>
65
- <div ref={ref} className={cn('divide-y divide-[var(--ui-border-subtle)] border-y border-[var(--ui-border-subtle)]', className)} {...props}>
66
- {children}
67
- </div>
68
- </AccordionContext.Provider>
69
- );
70
- }
71
- );
72
- Accordion.displayName = 'Accordion';
73
-
74
- interface AccordionItemContextType {
75
- id: string;
76
- }
77
-
78
- const AccordionItemContext = createContext<AccordionItemContextType | null>(null);
79
-
80
- export interface AccordionItemProps extends React.HTMLAttributes<HTMLDivElement> {
81
- value: string;
82
- }
83
-
84
- export const AccordionItem = forwardRef<HTMLDivElement, AccordionItemProps>(
85
- ({ className, value, children, ...props }, ref) => {
86
- return (
87
- <AccordionItemContext.Provider value={{ id: value }}>
88
- <div ref={ref} className={cn('w-full', className)} {...props}>
89
- {children}
90
- </div>
91
- </AccordionItemContext.Provider>
92
- );
93
- }
94
- );
95
- AccordionItem.displayName = 'AccordionItem';
96
-
97
- export const AccordionTrigger = forwardRef<HTMLButtonElement, React.ButtonHTMLAttributes<HTMLButtonElement>>(
98
- ({ className, children, ...props }, ref) => {
99
- const { openItems, toggleItem } = useAccordion();
100
- const item = useContext(AccordionItemContext);
101
- const isOpen = item ? openItems.includes(item.id) : false;
102
-
103
- return (
104
- <button
105
- ref={ref}
106
- type="button"
107
- aria-expanded={isOpen}
108
- onClick={() => item && toggleItem(item.id)}
109
- className={cn(
110
- 'flex w-full items-center justify-between py-4 text-sm font-semibold text-[var(--ui-text-primary)] transition-all hover:text-[var(--ui-primary)] text-left',
111
- className
112
- )}
113
- {...props}
114
- >
115
- {children}
116
- <ChevronDown
117
- className={cn(
118
- 'h-4 w-4 shrink-0 text-[var(--ui-text-muted)] transition-transform duration-200',
119
- isOpen && 'rotate-180 text-[var(--ui-primary)]'
120
- )}
121
- />
122
- </button>
123
- );
124
- }
125
- );
126
- AccordionTrigger.displayName = 'AccordionTrigger';
127
-
128
- export const AccordionContent = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
129
- ({ className, children, ...props }, ref) => {
130
- const { openItems } = useAccordion();
131
- const item = useContext(AccordionItemContext);
132
- const isOpen = item ? openItems.includes(item.id) : false;
133
-
134
- if (!isOpen) return null;
135
-
136
- return (
137
- <div
138
- ref={ref}
139
- className={cn('pb-4 pt-0 text-sm text-[var(--ui-text-secondary)] animate-in fade-in duration-200', className)}
140
- {...props}
141
- >
142
- {children}
143
- </div>
144
- );
145
- }
146
- );
147
- AccordionContent.displayName = 'AccordionContent';
1
+ import React, { createContext, useContext, useState, forwardRef } from 'react';
2
+ import { ChevronDown } from 'lucide-react';
3
+ import { cn } from '../utils/cn';
4
+
5
+ interface AccordionContextType {
6
+ openItems: string[];
7
+ toggleItem: (id: string) => void;
8
+ }
9
+
10
+ const AccordionContext = createContext<AccordionContextType | null>(null);
11
+
12
+ export function useAccordion() {
13
+ const context = useContext(AccordionContext);
14
+ if (!context) throw new Error('AccordionItem components must be used within <Accordion />');
15
+ return context;
16
+ }
17
+
18
+ export interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {
19
+ type?: 'single' | 'multiple';
20
+ defaultValue?: string | string[];
21
+ value?: string | string[];
22
+ onValueChange?: (val: any) => void;
23
+ }
24
+
25
+ export const Accordion = forwardRef<HTMLDivElement, AccordionProps>(
26
+ (
27
+ {
28
+ className,
29
+ type = 'single',
30
+ defaultValue,
31
+ value: controlledValue,
32
+ onValueChange,
33
+ children,
34
+ ...props
35
+ },
36
+ ref
37
+ ) => {
38
+ const [internalOpen, setInternalOpen] = useState<string[]>(() => {
39
+ if (Array.isArray(defaultValue)) return defaultValue;
40
+ if (typeof defaultValue === 'string') return [defaultValue];
41
+ return [];
42
+ });
43
+
44
+ const openItems =
45
+ controlledValue !== undefined
46
+ ? Array.isArray(controlledValue)
47
+ ? controlledValue
48
+ : [controlledValue]
49
+ : internalOpen;
50
+
51
+ const toggleItem = (id: string) => {
52
+ let next: string[];
53
+ if (type === 'single') {
54
+ next = openItems.includes(id) ? [] : [id];
55
+ } else {
56
+ next = openItems.includes(id) ? openItems.filter((i) => i !== id) : [...openItems, id];
57
+ }
58
+
59
+ setInternalOpen(next);
60
+ onValueChange?.(type === 'single' ? next[0] || '' : next);
61
+ };
62
+
63
+ return (
64
+ <AccordionContext.Provider value={{ openItems, toggleItem }}>
65
+ <div ref={ref} className={cn('divide-y divide-[var(--ui-border-subtle)] border-y border-[var(--ui-border-subtle)]', className)} {...props}>
66
+ {children}
67
+ </div>
68
+ </AccordionContext.Provider>
69
+ );
70
+ }
71
+ );
72
+ Accordion.displayName = 'Accordion';
73
+
74
+ interface AccordionItemContextType {
75
+ id: string;
76
+ }
77
+
78
+ const AccordionItemContext = createContext<AccordionItemContextType | null>(null);
79
+
80
+ export interface AccordionItemProps extends React.HTMLAttributes<HTMLDivElement> {
81
+ value: string;
82
+ }
83
+
84
+ export const AccordionItem = forwardRef<HTMLDivElement, AccordionItemProps>(
85
+ ({ className, value, children, ...props }, ref) => {
86
+ return (
87
+ <AccordionItemContext.Provider value={{ id: value }}>
88
+ <div ref={ref} className={cn('w-full', className)} {...props}>
89
+ {children}
90
+ </div>
91
+ </AccordionItemContext.Provider>
92
+ );
93
+ }
94
+ );
95
+ AccordionItem.displayName = 'AccordionItem';
96
+
97
+ export const AccordionTrigger = forwardRef<HTMLButtonElement, React.ButtonHTMLAttributes<HTMLButtonElement>>(
98
+ ({ className, children, ...props }, ref) => {
99
+ const { openItems, toggleItem } = useAccordion();
100
+ const item = useContext(AccordionItemContext);
101
+ const isOpen = item ? openItems.includes(item.id) : false;
102
+
103
+ return (
104
+ <button
105
+ ref={ref}
106
+ type="button"
107
+ aria-expanded={isOpen}
108
+ onClick={() => item && toggleItem(item.id)}
109
+ className={cn(
110
+ 'flex w-full items-center justify-between py-4 text-sm font-semibold text-[var(--ui-text-primary)] transition-all hover:text-[var(--ui-primary)] text-left',
111
+ className
112
+ )}
113
+ {...props}
114
+ >
115
+ {children}
116
+ <ChevronDown
117
+ className={cn(
118
+ 'h-4 w-4 shrink-0 text-[var(--ui-text-muted)] transition-transform duration-200',
119
+ isOpen && 'rotate-180 text-[var(--ui-primary)]'
120
+ )}
121
+ />
122
+ </button>
123
+ );
124
+ }
125
+ );
126
+ AccordionTrigger.displayName = 'AccordionTrigger';
127
+
128
+ export const AccordionContent = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
129
+ ({ className, children, ...props }, ref) => {
130
+ const { openItems } = useAccordion();
131
+ const item = useContext(AccordionItemContext);
132
+ const isOpen = item ? openItems.includes(item.id) : false;
133
+
134
+ if (!isOpen) return null;
135
+
136
+ return (
137
+ <div
138
+ ref={ref}
139
+ className={cn('pb-4 pt-0 text-sm text-[var(--ui-text-secondary)] animate-in fade-in duration-200', className)}
140
+ {...props}
141
+ >
142
+ {children}
143
+ </div>
144
+ );
145
+ }
146
+ );
147
+ AccordionContent.displayName = 'AccordionContent';