@sophostechne/ui 0.18.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. package/CHANGELOG.md +268 -0
  2. package/README.md +112 -0
  3. package/dist/assets/filler-bg0.webp +0 -0
  4. package/dist/assets.d.ts +38 -0
  5. package/dist/fonts/Collapse-Bold.woff2 +0 -0
  6. package/dist/fonts/Collapse-BoldItalic.woff2 +0 -0
  7. package/dist/fonts/Collapse-Italic.woff2 +0 -0
  8. package/dist/fonts/Collapse-Light.woff2 +0 -0
  9. package/dist/fonts/Collapse-LightItalic.woff2 +0 -0
  10. package/dist/fonts/Collapse-Regular.woff2 +0 -0
  11. package/dist/fonts/Collapse-Thin.woff2 +0 -0
  12. package/dist/fonts/Collapse-ThinItalic.woff2 +0 -0
  13. package/dist/fonts/Mondwest-Regular.woff2 +0 -0
  14. package/dist/fonts/Neuebit-Bold.woff2 +0 -0
  15. package/dist/fonts/RulesCompressed-Medium.woff2 +0 -0
  16. package/dist/fonts/RulesCompressed-Regular.woff2 +0 -0
  17. package/dist/fonts/RulesExpanded-Bold.woff2 +0 -0
  18. package/dist/fonts/RulesExpanded-Regular.woff2 +0 -0
  19. package/dist/fonts.d.ts +6 -0
  20. package/dist/fonts.js +6 -0
  21. package/dist/hooks/use-below-breakpoint.d.ts +2 -0
  22. package/dist/hooks/use-below-breakpoint.js +17 -0
  23. package/dist/hooks/use-capped-frame.d.ts +2 -0
  24. package/dist/hooks/use-capped-frame.js +15 -0
  25. package/dist/hooks/use-confirm-delete.d.ts +10 -0
  26. package/dist/hooks/use-confirm-delete.js +35 -0
  27. package/dist/hooks/use-css-var-dims.d.ts +1 -0
  28. package/dist/hooks/use-css-var-dims.js +29 -0
  29. package/dist/hooks/use-gpu-tier.d.ts +34 -0
  30. package/dist/hooks/use-gpu-tier.js +111 -0
  31. package/dist/hooks/use-render-loop.d.ts +41 -0
  32. package/dist/hooks/use-render-loop.js +63 -0
  33. package/dist/hooks/use-smooth-controls.d.ts +16 -0
  34. package/dist/hooks/use-smooth-controls.js +217 -0
  35. package/dist/hooks/use-toast.d.ts +7 -0
  36. package/dist/hooks/use-toast.js +21 -0
  37. package/dist/index.d.ts +79 -0
  38. package/dist/index.js +107 -0
  39. package/dist/ui/basic-page.d.ts +7 -0
  40. package/dist/ui/basic-page.js +18 -0
  41. package/dist/ui/build.css +4 -0
  42. package/dist/ui/components/animated-count.d.ts +10 -0
  43. package/dist/ui/components/animated-count.js +113 -0
  44. package/dist/ui/components/ascii.d.ts +10 -0
  45. package/dist/ui/components/ascii.js +79 -0
  46. package/dist/ui/components/badge.d.ts +6 -0
  47. package/dist/ui/components/badge.js +40 -0
  48. package/dist/ui/components/badges/nous-girl.d.ts +2 -0
  49. package/dist/ui/components/badges/nous-girl.js +83 -0
  50. package/dist/ui/components/blend-mode.d.ts +28 -0
  51. package/dist/ui/components/blend-mode.js +69 -0
  52. package/dist/ui/components/blink.d.ts +6 -0
  53. package/dist/ui/components/blink.js +17 -0
  54. package/dist/ui/components/bottom-sheet.d.ts +15 -0
  55. package/dist/ui/components/bottom-sheet.js +192 -0
  56. package/dist/ui/components/button.d.ts +14 -0
  57. package/dist/ui/components/button.js +147 -0
  58. package/dist/ui/components/card.d.ts +5 -0
  59. package/dist/ui/components/card.js +74 -0
  60. package/dist/ui/components/checkbox.d.ts +2 -0
  61. package/dist/ui/components/checkbox.js +27 -0
  62. package/dist/ui/components/command-block.d.ts +24 -0
  63. package/dist/ui/components/command-block.js +56 -0
  64. package/dist/ui/components/confirm-dialog.d.ts +13 -0
  65. package/dist/ui/components/confirm-dialog.js +113 -0
  66. package/dist/ui/components/cursor.d.ts +3 -0
  67. package/dist/ui/components/cursor.js +97 -0
  68. package/dist/ui/components/dialog.d.ts +15 -0
  69. package/dist/ui/components/dialog.js +171 -0
  70. package/dist/ui/components/dropdown-menu.d.ts +12 -0
  71. package/dist/ui/components/dropdown-menu.js +102 -0
  72. package/dist/ui/components/fit-text/fit-text.css +42 -0
  73. package/dist/ui/components/fit-text/index.d.ts +9 -0
  74. package/dist/ui/components/fit-text/index.js +25 -0
  75. package/dist/ui/components/graphs/bar-chart.d.ts +12 -0
  76. package/dist/ui/components/graphs/bar-chart.js +129 -0
  77. package/dist/ui/components/graphs/index.d.ts +3 -0
  78. package/dist/ui/components/graphs/index.js +4 -0
  79. package/dist/ui/components/graphs/line-chart.d.ts +14 -0
  80. package/dist/ui/components/graphs/line-chart.js +175 -0
  81. package/dist/ui/components/graphs/utils.d.ts +52 -0
  82. package/dist/ui/components/graphs/utils.js +162 -0
  83. package/dist/ui/components/grid/grid.css +79 -0
  84. package/dist/ui/components/grid/index.d.ts +2 -0
  85. package/dist/ui/components/grid/index.js +17 -0
  86. package/dist/ui/components/hover-bg.d.ts +1 -0
  87. package/dist/ui/components/hover-bg.js +14 -0
  88. package/dist/ui/components/icons/arrow.d.ts +6 -0
  89. package/dist/ui/components/icons/arrow.js +44 -0
  90. package/dist/ui/components/icons/check.d.ts +2 -0
  91. package/dist/ui/components/icons/check.js +13 -0
  92. package/dist/ui/components/icons/chevron.d.ts +6 -0
  93. package/dist/ui/components/icons/chevron.js +51 -0
  94. package/dist/ui/components/icons/discord.d.ts +2 -0
  95. package/dist/ui/components/icons/discord.js +15 -0
  96. package/dist/ui/components/icons/eye.d.ts +2 -0
  97. package/dist/ui/components/icons/eye.js +8 -0
  98. package/dist/ui/components/icons/gear.d.ts +6 -0
  99. package/dist/ui/components/icons/gear.js +30 -0
  100. package/dist/ui/components/icons/github.d.ts +2 -0
  101. package/dist/ui/components/icons/github.js +15 -0
  102. package/dist/ui/components/icons/hamburger.d.ts +6 -0
  103. package/dist/ui/components/icons/hamburger.js +56 -0
  104. package/dist/ui/components/icons/heart.d.ts +2 -0
  105. package/dist/ui/components/icons/heart.js +11 -0
  106. package/dist/ui/components/icons/index.d.ts +12 -0
  107. package/dist/ui/components/icons/index.js +13 -0
  108. package/dist/ui/components/icons/link.d.ts +2 -0
  109. package/dist/ui/components/icons/link.js +13 -0
  110. package/dist/ui/components/icons/minus.d.ts +2 -0
  111. package/dist/ui/components/icons/minus.js +13 -0
  112. package/dist/ui/components/icons/search.d.ts +2 -0
  113. package/dist/ui/components/icons/search.js +33 -0
  114. package/dist/ui/components/image-distortion.d.ts +21 -0
  115. package/dist/ui/components/image-distortion.js +398 -0
  116. package/dist/ui/components/input.d.ts +1 -0
  117. package/dist/ui/components/input.js +21 -0
  118. package/dist/ui/components/label.d.ts +1 -0
  119. package/dist/ui/components/label.js +18 -0
  120. package/dist/ui/components/leva-client.d.ts +1 -0
  121. package/dist/ui/components/leva-client.js +12 -0
  122. package/dist/ui/components/list-item.d.ts +6 -0
  123. package/dist/ui/components/list-item.js +27 -0
  124. package/dist/ui/components/overlays/blend-modes.d.ts +1 -0
  125. package/dist/ui/components/overlays/blend-modes.js +14 -0
  126. package/dist/ui/components/overlays/glitch.d.ts +6 -0
  127. package/dist/ui/components/overlays/glitch.js +209 -0
  128. package/dist/ui/components/overlays/greys.d.ts +6 -0
  129. package/dist/ui/components/overlays/greys.js +339 -0
  130. package/dist/ui/components/overlays/index.d.ts +14 -0
  131. package/dist/ui/components/overlays/index.js +34 -0
  132. package/dist/ui/components/overlays/lens-layers.d.ts +14 -0
  133. package/dist/ui/components/overlays/lens-layers.js +95 -0
  134. package/dist/ui/components/overlays/lens.d.ts +44 -0
  135. package/dist/ui/components/overlays/lens.js +60 -0
  136. package/dist/ui/components/overlays/noise.d.ts +6 -0
  137. package/dist/ui/components/overlays/noise.js +136 -0
  138. package/dist/ui/components/overlays/vignette.d.ts +6 -0
  139. package/dist/ui/components/overlays/vignette.js +47 -0
  140. package/dist/ui/components/poster.d.ts +62 -0
  141. package/dist/ui/components/poster.js +256 -0
  142. package/dist/ui/components/progress.d.ts +9 -0
  143. package/dist/ui/components/progress.js +53 -0
  144. package/dist/ui/components/scene-canvas.d.ts +23 -0
  145. package/dist/ui/components/scene-canvas.js +179 -0
  146. package/dist/ui/components/scramble.d.ts +9 -0
  147. package/dist/ui/components/scramble.js +63 -0
  148. package/dist/ui/components/segmented.d.ts +20 -0
  149. package/dist/ui/components/segmented.js +51 -0
  150. package/dist/ui/components/select.d.ts +18 -0
  151. package/dist/ui/components/select.js +215 -0
  152. package/dist/ui/components/selection-switcher.d.ts +1 -0
  153. package/dist/ui/components/selection-switcher.js +34 -0
  154. package/dist/ui/components/separator.d.ts +5 -0
  155. package/dist/ui/components/separator.js +22 -0
  156. package/dist/ui/components/shader.d.ts +7 -0
  157. package/dist/ui/components/shader.js +60 -0
  158. package/dist/ui/components/socials.d.ts +20 -0
  159. package/dist/ui/components/socials.js +21 -0
  160. package/dist/ui/components/spinner.d.ts +20 -0
  161. package/dist/ui/components/spinner.js +38 -0
  162. package/dist/ui/components/stats.d.ts +16 -0
  163. package/dist/ui/components/stats.js +36 -0
  164. package/dist/ui/components/switch.d.ts +7 -0
  165. package/dist/ui/components/switch.js +37 -0
  166. package/dist/ui/components/tabs.d.ts +14 -0
  167. package/dist/ui/components/tabs.js +44 -0
  168. package/dist/ui/components/terminal-demo.d.ts +32 -0
  169. package/dist/ui/components/terminal-demo.js +125 -0
  170. package/dist/ui/components/theme-toggle.d.ts +6 -0
  171. package/dist/ui/components/theme-toggle.js +66 -0
  172. package/dist/ui/components/tier-card.d.ts +53 -0
  173. package/dist/ui/components/tier-card.js +146 -0
  174. package/dist/ui/components/toast.d.ts +8 -0
  175. package/dist/ui/components/toast.js +39 -0
  176. package/dist/ui/components/tv.d.ts +3 -0
  177. package/dist/ui/components/tv.js +239 -0
  178. package/dist/ui/components/typography/h1.d.ts +11 -0
  179. package/dist/ui/components/typography/h1.js +18 -0
  180. package/dist/ui/components/typography/h2.d.ts +11 -0
  181. package/dist/ui/components/typography/h2.js +18 -0
  182. package/dist/ui/components/typography/index.d.ts +15 -0
  183. package/dist/ui/components/typography/index.js +41 -0
  184. package/dist/ui/components/typography/legend.d.ts +6 -0
  185. package/dist/ui/components/typography/legend.js +20 -0
  186. package/dist/ui/components/typography/small.d.ts +2 -0
  187. package/dist/ui/components/typography/small.js +9 -0
  188. package/dist/ui/components/watchlist.d.ts +11 -0
  189. package/dist/ui/components/watchlist.js +80 -0
  190. package/dist/ui/fonts.css +63 -0
  191. package/dist/ui/footer.d.ts +20 -0
  192. package/dist/ui/footer.js +65 -0
  193. package/dist/ui/globals.css +395 -0
  194. package/dist/ui/header.d.ts +41 -0
  195. package/dist/ui/header.js +270 -0
  196. package/dist/ui/layout-wrapper.d.ts +1 -0
  197. package/dist/ui/layout-wrapper.js +7 -0
  198. package/dist/utils/color.d.ts +4 -0
  199. package/dist/utils/color.js +14 -0
  200. package/dist/utils/index.d.ts +15 -0
  201. package/dist/utils/index.js +48 -0
  202. package/dist/utils/poly.d.ts +8 -0
  203. package/dist/utils/poly.js +3 -0
  204. package/package.json +129 -0
  205. package/src/assets/filler-bg0.webp +0 -0
  206. package/src/assets.d.ts +38 -0
  207. package/src/fonts/Collapse-Bold.woff2 +0 -0
  208. package/src/fonts/Collapse-BoldItalic.woff2 +0 -0
  209. package/src/fonts/Collapse-Italic.woff2 +0 -0
  210. package/src/fonts/Collapse-Light.woff2 +0 -0
  211. package/src/fonts/Collapse-LightItalic.woff2 +0 -0
  212. package/src/fonts/Collapse-Regular.woff2 +0 -0
  213. package/src/fonts/Collapse-Thin.woff2 +0 -0
  214. package/src/fonts/Collapse-ThinItalic.woff2 +0 -0
  215. package/src/fonts/Mondwest-Regular.woff2 +0 -0
  216. package/src/fonts/Neuebit-Bold.woff2 +0 -0
  217. package/src/fonts/RulesCompressed-Medium.woff2 +0 -0
  218. package/src/fonts/RulesCompressed-Regular.woff2 +0 -0
  219. package/src/fonts/RulesExpanded-Bold.woff2 +0 -0
  220. package/src/fonts/RulesExpanded-Regular.woff2 +0 -0
  221. package/src/fonts.ts +6 -0
  222. package/src/hooks/use-below-breakpoint.ts +21 -0
  223. package/src/hooks/use-capped-frame.ts +18 -0
  224. package/src/hooks/use-confirm-delete.ts +43 -0
  225. package/src/hooks/use-css-var-dims.ts +39 -0
  226. package/src/hooks/use-gpu-tier.ts +190 -0
  227. package/src/hooks/use-render-loop.ts +121 -0
  228. package/src/hooks/use-smooth-controls.ts +318 -0
  229. package/src/hooks/use-toast.ts +29 -0
  230. package/src/index.ts +130 -0
  231. package/src/ui/basic-page.tsx +34 -0
  232. package/src/ui/build.css +4 -0
  233. package/src/ui/components/animated-count.stories.tsx +67 -0
  234. package/src/ui/components/animated-count.tsx +168 -0
  235. package/src/ui/components/ascii.stories.tsx +30 -0
  236. package/src/ui/components/ascii.tsx +110 -0
  237. package/src/ui/components/badge.stories.tsx +31 -0
  238. package/src/ui/components/badge.tsx +60 -0
  239. package/src/ui/components/badges/nous-girl.tsx +52 -0
  240. package/src/ui/components/blend-mode.stories.tsx +33 -0
  241. package/src/ui/components/blend-mode.tsx +129 -0
  242. package/src/ui/components/blink.stories.tsx +32 -0
  243. package/src/ui/components/blink.tsx +21 -0
  244. package/src/ui/components/bottom-sheet.stories.tsx +43 -0
  245. package/src/ui/components/bottom-sheet.tsx +227 -0
  246. package/src/ui/components/button.stories.tsx +68 -0
  247. package/src/ui/components/button.tsx +170 -0
  248. package/src/ui/components/card.stories.tsx +63 -0
  249. package/src/ui/components/card.tsx +85 -0
  250. package/src/ui/components/checkbox.stories.tsx +113 -0
  251. package/src/ui/components/checkbox.tsx +36 -0
  252. package/src/ui/components/command-block.stories.tsx +52 -0
  253. package/src/ui/components/command-block.tsx +86 -0
  254. package/src/ui/components/confirm-dialog.stories.tsx +91 -0
  255. package/src/ui/components/confirm-dialog.tsx +130 -0
  256. package/src/ui/components/cursor.tsx +115 -0
  257. package/src/ui/components/dialog.stories.tsx +169 -0
  258. package/src/ui/components/dialog.tsx +177 -0
  259. package/src/ui/components/dropdown-menu.stories.tsx +52 -0
  260. package/src/ui/components/dropdown-menu.tsx +117 -0
  261. package/src/ui/components/fit-text/fit-text.css +42 -0
  262. package/src/ui/components/fit-text/index.stories.tsx +33 -0
  263. package/src/ui/components/fit-text/index.tsx +45 -0
  264. package/src/ui/components/forms.stories.tsx +173 -0
  265. package/src/ui/components/graphs/bar-chart.tsx +153 -0
  266. package/src/ui/components/graphs/index.stories.tsx +64 -0
  267. package/src/ui/components/graphs/index.tsx +4 -0
  268. package/src/ui/components/graphs/line-chart.tsx +213 -0
  269. package/src/ui/components/graphs/utils.tsx +265 -0
  270. package/src/ui/components/grid/grid.css +79 -0
  271. package/src/ui/components/grid/index.tsx +19 -0
  272. package/src/ui/components/hover-bg.stories.tsx +29 -0
  273. package/src/ui/components/hover-bg.tsx +15 -0
  274. package/src/ui/components/icons/arrow.tsx +42 -0
  275. package/src/ui/components/icons/check.tsx +14 -0
  276. package/src/ui/components/icons/chevron.tsx +45 -0
  277. package/src/ui/components/icons/discord.tsx +16 -0
  278. package/src/ui/components/icons/eye.tsx +12 -0
  279. package/src/ui/components/icons/gear.tsx +51 -0
  280. package/src/ui/components/icons/github.tsx +16 -0
  281. package/src/ui/components/icons/hamburger.tsx +52 -0
  282. package/src/ui/components/icons/heart.tsx +12 -0
  283. package/src/ui/components/icons/index.ts +12 -0
  284. package/src/ui/components/icons/link.tsx +14 -0
  285. package/src/ui/components/icons/minus.tsx +14 -0
  286. package/src/ui/components/icons/search.tsx +28 -0
  287. package/src/ui/components/image-distortion.stories.tsx +120 -0
  288. package/src/ui/components/image-distortion.tsx +499 -0
  289. package/src/ui/components/input.stories.tsx +39 -0
  290. package/src/ui/components/input.tsx +20 -0
  291. package/src/ui/components/label.stories.tsx +26 -0
  292. package/src/ui/components/label.tsx +16 -0
  293. package/src/ui/components/leva-client.tsx +14 -0
  294. package/src/ui/components/list-item.stories.tsx +83 -0
  295. package/src/ui/components/list-item.tsx +37 -0
  296. package/src/ui/components/overlays/blend-modes.ts +13 -0
  297. package/src/ui/components/overlays/glitch.tsx +243 -0
  298. package/src/ui/components/overlays/greys.tsx +386 -0
  299. package/src/ui/components/overlays/index.tsx +47 -0
  300. package/src/ui/components/overlays/lens-layers.tsx +121 -0
  301. package/src/ui/components/overlays/lens.ts +91 -0
  302. package/src/ui/components/overlays/noise.tsx +174 -0
  303. package/src/ui/components/overlays/vignette.tsx +60 -0
  304. package/src/ui/components/poster.stories.tsx +513 -0
  305. package/src/ui/components/poster.tsx +411 -0
  306. package/src/ui/components/progress.stories.tsx +48 -0
  307. package/src/ui/components/progress.tsx +56 -0
  308. package/src/ui/components/scene-canvas.tsx +254 -0
  309. package/src/ui/components/scramble.stories.tsx +49 -0
  310. package/src/ui/components/scramble.tsx +95 -0
  311. package/src/ui/components/segmented.stories.tsx +101 -0
  312. package/src/ui/components/segmented.tsx +81 -0
  313. package/src/ui/components/select.stories.tsx +88 -0
  314. package/src/ui/components/select.tsx +267 -0
  315. package/src/ui/components/selection-switcher.tsx +44 -0
  316. package/src/ui/components/separator.stories.tsx +33 -0
  317. package/src/ui/components/separator.tsx +24 -0
  318. package/src/ui/components/shader.tsx +83 -0
  319. package/src/ui/components/socials.tsx +42 -0
  320. package/src/ui/components/spinner.stories.tsx +101 -0
  321. package/src/ui/components/spinner.tsx +60 -0
  322. package/src/ui/components/stats.stories.tsx +24 -0
  323. package/src/ui/components/stats.tsx +53 -0
  324. package/src/ui/components/switch.stories.tsx +77 -0
  325. package/src/ui/components/switch.tsx +48 -0
  326. package/src/ui/components/tabs.stories.tsx +101 -0
  327. package/src/ui/components/tabs.tsx +66 -0
  328. package/src/ui/components/terminal-demo.stories.tsx +67 -0
  329. package/src/ui/components/terminal-demo.tsx +189 -0
  330. package/src/ui/components/theme-toggle.stories.tsx +47 -0
  331. package/src/ui/components/theme-toggle.tsx +66 -0
  332. package/src/ui/components/tier-card.stories.tsx +217 -0
  333. package/src/ui/components/tier-card.tsx +190 -0
  334. package/src/ui/components/toast.stories.tsx +55 -0
  335. package/src/ui/components/toast.tsx +49 -0
  336. package/src/ui/components/tv.stories.tsx +37 -0
  337. package/src/ui/components/tv.tsx +257 -0
  338. package/src/ui/components/typography/h1.tsx +18 -0
  339. package/src/ui/components/typography/h2.tsx +18 -0
  340. package/src/ui/components/typography/index.tsx +54 -0
  341. package/src/ui/components/typography/legend.tsx +24 -0
  342. package/src/ui/components/typography/small.tsx +11 -0
  343. package/src/ui/components/watchlist.stories.tsx +33 -0
  344. package/src/ui/components/watchlist.tsx +105 -0
  345. package/src/ui/fonts.css +63 -0
  346. package/src/ui/footer.tsx +111 -0
  347. package/src/ui/globals.css +395 -0
  348. package/src/ui/header.tsx +398 -0
  349. package/src/ui/layout-wrapper.tsx +11 -0
  350. package/src/utils/color.ts +21 -0
  351. package/src/utils/index.ts +62 -0
  352. package/src/utils/poly.ts +26 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,268 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@sophostechne/ui` are documented here. Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
4
+
5
+ ## 0.18.2
6
+
7
+ ### Changed
8
+
9
+ - **`filler-bg0` asset replaced** — new HACK//IT themed artwork: a hooded operator at a CRT terminal, with code rain, circuit traces, and a perspective grid floor. Same duotone risograph treatment (cream paper, federal blue ink, ordered-dither stipple, misregistered second pass) and the same 1024×1024 WebP filename, so `Poster`, `ImageDistortion`, and the lens overlays pick it up with no code change.
10
+
11
+ ## 0.17.0
12
+
13
+ Promotes reusable components and hooks from `hackit-agent/web` into the shared design system, and consolidates all dialog/modal implementations on Radix UI primitives.
14
+
15
+ ### Added
16
+
17
+ - **`Dialog` compound component** — general-purpose modal built on Radix Dialog primitive. Compound API: `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogFooter`, `DialogTitle`, `DialogDescription`, `DialogClose`. Dismissible via backdrop click or ESC.
18
+ - **`Input`** — styled text input with focus ring, disabled state, courier font.
19
+ - **`Label`** — form label with mondwest font, uppercase tracking, peer-disabled opacity.
20
+ - **`Separator`** — horizontal/vertical divider with `role="separator"`.
21
+ - **`Card`** compound component — `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardContent` with themeable `--component-card-*` CSS custom properties.
22
+ - **`Toast`** — portal-based success/error notification with enter/exit animations.
23
+ - **`BottomSheet`** — mobile-first bottom sheet with drag-to-dismiss, backdrop, reduced-motion support.
24
+ - **`useToast`** — toast state management with auto-dismiss timer.
25
+ - **`useBelowBreakpoint`** — `matchMedia`-based responsive breakpoint query (SSR-safe).
26
+ - **`useConfirmDelete`** — generic confirm-delete flow state machine.
27
+ - **Forms overview story** — showcases all form controls in one view.
28
+ - Toast keyframes (`toast-in`, `toast-out`) in `globals.css`.
29
+
30
+ ### Changed
31
+
32
+ - **`ConfirmDialog` rebuilt on Radix AlertDialog** — same external API (`open`, `onCancel`, `onConfirm`, `title`, `description`, `destructive`, `loading`), but ESC handling, focus trapping, scroll lock, and portal rendering are now handled by Radix. Backdrop click does not dismiss (correct for destructive confirms).
33
+ - **`Checkbox` migrated to unified `radix-ui` package** — import changed from `@radix-ui/react-checkbox` to `radix-ui`.
34
+ - **Dependency:** `@radix-ui/react-checkbox` replaced with unified `radix-ui` package.
35
+ - Storybook stories organized into categories (Forms, Feedback, Overlays, Data Display, Layout, Effects).
36
+ - Kitchen-sink demo updated to use new `Dialog`.
37
+
38
+ ### Removed
39
+
40
+ - **`Modal` component** (`modal/index.tsx`, `modal.css`) — unused by any consumer app; replaced by `Dialog`.
41
+ - **`useModalBehavior` hook** — functionality now provided natively by Radix Dialog/AlertDialog primitives.
42
+ - Stale `modal.css` import from `globals.css`.
43
+
44
+ ### Fixed
45
+
46
+ - Portal text color: dialogs now use `text-foreground-base` for correct rendering outside the blend-mode stack.
47
+
48
+ ## 0.16.0
49
+
50
+ Reworks how the brand uppercase + Mondwest styling and color hierarchy are applied, addressing legibility, contrast, and themability complaints from consumers (notably the Hackit Dashboard).
51
+
52
+ ### Added
53
+
54
+ - **`text-display` utility** — composable brand display style (`text-transform: uppercase` + `letter-spacing: 0.05em`). Purely typographic; pairs with any font utility.
55
+ - **Semantic text-color tokens** — `text-text-primary`, `text-text-secondary`, `text-text-tertiary`, `text-text-disabled`, `text-text-on-accent`, `text-text-display` with WCAG AA-targeted defaults in `globals.css`.
56
+
57
+ ### Changed
58
+
59
+ - **Breaking:** `LayoutWrapper` and Storybook shell no longer apply global `uppercase` or `font-mondwest`. Apply `text-display` (and `font-mondwest` where desired) on brand chrome only.
60
+ - DS components (`Button`, `Badge`, `Tabs`, `Segmented`, `FilterGroup`, `CopyButton`, `Stats`, `TierCard`, `TerminalDemo`, `Watchlist`) use `text-display` instead of hard-coded `uppercase`.
61
+ - Component legibility: micro-type bumped to `text-xs`; inactive/disabled states use semantic tokens instead of stacked opacity.
62
+
63
+ ### Tooling
64
+
65
+ - `src/` included in the published tarball.
66
+ - Inline source maps embedded in `dist/ui/*.js`.
67
+ - Storybook: **Display type** story and **Docs → Changelog** page.
68
+
69
+ ## 0.15.0
70
+
71
+ ### Added
72
+
73
+ - Storybook autodocs enabled for all components ([#21](https://github.com/SophosTechne/design-language/pull/21)).
74
+
75
+ ## 0.14.2
76
+
77
+ ### Added
78
+
79
+ - `Checkbox` component built on Radix primitive ([#20](https://github.com/SophosTechne/design-language/pull/20)).
80
+
81
+ ### Fixed
82
+
83
+ - `defaultChecked` preserved on native input for form reset.
84
+ - Checkbox visuals in uncontrolled mode.
85
+
86
+ ## 0.14.1
87
+
88
+ ### Changed
89
+
90
+ - `@font-face` declarations moved out of `globals.css` into optional `fonts.css`.
91
+ - Documented optional font stylesheet setup in README.
92
+
93
+ ### Fixed
94
+
95
+ - Font variable defaults remain in `globals.css`.
96
+
97
+ ## 0.14.0
98
+
99
+ ### Added
100
+
101
+ - `unbuild` / `mkdist` library build pipeline.
102
+ - `vite-plugin-static-copy` for asset handling in the build.
103
+
104
+ ### Changed
105
+
106
+ - Bundle size reduced (~4.9 MB → ~1.9 MB).
107
+ - Storybook stories reorganized; stories excluded from Vite library entries.
108
+
109
+ ## 0.13.2
110
+
111
+ ### Added
112
+
113
+ - GitHub Actions workflow for trusted npm publishing on merge to `main`.
114
+
115
+ ### Removed
116
+
117
+ - Manual release script and pnpm workspace file.
118
+
119
+ ### Fixed
120
+
121
+ - Publish workflow condition syntax.
122
+
123
+ ## 0.13.1
124
+
125
+ ### Fixed
126
+
127
+ - Text readability improvements.
128
+
129
+ ## 0.13.0
130
+
131
+ ### Changed
132
+
133
+ - Overlay/canvas performance: pause render loops when hidden/offscreen; cap FPS and DPR.
134
+
135
+ ## 0.12.0
136
+
137
+ ### Fixed
138
+
139
+ - Eager GPU tier detection to avoid WebGL crash on first render.
140
+
141
+ ## 0.11.0
142
+
143
+ ### Added
144
+
145
+ - Expanded `Header` component.
146
+ - Icon exports.
147
+
148
+ ### Changed
149
+
150
+ - Overlays decoupled from layout concerns.
151
+ - Introduction story updates.
152
+
153
+ ## 0.10.0
154
+
155
+ ### Added
156
+
157
+ - Unicode/braille spinners.
158
+
159
+ ## 0.9.0
160
+
161
+ ### Added
162
+
163
+ - `Switch`, `Tabs`, `Segmented`, and `ListItem` components.
164
+
165
+ ## 0.8.0
166
+
167
+ ### Added
168
+
169
+ - `Select` component.
170
+
171
+ ## 0.7.0
172
+
173
+ ### Changed
174
+
175
+ - Package renamed `nouse` → `sophos`.
176
+ - Badge support improvements.
177
+
178
+ ### Fixed
179
+
180
+ - Button styling.
181
+
182
+ ## 0.6.0
183
+
184
+ ### Fixed
185
+
186
+ - Button component fixes.
187
+
188
+ ## 0.5.0
189
+
190
+ ### Added
191
+
192
+ - `Poster` and `TierCard` components.
193
+
194
+ ### Fixed
195
+
196
+ - Poster and build fixes.
197
+
198
+ ## 0.4.0
199
+
200
+ ### Added
201
+
202
+ - Migrated components: image distortion, hamburger icon, terminal demo, theme toggle, click-to-copy command blocks.
203
+
204
+ ## 0.3.0
205
+
206
+ ### Added
207
+
208
+ - Storybook setup.
209
+
210
+ ### Fixed
211
+
212
+ - Removed Next.js dependencies from the package.
213
+
214
+ ## 0.2.7
215
+
216
+ ### Fixed
217
+
218
+ - Stats flip animation.
219
+
220
+ ## 0.2.6
221
+
222
+ ### Added
223
+
224
+ - Flip animation on `Stats`.
225
+
226
+ ## 0.2.5
227
+
228
+ ### Changed
229
+
230
+ - Global font size adjustments.
231
+
232
+ ## 0.2.4
233
+
234
+ ### Changed
235
+
236
+ - Slightly increased global font size.
237
+
238
+ ### Fixed
239
+
240
+ - Hover state for inverted/outlined buttons when foreground alpha is near zero.
241
+
242
+ ## 0.2.3
243
+
244
+ ### Fixed
245
+
246
+ - Hover state for inverted/outlined on low foreground alpha.
247
+
248
+ ## 0.2.2
249
+
250
+ ### Fixed
251
+
252
+ - Global CSS selector update.
253
+
254
+ ## 0.2.1
255
+
256
+ ### Changed
257
+
258
+ - Simplified style setup for consumers.
259
+
260
+ ## 0.2.0
261
+
262
+ ### Added
263
+
264
+ - Initial tagged release of the shared design system package.
265
+
266
+ ## 0.1.x
267
+
268
+ Versions `0.1.0`–`0.1.3` were published to npm before git tags were added in this repository. See [npm version history](https://www.npmjs.com/package/@sophostechne/ui?activeTab=versions) for install pins.
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # sophos ui
2
+
3
+ the shared design system for react ui @ sophos. components, hooks, utils, fonts, overlays, etc.
4
+
5
+ ## setup
6
+
7
+ `npm i @sophostechne/ui` or `pnpm i @sophostechne/ui`
8
+
9
+ import the global styles in your app's root css file:
10
+
11
+ ```css
12
+ @import 'tailwindcss';
13
+ @import '@sophostechne/ui/styles/globals.css';
14
+ ```
15
+
16
+ `globals.css` includes the design-system tokens, utilities, component styles,
17
+ and default `--font-*` variable values, but does not register font files.
18
+ Import the optional font stylesheet first if your app wants CSS-managed
19
+ `@font-face` declarations:
20
+
21
+ ```css
22
+ @import 'tailwindcss';
23
+ @import '@sophostechne/ui/styles/fonts.css';
24
+ @import '@sophostechne/ui/styles/globals.css';
25
+ ```
26
+
27
+ Next.js apps should prefer `next/font/local` with the exported
28
+ `@sophostechne/ui/fonts/*` files and map them to the same `--font-*`
29
+ variables. Apps can also provide their own `--font-*` variables while keeping
30
+ the design-system utilities from `globals.css`.
31
+
32
+ ## usage
33
+
34
+ everything exports from the top level export:
35
+
36
+ ```tsx
37
+ import {
38
+ Button,
39
+ Grid
40
+ // whatever else!
41
+ } from '@sophostechne/ui'
42
+ ```
43
+
44
+ ## local development
45
+
46
+ two ways to preview components while editing:
47
+
48
+ ### storybook (per-component, primary)
49
+
50
+ ```
51
+ pnpm storybook # dev server on http://localhost:6006
52
+ pnpm build-storybook # static build → ./storybook-static
53
+ ```
54
+
55
+ stories live in `stories/*.stories.tsx`. the **Overview** story re-renders
56
+ the entire `/ds` page, so you always have a kitchen-sink view alongside the
57
+ isolated component stories. the **Lens** toolbar above the preview cycles
58
+ between the lens presets (`0`, `1`, `2`, `3`, `4`, `5`, `5i`, `6`).
59
+
60
+ ### next.js showcase (kitchen-sink, secondary)
61
+
62
+ ```
63
+ pnpm dev # next dev on http://localhost:3000 → redirects to /ds
64
+ ```
65
+
66
+ `app/ds/page.tsx` is the same content the Overview story renders.
67
+
68
+ ## publishing
69
+
70
+ ```
71
+ pnpm build # tsc → dist/ + copies css / fonts / assets
72
+ ```
73
+
74
+ releases are published automatically when PRs merge to `main`. the github
75
+ workflow bumps the package version from the merged PR labels (`major`, `minor`,
76
+ or `patch`), pushes the tag, publishes to npm via trusted publishing, and
77
+ creates a [GitHub Release](https://github.com/SophosTechne/design-language/releases)
78
+ with notes from `CHANGELOG.md`.
79
+
80
+ before merging:
81
+
82
+ 1. leave `package.json` at the **current published** version on `main` (CI bumps
83
+ it after merge).
84
+ 2. label the PR so the bump matches your changelog section:
85
+
86
+ | PR label | bump from `0.15.0` | changelog heading |
87
+ | --- | --- | --- |
88
+ | `patch` (default) | `0.15.1` | `## 0.15.1` |
89
+ | `minor` | `0.16.0` | `## 0.16.0` |
90
+ | `major` | `1.0.0` | `## 1.0.0` |
91
+
92
+ 3. add that `## X.Y.Z` section to [`CHANGELOG.md`](./CHANGELOG.md) — release
93
+ notes are pulled from it for npm and GitHub Releases.
94
+
95
+ the same file is rendered in Storybook under **Docs → Changelog** and shipped in
96
+ the npm tarball.
97
+
98
+ the published tarball ships `dist/`, `src/`, `README.md`, and `CHANGELOG.md`
99
+ (see `files` in `package.json`). inline source maps are embedded in `dist/` so
100
+ consumers can debug into the TypeScript source.
101
+
102
+ ## deployment
103
+
104
+ `vercel.json` builds both and serves them on a single Next.js deployment:
105
+
106
+ - `/` and `/ds` — the Next.js showcase (same as `pnpm dev`)
107
+ - `/storybook` — the static Storybook build (copied to `public/storybook/`
108
+ before `next build` so Next serves it like any other static asset)
109
+
110
+ Want Storybook-only? replace `buildCommand` with `pnpm build-storybook` and
111
+ add `"outputDirectory": "storybook-static"`. `app/ds` can stay for local
112
+ `pnpm dev` either way — the Overview story renders the same content.
Binary file
@@ -0,0 +1,38 @@
1
+ interface StaticImageData {
2
+ src: string
3
+ height: number
4
+ width: number
5
+ blurDataURL?: string
6
+ blurWidth?: number
7
+ blurHeight?: number
8
+ }
9
+
10
+ declare module '*.jpg' {
11
+ const content: StaticImageData
12
+ export default content
13
+ }
14
+
15
+ declare module '*.jpeg' {
16
+ const content: StaticImageData
17
+ export default content
18
+ }
19
+
20
+ declare module '*.png' {
21
+ const content: StaticImageData
22
+ export default content
23
+ }
24
+
25
+ declare module '*.svg' {
26
+ const content: StaticImageData
27
+ export default content
28
+ }
29
+
30
+ declare module '*.gif' {
31
+ const content: StaticImageData
32
+ export default content
33
+ }
34
+
35
+ declare module '*.webp' {
36
+ const content: StaticImageData
37
+ export default content
38
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,6 @@
1
+ /** CSS variable names for the design language fonts. Set automatically by fonts.css. */
2
+ export declare const FONT_SANS = "--font-sans";
3
+ export declare const FONT_MONO = "--font-mono";
4
+ export declare const FONT_RULES_COMPRESSED = "--font-rules-compressed";
5
+ export declare const FONT_RULES_EXPANDED = "--font-rules-expanded";
6
+ export declare const FONT_MONDWEST = "--font-mondwest";
package/dist/fonts.js ADDED
@@ -0,0 +1,6 @@
1
+ export const FONT_SANS = "--font-sans";
2
+ export const FONT_MONO = "--font-mono";
3
+ export const FONT_RULES_COMPRESSED = "--font-rules-compressed";
4
+ export const FONT_RULES_EXPANDED = "--font-rules-expanded";
5
+ export const FONT_MONDWEST = "--font-mondwest";
6
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiPHN0ZGluPiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqIENTUyB2YXJpYWJsZSBuYW1lcyBmb3IgdGhlIGRlc2lnbiBsYW5ndWFnZSBmb250cy4gU2V0IGF1dG9tYXRpY2FsbHkgYnkgZm9udHMuY3NzLiAqL1xuZXhwb3J0IGNvbnN0IEZPTlRfU0FOUyA9ICctLWZvbnQtc2FucydcbmV4cG9ydCBjb25zdCBGT05UX01PTk8gPSAnLS1mb250LW1vbm8nXG5leHBvcnQgY29uc3QgRk9OVF9SVUxFU19DT01QUkVTU0VEID0gJy0tZm9udC1ydWxlcy1jb21wcmVzc2VkJ1xuZXhwb3J0IGNvbnN0IEZPTlRfUlVMRVNfRVhQQU5ERUQgPSAnLS1mb250LXJ1bGVzLWV4cGFuZGVkJ1xuZXhwb3J0IGNvbnN0IEZPTlRfTU9ORFdFU1QgPSAnLS1mb250LW1vbmR3ZXN0J1xuIl0sCiAgIm1hcHBpbmdzIjogIkFBQ08sYUFBTSxZQUFZO0FBQ2xCLGFBQU0sWUFBWTtBQUNsQixhQUFNLHdCQUF3QjtBQUM5QixhQUFNLHNCQUFzQjtBQUM1QixhQUFNLGdCQUFnQjsiLAogICJuYW1lcyI6IFtdCn0K
@@ -0,0 +1,2 @@
1
+ /** True when viewport width is strictly below `px`. */
2
+ export declare function useBelowBreakpoint(px: number): boolean;
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { useEffect, useState } from "react";
3
+ export function useBelowBreakpoint(px) {
4
+ const query = `(max-width: ${px - 1}px)`;
5
+ const [matches, setMatches] = useState(
6
+ () => typeof window !== "undefined" ? window.matchMedia(query).matches : false
7
+ );
8
+ useEffect(() => {
9
+ const mql = window.matchMedia(query);
10
+ const sync = () => setMatches(mql.matches);
11
+ sync();
12
+ mql.addEventListener("change", sync);
13
+ return () => mql.removeEventListener("change", sync);
14
+ }, [query]);
15
+ return matches;
16
+ }
17
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiPHN0ZGluPiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiJ3VzZSBjbGllbnQnXG5cbmltcG9ydCB7IHVzZUVmZmVjdCwgdXNlU3RhdGUgfSBmcm9tICdyZWFjdCdcblxuLyoqIFRydWUgd2hlbiB2aWV3cG9ydCB3aWR0aCBpcyBzdHJpY3RseSBiZWxvdyBgcHhgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZUJlbG93QnJlYWtwb2ludChweDogbnVtYmVyKSB7XG4gIGNvbnN0IHF1ZXJ5ID0gYChtYXgtd2lkdGg6ICR7cHggLSAxfXB4KWBcbiAgY29uc3QgW21hdGNoZXMsIHNldE1hdGNoZXNdID0gdXNlU3RhdGUoKCkgPT5cbiAgICB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdy5tYXRjaE1lZGlhKHF1ZXJ5KS5tYXRjaGVzIDogZmFsc2VcbiAgKVxuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgbXFsID0gd2luZG93Lm1hdGNoTWVkaWEocXVlcnkpXG4gICAgY29uc3Qgc3luYyA9ICgpID0+IHNldE1hdGNoZXMobXFsLm1hdGNoZXMpXG4gICAgc3luYygpXG4gICAgbXFsLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHN5bmMpXG4gICAgcmV0dXJuICgpID0+IG1xbC5yZW1vdmVFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBzeW5jKVxuICB9LCBbcXVlcnldKVxuXG4gIHJldHVybiBtYXRjaGVzXG59XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBRUEsU0FBUyxXQUFXLGdCQUFnQjtBQUc3QixnQkFBUyxtQkFBbUIsSUFBWTtBQUM3QyxRQUFNLFFBQVEsZUFBZSxLQUFLLENBQUM7QUFDbkMsUUFBTSxDQUFDLFNBQVMsVUFBVSxJQUFJO0FBQUEsSUFBUyxNQUNyQyxPQUFPLFdBQVcsY0FBYyxPQUFPLFdBQVcsS0FBSyxFQUFFLFVBQVU7QUFBQSxFQUNyRTtBQUVBLFlBQVUsTUFBTTtBQUNkLFVBQU0sTUFBTSxPQUFPLFdBQVcsS0FBSztBQUNuQyxVQUFNLE9BQU8sTUFBTSxXQUFXLElBQUksT0FBTztBQUN6QyxTQUFLO0FBQ0wsUUFBSSxpQkFBaUIsVUFBVSxJQUFJO0FBQ25DLFdBQU8sTUFBTSxJQUFJLG9CQUFvQixVQUFVLElBQUk7QUFBQSxFQUNyRCxHQUFHLENBQUMsS0FBSyxDQUFDO0FBRVYsU0FBTztBQUNUOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -0,0 +1,2 @@
1
+ import type { RenderCallback } from '@react-three/fiber';
2
+ export declare function useCappedFrame(cb: RenderCallback, max?: number): void;
@@ -0,0 +1,15 @@
1
+ "use client";
2
+ import { useFrame, useThree } from "@react-three/fiber";
3
+ import { useRef } from "react";
4
+ export function useCappedFrame(cb, max) {
5
+ const last = useRef(performance.now());
6
+ const { size } = useThree();
7
+ const interval = 1e3 / (max ?? (size.width < 1024 ? 60 : 120));
8
+ useFrame((st, delta) => {
9
+ if (performance.now() - last.current > interval) {
10
+ last.current = performance.now();
11
+ cb(st, delta);
12
+ }
13
+ });
14
+ }
15
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiPHN0ZGluPiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiJ3VzZSBjbGllbnQnXG5cbmltcG9ydCB7IHVzZUZyYW1lLCB1c2VUaHJlZSB9IGZyb20gJ0ByZWFjdC10aHJlZS9maWJlcidcbmltcG9ydCB0eXBlIHsgUmVuZGVyQ2FsbGJhY2sgfSBmcm9tICdAcmVhY3QtdGhyZWUvZmliZXInXG5pbXBvcnQgeyB1c2VSZWYgfSBmcm9tICdyZWFjdCdcblxuZXhwb3J0IGZ1bmN0aW9uIHVzZUNhcHBlZEZyYW1lKGNiOiBSZW5kZXJDYWxsYmFjaywgbWF4PzogbnVtYmVyKSB7XG4gIGNvbnN0IGxhc3QgPSB1c2VSZWYocGVyZm9ybWFuY2Uubm93KCkpXG4gIGNvbnN0IHsgc2l6ZSB9ID0gdXNlVGhyZWUoKVxuICBjb25zdCBpbnRlcnZhbCA9IDFlMyAvIChtYXggPz8gKHNpemUud2lkdGggPCAxMDI0ID8gNjAgOiAxMjApKVxuXG4gIHVzZUZyYW1lKChzdCwgZGVsdGEpID0+IHtcbiAgICBpZiAocGVyZm9ybWFuY2Uubm93KCkgLSBsYXN0LmN1cnJlbnQgPiBpbnRlcnZhbCkge1xuICAgICAgbGFzdC5jdXJyZW50ID0gcGVyZm9ybWFuY2Uubm93KClcbiAgICAgIGNiKHN0LCBkZWx0YSlcbiAgICB9XG4gIH0pXG59XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBRUEsU0FBUyxVQUFVLGdCQUFnQjtBQUVuQyxTQUFTLGNBQWM7QUFFaEIsZ0JBQVMsZUFBZSxJQUFvQixLQUFjO0FBQy9ELFFBQU0sT0FBTyxPQUFPLFlBQVksSUFBSSxDQUFDO0FBQ3JDLFFBQU0sRUFBRSxLQUFLLElBQUksU0FBUztBQUMxQixRQUFNLFdBQVcsT0FBTyxRQUFRLEtBQUssUUFBUSxPQUFPLEtBQUs7QUFFekQsV0FBUyxDQUFDLElBQUksVUFBVTtBQUN0QixRQUFJLFlBQVksSUFBSSxJQUFJLEtBQUssVUFBVSxVQUFVO0FBQy9DLFdBQUssVUFBVSxZQUFZLElBQUk7QUFDL0IsU0FBRyxJQUFJLEtBQUs7QUFBQSxJQUNkO0FBQUEsRUFDRixDQUFDO0FBQ0g7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,10 @@
1
+ export declare function useConfirmDelete<TId>({ onDelete }: {
2
+ onDelete: (id: TId) => Promise<void>;
3
+ }): {
4
+ readonly cancel: () => void;
5
+ readonly confirm: () => Promise<void>;
6
+ readonly isDeleting: boolean;
7
+ readonly isOpen: boolean;
8
+ readonly pendingId: TId | null;
9
+ readonly requestDelete: (id: TId) => void;
10
+ };
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import { useCallback, useState } from "react";
3
+ export function useConfirmDelete({
4
+ onDelete
5
+ }) {
6
+ const [pendingId, setPendingId] = useState(null);
7
+ const [isDeleting, setIsDeleting] = useState(false);
8
+ const requestDelete = useCallback((id) => {
9
+ setPendingId(id);
10
+ }, []);
11
+ const cancel = useCallback(() => {
12
+ if (!isDeleting) setPendingId(null);
13
+ }, [isDeleting]);
14
+ const confirm = useCallback(async () => {
15
+ if (pendingId === null) return;
16
+ const id = pendingId;
17
+ setIsDeleting(true);
18
+ try {
19
+ await onDelete(id);
20
+ setPendingId(null);
21
+ } catch {
22
+ } finally {
23
+ setIsDeleting(false);
24
+ }
25
+ }, [pendingId, onDelete]);
26
+ return {
27
+ cancel,
28
+ confirm,
29
+ isDeleting,
30
+ isOpen: pendingId !== null,
31
+ pendingId,
32
+ requestDelete
33
+ };
34
+ }
35
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiPHN0ZGluPiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiJ3VzZSBjbGllbnQnXG5cbmltcG9ydCB7IHVzZUNhbGxiYWNrLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0J1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlQ29uZmlybURlbGV0ZTxUSWQ+KHtcbiAgb25EZWxldGVcbn06IHtcbiAgb25EZWxldGU6IChpZDogVElkKSA9PiBQcm9taXNlPHZvaWQ+XG59KSB7XG4gIGNvbnN0IFtwZW5kaW5nSWQsIHNldFBlbmRpbmdJZF0gPSB1c2VTdGF0ZTxUSWQgfCBudWxsPihudWxsKVxuICBjb25zdCBbaXNEZWxldGluZywgc2V0SXNEZWxldGluZ10gPSB1c2VTdGF0ZShmYWxzZSlcblxuICBjb25zdCByZXF1ZXN0RGVsZXRlID0gdXNlQ2FsbGJhY2soKGlkOiBUSWQpID0+IHtcbiAgICBzZXRQZW5kaW5nSWQoaWQpXG4gIH0sIFtdKVxuXG4gIGNvbnN0IGNhbmNlbCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBpZiAoIWlzRGVsZXRpbmcpIHNldFBlbmRpbmdJZChudWxsKVxuICB9LCBbaXNEZWxldGluZ10pXG5cbiAgY29uc3QgY29uZmlybSA9IHVzZUNhbGxiYWNrKGFzeW5jICgpID0+IHtcbiAgICBpZiAocGVuZGluZ0lkID09PSBudWxsKSByZXR1cm5cbiAgICBjb25zdCBpZCA9IHBlbmRpbmdJZFxuICAgIHNldElzRGVsZXRpbmcodHJ1ZSlcbiAgICB0cnkge1xuICAgICAgYXdhaXQgb25EZWxldGUoaWQpXG4gICAgICBzZXRQZW5kaW5nSWQobnVsbClcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIERpYWxvZyBzdGF5cyBvcGVuOyBjYWxsZXIgY2FuIHN1cmZhY2UgZXJyb3JzIGluIG9uRGVsZXRlXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHNldElzRGVsZXRpbmcoZmFsc2UpXG4gICAgfVxuICB9LCBbcGVuZGluZ0lkLCBvbkRlbGV0ZV0pXG5cbiAgcmV0dXJuIHtcbiAgICBjYW5jZWwsXG4gICAgY29uZmlybSxcbiAgICBpc0RlbGV0aW5nLFxuICAgIGlzT3BlbjogcGVuZGluZ0lkICE9PSBudWxsLFxuICAgIHBlbmRpbmdJZCxcbiAgICByZXF1ZXN0RGVsZXRlXG4gIH0gYXMgY29uc3Rcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7QUFFQSxTQUFTLGFBQWEsZ0JBQWdCO0FBRS9CLGdCQUFTLGlCQUFzQjtBQUFBLEVBQ3BDO0FBQ0YsR0FFRztBQUNELFFBQU0sQ0FBQyxXQUFXLFlBQVksSUFBSSxTQUFxQixJQUFJO0FBQzNELFFBQU0sQ0FBQyxZQUFZLGFBQWEsSUFBSSxTQUFTLEtBQUs7QUFFbEQsUUFBTSxnQkFBZ0IsWUFBWSxDQUFDLE9BQVk7QUFDN0MsaUJBQWEsRUFBRTtBQUFBLEVBQ2pCLEdBQUcsQ0FBQyxDQUFDO0FBRUwsUUFBTSxTQUFTLFlBQVksTUFBTTtBQUMvQixRQUFJLENBQUMsV0FBWSxjQUFhLElBQUk7QUFBQSxFQUNwQyxHQUFHLENBQUMsVUFBVSxDQUFDO0FBRWYsUUFBTSxVQUFVLFlBQVksWUFBWTtBQUN0QyxRQUFJLGNBQWMsS0FBTTtBQUN4QixVQUFNLEtBQUs7QUFDWCxrQkFBYyxJQUFJO0FBQ2xCLFFBQUk7QUFDRixZQUFNLFNBQVMsRUFBRTtBQUNqQixtQkFBYSxJQUFJO0FBQUEsSUFDbkIsUUFBUTtBQUFBLElBRVIsVUFBRTtBQUNBLG9CQUFjLEtBQUs7QUFBQSxJQUNyQjtBQUFBLEVBQ0YsR0FBRyxDQUFDLFdBQVcsUUFBUSxDQUFDO0FBRXhCLFNBQU87QUFBQSxJQUNMO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBLFFBQVEsY0FBYztBQUFBLElBQ3RCO0FBQUEsSUFDQTtBQUFBLEVBQ0Y7QUFDRjsiLAogICJuYW1lcyI6IFtdCn0K
@@ -0,0 +1 @@
1
+ export declare function useCssVarDims(name: string, ref: React.RefObject<HTMLElement | null>): void;
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { useEffect } from "react";
3
+ export function useCssVarDims(name, ref) {
4
+ useEffect(() => {
5
+ if (!ref.current) {
6
+ return;
7
+ }
8
+ const update = (width2, height2) => {
9
+ document.documentElement.style.setProperty(
10
+ `--${name}-width`,
11
+ `${width2}px`
12
+ );
13
+ document.documentElement.style.setProperty(
14
+ `--${name}-height`,
15
+ `${height2}px`
16
+ );
17
+ };
18
+ const { height, width } = ref.current.getBoundingClientRect();
19
+ update(width, height);
20
+ const ro = new ResizeObserver((entries) => {
21
+ for (const entry of entries) {
22
+ update(entry.contentRect.width, entry.contentRect.height);
23
+ }
24
+ });
25
+ ro.observe(ref.current);
26
+ return () => ro.disconnect();
27
+ }, [name, ref]);
28
+ }
29
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiPHN0ZGluPiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiJ3VzZSBjbGllbnQnXG5cbmltcG9ydCB7IHVzZUVmZmVjdCB9IGZyb20gJ3JlYWN0J1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlQ3NzVmFyRGltcyhcbiAgbmFtZTogc3RyaW5nLFxuICByZWY6IFJlYWN0LlJlZk9iamVjdDxIVE1MRWxlbWVudCB8IG51bGw+XG4pIHtcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIXJlZi5jdXJyZW50KSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCB1cGRhdGUgPSAod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpID0+IHtcbiAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgYC0tJHtuYW1lfS13aWR0aGAsXG4gICAgICAgIGAke3dpZHRofXB4YFxuICAgICAgKVxuXG4gICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIGAtLSR7bmFtZX0taGVpZ2h0YCxcbiAgICAgICAgYCR7aGVpZ2h0fXB4YFxuICAgICAgKVxuICAgIH1cblxuICAgIGNvbnN0IHsgaGVpZ2h0LCB3aWR0aCB9ID0gcmVmLmN1cnJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICB1cGRhdGUod2lkdGgsIGhlaWdodClcblxuICAgIGNvbnN0IHJvID0gbmV3IFJlc2l6ZU9ic2VydmVyKGVudHJpZXMgPT4ge1xuICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICAgIHVwZGF0ZShlbnRyeS5jb250ZW50UmVjdC53aWR0aCwgZW50cnkuY29udGVudFJlY3QuaGVpZ2h0KVxuICAgICAgfVxuICAgIH0pXG5cbiAgICByby5vYnNlcnZlKHJlZi5jdXJyZW50KVxuXG4gICAgcmV0dXJuICgpID0+IHJvLmRpc2Nvbm5lY3QoKVxuICB9LCBbbmFtZSwgcmVmXSlcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7QUFFQSxTQUFTLGlCQUFpQjtBQUVuQixnQkFBUyxjQUNkLE1BQ0EsS0FDQTtBQUNBLFlBQVUsTUFBTTtBQUNkLFFBQUksQ0FBQyxJQUFJLFNBQVM7QUFDaEI7QUFBQSxJQUNGO0FBRUEsVUFBTSxTQUFTLENBQUNBLFFBQWVDLFlBQW1CO0FBQ2hELGVBQVMsZ0JBQWdCLE1BQU07QUFBQSxRQUM3QixLQUFLLElBQUk7QUFBQSxRQUNULEdBQUdELE1BQUs7QUFBQSxNQUNWO0FBRUEsZUFBUyxnQkFBZ0IsTUFBTTtBQUFBLFFBQzdCLEtBQUssSUFBSTtBQUFBLFFBQ1QsR0FBR0MsT0FBTTtBQUFBLE1BQ1g7QUFBQSxJQUNGO0FBRUEsVUFBTSxFQUFFLFFBQVEsTUFBTSxJQUFJLElBQUksUUFBUSxzQkFBc0I7QUFDNUQsV0FBTyxPQUFPLE1BQU07QUFFcEIsVUFBTSxLQUFLLElBQUksZUFBZSxhQUFXO0FBQ3ZDLGlCQUFXLFNBQVMsU0FBUztBQUMzQixlQUFPLE1BQU0sWUFBWSxPQUFPLE1BQU0sWUFBWSxNQUFNO0FBQUEsTUFDMUQ7QUFBQSxJQUNGLENBQUM7QUFFRCxPQUFHLFFBQVEsSUFBSSxPQUFPO0FBRXRCLFdBQU8sTUFBTSxHQUFHLFdBQVc7QUFBQSxFQUM3QixHQUFHLENBQUMsTUFBTSxHQUFHLENBQUM7QUFDaEI7IiwKICAibmFtZXMiOiBbIndpZHRoIiwgImhlaWdodCJdCn0K
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Tiers:
3
+ * 0 — no WebGL / software renderer / prefers-reduced-motion / WebGL ctx
4
+ * creation failed / detection not yet run
5
+ * 1 — low-end GPU (integrated, mobile, or failed perf benchmark)
6
+ * 2 — capable GPU (discrete / high-end integrated)
7
+ *
8
+ * The atom starts **pessimistic** (`0`) and the probe is scheduled to run
9
+ * *after the first paint* (see `scheduleDetection` below), never synchronously
10
+ * at module-evaluation time.
11
+ *
12
+ * Why pessimistic + deferred:
13
+ * - Every consumer gates its `<canvas>` / `THREE.WebGLRenderer` on `tier > 0`
14
+ * (or `=== 2`). Starting at `0` means a consumer reading `$gpuTier` during
15
+ * its first render never attempts to create a renderer before detection has
16
+ * run, so the `THREE.WebGLRenderer: Error creating WebGL context` crash on
17
+ * hardware where context creation fails cannot happen — the component
18
+ * renders its fallback and upgrades once detection resolves to a capable
19
+ * tier. (A previous version made the probe synchronous-at-module-load to
20
+ * dodge this crash; the pessimistic default removes the crash without that
21
+ * cost.)
22
+ * - Probing WebGL is *expensive* on software renderers: creating a context
23
+ * under SwiftShader / llvmpipe can block the main thread for hundreds of
24
+ * milliseconds. Running it synchronously at module load stalled first paint
25
+ * and produced a visible boot-time flash in apps that merely import this
26
+ * hook (e.g. the Hackit dashboard backdrop). Deferring past first paint
27
+ * keeps boot smooth; the tier just upgrades a frame or two later.
28
+ * - For SSR the server keeps the default `0` and the client's first render
29
+ * also reads `0`, so there is no hydration mismatch.
30
+ */
31
+ export declare const $gpuTier: import("nanostores").PreinitializedWritableAtom<GpuTier> & object;
32
+ export declare function useGpuTier(): GpuTier;
33
+ type GpuTier = 0 | 1 | 2;
34
+ export {};