@hyperpackai/hyperui 0.1.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 (321) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +82 -0
  3. package/dist/components/Accordion/index.d.ts +17 -0
  4. package/dist/components/Accordion/index.d.ts.map +1 -0
  5. package/dist/components/Accordion/index.js +46 -0
  6. package/dist/components/Alert/index.d.ts +13 -0
  7. package/dist/components/Alert/index.d.ts.map +1 -0
  8. package/dist/components/Alert/index.js +46 -0
  9. package/dist/components/AppBar/index.d.ts +19 -0
  10. package/dist/components/AppBar/index.d.ts.map +1 -0
  11. package/dist/components/AppBar/index.js +48 -0
  12. package/dist/components/AspectRatio/index.d.ts +8 -0
  13. package/dist/components/AspectRatio/index.d.ts.map +1 -0
  14. package/dist/components/AspectRatio/index.js +32 -0
  15. package/dist/components/Autocomplete/index.d.ts +21 -0
  16. package/dist/components/Autocomplete/index.d.ts.map +1 -0
  17. package/dist/components/Autocomplete/index.js +94 -0
  18. package/dist/components/Avatar/index.d.ts +12 -0
  19. package/dist/components/Avatar/index.d.ts.map +1 -0
  20. package/dist/components/Avatar/index.js +32 -0
  21. package/dist/components/AvatarGroup/index.d.ts +9 -0
  22. package/dist/components/AvatarGroup/index.d.ts.map +1 -0
  23. package/dist/components/AvatarGroup/index.js +24 -0
  24. package/dist/components/Backdrop/index.d.ts +10 -0
  25. package/dist/components/Backdrop/index.d.ts.map +1 -0
  26. package/dist/components/Backdrop/index.js +25 -0
  27. package/dist/components/Badge/index.d.ts +10 -0
  28. package/dist/components/Badge/index.d.ts.map +1 -0
  29. package/dist/components/Badge/index.js +30 -0
  30. package/dist/components/BottomNavigation/index.d.ts +16 -0
  31. package/dist/components/BottomNavigation/index.d.ts.map +1 -0
  32. package/dist/components/BottomNavigation/index.js +43 -0
  33. package/dist/components/Box/index.d.ts +21 -0
  34. package/dist/components/Box/index.d.ts.map +1 -0
  35. package/dist/components/Box/index.js +30 -0
  36. package/dist/components/Breadcrumb/index.d.ts +13 -0
  37. package/dist/components/Breadcrumb/index.d.ts.map +1 -0
  38. package/dist/components/Breadcrumb/index.js +19 -0
  39. package/dist/components/Button/index.d.ts +22 -0
  40. package/dist/components/Button/index.d.ts.map +1 -0
  41. package/dist/components/Button/index.js +93 -0
  42. package/dist/components/ButtonGroup/index.d.ts +9 -0
  43. package/dist/components/ButtonGroup/index.d.ts.map +1 -0
  44. package/dist/components/ButtonGroup/index.js +27 -0
  45. package/dist/components/Card/index.d.ts +14 -0
  46. package/dist/components/Card/index.d.ts.map +1 -0
  47. package/dist/components/Card/index.js +33 -0
  48. package/dist/components/Checkbox/index.d.ts +17 -0
  49. package/dist/components/Checkbox/index.d.ts.map +1 -0
  50. package/dist/components/Checkbox/index.js +42 -0
  51. package/dist/components/Chip/index.d.ts +18 -0
  52. package/dist/components/Chip/index.d.ts.map +1 -0
  53. package/dist/components/Chip/index.js +60 -0
  54. package/dist/components/CircularProgress/index.d.ts +14 -0
  55. package/dist/components/CircularProgress/index.d.ts.map +1 -0
  56. package/dist/components/CircularProgress/index.js +58 -0
  57. package/dist/components/ClickAwayListener/index.d.ts +11 -0
  58. package/dist/components/ClickAwayListener/index.d.ts.map +1 -0
  59. package/dist/components/ClickAwayListener/index.js +31 -0
  60. package/dist/components/Code/index.d.ts +9 -0
  61. package/dist/components/Code/index.d.ts.map +1 -0
  62. package/dist/components/Code/index.js +50 -0
  63. package/dist/components/Collapse/index.d.ts +11 -0
  64. package/dist/components/Collapse/index.d.ts.map +1 -0
  65. package/dist/components/Collapse/index.js +30 -0
  66. package/dist/components/CommandPalette/index.d.ts +26 -0
  67. package/dist/components/CommandPalette/index.d.ts.map +1 -0
  68. package/dist/components/CommandPalette/index.js +141 -0
  69. package/dist/components/Container/index.d.ts +11 -0
  70. package/dist/components/Container/index.d.ts.map +1 -0
  71. package/dist/components/Container/index.js +18 -0
  72. package/dist/components/DashboardLayout/index.d.ts +15 -0
  73. package/dist/components/DashboardLayout/index.d.ts.map +1 -0
  74. package/dist/components/DashboardLayout/index.js +67 -0
  75. package/dist/components/DataTable/index.d.ts +27 -0
  76. package/dist/components/DataTable/index.d.ts.map +1 -0
  77. package/dist/components/DataTable/index.js +59 -0
  78. package/dist/components/Dialog/index.d.ts +19 -0
  79. package/dist/components/Dialog/index.d.ts.map +1 -0
  80. package/dist/components/Dialog/index.js +96 -0
  81. package/dist/components/Divider/index.d.ts +13 -0
  82. package/dist/components/Divider/index.d.ts.map +1 -0
  83. package/dist/components/Divider/index.js +40 -0
  84. package/dist/components/Drawer/index.d.ts +17 -0
  85. package/dist/components/Drawer/index.d.ts.map +1 -0
  86. package/dist/components/Drawer/index.js +77 -0
  87. package/dist/components/DropdownMenu/index.d.ts +25 -0
  88. package/dist/components/DropdownMenu/index.d.ts.map +1 -0
  89. package/dist/components/DropdownMenu/index.js +67 -0
  90. package/dist/components/EmptyState/index.d.ts +11 -0
  91. package/dist/components/EmptyState/index.d.ts.map +1 -0
  92. package/dist/components/EmptyState/index.js +53 -0
  93. package/dist/components/ErrorState/index.d.ts +12 -0
  94. package/dist/components/ErrorState/index.d.ts.map +1 -0
  95. package/dist/components/ErrorState/index.js +54 -0
  96. package/dist/components/Fab/index.d.ts +16 -0
  97. package/dist/components/Fab/index.d.ts.map +1 -0
  98. package/dist/components/Fab/index.js +39 -0
  99. package/dist/components/Fade/index.d.ts +10 -0
  100. package/dist/components/Fade/index.d.ts.map +1 -0
  101. package/dist/components/Fade/index.js +13 -0
  102. package/dist/components/FocusTrap/index.d.ts +11 -0
  103. package/dist/components/FocusTrap/index.d.ts.map +1 -0
  104. package/dist/components/FocusTrap/index.js +69 -0
  105. package/dist/components/FormControl/index.d.ts +34 -0
  106. package/dist/components/FormControl/index.d.ts.map +1 -0
  107. package/dist/components/FormControl/index.js +52 -0
  108. package/dist/components/GlobalSearch/index.d.ts +23 -0
  109. package/dist/components/GlobalSearch/index.d.ts.map +1 -0
  110. package/dist/components/GlobalSearch/index.js +91 -0
  111. package/dist/components/Grid/index.d.ts +19 -0
  112. package/dist/components/Grid/index.d.ts.map +1 -0
  113. package/dist/components/Grid/index.js +30 -0
  114. package/dist/components/Grow/index.d.ts +10 -0
  115. package/dist/components/Grow/index.d.ts.map +1 -0
  116. package/dist/components/Grow/index.js +13 -0
  117. package/dist/components/IconButton/index.d.ts +16 -0
  118. package/dist/components/IconButton/index.d.ts.map +1 -0
  119. package/dist/components/IconButton/index.js +43 -0
  120. package/dist/components/ImageList/index.d.ts +21 -0
  121. package/dist/components/ImageList/index.d.ts.map +1 -0
  122. package/dist/components/ImageList/index.js +39 -0
  123. package/dist/components/Input/index.d.ts +33 -0
  124. package/dist/components/Input/index.d.ts.map +1 -0
  125. package/dist/components/Input/index.js +45 -0
  126. package/dist/components/Kbd/index.d.ts +8 -0
  127. package/dist/components/Kbd/index.d.ts.map +1 -0
  128. package/dist/components/Kbd/index.js +41 -0
  129. package/dist/components/KeyboardShortcut/index.d.ts +20 -0
  130. package/dist/components/KeyboardShortcut/index.d.ts.map +1 -0
  131. package/dist/components/KeyboardShortcut/index.js +63 -0
  132. package/dist/components/Label/index.d.ts +10 -0
  133. package/dist/components/Label/index.d.ts.map +1 -0
  134. package/dist/components/Label/index.js +17 -0
  135. package/dist/components/LinearProgress/index.d.ts +13 -0
  136. package/dist/components/LinearProgress/index.d.ts.map +1 -0
  137. package/dist/components/LinearProgress/index.js +69 -0
  138. package/dist/components/Link/index.d.ts +16 -0
  139. package/dist/components/Link/index.d.ts.map +1 -0
  140. package/dist/components/Link/index.js +25 -0
  141. package/dist/components/List/index.d.ts +40 -0
  142. package/dist/components/List/index.d.ts.map +1 -0
  143. package/dist/components/List/index.js +70 -0
  144. package/dist/components/LoadingState/index.d.ts +11 -0
  145. package/dist/components/LoadingState/index.d.ts.map +1 -0
  146. package/dist/components/LoadingState/index.js +66 -0
  147. package/dist/components/Menu/index.d.ts +40 -0
  148. package/dist/components/Menu/index.d.ts.map +1 -0
  149. package/dist/components/Menu/index.js +103 -0
  150. package/dist/components/MobileStepper/index.d.ts +16 -0
  151. package/dist/components/MobileStepper/index.d.ts.map +1 -0
  152. package/dist/components/MobileStepper/index.js +67 -0
  153. package/dist/components/Modal/index.d.ts +14 -0
  154. package/dist/components/Modal/index.d.ts.map +1 -0
  155. package/dist/components/Modal/index.js +51 -0
  156. package/dist/components/Navbar/index.d.ts +14 -0
  157. package/dist/components/Navbar/index.d.ts.map +1 -0
  158. package/dist/components/Navbar/index.js +27 -0
  159. package/dist/components/NoSSR/index.d.ts +7 -0
  160. package/dist/components/NoSSR/index.d.ts.map +1 -0
  161. package/dist/components/NoSSR/index.js +9 -0
  162. package/dist/components/PageLayout/index.d.ts +13 -0
  163. package/dist/components/PageLayout/index.d.ts.map +1 -0
  164. package/dist/components/PageLayout/index.js +41 -0
  165. package/dist/components/Pagination/index.d.ts +11 -0
  166. package/dist/components/Pagination/index.d.ts.map +1 -0
  167. package/dist/components/Pagination/index.js +56 -0
  168. package/dist/components/Paper/index.d.ts +12 -0
  169. package/dist/components/Paper/index.d.ts.map +1 -0
  170. package/dist/components/Paper/index.js +24 -0
  171. package/dist/components/Popover/index.d.ts +13 -0
  172. package/dist/components/Popover/index.d.ts.map +1 -0
  173. package/dist/components/Popover/index.js +34 -0
  174. package/dist/components/Progress/index.d.ts +13 -0
  175. package/dist/components/Progress/index.d.ts.map +1 -0
  176. package/dist/components/Progress/index.js +40 -0
  177. package/dist/components/Radio/index.d.ts +7 -0
  178. package/dist/components/Radio/index.d.ts.map +1 -0
  179. package/dist/components/Radio/index.js +28 -0
  180. package/dist/components/Rating/index.d.ts +15 -0
  181. package/dist/components/Rating/index.d.ts.map +1 -0
  182. package/dist/components/Rating/index.js +41 -0
  183. package/dist/components/ResizablePanel/index.d.ts +16 -0
  184. package/dist/components/ResizablePanel/index.d.ts.map +1 -0
  185. package/dist/components/ResizablePanel/index.js +41 -0
  186. package/dist/components/ScrollArea/index.d.ts +12 -0
  187. package/dist/components/ScrollArea/index.d.ts.map +1 -0
  188. package/dist/components/ScrollArea/index.js +50 -0
  189. package/dist/components/Select/index.d.ts +23 -0
  190. package/dist/components/Select/index.d.ts.map +1 -0
  191. package/dist/components/Select/index.js +52 -0
  192. package/dist/components/Sheet/index.d.ts +15 -0
  193. package/dist/components/Sheet/index.d.ts.map +1 -0
  194. package/dist/components/Sheet/index.js +61 -0
  195. package/dist/components/Sidebar/index.d.ts +23 -0
  196. package/dist/components/Sidebar/index.d.ts.map +1 -0
  197. package/dist/components/Sidebar/index.js +37 -0
  198. package/dist/components/Skeleton/index.d.ts +9 -0
  199. package/dist/components/Skeleton/index.d.ts.map +1 -0
  200. package/dist/components/Skeleton/index.js +22 -0
  201. package/dist/components/Slide/index.d.ts +12 -0
  202. package/dist/components/Slide/index.d.ts.map +1 -0
  203. package/dist/components/Slide/index.js +21 -0
  204. package/dist/components/Slider/index.d.ts +19 -0
  205. package/dist/components/Slider/index.d.ts.map +1 -0
  206. package/dist/components/Slider/index.js +49 -0
  207. package/dist/components/Snackbar/index.d.ts +28 -0
  208. package/dist/components/Snackbar/index.d.ts.map +1 -0
  209. package/dist/components/Snackbar/index.js +71 -0
  210. package/dist/components/SpeedDial/index.d.ts +18 -0
  211. package/dist/components/SpeedDial/index.d.ts.map +1 -0
  212. package/dist/components/SpeedDial/index.js +71 -0
  213. package/dist/components/Spinner/index.d.ts +10 -0
  214. package/dist/components/Spinner/index.d.ts.map +1 -0
  215. package/dist/components/Spinner/index.js +67 -0
  216. package/dist/components/SplitPane/index.d.ts +11 -0
  217. package/dist/components/SplitPane/index.d.ts.map +1 -0
  218. package/dist/components/SplitPane/index.js +46 -0
  219. package/dist/components/Stack/index.d.ts +17 -0
  220. package/dist/components/Stack/index.d.ts.map +1 -0
  221. package/dist/components/Stack/index.js +30 -0
  222. package/dist/components/Stepper/index.d.ts +20 -0
  223. package/dist/components/Stepper/index.d.ts.map +1 -0
  224. package/dist/components/Stepper/index.js +66 -0
  225. package/dist/components/Switch/index.d.ts +13 -0
  226. package/dist/components/Switch/index.d.ts.map +1 -0
  227. package/dist/components/Switch/index.js +38 -0
  228. package/dist/components/Tabs/index.d.ts +20 -0
  229. package/dist/components/Tabs/index.d.ts.map +1 -0
  230. package/dist/components/Tabs/index.js +62 -0
  231. package/dist/components/TextField/index.d.ts +35 -0
  232. package/dist/components/TextField/index.d.ts.map +1 -0
  233. package/dist/components/TextField/index.js +69 -0
  234. package/dist/components/Textarea/index.d.ts +22 -0
  235. package/dist/components/Textarea/index.d.ts.map +1 -0
  236. package/dist/components/Textarea/index.js +27 -0
  237. package/dist/components/Timeline/index.d.ts +16 -0
  238. package/dist/components/Timeline/index.d.ts.map +1 -0
  239. package/dist/components/Timeline/index.js +30 -0
  240. package/dist/components/Toast/index.d.ts +34 -0
  241. package/dist/components/Toast/index.d.ts.map +1 -0
  242. package/dist/components/Toast/index.js +106 -0
  243. package/dist/components/ToggleButton/index.d.ts +21 -0
  244. package/dist/components/ToggleButton/index.d.ts.map +1 -0
  245. package/dist/components/ToggleButton/index.js +81 -0
  246. package/dist/components/Tooltip/index.d.ts +14 -0
  247. package/dist/components/Tooltip/index.d.ts.map +1 -0
  248. package/dist/components/Tooltip/index.js +47 -0
  249. package/dist/components/TreeView/index.d.ts +19 -0
  250. package/dist/components/TreeView/index.d.ts.map +1 -0
  251. package/dist/components/TreeView/index.js +50 -0
  252. package/dist/components/Typography/index.d.ts +17 -0
  253. package/dist/components/Typography/index.d.ts.map +1 -0
  254. package/dist/components/Typography/index.js +44 -0
  255. package/dist/components/VisuallyHidden/index.d.ts +7 -0
  256. package/dist/components/VisuallyHidden/index.d.ts.map +1 -0
  257. package/dist/components/VisuallyHidden/index.js +18 -0
  258. package/dist/components/Zoom/index.d.ts +10 -0
  259. package/dist/components/Zoom/index.d.ts.map +1 -0
  260. package/dist/components/Zoom/index.js +13 -0
  261. package/dist/components/ai.d.ts +133 -0
  262. package/dist/components/ai.d.ts.map +1 -0
  263. package/dist/components/ai.js +184 -0
  264. package/dist/components/charts.d.ts +143 -0
  265. package/dist/components/charts.d.ts.map +1 -0
  266. package/dist/components/charts.js +435 -0
  267. package/dist/components/data.d.ts +192 -0
  268. package/dist/components/data.d.ts.map +1 -0
  269. package/dist/components/data.js +581 -0
  270. package/dist/components/date.d.ts +73 -0
  271. package/dist/components/date.d.ts.map +1 -0
  272. package/dist/components/date.js +199 -0
  273. package/dist/components/enterprise.d.ts +246 -0
  274. package/dist/components/enterprise.d.ts.map +1 -0
  275. package/dist/components/enterprise.js +428 -0
  276. package/dist/components/form.d.ts +132 -0
  277. package/dist/components/form.d.ts.map +1 -0
  278. package/dist/components/form.js +380 -0
  279. package/dist/components/index.d.ts +173 -0
  280. package/dist/components/index.d.ts.map +1 -0
  281. package/dist/components/index.js +107 -0
  282. package/dist/components/inputs.d.ts +169 -0
  283. package/dist/components/inputs.d.ts.map +1 -0
  284. package/dist/components/inputs.js +437 -0
  285. package/dist/components/layout.d.ts +224 -0
  286. package/dist/components/layout.d.ts.map +1 -0
  287. package/dist/components/layout.js +644 -0
  288. package/dist/components/overlay.d.ts +102 -0
  289. package/dist/components/overlay.d.ts.map +1 -0
  290. package/dist/components/overlay.js +318 -0
  291. package/dist/components/surfaces.d.ts +180 -0
  292. package/dist/components/surfaces.d.ts.map +1 -0
  293. package/dist/components/surfaces.js +423 -0
  294. package/dist/components/typography.d.ts +69 -0
  295. package/dist/components/typography.d.ts.map +1 -0
  296. package/dist/components/typography.js +206 -0
  297. package/dist/index.d.ts +23 -0
  298. package/dist/index.d.ts.map +1 -0
  299. package/dist/index.js +29 -0
  300. package/dist/portal.d.ts +3 -0
  301. package/dist/portal.d.ts.map +1 -0
  302. package/dist/portal.js +17 -0
  303. package/dist/theme/index.d.ts +31 -0
  304. package/dist/theme/index.d.ts.map +1 -0
  305. package/dist/theme/index.js +258 -0
  306. package/dist/tokens/component.d.ts +124 -0
  307. package/dist/tokens/component.d.ts.map +1 -0
  308. package/dist/tokens/component.js +113 -0
  309. package/dist/tokens/index.d.ts +494 -0
  310. package/dist/tokens/index.d.ts.map +1 -0
  311. package/dist/tokens/index.js +345 -0
  312. package/dist/tokens/primitives.d.ts +675 -0
  313. package/dist/tokens/primitives.d.ts.map +1 -0
  314. package/dist/tokens/primitives.js +356 -0
  315. package/dist/tokens/semantic.d.ts +252 -0
  316. package/dist/tokens/semantic.d.ts.map +1 -0
  317. package/dist/tokens/semantic.js +242 -0
  318. package/dist/tokens/themes.d.ts +18 -0
  319. package/dist/tokens/themes.d.ts.map +1 -0
  320. package/dist/tokens/themes.js +316 -0
  321. package/package.json +69 -0
@@ -0,0 +1,345 @@
1
+ /**
2
+ * HyperUI Design Token API
3
+ *
4
+ * The complete token system in one import.
5
+ *
6
+ * Quick start:
7
+ * import { createTheme, applyTheme, tokens, useTokens } from "@hyperpackai/hyperui/tokens";
8
+ *
9
+ * // Apply a built-in theme:
10
+ * applyTheme("forest");
11
+ *
12
+ * // Build a custom brand theme:
13
+ * applyTheme(createTheme({ primaryColor: "#7c3aed", radius: "12px" }));
14
+ *
15
+ * // Access tokens in JS/TS:
16
+ * console.log(tokens.colors.indigo[500]); // "#6366f1"
17
+ *
18
+ * // Reactive token access in components:
19
+ * const { colors } = useTokens();
20
+ */
21
+ import { signal, effect } from "@hyperpackai/hyperion";
22
+ import { h } from "../theme/index.js";
23
+ import { primitives } from "./primitives.js";
24
+ import { lightSemanticTokens, darkSemanticTokens } from "./semantic.js";
25
+ import { defaultComponentTokens } from "./component.js";
26
+ import { themes, getDarkVariant } from "./themes.js";
27
+ // Re-export everything for convenience
28
+ export { primitives } from "./primitives.js";
29
+ export { lightSemanticTokens, darkSemanticTokens, lightColors, darkColors, semanticSpacing, semanticTypography, semanticShadow, semanticMotion, semanticRadius, semanticZIndex } from "./semantic.js";
30
+ export { defaultComponentTokens } from "./component.js";
31
+ export { themes, getDarkVariant } from "./themes.js";
32
+ let _activeTheme = themes.default.overrides;
33
+ let _isDark = false;
34
+ let _direction = "ltr";
35
+ const _tokensSignal = signal({
36
+ primitives,
37
+ semantic: lightSemanticTokens,
38
+ component: defaultComponentTokens
39
+ });
40
+ // Shorthand — the raw primitives object (no reactivity needed)
41
+ export const tokens = primitives;
42
+ // ============================================================
43
+ // CSS variable generation
44
+ // ============================================================
45
+ function buildCSSVars(overrides, dark) {
46
+ const base = {};
47
+ if (overrides.primaryColor)
48
+ base["--hu-primary"] = overrides.primaryColor;
49
+ if (overrides.primaryDark)
50
+ base["--hu-primary-dk"] = overrides.primaryDark;
51
+ if (overrides.primaryLight)
52
+ base["--hu-primary-lt"] = overrides.primaryLight;
53
+ if (overrides.primaryBg)
54
+ base["--hu-primary-bg"] = overrides.primaryBg;
55
+ if (overrides.radius)
56
+ base["--hu-radius"] = overrides.radius;
57
+ if (overrides.fontFamily)
58
+ base["--hu-font-sans"] = overrides.fontFamily;
59
+ // Density scale — adjusts spacing and font sizes proportionally
60
+ if (overrides.densityScale && overrides.densityScale !== 1) {
61
+ const d = overrides.densityScale;
62
+ const scale = (px) => `${Math.round(px * d)}px`;
63
+ base["--hu-space-1"] = scale(4);
64
+ base["--hu-space-2"] = scale(8);
65
+ base["--hu-space-3"] = scale(12);
66
+ base["--hu-space-4"] = scale(16);
67
+ base["--hu-space-5"] = scale(20);
68
+ base["--hu-space-6"] = scale(24);
69
+ }
70
+ // Dark mode overrides
71
+ if (dark) {
72
+ const darkVars = getDarkVariant("default").cssVars ?? {};
73
+ Object.assign(base, darkVars);
74
+ }
75
+ // Custom CSS variable overrides (highest specificity)
76
+ if (overrides.cssVars) {
77
+ Object.assign(base, overrides.cssVars);
78
+ }
79
+ return base;
80
+ }
81
+ function getDefaultThemeTarget() {
82
+ return typeof document === "undefined" ? undefined : document.documentElement;
83
+ }
84
+ function applyCSSVars(vars, target) {
85
+ if (!target)
86
+ return;
87
+ for (const [key, value] of Object.entries(vars)) {
88
+ target.style.setProperty(key, value);
89
+ }
90
+ }
91
+ /**
92
+ * Apply a theme to the document root. Accepts either a built-in theme name
93
+ * or a custom `ThemeOverrides` object.
94
+ *
95
+ * applyTheme("ocean");
96
+ * applyTheme("compact");
97
+ * applyTheme({ primaryColor: "#7c3aed", radius: "12px" });
98
+ * applyTheme("forest", { dark: true });
99
+ */
100
+ export function applyTheme(theme, options = {}) {
101
+ const { dark = _isDark, direction = _direction } = options;
102
+ const target = options.target ?? getDefaultThemeTarget();
103
+ const overrides = typeof theme === "string"
104
+ ? (themes[theme]?.overrides ?? themes.default.overrides)
105
+ : theme;
106
+ _activeTheme = overrides;
107
+ _isDark = dark;
108
+ _direction = direction;
109
+ const cssVars = buildCSSVars(overrides, dark);
110
+ applyCSSVars(cssVars, target);
111
+ // Update data-theme for CSS selector targeting
112
+ target?.setAttribute("data-theme", dark ? "dark" : "light");
113
+ target?.setAttribute("dir", direction);
114
+ // Update reactive token signal
115
+ _tokensSignal.value = {
116
+ primitives,
117
+ semantic: dark ? darkSemanticTokens : lightSemanticTokens,
118
+ component: defaultComponentTokens
119
+ };
120
+ }
121
+ // ============================================================
122
+ // createTheme — compose a custom theme
123
+ // ============================================================
124
+ /**
125
+ * Composes a theme from a base theme and partial overrides.
126
+ * Returns a `ThemeOverrides` object ready for `applyTheme()`.
127
+ *
128
+ * const myBrand = createTheme("default", {
129
+ * primaryColor: "#7c3aed",
130
+ * radius: "12px",
131
+ * fontFamily: "Inter, sans-serif"
132
+ * });
133
+ * applyTheme(myBrand);
134
+ */
135
+ export function createTheme(baseOrOverrides, overrides = {}) {
136
+ const base = typeof baseOrOverrides === "string"
137
+ ? (themes[baseOrOverrides]?.overrides ?? themes.default.overrides)
138
+ : baseOrOverrides;
139
+ return {
140
+ ...base,
141
+ ...overrides,
142
+ cssVars: { ...(base.cssVars ?? {}), ...(overrides.cssVars ?? {}) }
143
+ };
144
+ }
145
+ let _colorMode = "system";
146
+ const _colorModeSignal = signal("light");
147
+ const _themeSignal = signal(_activeTheme);
148
+ const _directionSignal = signal(_direction);
149
+ /**
150
+ * Set the colour mode. Pass `"system"` to follow `prefers-color-scheme`.
151
+ *
152
+ * setColorMode("dark");
153
+ * setColorMode("system"); // auto
154
+ */
155
+ export function setColorMode(mode) {
156
+ _colorMode = mode;
157
+ if (mode === "system") {
158
+ if (typeof window === "undefined") {
159
+ _colorModeSignal.value = _isDark ? "dark" : "light";
160
+ applyTheme(_activeTheme, { dark: _isDark });
161
+ return;
162
+ }
163
+ const mq = window.matchMedia("(prefers-color-scheme: dark)");
164
+ const apply = (dark) => {
165
+ _colorModeSignal.value = dark ? "dark" : "light";
166
+ applyTheme(_activeTheme, { dark });
167
+ };
168
+ apply(mq.matches);
169
+ mq.addEventListener("change", (e) => apply(e.matches));
170
+ }
171
+ else {
172
+ _colorModeSignal.value = mode;
173
+ applyTheme(_activeTheme, { dark: mode === "dark" });
174
+ }
175
+ }
176
+ function resolveThemeInput(theme, density) {
177
+ if (theme)
178
+ return theme;
179
+ if (density === "compact")
180
+ return "compact";
181
+ if (density === "comfortable")
182
+ return "comfortable";
183
+ return "default";
184
+ }
185
+ function resolveDarkMode(mode) {
186
+ if (mode === "dark")
187
+ return true;
188
+ if (mode === "light")
189
+ return false;
190
+ return typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches;
191
+ }
192
+ function currentThemeState() {
193
+ const isDark = signal(_colorModeSignal.value === "dark");
194
+ effect(() => { isDark.value = _colorModeSignal.value === "dark"; });
195
+ return {
196
+ theme: _themeSignal,
197
+ colorMode: _colorModeSignal,
198
+ direction: _directionSignal,
199
+ isDark,
200
+ setTheme(theme, options = {}) {
201
+ const nextMode = options.colorMode ?? _colorMode;
202
+ const nextDirection = options.direction ?? _direction;
203
+ const dark = resolveDarkMode(nextMode);
204
+ applyTheme(theme, { dark, direction: nextDirection });
205
+ _themeSignal.value = typeof theme === "string"
206
+ ? (themes[theme]?.overrides ?? themes.default.overrides)
207
+ : theme;
208
+ _colorMode = nextMode;
209
+ _colorModeSignal.value = dark ? "dark" : "light";
210
+ _directionSignal.value = nextDirection;
211
+ },
212
+ setColorMode(mode) {
213
+ setColorMode(mode);
214
+ _colorModeSignal.value = resolveDarkMode(mode) ? "dark" : "light";
215
+ },
216
+ setDirection(direction) {
217
+ _direction = direction;
218
+ _directionSignal.value = direction;
219
+ applyTheme(_activeTheme, { dark: _isDark, direction });
220
+ }
221
+ };
222
+ }
223
+ /**
224
+ * Applies a HyperUI theme and returns a lightweight provider wrapper.
225
+ * In browser apps this mutates the target root with CSS variables.
226
+ * In SSR/Node it still returns a VNode with data attributes and inline variables.
227
+ */
228
+ export function ThemeProvider(props) {
229
+ const theme = resolveThemeInput(props.theme, props.density);
230
+ const mode = props.colorMode ?? "system";
231
+ const direction = props.direction ?? "ltr";
232
+ const dark = resolveDarkMode(mode);
233
+ const resolvedTheme = typeof theme === "string"
234
+ ? (themes[theme]?.overrides ?? themes.default.overrides)
235
+ : theme;
236
+ applyTheme(resolvedTheme, { dark, target: props.target, direction });
237
+ _themeSignal.value = resolvedTheme;
238
+ _colorMode = mode;
239
+ _colorModeSignal.value = dark ? "dark" : "light";
240
+ _directionSignal.value = direction;
241
+ const vars = buildCSSVars(resolvedTheme, dark);
242
+ const style = Object.entries(vars).map(([key, value]) => `${key}:${value}`).join(";");
243
+ return h("div", {
244
+ class: props.class,
245
+ "data-hu-provider": "true",
246
+ "data-theme": dark ? "dark" : "light",
247
+ dir: direction,
248
+ style
249
+ }, props.children);
250
+ }
251
+ export function useTheme() {
252
+ return currentThemeState();
253
+ }
254
+ // ============================================================
255
+ // useTokens — reactive token access in components
256
+ // ============================================================
257
+ /**
258
+ * Returns the current design tokens as reactive signals. Re-renders
259
+ * the component when the theme or colour mode changes.
260
+ *
261
+ * const { semantic, primitives } = useTokens();
262
+ * <div style={{ color: semantic.value.colors.text.default }}>Hello</div>
263
+ */
264
+ export function useTokens() {
265
+ const isDark = signal(_colorModeSignal.value === "dark");
266
+ effect(() => { isDark.value = _colorModeSignal.value === "dark"; });
267
+ return {
268
+ tokens: _tokensSignal,
269
+ colorMode: _colorModeSignal,
270
+ isDark
271
+ };
272
+ }
273
+ // ============================================================
274
+ // getCSSVar — read a CSS variable value at runtime
275
+ // ============================================================
276
+ /**
277
+ * Reads the current value of a CSS custom property from the document root.
278
+ * Useful for reading computed tokens in JavaScript.
279
+ *
280
+ * const primary = getCSSVar("--hu-primary"); // "#6366f1"
281
+ */
282
+ export function getCSSVar(name, element) {
283
+ const el = element ?? getDefaultThemeTarget();
284
+ if (!el || typeof getComputedStyle === "undefined")
285
+ return "";
286
+ return getComputedStyle(el).getPropertyValue(name).trim();
287
+ }
288
+ // ============================================================
289
+ // tokenToCSS — generate a full CSS variable block from tokens
290
+ // ============================================================
291
+ /**
292
+ * Generates a CSS variable block string from a `ThemeOverrides` object.
293
+ * Useful for SSR head injection or CSS-in-JS integration.
294
+ *
295
+ * const css = tokenToCSS(myTheme);
296
+ * // ":root { --hu-primary: #7c3aed; ... }"
297
+ */
298
+ export function tokenToCSS(overrides, dark = false, selector = ":root") {
299
+ const vars = buildCSSVars(overrides, dark);
300
+ const declarations = Object.entries(vars)
301
+ .map(([k, v]) => ` ${k}: ${v};`)
302
+ .join("\n");
303
+ return `${selector} {\n${declarations}\n}`;
304
+ }
305
+ /**
306
+ * Exports the complete design token system as a plain JSON-serialisable
307
+ * object. Use with Style Dictionary or Figma Tokens plugins.
308
+ *
309
+ * const json = JSON.stringify(exportTokens(), null, 2);
310
+ * fs.writeFileSync("tokens.json", json);
311
+ */
312
+ export function exportTokens() {
313
+ return {
314
+ version: "1.0.0",
315
+ generated: new Date().toISOString(),
316
+ primitives,
317
+ semantic: {
318
+ light: lightSemanticTokens,
319
+ dark: darkSemanticTokens
320
+ },
321
+ components: defaultComponentTokens,
322
+ themes
323
+ };
324
+ }
325
+ // ============================================================
326
+ // Convenience: all tokens in a flat CSS variable map
327
+ // ============================================================
328
+ /**
329
+ * Returns every CSS variable defined by HyperUI as a flat Record.
330
+ * Useful for debugging or for exporting to a CSS file.
331
+ *
332
+ * console.log(getAllCSSVars()["--hu-primary"]); // "#6366f1"
333
+ */
334
+ export function getAllCSSVars() {
335
+ if (typeof document === "undefined")
336
+ return {};
337
+ const styles = getComputedStyle(document.documentElement);
338
+ const vars = {};
339
+ for (const prop of Array.from(styles)) {
340
+ if (prop.startsWith("--hu-")) {
341
+ vars[prop] = styles.getPropertyValue(prop).trim();
342
+ }
343
+ }
344
+ return vars;
345
+ }