@happyvertical/smrt-ui 0.30.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 (330) hide show
  1. package/AGENTS.md +50 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/dist/actions/__tests__/ripple.test.js +28 -0
  5. package/dist/actions/permission.d.ts +34 -0
  6. package/dist/actions/permission.d.ts.map +1 -0
  7. package/dist/actions/permission.js +70 -0
  8. package/dist/actions/ripple.d.ts +7 -0
  9. package/dist/actions/ripple.d.ts.map +1 -0
  10. package/dist/actions/ripple.js +65 -0
  11. package/dist/components/calendar/Calendar.svelte +520 -0
  12. package/dist/components/calendar/Calendar.svelte.d.ts +17 -0
  13. package/dist/components/calendar/Calendar.svelte.d.ts.map +1 -0
  14. package/dist/components/calendar/DayView.svelte +389 -0
  15. package/dist/components/calendar/DayView.svelte.d.ts +13 -0
  16. package/dist/components/calendar/DayView.svelte.d.ts.map +1 -0
  17. package/dist/components/calendar/index.d.ts +6 -0
  18. package/dist/components/calendar/index.d.ts.map +1 -0
  19. package/dist/components/calendar/index.js +5 -0
  20. package/dist/components/chat/MessageBubble.svelte +126 -0
  21. package/dist/components/chat/MessageBubble.svelte.d.ts +30 -0
  22. package/dist/components/chat/MessageBubble.svelte.d.ts.map +1 -0
  23. package/dist/components/chat/ReactionPicker.svelte +89 -0
  24. package/dist/components/chat/ReactionPicker.svelte.d.ts +19 -0
  25. package/dist/components/chat/ReactionPicker.svelte.d.ts.map +1 -0
  26. package/dist/components/chat/TypingIndicator.svelte +90 -0
  27. package/dist/components/chat/TypingIndicator.svelte.d.ts +17 -0
  28. package/dist/components/chat/TypingIndicator.svelte.d.ts.map +1 -0
  29. package/dist/components/chat/__tests__/chat-primitives.test.js +67 -0
  30. package/dist/components/chat/index.d.ts +10 -0
  31. package/dist/components/chat/index.d.ts.map +1 -0
  32. package/dist/components/chat/index.js +9 -0
  33. package/dist/components/data/DataTable.svelte +519 -0
  34. package/dist/components/data/DataTable.svelte.d.ts +49 -0
  35. package/dist/components/data/DataTable.svelte.d.ts.map +1 -0
  36. package/dist/components/data/__tests__/DataTable.test.js +48 -0
  37. package/dist/components/data/__tests__/data-table-helpers.test.js +36 -0
  38. package/dist/components/data/index.d.ts +6 -0
  39. package/dist/components/data/index.d.ts.map +1 -0
  40. package/dist/components/data/index.js +5 -0
  41. package/dist/components/data/types.d.ts +104 -0
  42. package/dist/components/data/types.d.ts.map +1 -0
  43. package/dist/components/data/types.js +45 -0
  44. package/dist/components/display/ConfidenceBadge.svelte +142 -0
  45. package/dist/components/display/ConfidenceBadge.svelte.d.ts +25 -0
  46. package/dist/components/display/ConfidenceBadge.svelte.d.ts.map +1 -0
  47. package/dist/components/display/CurrencyDisplay.svelte +106 -0
  48. package/dist/components/display/CurrencyDisplay.svelte.d.ts +30 -0
  49. package/dist/components/display/CurrencyDisplay.svelte.d.ts.map +1 -0
  50. package/dist/components/display/DateDisplay.svelte +122 -0
  51. package/dist/components/display/DateDisplay.svelte.d.ts +24 -0
  52. package/dist/components/display/DateDisplay.svelte.d.ts.map +1 -0
  53. package/dist/components/display/Icon.svelte +77 -0
  54. package/dist/components/display/Icon.svelte.d.ts +28 -0
  55. package/dist/components/display/Icon.svelte.d.ts.map +1 -0
  56. package/dist/components/display/StatusBadge.svelte +256 -0
  57. package/dist/components/display/StatusBadge.svelte.d.ts +24 -0
  58. package/dist/components/display/StatusBadge.svelte.d.ts.map +1 -0
  59. package/dist/components/display/__tests__/ConfidenceBadge.test.js +96 -0
  60. package/dist/components/display/__tests__/CurrencyDisplay.test.js +114 -0
  61. package/dist/components/display/__tests__/DateDisplay.test.js +114 -0
  62. package/dist/components/display/__tests__/Icon.test.js +93 -0
  63. package/dist/components/display/__tests__/StatusBadge.test.js +98 -0
  64. package/dist/components/display/index.d.ts +10 -0
  65. package/dist/components/display/index.d.ts.map +1 -0
  66. package/dist/components/display/index.js +9 -0
  67. package/dist/components/display/types.d.ts +5 -0
  68. package/dist/components/display/types.d.ts.map +1 -0
  69. package/dist/components/display/types.js +4 -0
  70. package/dist/components/feedback/ConfirmDialog.svelte +226 -0
  71. package/dist/components/feedback/ConfirmDialog.svelte.d.ts +25 -0
  72. package/dist/components/feedback/ConfirmDialog.svelte.d.ts.map +1 -0
  73. package/dist/components/feedback/LoadingOverlay.svelte +281 -0
  74. package/dist/components/feedback/LoadingOverlay.svelte.d.ts +31 -0
  75. package/dist/components/feedback/LoadingOverlay.svelte.d.ts.map +1 -0
  76. package/dist/components/feedback/Modal.svelte +393 -0
  77. package/dist/components/feedback/Modal.svelte.d.ts +46 -0
  78. package/dist/components/feedback/Modal.svelte.d.ts.map +1 -0
  79. package/dist/components/feedback/ProgressBar.svelte +162 -0
  80. package/dist/components/feedback/ProgressBar.svelte.d.ts +21 -0
  81. package/dist/components/feedback/ProgressBar.svelte.d.ts.map +1 -0
  82. package/dist/components/feedback/__tests__/ConfirmDialog.test.js +111 -0
  83. package/dist/components/feedback/__tests__/LoadingOverlay.test.js +99 -0
  84. package/dist/components/feedback/__tests__/Modal.test.js +72 -0
  85. package/dist/components/feedback/__tests__/ProgressBar.test.js +89 -0
  86. package/dist/components/feedback/index.d.ts +8 -0
  87. package/dist/components/feedback/index.d.ts.map +1 -0
  88. package/dist/components/feedback/index.js +10 -0
  89. package/dist/components/layout/Container.svelte +53 -0
  90. package/dist/components/layout/Container.svelte.d.ts +11 -0
  91. package/dist/components/layout/Container.svelte.d.ts.map +1 -0
  92. package/dist/components/layout/EmptyState.svelte +187 -0
  93. package/dist/components/layout/EmptyState.svelte.d.ts +28 -0
  94. package/dist/components/layout/EmptyState.svelte.d.ts.map +1 -0
  95. package/dist/components/layout/Footer.svelte +63 -0
  96. package/dist/components/layout/Footer.svelte.d.ts +8 -0
  97. package/dist/components/layout/Footer.svelte.d.ts.map +1 -0
  98. package/dist/components/layout/Grid.svelte +241 -0
  99. package/dist/components/layout/Grid.svelte.d.ts +56 -0
  100. package/dist/components/layout/Grid.svelte.d.ts.map +1 -0
  101. package/dist/components/layout/Header.svelte +86 -0
  102. package/dist/components/layout/Header.svelte.d.ts +9 -0
  103. package/dist/components/layout/Header.svelte.d.ts.map +1 -0
  104. package/dist/components/layout/Masthead.svelte +219 -0
  105. package/dist/components/layout/Masthead.svelte.d.ts +13 -0
  106. package/dist/components/layout/Masthead.svelte.d.ts.map +1 -0
  107. package/dist/components/layout/PageHeader.svelte +131 -0
  108. package/dist/components/layout/PageHeader.svelte.d.ts +26 -0
  109. package/dist/components/layout/PageHeader.svelte.d.ts.map +1 -0
  110. package/dist/components/layout/SummaryCard.svelte +203 -0
  111. package/dist/components/layout/SummaryCard.svelte.d.ts +20 -0
  112. package/dist/components/layout/SummaryCard.svelte.d.ts.map +1 -0
  113. package/dist/components/layout/__tests__/Container.test.js +62 -0
  114. package/dist/components/layout/__tests__/EmptyState.test.js +83 -0
  115. package/dist/components/layout/__tests__/Footer.test.js +50 -0
  116. package/dist/components/layout/__tests__/Grid.test.js +121 -0
  117. package/dist/components/layout/__tests__/Header.test.js +48 -0
  118. package/dist/components/layout/__tests__/Masthead.test.js +93 -0
  119. package/dist/components/layout/__tests__/PageHeader.test.js +80 -0
  120. package/dist/components/layout/__tests__/SummaryCard.test.js +82 -0
  121. package/dist/components/layout/index.d.ts +12 -0
  122. package/dist/components/layout/index.d.ts.map +1 -0
  123. package/dist/components/layout/index.js +11 -0
  124. package/dist/components/memberships/MembershipCard.svelte +163 -0
  125. package/dist/components/memberships/MembershipCard.svelte.d.ts +12 -0
  126. package/dist/components/memberships/MembershipCard.svelte.d.ts.map +1 -0
  127. package/dist/components/memberships/MembershipList.svelte +98 -0
  128. package/dist/components/memberships/MembershipList.svelte.d.ts +19 -0
  129. package/dist/components/memberships/MembershipList.svelte.d.ts.map +1 -0
  130. package/dist/components/nav/FilterChips.svelte +152 -0
  131. package/dist/components/nav/FilterChips.svelte.d.ts +19 -0
  132. package/dist/components/nav/FilterChips.svelte.d.ts.map +1 -0
  133. package/dist/components/nav/Tabs.svelte +252 -0
  134. package/dist/components/nav/Tabs.svelte.d.ts +34 -0
  135. package/dist/components/nav/Tabs.svelte.d.ts.map +1 -0
  136. package/dist/components/nav/__tests__/FilterChips.test.js +94 -0
  137. package/dist/components/nav/__tests__/Tabs.test.js +128 -0
  138. package/dist/components/nav/index.d.ts +7 -0
  139. package/dist/components/nav/index.d.ts.map +1 -0
  140. package/dist/components/nav/index.js +6 -0
  141. package/dist/components/nav/types.d.ts +24 -0
  142. package/dist/components/nav/types.d.ts.map +1 -0
  143. package/dist/components/nav/types.js +4 -0
  144. package/dist/components/permissions/PermissionCheck.svelte +45 -0
  145. package/dist/components/permissions/PermissionCheck.svelte.d.ts +19 -0
  146. package/dist/components/permissions/PermissionCheck.svelte.d.ts.map +1 -0
  147. package/dist/components/roles/RoleBadge.svelte +84 -0
  148. package/dist/components/roles/RoleBadge.svelte.d.ts +13 -0
  149. package/dist/components/roles/RoleBadge.svelte.d.ts.map +1 -0
  150. package/dist/components/roles/RoleSelector.svelte +216 -0
  151. package/dist/components/roles/RoleSelector.svelte.d.ts +13 -0
  152. package/dist/components/roles/RoleSelector.svelte.d.ts.map +1 -0
  153. package/dist/components/theme/ThemeProvider.svelte +71 -0
  154. package/dist/components/theme/ThemeProvider.svelte.d.ts +10 -0
  155. package/dist/components/theme/ThemeProvider.svelte.d.ts.map +1 -0
  156. package/dist/components/theme/context.svelte.d.ts +15 -0
  157. package/dist/components/theme/context.svelte.d.ts.map +1 -0
  158. package/dist/components/theme/context.svelte.js +42 -0
  159. package/dist/components/theme/index.d.ts +3 -0
  160. package/dist/components/theme/index.d.ts.map +1 -0
  161. package/dist/components/theme/index.js +2 -0
  162. package/dist/components/ui/Avatar.svelte +167 -0
  163. package/dist/components/ui/Avatar.svelte.d.ts +26 -0
  164. package/dist/components/ui/Avatar.svelte.d.ts.map +1 -0
  165. package/dist/components/ui/Badge.svelte +70 -0
  166. package/dist/components/ui/Badge.svelte.d.ts +12 -0
  167. package/dist/components/ui/Badge.svelte.d.ts.map +1 -0
  168. package/dist/components/ui/Button.svelte +226 -0
  169. package/dist/components/ui/Button.svelte.d.ts +28 -0
  170. package/dist/components/ui/Button.svelte.d.ts.map +1 -0
  171. package/dist/components/ui/Card.svelte +122 -0
  172. package/dist/components/ui/Card.svelte.d.ts +15 -0
  173. package/dist/components/ui/Card.svelte.d.ts.map +1 -0
  174. package/dist/components/ui/Chip.svelte +167 -0
  175. package/dist/components/ui/Chip.svelte.d.ts +33 -0
  176. package/dist/components/ui/Chip.svelte.d.ts.map +1 -0
  177. package/dist/components/ui/Dropdown.svelte +250 -0
  178. package/dist/components/ui/Dropdown.svelte.d.ts +20 -0
  179. package/dist/components/ui/Dropdown.svelte.d.ts.map +1 -0
  180. package/dist/components/ui/Pagination.svelte +294 -0
  181. package/dist/components/ui/Pagination.svelte.d.ts +21 -0
  182. package/dist/components/ui/Pagination.svelte.d.ts.map +1 -0
  183. package/dist/components/ui/Skeleton.svelte +113 -0
  184. package/dist/components/ui/Skeleton.svelte.d.ts +24 -0
  185. package/dist/components/ui/Skeleton.svelte.d.ts.map +1 -0
  186. package/dist/components/ui/Tooltip.svelte +120 -0
  187. package/dist/components/ui/Tooltip.svelte.d.ts +24 -0
  188. package/dist/components/ui/Tooltip.svelte.d.ts.map +1 -0
  189. package/dist/components/ui/Tree.svelte +209 -0
  190. package/dist/components/ui/Tree.svelte.d.ts +17 -0
  191. package/dist/components/ui/Tree.svelte.d.ts.map +1 -0
  192. package/dist/components/ui/__tests__/Badge.test.js +76 -0
  193. package/dist/components/ui/__tests__/Button.test.js +69 -0
  194. package/dist/components/ui/__tests__/Card.test.js +103 -0
  195. package/dist/components/ui/__tests__/Pagination.test.js +99 -0
  196. package/dist/components/ui/__tests__/gap-primitives-interactive.test.js +112 -0
  197. package/dist/components/ui/__tests__/gap-primitives.test.js +84 -0
  198. package/dist/components/ui/index.d.ts +14 -0
  199. package/dist/components/ui/index.d.ts.map +1 -0
  200. package/dist/components/ui/index.js +18 -0
  201. package/dist/i18n/Trans.svelte +29 -0
  202. package/dist/i18n/Trans.svelte.d.ts +24 -0
  203. package/dist/i18n/Trans.svelte.d.ts.map +1 -0
  204. package/dist/i18n/__tests__/i18n.test.js +74 -0
  205. package/dist/i18n/__tests__/render-parity.spec.js +37 -0
  206. package/dist/i18n/context.svelte.d.ts +43 -0
  207. package/dist/i18n/context.svelte.d.ts.map +1 -0
  208. package/dist/i18n/context.svelte.js +69 -0
  209. package/dist/i18n/index.d.ts +17 -0
  210. package/dist/i18n/index.d.ts.map +1 -0
  211. package/dist/i18n/index.js +24 -0
  212. package/dist/i18n/registry.d.ts +44 -0
  213. package/dist/i18n/registry.d.ts.map +1 -0
  214. package/dist/i18n/registry.js +60 -0
  215. package/dist/i18n/render.d.ts +22 -0
  216. package/dist/i18n/render.d.ts.map +1 -0
  217. package/dist/i18n/render.js +44 -0
  218. package/dist/i18n/strings.d.ts +7 -0
  219. package/dist/i18n/strings.d.ts.map +1 -0
  220. package/dist/i18n/strings.js +19 -0
  221. package/dist/i18n/strings.ui.d.ts +34 -0
  222. package/dist/i18n/strings.ui.d.ts.map +1 -0
  223. package/dist/i18n/strings.ui.js +44 -0
  224. package/dist/i18n/use-i18n.d.ts +20 -0
  225. package/dist/i18n/use-i18n.d.ts.map +1 -0
  226. package/dist/i18n/use-i18n.js +21 -0
  227. package/dist/index.d.ts +28 -0
  228. package/dist/index.d.ts.map +1 -0
  229. package/dist/index.js +38 -0
  230. package/dist/registry/index.d.ts +6 -0
  231. package/dist/registry/index.d.ts.map +1 -0
  232. package/dist/registry/index.js +4 -0
  233. package/dist/registry/module-registry.d.ts +58 -0
  234. package/dist/registry/module-registry.d.ts.map +1 -0
  235. package/dist/registry/module-registry.js +94 -0
  236. package/dist/styles/index.d.ts +4 -0
  237. package/dist/styles/index.d.ts.map +1 -0
  238. package/dist/styles/index.js +6 -0
  239. package/dist/styles/tokens.css +76 -0
  240. package/dist/test-support/a11y.d.ts +16 -0
  241. package/dist/test-support/a11y.d.ts.map +1 -0
  242. package/dist/test-support/a11y.js +32 -0
  243. package/dist/test-support/setup.d.ts +11 -0
  244. package/dist/test-support/setup.d.ts.map +1 -0
  245. package/dist/test-support/setup.js +33 -0
  246. package/dist/theme/ThemeProvider.svelte +207 -0
  247. package/dist/theme/ThemeProvider.svelte.d.ts +22 -0
  248. package/dist/theme/ThemeProvider.svelte.d.ts.map +1 -0
  249. package/dist/theme/context.d.ts +49 -0
  250. package/dist/theme/context.d.ts.map +1 -0
  251. package/dist/theme/context.js +32 -0
  252. package/dist/theme/index.d.ts +7 -0
  253. package/dist/theme/index.d.ts.map +1 -0
  254. package/dist/theme/index.js +9 -0
  255. package/dist/theme/tokens.d.ts +309 -0
  256. package/dist/theme/tokens.d.ts.map +1 -0
  257. package/dist/theme/tokens.js +418 -0
  258. package/dist/themes/CUSTOM_THEME_GUIDE.md +341 -0
  259. package/dist/themes/README.md +675 -0
  260. package/dist/themes/ThemeProvider.svelte +275 -0
  261. package/dist/themes/ThemeProvider.svelte.d.ts +24 -0
  262. package/dist/themes/ThemeProvider.svelte.d.ts.map +1 -0
  263. package/dist/themes/__tests__/css-generator.test.js +32 -0
  264. package/dist/themes/__tests__/registry.test.js +43 -0
  265. package/dist/themes/__tests__/token-aliases.test.js +176 -0
  266. package/dist/themes/components/ColorSchemeToggle.svelte +205 -0
  267. package/dist/themes/components/ColorSchemeToggle.svelte.d.ts +14 -0
  268. package/dist/themes/components/ColorSchemeToggle.svelte.d.ts.map +1 -0
  269. package/dist/themes/components/ThemeSwitcher.svelte +188 -0
  270. package/dist/themes/components/ThemeSwitcher.svelte.d.ts +14 -0
  271. package/dist/themes/components/ThemeSwitcher.svelte.d.ts.map +1 -0
  272. package/dist/themes/components/index.d.ts +8 -0
  273. package/dist/themes/components/index.d.ts.map +1 -0
  274. package/dist/themes/components/index.js +7 -0
  275. package/dist/themes/context.svelte.d.ts +30 -0
  276. package/dist/themes/context.svelte.d.ts.map +1 -0
  277. package/dist/themes/context.svelte.js +42 -0
  278. package/dist/themes/create-theme.d.ts +99 -0
  279. package/dist/themes/create-theme.d.ts.map +1 -0
  280. package/dist/themes/create-theme.js +389 -0
  281. package/dist/themes/css-generator.d.ts +44 -0
  282. package/dist/themes/css-generator.d.ts.map +1 -0
  283. package/dist/themes/css-generator.js +226 -0
  284. package/dist/themes/glass/index.d.ts +14 -0
  285. package/dist/themes/glass/index.d.ts.map +1 -0
  286. package/dist/themes/glass/index.js +286 -0
  287. package/dist/themes/index.d.ts +31 -0
  288. package/dist/themes/index.d.ts.map +1 -0
  289. package/dist/themes/index.js +37 -0
  290. package/dist/themes/material/index.d.ts +13 -0
  291. package/dist/themes/material/index.d.ts.map +1 -0
  292. package/dist/themes/material/index.js +269 -0
  293. package/dist/themes/registry.d.ts +64 -0
  294. package/dist/themes/registry.d.ts.map +1 -0
  295. package/dist/themes/registry.js +122 -0
  296. package/dist/themes/shared.d.ts +78 -0
  297. package/dist/themes/shared.d.ts.map +1 -0
  298. package/dist/themes/shared.js +179 -0
  299. package/dist/themes/studio/index.d.ts +14 -0
  300. package/dist/themes/studio/index.d.ts.map +1 -0
  301. package/dist/themes/studio/index.js +270 -0
  302. package/dist/themes/styles/all.css +12 -0
  303. package/dist/themes/styles/glass.css +432 -0
  304. package/dist/themes/styles/index.d.ts +22 -0
  305. package/dist/themes/styles/index.d.ts.map +1 -0
  306. package/dist/themes/styles/index.js +23 -0
  307. package/dist/themes/styles/material.css +364 -0
  308. package/dist/themes/styles/studio.css +416 -0
  309. package/dist/themes/types.d.ts +273 -0
  310. package/dist/themes/types.d.ts.map +1 -0
  311. package/dist/themes/types.js +15 -0
  312. package/dist/types-generic.d.ts +75 -0
  313. package/dist/types-generic.d.ts.map +1 -0
  314. package/dist/types-generic.js +1 -0
  315. package/dist/utils/forms/__tests__/formatters.test.js +27 -0
  316. package/dist/utils/forms/formatters.d.ts +14 -0
  317. package/dist/utils/forms/formatters.d.ts.map +1 -0
  318. package/dist/utils/forms/formatters.js +77 -0
  319. package/dist/utils/import-optional.d.ts +5 -0
  320. package/dist/utils/import-optional.d.ts.map +1 -0
  321. package/dist/utils/import-optional.js +7 -0
  322. package/dist/utils/theme/__tests__/color.test.js +72 -0
  323. package/dist/utils/theme/__tests__/typography.test.js +11 -0
  324. package/dist/utils/theme/color.d.ts +70 -0
  325. package/dist/utils/theme/color.d.ts.map +1 -0
  326. package/dist/utils/theme/color.js +221 -0
  327. package/dist/utils/theme/typography.d.ts +27 -0
  328. package/dist/utils/theme/typography.d.ts.map +1 -0
  329. package/dist/utils/theme/typography.js +30 -0
  330. package/package.json +143 -0
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Unified Theme System Types
3
+ *
4
+ * Core types for the multi-theme architecture supporting Material, Glass, and Studio themes.
5
+ */
6
+ /**
7
+ * Default theme configuration
8
+ */
9
+ export const defaultThemeConfig = {
10
+ preset: 'material',
11
+ colorScheme: 'system',
12
+ borderRadius: 'md',
13
+ persist: true,
14
+ storageKey: 'smrt-theme',
15
+ };
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Generic component types migrated from @happyvertical/svelte
3
+ */
4
+ import type { Snippet } from 'svelte';
5
+ import type { HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
6
+ export type BadgeVariant = 'default' | 'primary' | 'success' | 'warning' | 'error' | 'info';
7
+ export type BadgeSize = 'sm' | 'md';
8
+ export interface BadgeProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'class'> {
9
+ variant?: BadgeVariant;
10
+ size?: BadgeSize;
11
+ children?: Snippet;
12
+ }
13
+ export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger';
14
+ export type ButtonSize = 'sm' | 'md' | 'lg';
15
+ export interface ButtonProps extends Omit<HTMLButtonAttributes, 'class'> {
16
+ variant?: ButtonVariant;
17
+ size?: ButtonSize;
18
+ href?: string;
19
+ children?: Snippet;
20
+ }
21
+ export type CardVariant = 'default' | 'outlined' | 'elevated';
22
+ export type CardPadding = 'none' | 'sm' | 'md' | 'lg';
23
+ export interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, 'class'> {
24
+ variant?: CardVariant;
25
+ padding?: CardPadding;
26
+ hoverable?: boolean;
27
+ children?: Snippet;
28
+ header?: Snippet;
29
+ footer?: Snippet;
30
+ }
31
+ export type AvatarSize = 'sm' | 'md' | 'lg' | 'xl';
32
+ export type AvatarStatus = 'online' | 'offline' | 'away' | 'busy';
33
+ export type ChipSize = 'sm' | 'md';
34
+ export type SkeletonVariant = 'text' | 'circle' | 'rect';
35
+ export type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
36
+ export type DropdownPlacement = 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end';
37
+ /** An item in a `Dropdown`/`Menu`. */
38
+ export interface MenuItem {
39
+ /** Stable id, returned by `onselect`. */
40
+ id: string;
41
+ /** Visible item label. */
42
+ label: string;
43
+ /** Disable this item. */
44
+ disabled?: boolean;
45
+ /** Per-item activation handler. */
46
+ onselect?: () => void;
47
+ }
48
+ /** A node in a `Tree`. */
49
+ export interface TreeNode {
50
+ /** Stable id, returned by `onselect`. */
51
+ id: string;
52
+ /** Visible node label. */
53
+ label: string;
54
+ /** Child nodes; presence makes the node expandable. */
55
+ children?: TreeNode[];
56
+ }
57
+ export type ChatMessageRole = 'user' | 'agent' | 'system';
58
+ export interface DayEventDetail {
59
+ type: string;
60
+ name: string;
61
+ slug: string;
62
+ startTime: string;
63
+ venue?: string;
64
+ councilSlug?: string;
65
+ }
66
+ export interface DayEventsData {
67
+ date: string;
68
+ events: DayEventDetail[];
69
+ }
70
+ export interface DayForecast {
71
+ icon: string;
72
+ high: number;
73
+ low: number;
74
+ }
75
+ //# sourceMappingURL=types-generic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-generic.d.ts","sourceRoot":"","sources":["../src/types-generic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { formatEmail, formatText, matchOption, parseSpokenBoolean, } from '../formatters';
3
+ describe('Form Formatters', () => {
4
+ it('should format email correctly', () => {
5
+ expect(formatEmail('john at example dot com')).toBe('john@example.com');
6
+ expect(formatEmail('JOHN DOT DOE AT GMAIL DOT COM')).toBe('john.doe@gmail.com');
7
+ });
8
+ it('should format text correctly', () => {
9
+ expect(formatText('my name is John')).toBe('John');
10
+ expect(formatText('um so well hello')).toBe('hello');
11
+ });
12
+ it('should parse spoken boolean correctly', () => {
13
+ expect(parseSpokenBoolean('yes please')).toBe(true);
14
+ expect(parseSpokenBoolean('no way')).toBe(false);
15
+ expect(parseSpokenBoolean('maybe')).toBe(null);
16
+ });
17
+ it('should match options correctly', () => {
18
+ const options = [
19
+ { label: 'Red', value: 'red' },
20
+ { label: 'Green', value: 'green' },
21
+ { label: 'Blue', value: 'blue' },
22
+ ];
23
+ expect(matchOption('red', options)).toBe('red');
24
+ expect(matchOption('I want green', options)).toBe('green');
25
+ expect(matchOption('yellow', options)).toBe(null);
26
+ });
27
+ });
@@ -0,0 +1,14 @@
1
+ export declare function formatEmail(transcript: string): string;
2
+ export declare function formatText(transcript: string): string;
3
+ /**
4
+ * Parses a spoken string into a boolean value.
5
+ */
6
+ export declare function parseSpokenBoolean(text: string): boolean | null;
7
+ /**
8
+ * Matches a spoken string against a list of options.
9
+ */
10
+ export declare function matchOption(spokenText: string, options: Array<{
11
+ label: string;
12
+ value: string;
13
+ }>): string | null;
14
+ //# sourceMappingURL=formatters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../../src/utils/forms/formatters.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAStD;AAED,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAsC/D;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAC/C,MAAM,GAAG,IAAI,CAwBf"}
@@ -0,0 +1,77 @@
1
+ export function formatEmail(transcript) {
2
+ return transcript
3
+ .toLowerCase()
4
+ .replace(/\s+at\s+/gi, '@')
5
+ .replace(/\bat\b/gi, '@')
6
+ .replace(/\s+dot\s+/gi, '.')
7
+ .replace(/\bdot\b/gi, '.')
8
+ .replace(/\s+/g, '')
9
+ .trim();
10
+ }
11
+ export function formatText(transcript) {
12
+ return transcript
13
+ .replace(/^(my name is|i am|i'm|it's|this is|the name is)\s*/i, '')
14
+ .replace(/\b(um|uh|like|so|well)\b\s*/gi, '')
15
+ .trim();
16
+ }
17
+ /**
18
+ * Parses a spoken string into a boolean value.
19
+ */
20
+ export function parseSpokenBoolean(text) {
21
+ const normalized = text.toLowerCase().trim();
22
+ const trueWords = [
23
+ 'yes',
24
+ 'yeah',
25
+ 'yep',
26
+ 'true',
27
+ 'correct',
28
+ 'affirmative',
29
+ 'check',
30
+ 'checked',
31
+ 'on',
32
+ 'enable',
33
+ 'enabled',
34
+ ];
35
+ const falseWords = [
36
+ 'no',
37
+ 'nope',
38
+ 'false',
39
+ 'incorrect',
40
+ 'negative',
41
+ 'uncheck',
42
+ 'unchecked',
43
+ 'off',
44
+ 'disable',
45
+ 'disabled',
46
+ ];
47
+ for (const word of trueWords) {
48
+ if (normalized.includes(word))
49
+ return true;
50
+ }
51
+ for (const word of falseWords) {
52
+ if (normalized.includes(word))
53
+ return false;
54
+ }
55
+ return null;
56
+ }
57
+ /**
58
+ * Matches a spoken string against a list of options.
59
+ */
60
+ export function matchOption(spokenText, options) {
61
+ const normalized = spokenText.toLowerCase().trim();
62
+ // Try exact match first
63
+ for (const opt of options) {
64
+ if (opt.value.toLowerCase() === normalized ||
65
+ opt.label.toLowerCase() === normalized) {
66
+ return opt.value;
67
+ }
68
+ }
69
+ // Try partial match
70
+ for (const opt of options) {
71
+ if (opt.label.toLowerCase().includes(normalized) ||
72
+ normalized.includes(opt.label.toLowerCase())) {
73
+ return opt.value;
74
+ }
75
+ }
76
+ return null;
77
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Load an optional dependency without forcing bundlers to statically include it.
3
+ */
4
+ export declare function importOptional<TModule = unknown>(moduleName: string): Promise<TModule>;
5
+ //# sourceMappingURL=import-optional.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-optional.d.ts","sourceRoot":"","sources":["../../src/utils/import-optional.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,GAAG,OAAO,EACpD,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CAGlB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Load an optional dependency without forcing bundlers to statically include it.
3
+ */
4
+ export async function importOptional(moduleName) {
5
+ const name = moduleName;
6
+ return import(/* @vite-ignore */ name);
7
+ }
@@ -0,0 +1,72 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { generateTheme, getContrastRatio, getLuminance, hexToRgb, meetsContrastAA, meetsContrastAAA, rgbToHex, } from '../color';
3
+ describe('Theme Color Utilities', () => {
4
+ it('should convert hex to rgb correctly', () => {
5
+ expect(hexToRgb('#000000')).toEqual({ r: 0, g: 0, b: 0 });
6
+ expect(hexToRgb('#ffffff')).toEqual({ r: 255, g: 255, b: 255 });
7
+ expect(hexToRgb('#FF5733')).toEqual({ r: 255, g: 87, b: 51 });
8
+ });
9
+ it('should convert rgb to hex correctly', () => {
10
+ expect(rgbToHex(0, 0, 0)).toBe('#000000');
11
+ expect(rgbToHex(255, 255, 255)).toBe('#ffffff');
12
+ expect(rgbToHex(255, 87, 51)).toBe('#ff5733');
13
+ });
14
+ it('should generate a theme palette from a seed color', () => {
15
+ const seed = '#6750A4'; // M3 Baseline Purple
16
+ const theme = generateTheme(seed);
17
+ // Check for critical M3 keys
18
+ expect(theme).toHaveProperty('primary');
19
+ expect(theme).toHaveProperty('onPrimary');
20
+ expect(theme).toHaveProperty('primaryContainer');
21
+ expect(theme).toHaveProperty('onPrimaryContainer');
22
+ expect(theme).toHaveProperty('secondary');
23
+ expect(theme).toHaveProperty('surface');
24
+ expect(theme).toHaveProperty('background');
25
+ expect(theme).toHaveProperty('error');
26
+ // Basic validity check (strings should be hex colors)
27
+ expect(theme.primary).toMatch(/^#[0-9a-fA-F]{6}$/);
28
+ });
29
+ it('should generate different palettes for light and dark modes', () => {
30
+ const seed = '#6750A4';
31
+ const lightTheme = generateTheme(seed, 'light');
32
+ const darkTheme = generateTheme(seed, 'dark');
33
+ expect(lightTheme.primary).not.toBe(darkTheme.primary);
34
+ // In M3, dark mode primary is usually lighter/desaturated compared to light mode
35
+ });
36
+ });
37
+ describe('Color Contrast Utilities', () => {
38
+ it('should calculate luminance correctly', () => {
39
+ // Black has luminance 0
40
+ expect(getLuminance({ r: 0, g: 0, b: 0 })).toBe(0);
41
+ // White has luminance 1
42
+ expect(getLuminance({ r: 255, g: 255, b: 255 })).toBe(1);
43
+ // Mid gray should be around 0.2
44
+ const midGray = getLuminance({ r: 128, g: 128, b: 128 });
45
+ expect(midGray).toBeGreaterThan(0.1);
46
+ expect(midGray).toBeLessThan(0.3);
47
+ });
48
+ it('should calculate contrast ratio correctly', () => {
49
+ const black = { r: 0, g: 0, b: 0 };
50
+ const white = { r: 255, g: 255, b: 255 };
51
+ // Black on white should be 21:1 (maximum contrast)
52
+ expect(getContrastRatio(black, white)).toBeCloseTo(21, 0);
53
+ // Same color should be 1:1 (no contrast)
54
+ expect(getContrastRatio(black, black)).toBe(1);
55
+ });
56
+ it('should validate WCAG AA contrast requirements', () => {
57
+ // Black on white passes AA
58
+ expect(meetsContrastAA('#000000', '#ffffff')).toBe(true);
59
+ // Light gray on white fails AA for normal text
60
+ expect(meetsContrastAA('#999999', '#ffffff')).toBe(false);
61
+ // Light gray on white passes AA for large text (3:1 threshold)
62
+ expect(meetsContrastAA('#767676', '#ffffff', true)).toBe(true);
63
+ });
64
+ it('should validate WCAG AAA contrast requirements', () => {
65
+ // Black on white passes AAA
66
+ expect(meetsContrastAAA('#000000', '#ffffff')).toBe(true);
67
+ // Medium gray on white fails AAA for normal text (needs 7:1)
68
+ expect(meetsContrastAAA('#666666', '#ffffff')).toBe(false);
69
+ // Darker gray passes AAA for large text (4.5:1 threshold)
70
+ expect(meetsContrastAAA('#595959', '#ffffff', true)).toBe(true);
71
+ });
72
+ });
@@ -0,0 +1,11 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { elevationTokens, typographyTokens } from '../typography';
3
+ describe('Typography & Elevation Tokens', () => {
4
+ it('should have valid typography tokens', () => {
5
+ expect(typographyTokens['--md-sys-typescale-body-large-font']).toBeDefined();
6
+ expect(typographyTokens['--md-sys-typescale-display-large-font']).toContain('Roboto');
7
+ });
8
+ it('should have valid elevation tokens', () => {
9
+ expect(elevationTokens['--md-sys-elevation-level1']).toBeDefined();
10
+ });
11
+ });
@@ -0,0 +1,70 @@
1
+ export interface Rgb {
2
+ r: number;
3
+ g: number;
4
+ b: number;
5
+ }
6
+ export interface Hsl {
7
+ h: number;
8
+ s: number;
9
+ l: number;
10
+ }
11
+ export interface Theme {
12
+ primary: string;
13
+ onPrimary: string;
14
+ primaryContainer: string;
15
+ onPrimaryContainer: string;
16
+ secondary: string;
17
+ onSecondary: string;
18
+ secondaryContainer: string;
19
+ onSecondaryContainer: string;
20
+ tertiary: string;
21
+ onTertiary: string;
22
+ tertiaryContainer: string;
23
+ onTertiaryContainer: string;
24
+ error: string;
25
+ onError: string;
26
+ errorContainer: string;
27
+ onErrorContainer: string;
28
+ background: string;
29
+ onBackground: string;
30
+ surface: string;
31
+ onSurface: string;
32
+ surfaceVariant: string;
33
+ onSurfaceVariant: string;
34
+ outline: string;
35
+ outlineVariant: string;
36
+ shadow: string;
37
+ scrim: string;
38
+ inverseSurface: string;
39
+ inverseOnSurface: string;
40
+ inversePrimary: string;
41
+ surfaceDim: string;
42
+ surfaceBright: string;
43
+ surfaceContainerLowest: string;
44
+ surfaceContainerLow: string;
45
+ surfaceContainer: string;
46
+ surfaceContainerHigh: string;
47
+ surfaceContainerHighest: string;
48
+ }
49
+ export declare function hexToRgb(hex: string): Rgb;
50
+ export declare function rgbToHex(r: number, g: number, b: number): string;
51
+ /**
52
+ * Calculate relative luminance of a color per WCAG 2.1
53
+ * https://www.w3.org/WAI/GL/wiki/Relative_luminance
54
+ */
55
+ export declare function getLuminance(rgb: Rgb): number;
56
+ /**
57
+ * Calculate contrast ratio between two colors per WCAG 2.1
58
+ * Returns a value between 1 and 21
59
+ */
60
+ export declare function getContrastRatio(fg: Rgb, bg: Rgb): number;
61
+ /**
62
+ * Check if contrast meets WCAG AA standard (4.5:1 for normal text, 3:1 for large text)
63
+ */
64
+ export declare function meetsContrastAA(fg: string | Rgb, bg: string | Rgb, largeText?: boolean): boolean;
65
+ /**
66
+ * Check if contrast meets WCAG AAA standard (7:1 for normal text, 4.5:1 for large text)
67
+ */
68
+ export declare function meetsContrastAAA(fg: string | Rgb, bg: string | Rgb, largeText?: boolean): boolean;
69
+ export declare function generateTheme(seedColor: string, mode?: 'light' | 'dark'): Theme;
70
+ //# sourceMappingURL=color.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../../src/utils/theme/color.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,GAAG;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAGD,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uBAAuB,EAAE,MAAM,CAAC;CACjC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAMzC;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAM7C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,MAAM,CAMzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,MAAM,GAAG,GAAG,EAChB,EAAE,EAAE,MAAM,GAAG,GAAG,EAChB,SAAS,UAAQ,GAChB,OAAO,CAKT;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,GAAG,GAAG,EAChB,EAAE,EAAE,MAAM,GAAG,GAAG,EAChB,SAAS,UAAQ,GAChB,OAAO,CAKT;AAmED,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,OAAO,GAAG,MAAgB,GAC/B,KAAK,CA2HP"}
@@ -0,0 +1,221 @@
1
+ export function hexToRgb(hex) {
2
+ const cleanHex = hex.replace('#', '');
3
+ const r = parseInt(cleanHex.substring(0, 2), 16);
4
+ const g = parseInt(cleanHex.substring(2, 4), 16);
5
+ const b = parseInt(cleanHex.substring(4, 6), 16);
6
+ return { r, g, b };
7
+ }
8
+ export function rgbToHex(r, g, b) {
9
+ const toHex = (c) => {
10
+ const hex = Math.round(Math.max(0, Math.min(255, c))).toString(16);
11
+ return hex.length === 1 ? `0${hex}` : hex;
12
+ };
13
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
14
+ }
15
+ /**
16
+ * Calculate relative luminance of a color per WCAG 2.1
17
+ * https://www.w3.org/WAI/GL/wiki/Relative_luminance
18
+ */
19
+ export function getLuminance(rgb) {
20
+ const [r, g, b] = [rgb.r, rgb.g, rgb.b].map((c) => {
21
+ const sRGB = c / 255;
22
+ return sRGB <= 0.03928 ? sRGB / 12.92 : ((sRGB + 0.055) / 1.055) ** 2.4;
23
+ });
24
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
25
+ }
26
+ /**
27
+ * Calculate contrast ratio between two colors per WCAG 2.1
28
+ * Returns a value between 1 and 21
29
+ */
30
+ export function getContrastRatio(fg, bg) {
31
+ const L1 = getLuminance(fg);
32
+ const L2 = getLuminance(bg);
33
+ const lighter = Math.max(L1, L2);
34
+ const darker = Math.min(L1, L2);
35
+ return (lighter + 0.05) / (darker + 0.05);
36
+ }
37
+ /**
38
+ * Check if contrast meets WCAG AA standard (4.5:1 for normal text, 3:1 for large text)
39
+ */
40
+ export function meetsContrastAA(fg, bg, largeText = false) {
41
+ const fgRgb = typeof fg === 'string' ? hexToRgb(fg) : fg;
42
+ const bgRgb = typeof bg === 'string' ? hexToRgb(bg) : bg;
43
+ const ratio = getContrastRatio(fgRgb, bgRgb);
44
+ return ratio >= (largeText ? 3 : 4.5);
45
+ }
46
+ /**
47
+ * Check if contrast meets WCAG AAA standard (7:1 for normal text, 4.5:1 for large text)
48
+ */
49
+ export function meetsContrastAAA(fg, bg, largeText = false) {
50
+ const fgRgb = typeof fg === 'string' ? hexToRgb(fg) : fg;
51
+ const bgRgb = typeof bg === 'string' ? hexToRgb(bg) : bg;
52
+ const ratio = getContrastRatio(fgRgb, bgRgb);
53
+ return ratio >= (largeText ? 4.5 : 7);
54
+ }
55
+ function rgbToHsl(r, g, b) {
56
+ r /= 255;
57
+ g /= 255;
58
+ b /= 255;
59
+ const max = Math.max(r, g, b);
60
+ const min = Math.min(r, g, b);
61
+ let h = 0, s = 0, l = (max + min) / 2;
62
+ if (max !== min) {
63
+ const d = max - min;
64
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
65
+ switch (max) {
66
+ case r:
67
+ h = (g - b) / d + (g < b ? 6 : 0);
68
+ break;
69
+ case g:
70
+ h = (b - r) / d + 2;
71
+ break;
72
+ case b:
73
+ h = (r - g) / d + 4;
74
+ break;
75
+ }
76
+ h /= 6;
77
+ }
78
+ return { h: h * 360, s: s * 100, l: l * 100 };
79
+ }
80
+ function hslToRgb(h, s, l) {
81
+ h /= 360;
82
+ s /= 100;
83
+ l /= 100;
84
+ let r, g, b;
85
+ if (s === 0) {
86
+ r = g = b = l;
87
+ }
88
+ else {
89
+ const hue2rgb = (p, q, t) => {
90
+ if (t < 0)
91
+ t += 1;
92
+ if (t > 1)
93
+ t -= 1;
94
+ if (t < 1 / 6)
95
+ return p + (q - p) * 6 * t;
96
+ if (t < 1 / 2)
97
+ return q;
98
+ if (t < 2 / 3)
99
+ return p + (q - p) * (2 / 3 - t) * 6;
100
+ return p;
101
+ };
102
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
103
+ const p = 2 * l - q;
104
+ r = hue2rgb(p, q, h + 1 / 3);
105
+ g = hue2rgb(p, q, h);
106
+ b = hue2rgb(p, q, h - 1 / 3);
107
+ }
108
+ return { r: r * 255, g: g * 255, b: b * 255 };
109
+ }
110
+ function hslToHex(h, s, l) {
111
+ const { r, g, b } = hslToRgb(h, s, l);
112
+ return rgbToHex(r, g, b);
113
+ }
114
+ // Generate a color with the same Hue and Saturation but specific Lightness
115
+ function tone(h, s, l) {
116
+ return hslToHex(h, s, l);
117
+ }
118
+ export function generateTheme(seedColor, mode = 'light') {
119
+ const rgb = hexToRgb(seedColor);
120
+ const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
121
+ // Tonal Palettes (Simplified M3 Logic)
122
+ // Primary: Keep seed hue/sat
123
+ const p_h = hsl.h;
124
+ const p_s = Math.max(hsl.s, 40); // Ensure some vibrancy
125
+ // Secondary: Less vibrant
126
+ const s_h = p_h;
127
+ const s_s = Math.max(p_s / 3, 20);
128
+ // Tertiary: Shifted hue
129
+ const t_h = (p_h + 60) % 360;
130
+ const t_s = Math.max(p_s / 1.5, 30);
131
+ // Neutral
132
+ const n_h = p_h;
133
+ const n_s = Math.min(p_s / 10, 8); // Very low saturation
134
+ // Neutral Variant
135
+ const nv_h = p_h;
136
+ const nv_s = Math.min(p_s / 6, 16);
137
+ // Error (Red)
138
+ const e_h = 0; // Red
139
+ const e_s = 80;
140
+ if (mode === 'light') {
141
+ return {
142
+ primary: tone(p_h, p_s, 40),
143
+ onPrimary: tone(p_h, p_s, 100),
144
+ primaryContainer: tone(p_h, p_s, 90),
145
+ onPrimaryContainer: tone(p_h, p_s, 10),
146
+ secondary: tone(s_h, s_s, 40),
147
+ onSecondary: tone(s_h, s_s, 100),
148
+ secondaryContainer: tone(s_h, s_s, 90),
149
+ onSecondaryContainer: tone(s_h, s_s, 10),
150
+ tertiary: tone(t_h, t_s, 40),
151
+ onTertiary: tone(t_h, t_s, 100),
152
+ tertiaryContainer: tone(t_h, t_s, 90),
153
+ onTertiaryContainer: tone(t_h, t_s, 10),
154
+ error: tone(e_h, e_s, 40),
155
+ onError: tone(e_h, e_s, 100),
156
+ errorContainer: tone(e_h, e_s, 90),
157
+ onErrorContainer: tone(e_h, e_s, 10),
158
+ background: tone(n_h, n_s, 99),
159
+ onBackground: tone(n_h, n_s, 10),
160
+ surface: tone(n_h, n_s, 99),
161
+ onSurface: tone(n_h, n_s, 10),
162
+ surfaceVariant: tone(nv_h, nv_s, 90),
163
+ onSurfaceVariant: tone(nv_h, nv_s, 30),
164
+ outline: tone(nv_h, nv_s, 50),
165
+ outlineVariant: tone(nv_h, nv_s, 80),
166
+ shadow: tone(0, 0, 0),
167
+ scrim: tone(0, 0, 0),
168
+ inverseSurface: tone(n_h, n_s, 20),
169
+ inverseOnSurface: tone(n_h, n_s, 95),
170
+ inversePrimary: tone(p_h, p_s, 80),
171
+ surfaceDim: tone(n_h, n_s, 87),
172
+ surfaceBright: tone(n_h, n_s, 98),
173
+ surfaceContainerLowest: tone(n_h, n_s, 100),
174
+ surfaceContainerLow: tone(n_h, n_s, 96),
175
+ surfaceContainer: tone(n_h, n_s, 94),
176
+ surfaceContainerHigh: tone(n_h, n_s, 92),
177
+ surfaceContainerHighest: tone(n_h, n_s, 90),
178
+ };
179
+ }
180
+ else {
181
+ // Dark Mode mappings
182
+ return {
183
+ primary: tone(p_h, p_s, 80),
184
+ onPrimary: tone(p_h, p_s, 20),
185
+ primaryContainer: tone(p_h, p_s, 30),
186
+ onPrimaryContainer: tone(p_h, p_s, 90),
187
+ secondary: tone(s_h, s_s, 80),
188
+ onSecondary: tone(s_h, s_s, 20),
189
+ secondaryContainer: tone(s_h, s_s, 30),
190
+ onSecondaryContainer: tone(s_h, s_s, 90),
191
+ tertiary: tone(t_h, t_s, 80),
192
+ onTertiary: tone(t_h, t_s, 20),
193
+ tertiaryContainer: tone(t_h, t_s, 30),
194
+ onTertiaryContainer: tone(t_h, t_s, 90),
195
+ error: tone(e_h, e_s, 80),
196
+ onError: tone(e_h, e_s, 20),
197
+ errorContainer: tone(e_h, e_s, 30),
198
+ onErrorContainer: tone(e_h, e_s, 90),
199
+ background: tone(n_h, n_s, 10),
200
+ onBackground: tone(n_h, n_s, 90),
201
+ surface: tone(n_h, n_s, 10),
202
+ onSurface: tone(n_h, n_s, 90),
203
+ surfaceVariant: tone(nv_h, nv_s, 30),
204
+ onSurfaceVariant: tone(nv_h, nv_s, 80),
205
+ outline: tone(nv_h, nv_s, 60),
206
+ outlineVariant: tone(nv_h, nv_s, 30),
207
+ shadow: tone(0, 0, 0),
208
+ scrim: tone(0, 0, 0),
209
+ inverseSurface: tone(n_h, n_s, 90),
210
+ inverseOnSurface: tone(n_h, n_s, 20),
211
+ inversePrimary: tone(p_h, p_s, 40),
212
+ surfaceDim: tone(n_h, n_s, 6),
213
+ surfaceBright: tone(n_h, n_s, 24),
214
+ surfaceContainerLowest: tone(n_h, n_s, 4),
215
+ surfaceContainerLow: tone(n_h, n_s, 10),
216
+ surfaceContainer: tone(n_h, n_s, 12),
217
+ surfaceContainerHigh: tone(n_h, n_s, 17),
218
+ surfaceContainerHighest: tone(n_h, n_s, 22),
219
+ };
220
+ }
221
+ }
@@ -0,0 +1,27 @@
1
+ export declare const typographyTokens: {
2
+ '--smrt-font-family': string;
3
+ '--md-sys-typescale-display-large-font': string;
4
+ '--md-sys-typescale-display-medium-font': string;
5
+ '--md-sys-typescale-display-small-font': string;
6
+ '--md-sys-typescale-headline-large-font': string;
7
+ '--md-sys-typescale-headline-medium-font': string;
8
+ '--md-sys-typescale-headline-small-font': string;
9
+ '--md-sys-typescale-title-large-font': string;
10
+ '--md-sys-typescale-title-medium-font': string;
11
+ '--md-sys-typescale-title-small-font': string;
12
+ '--md-sys-typescale-label-large-font': string;
13
+ '--md-sys-typescale-label-medium-font': string;
14
+ '--md-sys-typescale-label-small-font': string;
15
+ '--md-sys-typescale-body-large-font': string;
16
+ '--md-sys-typescale-body-medium-font': string;
17
+ '--md-sys-typescale-body-small-font': string;
18
+ };
19
+ export declare const elevationTokens: {
20
+ '--md-sys-elevation-level0': string;
21
+ '--md-sys-elevation-level1': string;
22
+ '--md-sys-elevation-level2': string;
23
+ '--md-sys-elevation-level3': string;
24
+ '--md-sys-elevation-level4': string;
25
+ '--md-sys-elevation-level5': string;
26
+ };
27
+ //# sourceMappingURL=typography.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typography.d.ts","sourceRoot":"","sources":["../../../src/utils/theme/typography.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;CAuB5B,CAAC;AAGF,eAAO,MAAM,eAAe;;;;;;;CAY3B,CAAC"}