@spatika/react 1.0.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 (406) hide show
  1. package/README.md +72 -0
  2. package/dist/composites/ActionBar.d.ts +7 -0
  3. package/dist/composites/ActionBar.d.ts.map +1 -0
  4. package/dist/composites/ActionBar.js +5 -0
  5. package/dist/composites/AmountInput.d.ts +10 -0
  6. package/dist/composites/AmountInput.d.ts.map +1 -0
  7. package/dist/composites/AmountInput.js +7 -0
  8. package/dist/composites/AppHeader.d.ts +25 -0
  9. package/dist/composites/AppHeader.d.ts.map +1 -0
  10. package/dist/composites/AppHeader.js +13 -0
  11. package/dist/composites/AppSidebar.d.ts +30 -0
  12. package/dist/composites/AppSidebar.d.ts.map +1 -0
  13. package/dist/composites/AppSidebar.js +15 -0
  14. package/dist/composites/BottomSheet.d.ts +36 -0
  15. package/dist/composites/BottomSheet.d.ts.map +1 -0
  16. package/dist/composites/BottomSheet.js +37 -0
  17. package/dist/composites/Breadcrumb.d.ts +10 -0
  18. package/dist/composites/Breadcrumb.d.ts.map +1 -0
  19. package/dist/composites/Breadcrumb.js +10 -0
  20. package/dist/composites/Callout.d.ts +8 -0
  21. package/dist/composites/Callout.d.ts.map +1 -0
  22. package/dist/composites/Callout.js +5 -0
  23. package/dist/composites/Card.d.ts +31 -0
  24. package/dist/composites/Card.d.ts.map +1 -0
  25. package/dist/composites/Card.js +33 -0
  26. package/dist/composites/Chip.d.ts +13 -0
  27. package/dist/composites/Chip.d.ts.map +1 -0
  28. package/dist/composites/Chip.js +59 -0
  29. package/dist/composites/ChipGroup.d.ts +23 -0
  30. package/dist/composites/ChipGroup.d.ts.map +1 -0
  31. package/dist/composites/ChipGroup.js +27 -0
  32. package/dist/composites/CommandSearchField.d.ts +27 -0
  33. package/dist/composites/CommandSearchField.d.ts.map +1 -0
  34. package/dist/composites/CommandSearchField.js +17 -0
  35. package/dist/composites/CoverHero.d.ts +51 -0
  36. package/dist/composites/CoverHero.d.ts.map +1 -0
  37. package/dist/composites/CoverHero.js +71 -0
  38. package/dist/composites/CoverPattern.d.ts +12 -0
  39. package/dist/composites/CoverPattern.d.ts.map +1 -0
  40. package/dist/composites/CoverPattern.js +14 -0
  41. package/dist/composites/DataTableToolbar.d.ts +13 -0
  42. package/dist/composites/DataTableToolbar.d.ts.map +1 -0
  43. package/dist/composites/DataTableToolbar.js +7 -0
  44. package/dist/composites/DividerLabel.d.ts +5 -0
  45. package/dist/composites/DividerLabel.d.ts.map +1 -0
  46. package/dist/composites/DividerLabel.js +5 -0
  47. package/dist/composites/EmptyState.d.ts +16 -0
  48. package/dist/composites/EmptyState.d.ts.map +1 -0
  49. package/dist/composites/EmptyState.js +10 -0
  50. package/dist/composites/EntityCard.d.ts +31 -0
  51. package/dist/composites/EntityCard.d.ts.map +1 -0
  52. package/dist/composites/EntityCard.js +21 -0
  53. package/dist/composites/EntityMediaCard.d.ts +25 -0
  54. package/dist/composites/EntityMediaCard.d.ts.map +1 -0
  55. package/dist/composites/EntityMediaCard.js +17 -0
  56. package/dist/composites/FilterSheet.d.ts +34 -0
  57. package/dist/composites/FilterSheet.d.ts.map +1 -0
  58. package/dist/composites/FilterSheet.js +36 -0
  59. package/dist/composites/FloatingPageChrome.d.ts +90 -0
  60. package/dist/composites/FloatingPageChrome.d.ts.map +1 -0
  61. package/dist/composites/FloatingPageChrome.js +67 -0
  62. package/dist/composites/FormField.d.ts +15 -0
  63. package/dist/composites/FormField.d.ts.map +1 -0
  64. package/dist/composites/FormField.js +9 -0
  65. package/dist/composites/GlassCard.d.ts +13 -0
  66. package/dist/composites/GlassCard.d.ts.map +1 -0
  67. package/dist/composites/GlassCard.js +32 -0
  68. package/dist/composites/HeaderIconButton.d.ts +13 -0
  69. package/dist/composites/HeaderIconButton.d.ts.map +1 -0
  70. package/dist/composites/HeaderIconButton.js +12 -0
  71. package/dist/composites/ListRow.d.ts +9 -0
  72. package/dist/composites/ListRow.d.ts.map +1 -0
  73. package/dist/composites/ListRow.js +6 -0
  74. package/dist/composites/MediaEntryCard.d.ts +25 -0
  75. package/dist/composites/MediaEntryCard.d.ts.map +1 -0
  76. package/dist/composites/MediaEntryCard.js +10 -0
  77. package/dist/composites/MobileTabBar.d.ts +33 -0
  78. package/dist/composites/MobileTabBar.d.ts.map +1 -0
  79. package/dist/composites/MobileTabBar.js +19 -0
  80. package/dist/composites/NotificationBell.d.ts +28 -0
  81. package/dist/composites/NotificationBell.d.ts.map +1 -0
  82. package/dist/composites/NotificationBell.js +25 -0
  83. package/dist/composites/PageHeader.d.ts +11 -0
  84. package/dist/composites/PageHeader.d.ts.map +1 -0
  85. package/dist/composites/PageHeader.js +6 -0
  86. package/dist/composites/PageShell.d.ts +12 -0
  87. package/dist/composites/PageShell.d.ts.map +1 -0
  88. package/dist/composites/PageShell.js +8 -0
  89. package/dist/composites/PageStickyHeader.d.ts +33 -0
  90. package/dist/composites/PageStickyHeader.d.ts.map +1 -0
  91. package/dist/composites/PageStickyHeader.js +19 -0
  92. package/dist/composites/Pagination.d.ts +7 -0
  93. package/dist/composites/Pagination.d.ts.map +1 -0
  94. package/dist/composites/Pagination.js +6 -0
  95. package/dist/composites/PhotoViewer.d.ts +18 -0
  96. package/dist/composites/PhotoViewer.d.ts.map +1 -0
  97. package/dist/composites/PhotoViewer.js +37 -0
  98. package/dist/composites/PinPad.d.ts +29 -0
  99. package/dist/composites/PinPad.d.ts.map +1 -0
  100. package/dist/composites/PinPad.js +58 -0
  101. package/dist/composites/ProfileHero.d.ts +34 -0
  102. package/dist/composites/ProfileHero.d.ts.map +1 -0
  103. package/dist/composites/ProfileHero.js +21 -0
  104. package/dist/composites/QuickFilterRail.d.ts +25 -0
  105. package/dist/composites/QuickFilterRail.d.ts.map +1 -0
  106. package/dist/composites/QuickFilterRail.js +18 -0
  107. package/dist/composites/QuickSettings.d.ts +27 -0
  108. package/dist/composites/QuickSettings.d.ts.map +1 -0
  109. package/dist/composites/QuickSettings.js +18 -0
  110. package/dist/composites/RichTextEditor.d.ts +13 -0
  111. package/dist/composites/RichTextEditor.d.ts.map +1 -0
  112. package/dist/composites/RichTextEditor.js +23 -0
  113. package/dist/composites/SearchField.d.ts +8 -0
  114. package/dist/composites/SearchField.d.ts.map +1 -0
  115. package/dist/composites/SearchField.js +8 -0
  116. package/dist/composites/SectionPanel.d.ts +16 -0
  117. package/dist/composites/SectionPanel.d.ts.map +1 -0
  118. package/dist/composites/SectionPanel.js +8 -0
  119. package/dist/composites/SegmentedControl.d.ts +17 -0
  120. package/dist/composites/SegmentedControl.d.ts.map +1 -0
  121. package/dist/composites/SegmentedControl.js +11 -0
  122. package/dist/composites/StatCard.d.ts +11 -0
  123. package/dist/composites/StatCard.d.ts.map +1 -0
  124. package/dist/composites/StatCard.js +6 -0
  125. package/dist/composites/StatusDot.d.ts +11 -0
  126. package/dist/composites/StatusDot.d.ts.map +1 -0
  127. package/dist/composites/StatusDot.js +23 -0
  128. package/dist/composites/SurfaceCard.d.ts +12 -0
  129. package/dist/composites/SurfaceCard.d.ts.map +1 -0
  130. package/dist/composites/SurfaceCard.js +24 -0
  131. package/dist/composites/Timeline.d.ts +19 -0
  132. package/dist/composites/Timeline.d.ts.map +1 -0
  133. package/dist/composites/Timeline.js +12 -0
  134. package/dist/composites/Toast.d.ts +26 -0
  135. package/dist/composites/Toast.d.ts.map +1 -0
  136. package/dist/composites/Toast.js +49 -0
  137. package/dist/composites/Toolbar.d.ts +6 -0
  138. package/dist/composites/Toolbar.d.ts.map +1 -0
  139. package/dist/composites/Toolbar.js +5 -0
  140. package/dist/composites/ViewFiltersPanel.d.ts +21 -0
  141. package/dist/composites/ViewFiltersPanel.d.ts.map +1 -0
  142. package/dist/composites/ViewFiltersPanel.js +11 -0
  143. package/dist/index.d.ts +96 -0
  144. package/dist/index.d.ts.map +1 -0
  145. package/dist/index.js +95 -0
  146. package/dist/lib/animations.d.ts +62 -0
  147. package/dist/lib/animations.d.ts.map +1 -0
  148. package/dist/lib/animations.js +37 -0
  149. package/dist/lib/avatar-utils.d.ts +10 -0
  150. package/dist/lib/avatar-utils.d.ts.map +1 -0
  151. package/dist/lib/avatar-utils.js +49 -0
  152. package/dist/lib/chips.d.ts +10 -0
  153. package/dist/lib/chips.d.ts.map +1 -0
  154. package/dist/lib/chips.js +30 -0
  155. package/dist/lib/cn.d.ts +4 -0
  156. package/dist/lib/cn.d.ts.map +1 -0
  157. package/dist/lib/cn.js +6 -0
  158. package/dist/lib/compose-refs.d.ts +6 -0
  159. package/dist/lib/compose-refs.d.ts.map +1 -0
  160. package/dist/lib/compose-refs.js +17 -0
  161. package/dist/lib/cover-chrome.d.ts +9 -0
  162. package/dist/lib/cover-chrome.d.ts.map +1 -0
  163. package/dist/lib/cover-chrome.js +23 -0
  164. package/dist/lib/cover-pattern.d.ts +75 -0
  165. package/dist/lib/cover-pattern.d.ts.map +1 -0
  166. package/dist/lib/cover-pattern.js +135 -0
  167. package/dist/lib/overlay-stack.d.ts +23 -0
  168. package/dist/lib/overlay-stack.d.ts.map +1 -0
  169. package/dist/lib/overlay-stack.js +37 -0
  170. package/dist/lib/portal.d.ts +12 -0
  171. package/dist/lib/portal.d.ts.map +1 -0
  172. package/dist/lib/portal.js +12 -0
  173. package/dist/lib/slot.d.ts +12 -0
  174. package/dist/lib/slot.d.ts.map +1 -0
  175. package/dist/lib/slot.js +55 -0
  176. package/dist/lib/surfaces.d.ts +14 -0
  177. package/dist/lib/surfaces.d.ts.map +1 -0
  178. package/dist/lib/surfaces.js +18 -0
  179. package/dist/lib/themes.d.ts +16 -0
  180. package/dist/lib/themes.d.ts.map +1 -0
  181. package/dist/lib/themes.js +53 -0
  182. package/dist/lib/typography.d.ts +17 -0
  183. package/dist/lib/typography.d.ts.map +1 -0
  184. package/dist/lib/typography.js +16 -0
  185. package/dist/lib/use-controllable-state.d.ts +12 -0
  186. package/dist/lib/use-controllable-state.d.ts.map +1 -0
  187. package/dist/lib/use-controllable-state.js +20 -0
  188. package/dist/lib/use-cover-chrome-bleed.d.ts +9 -0
  189. package/dist/lib/use-cover-chrome-bleed.d.ts.map +1 -0
  190. package/dist/lib/use-cover-chrome-bleed.js +28 -0
  191. package/dist/lib/use-dismissable.d.ts +13 -0
  192. package/dist/lib/use-dismissable.d.ts.map +1 -0
  193. package/dist/lib/use-dismissable.js +33 -0
  194. package/dist/lib/use-floating-position.d.ts +27 -0
  195. package/dist/lib/use-floating-position.d.ts.map +1 -0
  196. package/dist/lib/use-floating-position.js +115 -0
  197. package/dist/lib/use-focus-trap.d.ts +7 -0
  198. package/dist/lib/use-focus-trap.d.ts.map +1 -0
  199. package/dist/lib/use-focus-trap.js +61 -0
  200. package/dist/lib/use-media-query.d.ts +5 -0
  201. package/dist/lib/use-media-query.d.ts.map +1 -0
  202. package/dist/lib/use-media-query.js +19 -0
  203. package/dist/primitives/Accordion.d.ts +24 -0
  204. package/dist/primitives/Accordion.d.ts.map +1 -0
  205. package/dist/primitives/Accordion.js +37 -0
  206. package/dist/primitives/Alert.d.ts +10 -0
  207. package/dist/primitives/Alert.d.ts.map +1 -0
  208. package/dist/primitives/Alert.js +25 -0
  209. package/dist/primitives/AlertDialog.d.ts +33 -0
  210. package/dist/primitives/AlertDialog.d.ts.map +1 -0
  211. package/dist/primitives/AlertDialog.js +96 -0
  212. package/dist/primitives/Avatar.d.ts +15 -0
  213. package/dist/primitives/Avatar.d.ts.map +1 -0
  214. package/dist/primitives/Avatar.js +52 -0
  215. package/dist/primitives/Badge.d.ts +12 -0
  216. package/dist/primitives/Badge.d.ts.map +1 -0
  217. package/dist/primitives/Badge.js +27 -0
  218. package/dist/primitives/Button.d.ts +14 -0
  219. package/dist/primitives/Button.d.ts.map +1 -0
  220. package/dist/primitives/Button.js +37 -0
  221. package/dist/primitives/Checkbox.d.ts +9 -0
  222. package/dist/primitives/Checkbox.d.ts.map +1 -0
  223. package/dist/primitives/Checkbox.js +22 -0
  224. package/dist/primitives/Command.d.ts +17 -0
  225. package/dist/primitives/Command.d.ts.map +1 -0
  226. package/dist/primitives/Command.js +33 -0
  227. package/dist/primitives/Dialog.d.ts +34 -0
  228. package/dist/primitives/Dialog.d.ts.map +1 -0
  229. package/dist/primitives/Dialog.js +96 -0
  230. package/dist/primitives/DropdownMenu.d.ts +65 -0
  231. package/dist/primitives/DropdownMenu.d.ts.map +1 -0
  232. package/dist/primitives/DropdownMenu.js +196 -0
  233. package/dist/primitives/Input.d.ts +4 -0
  234. package/dist/primitives/Input.d.ts.map +1 -0
  235. package/dist/primitives/Input.js +6 -0
  236. package/dist/primitives/Kbd.d.ts +4 -0
  237. package/dist/primitives/Kbd.d.ts.map +1 -0
  238. package/dist/primitives/Kbd.js +6 -0
  239. package/dist/primitives/Label.d.ts +4 -0
  240. package/dist/primitives/Label.d.ts.map +1 -0
  241. package/dist/primitives/Label.js +6 -0
  242. package/dist/primitives/NativeSelect.d.ts +7 -0
  243. package/dist/primitives/NativeSelect.d.ts.map +1 -0
  244. package/dist/primitives/NativeSelect.js +10 -0
  245. package/dist/primitives/Popover.d.ts +29 -0
  246. package/dist/primitives/Popover.d.ts.map +1 -0
  247. package/dist/primitives/Popover.js +95 -0
  248. package/dist/primitives/Progress.d.ts +8 -0
  249. package/dist/primitives/Progress.d.ts.map +1 -0
  250. package/dist/primitives/Progress.js +7 -0
  251. package/dist/primitives/RadioGroup.d.ts +13 -0
  252. package/dist/primitives/RadioGroup.d.ts.map +1 -0
  253. package/dist/primitives/RadioGroup.js +33 -0
  254. package/dist/primitives/Select.d.ts +33 -0
  255. package/dist/primitives/Select.d.ts.map +1 -0
  256. package/dist/primitives/Select.js +178 -0
  257. package/dist/primitives/Separator.d.ts +7 -0
  258. package/dist/primitives/Separator.d.ts.map +1 -0
  259. package/dist/primitives/Separator.js +6 -0
  260. package/dist/primitives/Sheet.d.ts +28 -0
  261. package/dist/primitives/Sheet.d.ts.map +1 -0
  262. package/dist/primitives/Sheet.js +96 -0
  263. package/dist/primitives/Skeleton.d.ts +4 -0
  264. package/dist/primitives/Skeleton.d.ts.map +1 -0
  265. package/dist/primitives/Skeleton.js +6 -0
  266. package/dist/primitives/Slider.d.ts +12 -0
  267. package/dist/primitives/Slider.d.ts.map +1 -0
  268. package/dist/primitives/Slider.js +23 -0
  269. package/dist/primitives/Spinner.d.ts +6 -0
  270. package/dist/primitives/Spinner.d.ts.map +1 -0
  271. package/dist/primitives/Spinner.js +7 -0
  272. package/dist/primitives/StarRating.d.ts +10 -0
  273. package/dist/primitives/StarRating.d.ts.map +1 -0
  274. package/dist/primitives/StarRating.js +11 -0
  275. package/dist/primitives/Switch.d.ts +8 -0
  276. package/dist/primitives/Switch.d.ts.map +1 -0
  277. package/dist/primitives/Switch.js +20 -0
  278. package/dist/primitives/Table.d.ts +13 -0
  279. package/dist/primitives/Table.d.ts.map +1 -0
  280. package/dist/primitives/Table.js +20 -0
  281. package/dist/primitives/Tabs.d.ts +17 -0
  282. package/dist/primitives/Tabs.d.ts.map +1 -0
  283. package/dist/primitives/Tabs.js +30 -0
  284. package/dist/primitives/Textarea.d.ts +4 -0
  285. package/dist/primitives/Textarea.d.ts.map +1 -0
  286. package/dist/primitives/Textarea.js +6 -0
  287. package/dist/primitives/Tooltip.d.ts +31 -0
  288. package/dist/primitives/Tooltip.d.ts.map +1 -0
  289. package/dist/primitives/Tooltip.js +94 -0
  290. package/dist/theme/OriginThemeProvider.d.ts +31 -0
  291. package/dist/theme/OriginThemeProvider.d.ts.map +1 -0
  292. package/dist/theme/OriginThemeProvider.js +37 -0
  293. package/dist/theme/SpatikaThemeProvider.d.ts +36 -0
  294. package/dist/theme/SpatikaThemeProvider.d.ts.map +1 -0
  295. package/dist/theme/SpatikaThemeProvider.js +38 -0
  296. package/package.json +58 -0
  297. package/src/composites/ActionBar.tsx +25 -0
  298. package/src/composites/AmountInput.tsx +40 -0
  299. package/src/composites/AppHeader.tsx +88 -0
  300. package/src/composites/AppSidebar.tsx +120 -0
  301. package/src/composites/BottomSheet.tsx +179 -0
  302. package/src/composites/Breadcrumb.tsx +42 -0
  303. package/src/composites/Callout.tsx +22 -0
  304. package/src/composites/Card.tsx +119 -0
  305. package/src/composites/Chip.tsx +87 -0
  306. package/src/composites/ChipGroup.component.test.tsx +31 -0
  307. package/src/composites/ChipGroup.test.ts +16 -0
  308. package/src/composites/ChipGroup.tsx +86 -0
  309. package/src/composites/CommandSearchField.tsx +124 -0
  310. package/src/composites/CoverHero.tsx +359 -0
  311. package/src/composites/CoverPattern.tsx +90 -0
  312. package/src/composites/DataTableToolbar.tsx +48 -0
  313. package/src/composites/DividerLabel.tsx +22 -0
  314. package/src/composites/EmptyState.tsx +55 -0
  315. package/src/composites/EntityCard.tsx +100 -0
  316. package/src/composites/EntityMediaCard.tsx +118 -0
  317. package/src/composites/FilterSheet.tsx +178 -0
  318. package/src/composites/FloatingPageChrome.tsx +294 -0
  319. package/src/composites/FormField.tsx +44 -0
  320. package/src/composites/GlassCard.tsx +47 -0
  321. package/src/composites/HeaderIconButton.tsx +49 -0
  322. package/src/composites/ListRow.tsx +29 -0
  323. package/src/composites/MediaEntryCard.tsx +95 -0
  324. package/src/composites/MobileTabBar.tsx +130 -0
  325. package/src/composites/NotificationBell.tsx +164 -0
  326. package/src/composites/PageHeader.tsx +27 -0
  327. package/src/composites/PageShell.tsx +20 -0
  328. package/src/composites/PageStickyHeader.tsx +157 -0
  329. package/src/composites/Pagination.tsx +41 -0
  330. package/src/composites/PhotoViewer.tsx +142 -0
  331. package/src/composites/PinPad.tsx +163 -0
  332. package/src/composites/ProfileHero.tsx +163 -0
  333. package/src/composites/QuickFilterRail.tsx +92 -0
  334. package/src/composites/QuickSettings.tsx +120 -0
  335. package/src/composites/RichTextEditor.tsx +103 -0
  336. package/src/composites/SearchField.tsx +38 -0
  337. package/src/composites/SectionPanel.tsx +59 -0
  338. package/src/composites/SegmentedControl.tsx +62 -0
  339. package/src/composites/StatCard.tsx +26 -0
  340. package/src/composites/StatusDot.tsx +40 -0
  341. package/src/composites/SurfaceCard.tsx +44 -0
  342. package/src/composites/Timeline.tsx +70 -0
  343. package/src/composites/Toast.tsx +135 -0
  344. package/src/composites/Toolbar.tsx +19 -0
  345. package/src/composites/ViewFiltersPanel.tsx +82 -0
  346. package/src/composites/chrome.test.tsx +170 -0
  347. package/src/composites/smoke.test.tsx +49 -0
  348. package/src/index.ts +355 -0
  349. package/src/lib/animations.ts +47 -0
  350. package/src/lib/avatar-utils.ts +52 -0
  351. package/src/lib/chips.ts +58 -0
  352. package/src/lib/cn.test.ts +16 -0
  353. package/src/lib/cn.ts +7 -0
  354. package/src/lib/compose-refs.ts +21 -0
  355. package/src/lib/cover-chrome.ts +31 -0
  356. package/src/lib/cover-pattern.ts +242 -0
  357. package/src/lib/overlay-stack.ts +44 -0
  358. package/src/lib/portal.tsx +21 -0
  359. package/src/lib/slot.tsx +69 -0
  360. package/src/lib/surfaces.ts +57 -0
  361. package/src/lib/themes.test.ts +73 -0
  362. package/src/lib/themes.ts +59 -0
  363. package/src/lib/tokens.test.ts +52 -0
  364. package/src/lib/typography.ts +27 -0
  365. package/src/lib/use-controllable-state.ts +38 -0
  366. package/src/lib/use-cover-chrome-bleed.ts +33 -0
  367. package/src/lib/use-dismissable.ts +49 -0
  368. package/src/lib/use-floating-position.ts +168 -0
  369. package/src/lib/use-focus-trap.ts +73 -0
  370. package/src/lib/use-media-query.ts +22 -0
  371. package/src/primitives/Accordion.tsx +114 -0
  372. package/src/primitives/Alert.tsx +57 -0
  373. package/src/primitives/AlertDialog.tsx +270 -0
  374. package/src/primitives/Avatar.tsx +140 -0
  375. package/src/primitives/Badge.test.tsx +15 -0
  376. package/src/primitives/Badge.tsx +43 -0
  377. package/src/primitives/Button.test.tsx +37 -0
  378. package/src/primitives/Button.tsx +58 -0
  379. package/src/primitives/Checkbox.tsx +75 -0
  380. package/src/primitives/Command.tsx +175 -0
  381. package/src/primitives/Dialog.tsx +241 -0
  382. package/src/primitives/DropdownMenu.tsx +552 -0
  383. package/src/primitives/Input.test.tsx +22 -0
  384. package/src/primitives/Input.tsx +22 -0
  385. package/src/primitives/Kbd.tsx +17 -0
  386. package/src/primitives/Label.tsx +20 -0
  387. package/src/primitives/NativeSelect.tsx +22 -0
  388. package/src/primitives/Popover.tsx +209 -0
  389. package/src/primitives/Progress.tsx +31 -0
  390. package/src/primitives/RadioGroup.tsx +116 -0
  391. package/src/primitives/Select.tsx +409 -0
  392. package/src/primitives/Separator.tsx +30 -0
  393. package/src/primitives/Sheet.tsx +265 -0
  394. package/src/primitives/Skeleton.tsx +16 -0
  395. package/src/primitives/Slider.tsx +97 -0
  396. package/src/primitives/Spinner.tsx +21 -0
  397. package/src/primitives/StarRating.tsx +53 -0
  398. package/src/primitives/Switch.tsx +68 -0
  399. package/src/primitives/Table.tsx +134 -0
  400. package/src/primitives/Tabs.tsx +97 -0
  401. package/src/primitives/Textarea.tsx +20 -0
  402. package/src/primitives/Tooltip.tsx +193 -0
  403. package/src/primitives/smoke.test.tsx +34 -0
  404. package/src/test/setup.ts +1 -0
  405. package/src/theme/SpatikaThemeProvider.test.tsx +82 -0
  406. package/src/theme/SpatikaThemeProvider.tsx +112 -0
@@ -0,0 +1,119 @@
1
+ import type { ReactNode } from "react";
2
+ import { cn } from "../lib/cn";
3
+
4
+ export type CardProps = {
5
+ children: ReactNode;
6
+ className?: string;
7
+ /** Glass elevation level */
8
+ variant?: "default" | "panel" | "subtle" | "elevated";
9
+ padding?: "none" | "sm" | "md" | "lg";
10
+ };
11
+
12
+ const variantClass = {
13
+ default: "glass",
14
+ panel: "glass-panel",
15
+ subtle: "glass-subtle",
16
+ elevated: "app-card-elevated",
17
+ } as const;
18
+
19
+ const paddingClass = {
20
+ none: "p-0",
21
+ sm: "p-3",
22
+ md: "p-4 sm:p-5",
23
+ lg: "p-5 sm:p-6",
24
+ } as const;
25
+
26
+ /** Structured content card with optional header/footer slots via subcomponents. */
27
+ export function Card({
28
+ children,
29
+ className,
30
+ variant = "panel",
31
+ padding = "md",
32
+ }: CardProps) {
33
+ return (
34
+ <div
35
+ data-slot="card"
36
+ className={cn(
37
+ "relative overflow-hidden rounded-[var(--radius-card)]",
38
+ variantClass[variant],
39
+ paddingClass[padding],
40
+ className,
41
+ )}
42
+ >
43
+ {children}
44
+ </div>
45
+ );
46
+ }
47
+
48
+ export function CardHeader({
49
+ className,
50
+ children,
51
+ }: {
52
+ className?: string;
53
+ children: ReactNode;
54
+ }) {
55
+ return (
56
+ <div data-slot="card-header" className={cn("mb-3 flex items-start justify-between gap-3", className)}>
57
+ {children}
58
+ </div>
59
+ );
60
+ }
61
+
62
+ export function CardTitle({
63
+ className,
64
+ children,
65
+ }: {
66
+ className?: string;
67
+ children: ReactNode;
68
+ }) {
69
+ return (
70
+ <h3 data-slot="card-title" className={cn("text-base font-black tracking-tight", className)}>
71
+ {children}
72
+ </h3>
73
+ );
74
+ }
75
+
76
+ export function CardDescription({
77
+ className,
78
+ children,
79
+ }: {
80
+ className?: string;
81
+ children: ReactNode;
82
+ }) {
83
+ return (
84
+ <p data-slot="card-description" className={cn("mt-0.5 text-sm text-muted-foreground", className)}>
85
+ {children}
86
+ </p>
87
+ );
88
+ }
89
+
90
+ export function CardContent({
91
+ className,
92
+ children,
93
+ }: {
94
+ className?: string;
95
+ children: ReactNode;
96
+ }) {
97
+ return (
98
+ <div data-slot="card-content" className={cn(className)}>
99
+ {children}
100
+ </div>
101
+ );
102
+ }
103
+
104
+ export function CardFooter({
105
+ className,
106
+ children,
107
+ }: {
108
+ className?: string;
109
+ children: ReactNode;
110
+ }) {
111
+ return (
112
+ <div
113
+ data-slot="card-footer"
114
+ className={cn("mt-4 flex flex-wrap items-center justify-end gap-2 border-t border-border/40 pt-3", className)}
115
+ >
116
+ {children}
117
+ </div>
118
+ );
119
+ }
@@ -0,0 +1,87 @@
1
+ import * as React from "react";
2
+ import { cva, type VariantProps } from "class-variance-authority";
3
+ import { cn } from "../lib/cn";
4
+
5
+ const chipVariants = cva(
6
+ "inline-flex items-center justify-center gap-1.5 touch-manipulation select-none outline-none focus-visible:ring-ring/50 focus-visible:ring-[3px]",
7
+ {
8
+ variants: {
9
+ variant: {
10
+ filter:
11
+ "min-h-7 max-w-full rounded-full border px-2 py-0.5 text-left text-[10px] font-bold leading-snug shadow-sm transition-colors active:scale-[0.98] sm:min-h-8 sm:px-2.5 sm:py-1 sm:text-xs",
12
+ preference:
13
+ "rounded-xl border px-3 py-2 text-[10px] font-black uppercase tracking-widest shadow-sm transition-[color,background-color,border-color,box-shadow,transform] duration-150 active:scale-95",
14
+ layout:
15
+ "min-h-11 rounded-xl border px-3 text-sm font-bold shadow-sm transition-colors active:scale-[0.98]",
16
+ },
17
+ active: {
18
+ true: "",
19
+ false: "",
20
+ },
21
+ },
22
+ compoundVariants: [
23
+ {
24
+ variant: "filter",
25
+ active: true,
26
+ className: "border-primary/50 bg-primary/15 text-primary",
27
+ },
28
+ {
29
+ variant: "filter",
30
+ active: false,
31
+ className:
32
+ "border-border/60 bg-background/80 text-foreground hover:bg-muted/40",
33
+ },
34
+ {
35
+ variant: "preference",
36
+ active: true,
37
+ className:
38
+ "scale-[1.02] border-primary bg-primary text-primary-foreground shadow-primary/20",
39
+ },
40
+ {
41
+ variant: "preference",
42
+ active: false,
43
+ className:
44
+ "border-border/50 bg-background/40 text-muted-foreground hover:border-primary/30 hover:text-primary",
45
+ },
46
+ {
47
+ variant: "layout",
48
+ active: true,
49
+ className: "border-primary/50 bg-primary/15 text-primary",
50
+ },
51
+ {
52
+ variant: "layout",
53
+ active: false,
54
+ className:
55
+ "border-border/60 bg-background/80 text-foreground hover:bg-muted/40",
56
+ },
57
+ ],
58
+ defaultVariants: {
59
+ variant: "filter",
60
+ active: false,
61
+ },
62
+ },
63
+ );
64
+
65
+ export type ChipProps = React.ComponentProps<"button"> &
66
+ VariantProps<typeof chipVariants>;
67
+
68
+ /**
69
+ * Unified chip control for filters, preferences, and layout toggles.
70
+ */
71
+ const Chip = React.forwardRef<HTMLButtonElement, ChipProps>(
72
+ ({ className, variant, active, type = "button", ...props }, ref) => (
73
+ <button
74
+ ref={ref}
75
+ type={type}
76
+ data-slot="chip"
77
+ data-variant={variant ?? "filter"}
78
+ data-active={active ? "true" : "false"}
79
+ aria-pressed={Boolean(active)}
80
+ className={cn(chipVariants({ variant, active }), className)}
81
+ {...props}
82
+ />
83
+ ),
84
+ );
85
+ Chip.displayName = "Chip";
86
+
87
+ export { Chip, chipVariants };
@@ -0,0 +1,31 @@
1
+ import { render, screen } from "@testing-library/react";
2
+ import userEvent from "@testing-library/user-event";
3
+ import { describe, expect, it, vi } from "vitest";
4
+ import { ChipGroup } from "./ChipGroup";
5
+
6
+ describe("ChipGroup", () => {
7
+ it("renders options and reports toggles", async () => {
8
+ const user = userEvent.setup();
9
+ const onToggle = vi.fn();
10
+ render(
11
+ <ChipGroup
12
+ title="Size"
13
+ options={[
14
+ { value: "S", label: "Small" },
15
+ { value: "L", label: "Large" },
16
+ ]}
17
+ selected={["S"]}
18
+ onToggle={onToggle}
19
+ />,
20
+ );
21
+
22
+ expect(screen.getByText("Size")).toBeInTheDocument();
23
+ expect(screen.getByRole("button", { name: "Small" })).toHaveAttribute(
24
+ "aria-pressed",
25
+ "true",
26
+ );
27
+
28
+ await user.click(screen.getByRole("button", { name: "Large" }));
29
+ expect(onToggle).toHaveBeenCalledWith("L");
30
+ });
31
+ });
@@ -0,0 +1,16 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { isOptionSelected, toggleOptionValue } from "./ChipGroup";
3
+
4
+ describe("ChipGroup helpers", () => {
5
+ it("detects selection case-insensitively", () => {
6
+ expect(isOptionSelected(["small"], "SMALL")).toBe(true);
7
+ expect(isOptionSelected(["small"], "large")).toBe(false);
8
+ expect(isOptionSelected(undefined, "x")).toBe(false);
9
+ });
10
+
11
+ it("toggles values in a list", () => {
12
+ expect(toggleOptionValue(["a"], "b")).toEqual(["a", "b"]);
13
+ expect(toggleOptionValue(["a", "b"], "A")).toEqual(["b"]);
14
+ expect(toggleOptionValue(undefined, "x")).toEqual(["x"]);
15
+ });
16
+ });
@@ -0,0 +1,86 @@
1
+ import { cn } from "../lib/cn";
2
+ import { typographyEyebrow } from "../lib/typography";
3
+ import { Chip } from "./Chip";
4
+
5
+ export type ChipOption = {
6
+ value: string;
7
+ label: string;
8
+ };
9
+
10
+ export type ChipGroupProps = {
11
+ title?: string;
12
+ options: ChipOption[];
13
+ selected: string[] | undefined;
14
+ onToggle: (value: string) => void;
15
+ /** filter = soft pills, preference = uppercase admin chips */
16
+ variant?: "filter" | "preference";
17
+ className?: string;
18
+ showCount?: boolean;
19
+ };
20
+
21
+ /** Case-insensitive membership check. */
22
+ export function isOptionSelected(list: string[] | undefined, value: string): boolean {
23
+ return (list || []).some(
24
+ (entry) => String(entry).toUpperCase() === String(value).toUpperCase(),
25
+ );
26
+ }
27
+
28
+ /** Toggle a value in a list (case-insensitive). */
29
+ export function toggleOptionValue<T extends string>(list: T[] | undefined, value: T): T[] {
30
+ const current = list || [];
31
+ const index = current.findIndex(
32
+ (entry) => String(entry).toUpperCase() === String(value).toUpperCase(),
33
+ );
34
+ if (index >= 0) {
35
+ return current.filter((_, i) => i !== index);
36
+ }
37
+ return [...current, value];
38
+ }
39
+
40
+ /**
41
+ * Titled multi-select chip row used in admin preferences and filter panels.
42
+ */
43
+ export function ChipGroup({
44
+ title,
45
+ options,
46
+ selected,
47
+ onToggle,
48
+ variant = "preference",
49
+ className,
50
+ showCount = true,
51
+ }: ChipGroupProps) {
52
+ const selectedCount = options.filter((opt) => isOptionSelected(selected, opt.value)).length;
53
+
54
+ return (
55
+ <div data-slot="chip-group" className={cn("space-y-3", className)}>
56
+ {title ? (
57
+ <div className="flex items-center justify-between gap-2 px-0.5">
58
+ <div className="flex items-center gap-2">
59
+ <div className="h-1.5 w-1.5 shrink-0 rounded-full bg-primary/70" />
60
+ <p className={typographyEyebrow}>{title}</p>
61
+ </div>
62
+ {showCount && selectedCount > 0 ? (
63
+ <span className="rounded-md border border-primary/20 bg-primary/10 px-1.5 py-0.5 text-[9px] font-black uppercase tracking-wider text-primary">
64
+ {selectedCount}
65
+ </span>
66
+ ) : null}
67
+ </div>
68
+ ) : null}
69
+ <div className="flex flex-wrap gap-2">
70
+ {options.map((opt) => {
71
+ const active = isOptionSelected(selected, opt.value);
72
+ return (
73
+ <Chip
74
+ key={opt.value}
75
+ variant={variant}
76
+ active={active}
77
+ onClick={() => onToggle(opt.value)}
78
+ >
79
+ {opt.label}
80
+ </Chip>
81
+ );
82
+ })}
83
+ </div>
84
+ </div>
85
+ );
86
+ }
@@ -0,0 +1,124 @@
1
+ import type { ReactNode } from "react";
2
+ import { Search, X } from "lucide-react";
3
+ import { cn } from "../lib/cn";
4
+
5
+ export type CommandSearchResult = {
6
+ id: string;
7
+ title: string;
8
+ subtitle?: string;
9
+ icon?: ReactNode;
10
+ typeLabel?: string;
11
+ onSelect?: () => void;
12
+ };
13
+
14
+ export type CommandSearchFieldProps = {
15
+ value: string;
16
+ onChange: (value: string) => void;
17
+ onSubmit?: () => void;
18
+ placeholder?: string;
19
+ shortcutHint?: string;
20
+ results?: CommandSearchResult[];
21
+ recent?: CommandSearchResult[];
22
+ loading?: boolean;
23
+ className?: string;
24
+ /** Called when clear is pressed */
25
+ onClear?: () => void;
26
+ };
27
+
28
+ /**
29
+ * Frosted command / global search field with optional result dropdown.
30
+ */
31
+ export function CommandSearchField({
32
+ value,
33
+ onChange,
34
+ onSubmit,
35
+ placeholder = "Search…",
36
+ shortcutHint = "⌘K",
37
+ results,
38
+ recent,
39
+ loading,
40
+ className,
41
+ onClear,
42
+ }: CommandSearchFieldProps) {
43
+ const focusedList = (results && results.length > 0 ? results : recent) ?? [];
44
+ const showDropdown = value.length > 0 ? Boolean(results) : Boolean(recent?.length);
45
+
46
+ return (
47
+ <div data-slot="command-search-field" className={cn("relative w-full", className)}>
48
+ <div
49
+ className={cn(
50
+ "group relative flex items-center rounded-2xl border border-border/20 bg-muted/10 backdrop-blur-xl transition-all",
51
+ "focus-within:border-primary/30 focus-within:bg-white/10 focus-within:shadow-[0_12px_40px_-12px_rgba(99,102,241,0.3)] focus-within:ring-4 focus-within:ring-primary/5",
52
+ )}
53
+ >
54
+ <span className="pointer-events-none absolute inset-y-0 left-3 z-10 flex items-center text-muted-foreground transition-colors group-focus-within:rounded-lg group-focus-within:bg-primary group-focus-within:p-1.5 group-focus-within:text-primary-foreground">
55
+ <Search className="h-4 w-4 shrink-0" aria-hidden />
56
+ </span>
57
+ <input
58
+ value={value}
59
+ onChange={(e) => onChange(e.target.value)}
60
+ onKeyDown={(e) => {
61
+ if (e.key === "Enter") onSubmit?.();
62
+ }}
63
+ placeholder={placeholder}
64
+ className="w-full bg-transparent py-3 pl-12 pr-12 text-sm font-black outline-none placeholder:font-medium placeholder:text-muted-foreground/30"
65
+ />
66
+ {value ? (
67
+ <button
68
+ type="button"
69
+ aria-label="Clear"
70
+ className="absolute right-3 text-muted-foreground hover:text-foreground"
71
+ onClick={() => {
72
+ onChange("");
73
+ onClear?.();
74
+ }}
75
+ >
76
+ <X className="size-4" />
77
+ </button>
78
+ ) : shortcutHint ? (
79
+ <kbd className="pointer-events-none absolute right-3 hidden rounded border border-border/50 bg-muted/50 px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground sm:inline">
80
+ {shortcutHint}
81
+ </kbd>
82
+ ) : null}
83
+ </div>
84
+
85
+ {showDropdown ? (
86
+ <div className="absolute inset-x-0 top-full z-50 mt-2 overflow-hidden rounded-[2rem] border border-border/60 bg-background shadow-[0_28px_64px_-20px_rgba(15,23,42,0.45)] dark:border-white/10 dark:bg-card dark:shadow-[0_28px_64px_-20px_rgba(0,0,0,0.65)]">
87
+ <div className="max-h-72 overflow-y-auto p-2">
88
+ {loading ? (
89
+ <p className="px-3 py-6 text-center text-sm text-muted-foreground">Searching…</p>
90
+ ) : focusedList.length === 0 ? (
91
+ <p className="px-3 py-6 text-center text-sm text-muted-foreground">No results</p>
92
+ ) : (
93
+ focusedList.map((item) => (
94
+ <button
95
+ key={item.id}
96
+ type="button"
97
+ className="flex w-full items-center gap-3 rounded-2xl border border-transparent px-4 py-3 text-left transition-colors hover:border-primary/40 hover:bg-muted/30"
98
+ onClick={item.onSelect}
99
+ >
100
+ <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-2xl bg-primary/10 text-primary">
101
+ {item.icon ?? <Search className="size-4" />}
102
+ </span>
103
+ <span className="min-w-0 flex-1">
104
+ <span className="block truncate text-sm font-bold">{item.title}</span>
105
+ {item.subtitle ? (
106
+ <span className="block truncate text-xs text-muted-foreground">
107
+ {item.subtitle}
108
+ </span>
109
+ ) : null}
110
+ </span>
111
+ {item.typeLabel ? (
112
+ <span className="text-[10px] font-black uppercase tracking-widest text-muted-foreground/70">
113
+ {item.typeLabel}
114
+ </span>
115
+ ) : null}
116
+ </button>
117
+ ))
118
+ )}
119
+ </div>
120
+ </div>
121
+ ) : null}
122
+ </div>
123
+ );
124
+ }