@misoto22/folio 0.0.0 → 0.16.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 (686) hide show
  1. package/AGENTS.md +88 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +21 -0
  4. package/README.md +208 -2
  5. package/bin/folio-design.mjs +277 -0
  6. package/bin/migrate-legacy.mjs +81 -0
  7. package/dist/agent/Accordion.md +65 -0
  8. package/dist/agent/Actions.md +49 -0
  9. package/dist/agent/Alert.md +65 -0
  10. package/dist/agent/AppShell.md +69 -0
  11. package/dist/agent/ArchitectureFigure.md +72 -0
  12. package/dist/agent/AreaChart.md +94 -0
  13. package/dist/agent/Article.md +65 -0
  14. package/dist/agent/AspectRatio.md +58 -0
  15. package/dist/agent/Avatar.md +53 -0
  16. package/dist/agent/Badge.md +62 -0
  17. package/dist/agent/BarChart.md +93 -0
  18. package/dist/agent/BarList.md +67 -0
  19. package/dist/agent/BigNumber.md +70 -0
  20. package/dist/agent/BoxPlot.md +82 -0
  21. package/dist/agent/Breadcrumb.md +55 -0
  22. package/dist/agent/BulletChart.md +71 -0
  23. package/dist/agent/Button.md +81 -0
  24. package/dist/agent/Calendar.md +77 -0
  25. package/dist/agent/CalendarHeatmap.md +75 -0
  26. package/dist/agent/Card.md +72 -0
  27. package/dist/agent/Checkbox.md +57 -0
  28. package/dist/agent/Code.md +51 -0
  29. package/dist/agent/CodeBlock.md +77 -0
  30. package/dist/agent/Collapsible.md +68 -0
  31. package/dist/agent/Collection.md +169 -0
  32. package/dist/agent/ColorPicker.md +76 -0
  33. package/dist/agent/Combobox.md +77 -0
  34. package/dist/agent/Command.md +122 -0
  35. package/dist/agent/ComposedChart.md +82 -0
  36. package/dist/agent/Contact.md +90 -0
  37. package/dist/agent/Content.md +70 -0
  38. package/dist/agent/ContextMenu.md +93 -0
  39. package/dist/agent/Conversation.md +247 -0
  40. package/dist/agent/DataflowFigure.md +49 -0
  41. package/dist/agent/DatePicker.md +104 -0
  42. package/dist/agent/DescriptionList.md +69 -0
  43. package/dist/agent/Diagram.md +71 -0
  44. package/dist/agent/DiagramCanvas.md +71 -0
  45. package/dist/agent/DiagramExportMenu.md +65 -0
  46. package/dist/agent/DiagramInspector.md +73 -0
  47. package/dist/agent/DiagramLegend.md +56 -0
  48. package/dist/agent/DiagramMinimap.md +69 -0
  49. package/dist/agent/DiagramToolbar.md +70 -0
  50. package/dist/agent/Dialog.md +76 -0
  51. package/dist/agent/DropdownMenu.md +110 -0
  52. package/dist/agent/EmptyState.md +63 -0
  53. package/dist/agent/ErrorState.md +67 -0
  54. package/dist/agent/Evidence.md +165 -0
  55. package/dist/agent/Facet.md +107 -0
  56. package/dist/agent/Field.md +79 -0
  57. package/dist/agent/FigureBand.md +49 -0
  58. package/dist/agent/FloatingIconButton.md +61 -0
  59. package/dist/agent/FunnelChart.md +75 -0
  60. package/dist/agent/Heading.md +65 -0
  61. package/dist/agent/Heatmap.md +78 -0
  62. package/dist/agent/Histogram.md +88 -0
  63. package/dist/agent/Input.md +52 -0
  64. package/dist/agent/Kbd.md +48 -0
  65. package/dist/agent/LifecycleFigure.md +50 -0
  66. package/dist/agent/LineChart.md +85 -0
  67. package/dist/agent/LinkArrow.md +49 -0
  68. package/dist/agent/Markdown.md +69 -0
  69. package/dist/agent/Media.md +261 -0
  70. package/dist/agent/Metric.md +70 -0
  71. package/dist/agent/Metrics.md +114 -0
  72. package/dist/agent/Music.md +86 -0
  73. package/dist/agent/NativeSelect.md +62 -0
  74. package/dist/agent/NavItem.md +56 -0
  75. package/dist/agent/NumberField.md +73 -0
  76. package/dist/agent/PageHeader.md +69 -0
  77. package/dist/agent/Pagination.md +70 -0
  78. package/dist/agent/PieChart.md +80 -0
  79. package/dist/agent/Popover.md +80 -0
  80. package/dist/agent/Portfolio.md +93 -0
  81. package/dist/agent/PortfolioIndex.md +34 -0
  82. package/dist/agent/Progress.md +58 -0
  83. package/dist/agent/RadarChart.md +79 -0
  84. package/dist/agent/RadialChart.md +81 -0
  85. package/dist/agent/RadioGroup.md +66 -0
  86. package/dist/agent/Reading.md +233 -0
  87. package/dist/agent/Recovery.md +72 -0
  88. package/dist/agent/SankeyChart.md +85 -0
  89. package/dist/agent/ScatterChart.md +80 -0
  90. package/dist/agent/ScrollArea.md +62 -0
  91. package/dist/agent/SearchPalette.md +51 -0
  92. package/dist/agent/SearchableMenu.md +69 -0
  93. package/dist/agent/Select.md +102 -0
  94. package/dist/agent/Separator.md +60 -0
  95. package/dist/agent/SequenceFigure.md +51 -0
  96. package/dist/agent/Sheet.md +82 -0
  97. package/dist/agent/Sidebar.md +194 -0
  98. package/dist/agent/SiteNavigation.md +62 -0
  99. package/dist/agent/SiteShell.md +67 -0
  100. package/dist/agent/Skeleton.md +96 -0
  101. package/dist/agent/Slider.md +67 -0
  102. package/dist/agent/Sparkline.md +68 -0
  103. package/dist/agent/Spinner.md +62 -0
  104. package/dist/agent/StatusDot.md +56 -0
  105. package/dist/agent/StatusPill.md +55 -0
  106. package/dist/agent/Steps.md +68 -0
  107. package/dist/agent/Switch.md +50 -0
  108. package/dist/agent/Table.md +111 -0
  109. package/dist/agent/Tabs.md +71 -0
  110. package/dist/agent/Tag.md +67 -0
  111. package/dist/agent/Text.md +66 -0
  112. package/dist/agent/Textarea.md +46 -0
  113. package/dist/agent/Timeline.md +114 -0
  114. package/dist/agent/Timestamp.md +65 -0
  115. package/dist/agent/Toast.md +51 -0
  116. package/dist/agent/ToggleGroup.md +67 -0
  117. package/dist/agent/Toolbar.md +72 -0
  118. package/dist/agent/Tooltip.md +74 -0
  119. package/dist/agent/TreemapChart.md +76 -0
  120. package/dist/agent/WaterfallChart.md +86 -0
  121. package/dist/agent/WorkflowFigure.md +51 -0
  122. package/dist/agent/catalog.json +8006 -0
  123. package/dist/agent/index.md +182 -0
  124. package/dist/article.css +407 -0
  125. package/dist/charts/AreaChart/AreaChart.d.ts +198 -0
  126. package/dist/charts/AreaChart/AreaChart.js +479 -0
  127. package/dist/charts/AreaChart/AreaChart.js.map +1 -0
  128. package/dist/charts/BarChart/BarChart.d.ts +190 -0
  129. package/dist/charts/BarChart/BarChart.js +599 -0
  130. package/dist/charts/BarChart/BarChart.js.map +1 -0
  131. package/dist/charts/BarList/BarList.d.ts +65 -0
  132. package/dist/charts/BarList/BarList.js +79 -0
  133. package/dist/charts/BarList/BarList.js.map +1 -0
  134. package/dist/charts/BigNumber/BigNumber.d.ts +72 -0
  135. package/dist/charts/BigNumber/BigNumber.js +51 -0
  136. package/dist/charts/BigNumber/BigNumber.js.map +1 -0
  137. package/dist/charts/BoxPlot/BoxPlot.d.ts +177 -0
  138. package/dist/charts/BoxPlot/BoxPlot.js +497 -0
  139. package/dist/charts/BoxPlot/BoxPlot.js.map +1 -0
  140. package/dist/charts/BulletChart/BulletChart.d.ts +100 -0
  141. package/dist/charts/BulletChart/BulletChart.js +197 -0
  142. package/dist/charts/BulletChart/BulletChart.js.map +1 -0
  143. package/dist/charts/CalendarHeatmap/CalendarHeatmap.d.ts +106 -0
  144. package/dist/charts/CalendarHeatmap/CalendarHeatmap.js +103 -0
  145. package/dist/charts/CalendarHeatmap/CalendarHeatmap.js.map +1 -0
  146. package/dist/charts/ComposedChart/ComposedChart.d.ts +178 -0
  147. package/dist/charts/ComposedChart/ComposedChart.js +667 -0
  148. package/dist/charts/ComposedChart/ComposedChart.js.map +1 -0
  149. package/dist/charts/Facet/Facet.d.ts +240 -0
  150. package/dist/charts/Facet/Facet.js +133 -0
  151. package/dist/charts/Facet/Facet.js.map +1 -0
  152. package/dist/charts/Facet/panels.d.ts +187 -0
  153. package/dist/charts/Facet/panels.js +203 -0
  154. package/dist/charts/Facet/panels.js.map +1 -0
  155. package/dist/charts/FunnelChart/FunnelChart.d.ts +106 -0
  156. package/dist/charts/FunnelChart/FunnelChart.js +137 -0
  157. package/dist/charts/FunnelChart/FunnelChart.js.map +1 -0
  158. package/dist/charts/Heatmap/Heatmap.d.ts +101 -0
  159. package/dist/charts/Heatmap/Heatmap.js +125 -0
  160. package/dist/charts/Heatmap/Heatmap.js.map +1 -0
  161. package/dist/charts/Histogram/Histogram.d.ts +188 -0
  162. package/dist/charts/Histogram/Histogram.js +382 -0
  163. package/dist/charts/Histogram/Histogram.js.map +1 -0
  164. package/dist/charts/LineChart/LineChart.d.ts +174 -0
  165. package/dist/charts/LineChart/LineChart.js +485 -0
  166. package/dist/charts/LineChart/LineChart.js.map +1 -0
  167. package/dist/charts/PieChart/PieChart.d.ts +140 -0
  168. package/dist/charts/PieChart/PieChart.js +317 -0
  169. package/dist/charts/PieChart/PieChart.js.map +1 -0
  170. package/dist/charts/RadarChart/RadarChart.d.ts +135 -0
  171. package/dist/charts/RadarChart/RadarChart.js +303 -0
  172. package/dist/charts/RadarChart/RadarChart.js.map +1 -0
  173. package/dist/charts/RadialChart/RadialChart.d.ts +142 -0
  174. package/dist/charts/RadialChart/RadialChart.js +279 -0
  175. package/dist/charts/RadialChart/RadialChart.js.map +1 -0
  176. package/dist/charts/SankeyChart/SankeyChart.d.ts +149 -0
  177. package/dist/charts/SankeyChart/SankeyChart.js +509 -0
  178. package/dist/charts/SankeyChart/SankeyChart.js.map +1 -0
  179. package/dist/charts/ScatterChart/ScatterChart.d.ts +149 -0
  180. package/dist/charts/ScatterChart/ScatterChart.js +275 -0
  181. package/dist/charts/ScatterChart/ScatterChart.js.map +1 -0
  182. package/dist/charts/Sparkline/Sparkline.d.ts +53 -0
  183. package/dist/charts/Sparkline/Sparkline.js +95 -0
  184. package/dist/charts/Sparkline/Sparkline.js.map +1 -0
  185. package/dist/charts/TreemapChart/TreemapChart.d.ts +98 -0
  186. package/dist/charts/TreemapChart/TreemapChart.js +127 -0
  187. package/dist/charts/TreemapChart/TreemapChart.js.map +1 -0
  188. package/dist/charts/WaterfallChart/WaterfallChart.d.ts +164 -0
  189. package/dist/charts/WaterfallChart/WaterfallChart.js +321 -0
  190. package/dist/charts/WaterfallChart/WaterfallChart.js.map +1 -0
  191. package/dist/charts/index.d.ts +43 -0
  192. package/dist/charts/index.js +130 -0
  193. package/dist/charts/index.js.map +1 -0
  194. package/dist/charts/lib/annotations.d.ts +103 -0
  195. package/dist/charts/lib/annotations.js +99 -0
  196. package/dist/charts/lib/annotations.js.map +1 -0
  197. package/dist/charts/lib/axis.d.ts +18 -0
  198. package/dist/charts/lib/axis.js +21 -0
  199. package/dist/charts/lib/axis.js.map +1 -0
  200. package/dist/charts/lib/background.d.ts +33 -0
  201. package/dist/charts/lib/background.js +173 -0
  202. package/dist/charts/lib/background.js.map +1 -0
  203. package/dist/charts/lib/brush.d.ts +94 -0
  204. package/dist/charts/lib/brush.js +535 -0
  205. package/dist/charts/lib/brush.js.map +1 -0
  206. package/dist/charts/lib/chart.d.ts +94 -0
  207. package/dist/charts/lib/chart.js +149 -0
  208. package/dist/charts/lib/chart.js.map +1 -0
  209. package/dist/charts/lib/dot.d.ts +29 -0
  210. package/dist/charts/lib/dot.js +78 -0
  211. package/dist/charts/lib/dot.js.map +1 -0
  212. package/dist/charts/lib/empty.d.ts +31 -0
  213. package/dist/charts/lib/empty.js +24 -0
  214. package/dist/charts/lib/empty.js.map +1 -0
  215. package/dist/charts/lib/export.d.ts +94 -0
  216. package/dist/charts/lib/export.js +62 -0
  217. package/dist/charts/lib/export.js.map +1 -0
  218. package/dist/charts/lib/figure.d.ts +81 -0
  219. package/dist/charts/lib/figure.js +62 -0
  220. package/dist/charts/lib/figure.js.map +1 -0
  221. package/dist/charts/lib/format.d.ts +46 -0
  222. package/dist/charts/lib/format.js +56 -0
  223. package/dist/charts/lib/format.js.map +1 -0
  224. package/dist/charts/lib/legend.d.ts +45 -0
  225. package/dist/charts/lib/legend.js +117 -0
  226. package/dist/charts/lib/legend.js.map +1 -0
  227. package/dist/charts/lib/loading.d.ts +48 -0
  228. package/dist/charts/lib/loading.js +105 -0
  229. package/dist/charts/lib/loading.js.map +1 -0
  230. package/dist/charts/lib/paint.d.ts +154 -0
  231. package/dist/charts/lib/paint.js +551 -0
  232. package/dist/charts/lib/paint.js.map +1 -0
  233. package/dist/charts/lib/scale.d.ts +23 -0
  234. package/dist/charts/lib/scale.js +13 -0
  235. package/dist/charts/lib/scale.js.map +1 -0
  236. package/dist/charts/lib/selection.d.ts +20 -0
  237. package/dist/charts/lib/selection.js +18 -0
  238. package/dist/charts/lib/selection.js.map +1 -0
  239. package/dist/charts/lib/sonify-control.d.ts +163 -0
  240. package/dist/charts/lib/sonify-control.js +172 -0
  241. package/dist/charts/lib/sonify-control.js.map +1 -0
  242. package/dist/charts/lib/sonify.d.ts +248 -0
  243. package/dist/charts/lib/sonify.js +262 -0
  244. package/dist/charts/lib/sonify.js.map +1 -0
  245. package/dist/charts/lib/toolbar.d.ts +144 -0
  246. package/dist/charts/lib/toolbar.js +156 -0
  247. package/dist/charts/lib/toolbar.js.map +1 -0
  248. package/dist/charts/lib/tooltip.d.ts +59 -0
  249. package/dist/charts/lib/tooltip.js +135 -0
  250. package/dist/charts/lib/tooltip.js.map +1 -0
  251. package/dist/charts/lib/values.d.ts +56 -0
  252. package/dist/charts/lib/values.js +71 -0
  253. package/dist/charts/lib/values.js.map +1 -0
  254. package/dist/charts/lib/zoom.d.ts +139 -0
  255. package/dist/charts/lib/zoom.js +314 -0
  256. package/dist/charts/lib/zoom.js.map +1 -0
  257. package/dist/components/Accordion/Accordion.d.ts +34 -0
  258. package/dist/components/Accordion/Accordion.js +43 -0
  259. package/dist/components/Accordion/Accordion.js.map +1 -0
  260. package/dist/components/Alert/Alert.d.ts +32 -0
  261. package/dist/components/Alert/Alert.js +49 -0
  262. package/dist/components/Alert/Alert.js.map +1 -0
  263. package/dist/components/AppShell/AppShell.d.ts +58 -0
  264. package/dist/components/AppShell/AppShell.js +126 -0
  265. package/dist/components/AppShell/AppShell.js.map +1 -0
  266. package/dist/components/Article/Article.d.ts +58 -0
  267. package/dist/components/Article/Article.js +34 -0
  268. package/dist/components/Article/Article.js.map +1 -0
  269. package/dist/components/AspectRatio/AspectRatio.d.ts +46 -0
  270. package/dist/components/AspectRatio/AspectRatio.js +33 -0
  271. package/dist/components/AspectRatio/AspectRatio.js.map +1 -0
  272. package/dist/components/Avatar/Avatar.d.ts +38 -0
  273. package/dist/components/Avatar/Avatar.js +44 -0
  274. package/dist/components/Avatar/Avatar.js.map +1 -0
  275. package/dist/components/Badge/Badge.d.ts +30 -0
  276. package/dist/components/Badge/Badge.js +29 -0
  277. package/dist/components/Badge/Badge.js.map +1 -0
  278. package/dist/components/Breadcrumb/Breadcrumb.d.ts +37 -0
  279. package/dist/components/Breadcrumb/Breadcrumb.js +46 -0
  280. package/dist/components/Breadcrumb/Breadcrumb.js.map +1 -0
  281. package/dist/components/Button/Button.d.ts +70 -0
  282. package/dist/components/Button/Button.js +95 -0
  283. package/dist/components/Button/Button.js.map +1 -0
  284. package/dist/components/Calendar/Calendar.d.ts +54 -0
  285. package/dist/components/Calendar/Calendar.js +369 -0
  286. package/dist/components/Calendar/Calendar.js.map +1 -0
  287. package/dist/components/Card/Card.d.ts +55 -0
  288. package/dist/components/Card/Card.js +64 -0
  289. package/dist/components/Card/Card.js.map +1 -0
  290. package/dist/components/Checkbox/Checkbox.d.ts +26 -0
  291. package/dist/components/Checkbox/Checkbox.js +34 -0
  292. package/dist/components/Checkbox/Checkbox.js.map +1 -0
  293. package/dist/components/Code/Code.d.ts +30 -0
  294. package/dist/components/Code/Code.js +21 -0
  295. package/dist/components/Code/Code.js.map +1 -0
  296. package/dist/components/CodeBlock/CodeBlock.d.ts +145 -0
  297. package/dist/components/CodeBlock/CodeBlock.js +114 -0
  298. package/dist/components/CodeBlock/CodeBlock.js.map +1 -0
  299. package/dist/components/Collapsible/Collapsible.d.ts +45 -0
  300. package/dist/components/Collapsible/Collapsible.js +60 -0
  301. package/dist/components/Collapsible/Collapsible.js.map +1 -0
  302. package/dist/components/ColorPicker/ColorPicker.d.ts +67 -0
  303. package/dist/components/ColorPicker/ColorPicker.js +334 -0
  304. package/dist/components/ColorPicker/ColorPicker.js.map +1 -0
  305. package/dist/components/Combobox/Combobox.d.ts +77 -0
  306. package/dist/components/Combobox/Combobox.js +170 -0
  307. package/dist/components/Combobox/Combobox.js.map +1 -0
  308. package/dist/components/Command/Command.d.ts +125 -0
  309. package/dist/components/Command/Command.js +204 -0
  310. package/dist/components/Command/Command.js.map +1 -0
  311. package/dist/components/ContextMenu/ContextMenu.d.ts +63 -0
  312. package/dist/components/ContextMenu/ContextMenu.js +109 -0
  313. package/dist/components/ContextMenu/ContextMenu.js.map +1 -0
  314. package/dist/components/DatePicker/DatePicker.d.ts +130 -0
  315. package/dist/components/DatePicker/DatePicker.js +257 -0
  316. package/dist/components/DatePicker/DatePicker.js.map +1 -0
  317. package/dist/components/DescriptionList/DescriptionList.d.ts +73 -0
  318. package/dist/components/DescriptionList/DescriptionList.js +35 -0
  319. package/dist/components/DescriptionList/DescriptionList.js.map +1 -0
  320. package/dist/components/Diagram/Diagram.d.ts +86 -0
  321. package/dist/components/Diagram/Diagram.js +211 -0
  322. package/dist/components/Diagram/Diagram.js.map +1 -0
  323. package/dist/components/Dialog/Dialog.d.ts +63 -0
  324. package/dist/components/Dialog/Dialog.js +90 -0
  325. package/dist/components/Dialog/Dialog.js.map +1 -0
  326. package/dist/components/DropdownMenu/DropdownMenu.d.ts +87 -0
  327. package/dist/components/DropdownMenu/DropdownMenu.js +120 -0
  328. package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -0
  329. package/dist/components/EmptyState/EmptyState.d.ts +55 -0
  330. package/dist/components/EmptyState/EmptyState.js +32 -0
  331. package/dist/components/EmptyState/EmptyState.js.map +1 -0
  332. package/dist/components/ErrorState/ErrorState.d.ts +55 -0
  333. package/dist/components/ErrorState/ErrorState.js +41 -0
  334. package/dist/components/ErrorState/ErrorState.js.map +1 -0
  335. package/dist/components/Field/Field.d.ts +111 -0
  336. package/dist/components/Field/Field.js +95 -0
  337. package/dist/components/Field/Field.js.map +1 -0
  338. package/dist/components/Field/field-control.d.ts +31 -0
  339. package/dist/components/Field/field-control.js +12 -0
  340. package/dist/components/Field/field-control.js.map +1 -0
  341. package/dist/components/FigureBand/FigureBand.d.ts +31 -0
  342. package/dist/components/FigureBand/FigureBand.js +51 -0
  343. package/dist/components/FigureBand/FigureBand.js.map +1 -0
  344. package/dist/components/FloatingIconButton/FloatingIconButton.d.ts +29 -0
  345. package/dist/components/FloatingIconButton/FloatingIconButton.js +34 -0
  346. package/dist/components/FloatingIconButton/FloatingIconButton.js.map +1 -0
  347. package/dist/components/Heading/Heading.d.ts +62 -0
  348. package/dist/components/Heading/Heading.js +44 -0
  349. package/dist/components/Heading/Heading.js.map +1 -0
  350. package/dist/components/Input/Input.d.ts +22 -0
  351. package/dist/components/Input/Input.js +21 -0
  352. package/dist/components/Input/Input.js.map +1 -0
  353. package/dist/components/Kbd/Kbd.d.ts +27 -0
  354. package/dist/components/Kbd/Kbd.js +21 -0
  355. package/dist/components/Kbd/Kbd.js.map +1 -0
  356. package/dist/components/LinkArrow/LinkArrow.d.ts +24 -0
  357. package/dist/components/LinkArrow/LinkArrow.js +24 -0
  358. package/dist/components/LinkArrow/LinkArrow.js.map +1 -0
  359. package/dist/components/Markdown/Markdown.d.ts +139 -0
  360. package/dist/components/Markdown/Markdown.js +135 -0
  361. package/dist/components/Markdown/Markdown.js.map +1 -0
  362. package/dist/components/Markdown/inline.d.ts +29 -0
  363. package/dist/components/Markdown/inline.js +74 -0
  364. package/dist/components/Markdown/inline.js.map +1 -0
  365. package/dist/components/Markdown/nodes.d.ts +65 -0
  366. package/dist/components/Markdown/nodes.js +1 -0
  367. package/dist/components/Markdown/nodes.js.map +1 -0
  368. package/dist/components/Markdown/parse.d.ts +24 -0
  369. package/dist/components/Markdown/parse.js +110 -0
  370. package/dist/components/Markdown/parse.js.map +1 -0
  371. package/dist/components/Markdown/slug.d.ts +15 -0
  372. package/dist/components/Markdown/slug.js +7 -0
  373. package/dist/components/Markdown/slug.js.map +1 -0
  374. package/dist/components/Metric/Metric.d.ts +61 -0
  375. package/dist/components/Metric/Metric.js +51 -0
  376. package/dist/components/Metric/Metric.js.map +1 -0
  377. package/dist/components/NativeSelect/NativeSelect.d.ts +33 -0
  378. package/dist/components/NativeSelect/NativeSelect.js +44 -0
  379. package/dist/components/NativeSelect/NativeSelect.js.map +1 -0
  380. package/dist/components/NavItem/NavItem.d.ts +39 -0
  381. package/dist/components/NavItem/NavItem.js +31 -0
  382. package/dist/components/NavItem/NavItem.js.map +1 -0
  383. package/dist/components/NumberField/NumberField.d.ts +69 -0
  384. package/dist/components/NumberField/NumberField.js +162 -0
  385. package/dist/components/NumberField/NumberField.js.map +1 -0
  386. package/dist/components/PageHeader/PageHeader.d.ts +92 -0
  387. package/dist/components/PageHeader/PageHeader.js +37 -0
  388. package/dist/components/PageHeader/PageHeader.js.map +1 -0
  389. package/dist/components/Pagination/Pagination.d.ts +67 -0
  390. package/dist/components/Pagination/Pagination.js +112 -0
  391. package/dist/components/Pagination/Pagination.js.map +1 -0
  392. package/dist/components/Popover/Popover.d.ts +39 -0
  393. package/dist/components/Popover/Popover.js +57 -0
  394. package/dist/components/Popover/Popover.js.map +1 -0
  395. package/dist/components/Progress/Progress.d.ts +43 -0
  396. package/dist/components/Progress/Progress.js +57 -0
  397. package/dist/components/Progress/Progress.js.map +1 -0
  398. package/dist/components/RadioGroup/RadioGroup.d.ts +49 -0
  399. package/dist/components/RadioGroup/RadioGroup.js +53 -0
  400. package/dist/components/RadioGroup/RadioGroup.js.map +1 -0
  401. package/dist/components/ScrollArea/ScrollArea.d.ts +46 -0
  402. package/dist/components/ScrollArea/ScrollArea.js +54 -0
  403. package/dist/components/ScrollArea/ScrollArea.js.map +1 -0
  404. package/dist/components/SearchableMenu/SearchableMenu.d.ts +68 -0
  405. package/dist/components/SearchableMenu/SearchableMenu.js +101 -0
  406. package/dist/components/SearchableMenu/SearchableMenu.js.map +1 -0
  407. package/dist/components/Select/Select.d.ts +87 -0
  408. package/dist/components/Select/Select.js +130 -0
  409. package/dist/components/Select/Select.js.map +1 -0
  410. package/dist/components/Separator/Separator.d.ts +48 -0
  411. package/dist/components/Separator/Separator.js +43 -0
  412. package/dist/components/Separator/Separator.js.map +1 -0
  413. package/dist/components/Sheet/Sheet.d.ts +43 -0
  414. package/dist/components/Sheet/Sheet.js +79 -0
  415. package/dist/components/Sheet/Sheet.js.map +1 -0
  416. package/dist/components/Sidebar/Sidebar.d.ts +357 -0
  417. package/dist/components/Sidebar/Sidebar.js +447 -0
  418. package/dist/components/Sidebar/Sidebar.js.map +1 -0
  419. package/dist/components/Skeleton/Skeleton.d.ts +70 -0
  420. package/dist/components/Skeleton/Skeleton.js +44 -0
  421. package/dist/components/Skeleton/Skeleton.js.map +1 -0
  422. package/dist/components/Slider/Slider.d.ts +74 -0
  423. package/dist/components/Slider/Slider.js +143 -0
  424. package/dist/components/Slider/Slider.js.map +1 -0
  425. package/dist/components/Spinner/Spinner.d.ts +58 -0
  426. package/dist/components/Spinner/Spinner.js +49 -0
  427. package/dist/components/Spinner/Spinner.js.map +1 -0
  428. package/dist/components/StatusDot/StatusDot.d.ts +29 -0
  429. package/dist/components/StatusDot/StatusDot.js +44 -0
  430. package/dist/components/StatusDot/StatusDot.js.map +1 -0
  431. package/dist/components/StatusPill/StatusPill.d.ts +30 -0
  432. package/dist/components/StatusPill/StatusPill.js +37 -0
  433. package/dist/components/StatusPill/StatusPill.js.map +1 -0
  434. package/dist/components/Steps/Steps.d.ts +65 -0
  435. package/dist/components/Steps/Steps.js +25 -0
  436. package/dist/components/Steps/Steps.js.map +1 -0
  437. package/dist/components/Switch/Switch.d.ts +23 -0
  438. package/dist/components/Switch/Switch.js +23 -0
  439. package/dist/components/Switch/Switch.js.map +1 -0
  440. package/dist/components/Table/Table.d.ts +116 -0
  441. package/dist/components/Table/Table.js +137 -0
  442. package/dist/components/Table/Table.js.map +1 -0
  443. package/dist/components/Tabs/Tabs.d.ts +37 -0
  444. package/dist/components/Tabs/Tabs.js +205 -0
  445. package/dist/components/Tabs/Tabs.js.map +1 -0
  446. package/dist/components/Tag/Tag.d.ts +87 -0
  447. package/dist/components/Tag/Tag.js +62 -0
  448. package/dist/components/Tag/Tag.js.map +1 -0
  449. package/dist/components/Text/Text.d.ts +62 -0
  450. package/dist/components/Text/Text.js +30 -0
  451. package/dist/components/Text/Text.js.map +1 -0
  452. package/dist/components/Textarea/Textarea.d.ts +20 -0
  453. package/dist/components/Textarea/Textarea.js +32 -0
  454. package/dist/components/Textarea/Textarea.js.map +1 -0
  455. package/dist/components/Timestamp/Timestamp.d.ts +59 -0
  456. package/dist/components/Timestamp/Timestamp.js +56 -0
  457. package/dist/components/Timestamp/Timestamp.js.map +1 -0
  458. package/dist/components/Toast/Toast.d.ts +32 -0
  459. package/dist/components/Toast/Toast.js +64 -0
  460. package/dist/components/Toast/Toast.js.map +1 -0
  461. package/dist/components/ToggleGroup/ToggleGroup.d.ts +46 -0
  462. package/dist/components/ToggleGroup/ToggleGroup.js +88 -0
  463. package/dist/components/ToggleGroup/ToggleGroup.js.map +1 -0
  464. package/dist/components/Toolbar/Toolbar.d.ts +55 -0
  465. package/dist/components/Toolbar/Toolbar.js +43 -0
  466. package/dist/components/Toolbar/Toolbar.js.map +1 -0
  467. package/dist/components/Tooltip/Tooltip.d.ts +43 -0
  468. package/dist/components/Tooltip/Tooltip.js +40 -0
  469. package/dist/components/Tooltip/Tooltip.js.map +1 -0
  470. package/dist/diagrams/ArchitectureFigure/ArchitectureFigure.d.ts +55 -0
  471. package/dist/diagrams/ArchitectureFigure/ArchitectureFigure.js +175 -0
  472. package/dist/diagrams/ArchitectureFigure/ArchitectureFigure.js.map +1 -0
  473. package/dist/diagrams/DataflowFigure/DataflowFigure.d.ts +28 -0
  474. package/dist/diagrams/DataflowFigure/DataflowFigure.js +148 -0
  475. package/dist/diagrams/DataflowFigure/DataflowFigure.js.map +1 -0
  476. package/dist/diagrams/DiagramCanvas/DiagramCanvas.d.ts +78 -0
  477. package/dist/diagrams/DiagramCanvas/DiagramCanvas.js +229 -0
  478. package/dist/diagrams/DiagramCanvas/DiagramCanvas.js.map +1 -0
  479. package/dist/diagrams/DiagramExportMenu/DiagramExportMenu.d.ts +106 -0
  480. package/dist/diagrams/DiagramExportMenu/DiagramExportMenu.js +123 -0
  481. package/dist/diagrams/DiagramExportMenu/DiagramExportMenu.js.map +1 -0
  482. package/dist/diagrams/DiagramInspector/DiagramInspector.d.ts +70 -0
  483. package/dist/diagrams/DiagramInspector/DiagramInspector.js +94 -0
  484. package/dist/diagrams/DiagramInspector/DiagramInspector.js.map +1 -0
  485. package/dist/diagrams/DiagramLegend/DiagramLegend.d.ts +42 -0
  486. package/dist/diagrams/DiagramLegend/DiagramLegend.js +35 -0
  487. package/dist/diagrams/DiagramLegend/DiagramLegend.js.map +1 -0
  488. package/dist/diagrams/DiagramMinimap/DiagramMinimap.d.ts +77 -0
  489. package/dist/diagrams/DiagramMinimap/DiagramMinimap.js +106 -0
  490. package/dist/diagrams/DiagramMinimap/DiagramMinimap.js.map +1 -0
  491. package/dist/diagrams/DiagramToolbar/DiagramToolbar.d.ts +48 -0
  492. package/dist/diagrams/DiagramToolbar/DiagramToolbar.js +53 -0
  493. package/dist/diagrams/DiagramToolbar/DiagramToolbar.js.map +1 -0
  494. package/dist/diagrams/LifecycleFigure/LifecycleFigure.d.ts +31 -0
  495. package/dist/diagrams/LifecycleFigure/LifecycleFigure.js +234 -0
  496. package/dist/diagrams/LifecycleFigure/LifecycleFigure.js.map +1 -0
  497. package/dist/diagrams/SequenceFigure/SequenceFigure.d.ts +38 -0
  498. package/dist/diagrams/SequenceFigure/SequenceFigure.js +261 -0
  499. package/dist/diagrams/SequenceFigure/SequenceFigure.js.map +1 -0
  500. package/dist/diagrams/WorkflowFigure/WorkflowFigure.d.ts +36 -0
  501. package/dist/diagrams/WorkflowFigure/WorkflowFigure.js +259 -0
  502. package/dist/diagrams/WorkflowFigure/WorkflowFigure.js.map +1 -0
  503. package/dist/diagrams/index.d.ts +17 -0
  504. package/dist/diagrams/index.js +29 -0
  505. package/dist/diagrams/index.js.map +1 -0
  506. package/dist/diagrams/lib/dev.d.ts +61 -0
  507. package/dist/diagrams/lib/dev.js +96 -0
  508. package/dist/diagrams/lib/dev.js.map +1 -0
  509. package/dist/diagrams/lib/frame.d.ts +138 -0
  510. package/dist/diagrams/lib/frame.js +131 -0
  511. package/dist/diagrams/lib/frame.js.map +1 -0
  512. package/dist/diagrams/lib/geometry.d.ts +114 -0
  513. package/dist/diagrams/lib/geometry.js +113 -0
  514. package/dist/diagrams/lib/geometry.js.map +1 -0
  515. package/dist/diagrams/lib/legend.d.ts +32 -0
  516. package/dist/diagrams/lib/legend.js +84 -0
  517. package/dist/diagrams/lib/legend.js.map +1 -0
  518. package/dist/diagrams/lib/marks.d.ts +207 -0
  519. package/dist/diagrams/lib/marks.js +480 -0
  520. package/dist/diagrams/lib/marks.js.map +1 -0
  521. package/dist/diagrams/lib/route.d.ts +106 -0
  522. package/dist/diagrams/lib/route.js +201 -0
  523. package/dist/diagrams/lib/route.js.map +1 -0
  524. package/dist/diagrams/lib/wires.d.ts +59 -0
  525. package/dist/diagrams/lib/wires.js +94 -0
  526. package/dist/diagrams/lib/wires.js.map +1 -0
  527. package/dist/diagrams/spec.d.ts +405 -0
  528. package/dist/diagrams/spec.js +1 -0
  529. package/dist/diagrams/spec.js.map +1 -0
  530. package/dist/fonts/hanken-grotesk-300.woff2 +0 -0
  531. package/dist/fonts/hanken-grotesk-400.woff2 +0 -0
  532. package/dist/fonts/hanken-grotesk-500.woff2 +0 -0
  533. package/dist/fonts/hanken-grotesk-600.woff2 +0 -0
  534. package/dist/fonts/hanken-grotesk-700.woff2 +0 -0
  535. package/dist/fonts/ibm-plex-mono-400.woff2 +0 -0
  536. package/dist/fonts/ibm-plex-mono-500.woff2 +0 -0
  537. package/dist/fonts/ibm-plex-mono-600.woff2 +0 -0
  538. package/dist/fonts/newsreader-300.woff2 +0 -0
  539. package/dist/fonts/newsreader-400.woff2 +0 -0
  540. package/dist/fonts/newsreader-500.woff2 +0 -0
  541. package/dist/fonts/newsreader-600.woff2 +0 -0
  542. package/dist/fonts.css +96 -0
  543. package/dist/index.d.ts +97 -0
  544. package/dist/index.js +80 -0
  545. package/dist/index.js.map +1 -0
  546. package/dist/keyframes.css +300 -0
  547. package/dist/lib/cn.d.ts +21 -0
  548. package/dist/lib/cn.js +9 -0
  549. package/dist/lib/cn.js.map +1 -0
  550. package/dist/lib/color.d.ts +80 -0
  551. package/dist/lib/color.js +189 -0
  552. package/dist/lib/color.js.map +1 -0
  553. package/dist/lib/control.d.ts +32 -0
  554. package/dist/lib/control.js +14 -0
  555. package/dist/lib/control.js.map +1 -0
  556. package/dist/lib/index.d.ts +4 -0
  557. package/dist/lib/index.js +11 -0
  558. package/dist/lib/index.js.map +1 -0
  559. package/dist/lib/numeric.d.ts +35 -0
  560. package/dist/lib/numeric.js +29 -0
  561. package/dist/lib/numeric.js.map +1 -0
  562. package/dist/lib/overlay-container.d.ts +48 -0
  563. package/dist/lib/overlay-container.js +15 -0
  564. package/dist/lib/overlay-container.js.map +1 -0
  565. package/dist/lib/slot-content.d.ts +8 -0
  566. package/dist/lib/slot-content.js +17 -0
  567. package/dist/lib/slot-content.js.map +1 -0
  568. package/dist/lib/step-rail.d.ts +45 -0
  569. package/dist/lib/step-rail.js +47 -0
  570. package/dist/lib/step-rail.js.map +1 -0
  571. package/dist/lib/svg-export.d.ts +138 -0
  572. package/dist/lib/svg-export.js +198 -0
  573. package/dist/lib/svg-export.js.map +1 -0
  574. package/dist/lib/useClipboardCopy.d.ts +30 -0
  575. package/dist/lib/useClipboardCopy.js +37 -0
  576. package/dist/lib/useClipboardCopy.js.map +1 -0
  577. package/dist/lib/useSelectionIndicator.d.ts +29 -0
  578. package/dist/lib/useSelectionIndicator.js +49 -0
  579. package/dist/lib/useSelectionIndicator.js.map +1 -0
  580. package/dist/lib/warn.d.ts +73 -0
  581. package/dist/lib/warn.js +38 -0
  582. package/dist/lib/warn.js.map +1 -0
  583. package/dist/semantic.css +193 -0
  584. package/dist/styles.css +98 -0
  585. package/dist/themes.css +514 -0
  586. package/dist/tokens/brand.d.ts +47 -0
  587. package/dist/tokens/brand.js +38 -0
  588. package/dist/tokens/brand.js.map +1 -0
  589. package/dist/tokens.css +652 -0
  590. package/dist/tokens.d.ts +198 -0
  591. package/dist/tokens.js +1020 -0
  592. package/dist/tokens.json +1019 -0
  593. package/dist/website/Actions/Actions.d.ts +34 -0
  594. package/dist/website/Actions/Actions.js +29 -0
  595. package/dist/website/Actions/Actions.js.map +1 -0
  596. package/dist/website/Collection/Collection.d.ts +128 -0
  597. package/dist/website/Collection/Collection.js +162 -0
  598. package/dist/website/Collection/Collection.js.map +1 -0
  599. package/dist/website/Contact/Contact.d.ts +87 -0
  600. package/dist/website/Contact/Contact.js +94 -0
  601. package/dist/website/Contact/Contact.js.map +1 -0
  602. package/dist/website/Content/CodePanel.d.ts +27 -0
  603. package/dist/website/Content/CodePanel.js +30 -0
  604. package/dist/website/Content/CodePanel.js.map +1 -0
  605. package/dist/website/Content/Content.d.ts +29 -0
  606. package/dist/website/Content/Content.js +38 -0
  607. package/dist/website/Content/Content.js.map +1 -0
  608. package/dist/website/Conversation/Conversation.d.ts +193 -0
  609. package/dist/website/Conversation/Conversation.js +252 -0
  610. package/dist/website/Conversation/Conversation.js.map +1 -0
  611. package/dist/website/Evidence/Evidence.d.ts +116 -0
  612. package/dist/website/Evidence/Evidence.js +142 -0
  613. package/dist/website/Evidence/Evidence.js.map +1 -0
  614. package/dist/website/Media/Media.d.ts +173 -0
  615. package/dist/website/Media/Media.js +225 -0
  616. package/dist/website/Media/Media.js.map +1 -0
  617. package/dist/website/Media/MediaLightbox.d.ts +18 -0
  618. package/dist/website/Media/MediaLightbox.js +38 -0
  619. package/dist/website/Media/MediaLightbox.js.map +1 -0
  620. package/dist/website/Metrics/Metrics.d.ts +74 -0
  621. package/dist/website/Metrics/Metrics.js +96 -0
  622. package/dist/website/Metrics/Metrics.js.map +1 -0
  623. package/dist/website/Music/Music.d.ts +60 -0
  624. package/dist/website/Music/Music.js +80 -0
  625. package/dist/website/Music/Music.js.map +1 -0
  626. package/dist/website/Portfolio/FrameLayout.d.ts +9 -0
  627. package/dist/website/Portfolio/FrameLayout.js +42 -0
  628. package/dist/website/Portfolio/FrameLayout.js.map +1 -0
  629. package/dist/website/Portfolio/Portfolio.d.ts +49 -0
  630. package/dist/website/Portfolio/Portfolio.js +66 -0
  631. package/dist/website/Portfolio/Portfolio.js.map +1 -0
  632. package/dist/website/Portfolio/QuestionCard.d.ts +22 -0
  633. package/dist/website/Portfolio/QuestionCard.js +33 -0
  634. package/dist/website/Portfolio/QuestionCard.js.map +1 -0
  635. package/dist/website/PortfolioIndex/PortfolioIndex.d.ts +21 -0
  636. package/dist/website/PortfolioIndex/PortfolioIndex.js +31 -0
  637. package/dist/website/PortfolioIndex/PortfolioIndex.js.map +1 -0
  638. package/dist/website/Reading/Reading.d.ts +203 -0
  639. package/dist/website/Reading/Reading.js +357 -0
  640. package/dist/website/Reading/Reading.js.map +1 -0
  641. package/dist/website/Recovery/Recovery.d.ts +39 -0
  642. package/dist/website/Recovery/Recovery.js +96 -0
  643. package/dist/website/Recovery/Recovery.js.map +1 -0
  644. package/dist/website/SearchPalette/SearchPalette.d.ts +59 -0
  645. package/dist/website/SearchPalette/SearchPalette.js +120 -0
  646. package/dist/website/SearchPalette/SearchPalette.js.map +1 -0
  647. package/dist/website/SiteNavigation/SiteNavigation.d.ts +46 -0
  648. package/dist/website/SiteNavigation/SiteNavigation.js +101 -0
  649. package/dist/website/SiteNavigation/SiteNavigation.js.map +1 -0
  650. package/dist/website/SiteShell/SiteShell.d.ts +45 -0
  651. package/dist/website/SiteShell/SiteShell.js +46 -0
  652. package/dist/website/SiteShell/SiteShell.js.map +1 -0
  653. package/dist/website/Timeline/Timeline.d.ts +80 -0
  654. package/dist/website/Timeline/Timeline.js +99 -0
  655. package/dist/website/Timeline/Timeline.js.map +1 -0
  656. package/dist/website/index.d.ts +27 -0
  657. package/dist/website/index.js +21 -0
  658. package/dist/website/index.js.map +1 -0
  659. package/dist/website-actions.css +6 -0
  660. package/dist/website-base.css +46 -0
  661. package/dist/website-collection.css +89 -0
  662. package/dist/website-contact.css +29 -0
  663. package/dist/website-content.css +17 -0
  664. package/dist/website-controls.css +91 -0
  665. package/dist/website-conversation.css +115 -0
  666. package/dist/website-evidence.css +56 -0
  667. package/dist/website-media.css +227 -0
  668. package/dist/website-metrics.css +15 -0
  669. package/dist/website-music.css +27 -0
  670. package/dist/website-portfolio.css +94 -0
  671. package/dist/website-reading.css +159 -0
  672. package/dist/website-recovery.css +28 -0
  673. package/dist/website-search.css +26 -0
  674. package/dist/website-shell.css +89 -0
  675. package/dist/website-timeline.css +43 -0
  676. package/dist/website.css +25 -0
  677. package/llms.txt +35 -0
  678. package/package.json +163 -5
  679. package/skills/folio-design/SKILL.md +228 -0
  680. package/skills/folio-design/evals/claims.json +95 -0
  681. package/skills/folio-design/evals/evals.json +84 -0
  682. package/skills/folio-design/rules/a11y.md +167 -0
  683. package/skills/folio-design/rules/composition.md +108 -0
  684. package/skills/folio-design/rules/forms.md +135 -0
  685. package/skills/folio-design/rules/naming.md +155 -0
  686. package/skills/folio-design/rules/tokens.md +133 -0
@@ -0,0 +1,205 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import * as TabsPrimitive from "@radix-ui/react-tabs";
4
+ import { createContext, useContext, useLayoutEffect, useRef, useState } from "react";
5
+ import { cn } from "../../lib/cn.js";
6
+ const MotionContext = createContext(null);
7
+ function Tabs({ value, defaultValue, onValueChange, swipe = true, orientation = "horizontal", activationMode = "automatic", className, ...rest }) {
8
+ const [internal, setInternal] = useState(defaultValue);
9
+ const current = value ?? internal;
10
+ const change = (next) => {
11
+ if (value === void 0) setInternal(next);
12
+ onValueChange?.(next);
13
+ };
14
+ return /* @__PURE__ */ jsx(MotionContext.Provider, { value: { value: current, change, swipe: swipe && orientation === "horizontal", automatic: activationMode === "automatic" }, children: /* @__PURE__ */ jsx(TabsPrimitive.Root, { ...rest, activationMode, orientation, value: current, onValueChange: change, className: cn("folio-tabs", className) }) });
15
+ }
16
+ function TabsList({ className, ref: forwardedRef, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onClickCapture, ...rest }) {
17
+ const motion = useContext(MotionContext);
18
+ const list = useRef(null);
19
+ const gesture = useRef(null);
20
+ const suppressClick = useRef(false);
21
+ const previousX = useRef(void 0);
22
+ useLayoutEffect(() => {
23
+ const element = list.current;
24
+ if (!element) return;
25
+ const measure = () => {
26
+ const active = element.querySelector("[role=tab][data-state=active]");
27
+ if (!active) return;
28
+ if (previousX.current !== void 0 && previousX.current !== active.offsetLeft) element.closest(".folio-tabs")?.style.setProperty("--tab-enter-x", active.offsetLeft > previousX.current ? "16px" : "-16px");
29
+ previousX.current = active.offsetLeft;
30
+ element.style.setProperty("--tab-x", `${active.offsetLeft}px`);
31
+ element.style.setProperty("--tab-y", `${active.offsetTop}px`);
32
+ element.style.setProperty("--tab-width", `${active.offsetWidth}px`);
33
+ element.style.setProperty("--tab-height", `${active.offsetHeight}px`);
34
+ element.dataset.measured = "true";
35
+ if (element.clientWidth > 0) {
36
+ const viewport = element.getBoundingClientRect();
37
+ const item = active.getBoundingClientRect();
38
+ const delta = item.left < viewport.left ? item.left - viewport.left : item.right > viewport.right ? item.right - viewport.right : 0;
39
+ if (delta) element.scrollBy({ left: delta, behavior: window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ? "instant" : "smooth" });
40
+ }
41
+ };
42
+ measure();
43
+ const observer = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(measure);
44
+ observer?.observe(element);
45
+ element.querySelectorAll("[role=tab]").forEach((tab) => observer?.observe(tab));
46
+ return () => observer?.disconnect();
47
+ }, [motion?.value]);
48
+ const reset = () => {
49
+ gesture.current = null;
50
+ list.current?.style.setProperty("--tab-drag-x", "0px");
51
+ list.current?.removeAttribute("data-dragging");
52
+ };
53
+ return /* @__PURE__ */ jsx(
54
+ TabsPrimitive.List,
55
+ {
56
+ ref: (element) => {
57
+ list.current = element;
58
+ if (typeof forwardedRef === "function") forwardedRef(element);
59
+ else if (forwardedRef) forwardedRef.current = element;
60
+ },
61
+ "data-swipe": motion?.swipe || void 0,
62
+ onPointerDown: (event) => {
63
+ onPointerDown?.(event);
64
+ if (event.defaultPrevented || !motion?.swipe || event.button !== 0 || !event.isPrimary) return;
65
+ suppressClick.current = false;
66
+ gesture.current = { x: event.clientX, y: event.clientY, id: event.pointerId, dragged: false };
67
+ },
68
+ onPointerMove: (event) => {
69
+ onPointerMove?.(event);
70
+ const start = gesture.current;
71
+ if (!start || event.pointerId !== start.id) return;
72
+ const dx = event.clientX - start.x;
73
+ if (Math.abs(event.clientY - start.y) > Math.abs(dx) && !start.dragged) {
74
+ reset();
75
+ return;
76
+ }
77
+ if (Math.abs(dx) > 8) {
78
+ start.dragged = true;
79
+ event.currentTarget.setPointerCapture(event.pointerId);
80
+ event.currentTarget.dataset.dragging = "true";
81
+ event.currentTarget.style.setProperty("--tab-drag-x", `${Math.max(-64, Math.min(64, dx * 0.4))}px`);
82
+ }
83
+ },
84
+ onPointerUp: (event) => {
85
+ onPointerUp?.(event);
86
+ const start = gesture.current;
87
+ if (!start) return;
88
+ const dx = event.clientX - start.x;
89
+ suppressClick.current = start.dragged;
90
+ if (start.dragged && Math.abs(dx) >= 36) {
91
+ const tabs = Array.from(event.currentTarget.querySelectorAll("[role=tab]:not([disabled])"));
92
+ const index = tabs.findIndex((tab) => tab.dataset.state === "active");
93
+ const rtl = getComputedStyle(event.currentTarget).direction === "rtl";
94
+ const next = tabs[index + (dx > 0 !== rtl ? 1 : -1)];
95
+ if (next?.dataset.tabValue) {
96
+ const alreadyFocused = document.activeElement === next;
97
+ next.focus({ preventScroll: true });
98
+ if (!motion?.automatic || alreadyFocused) motion?.change(next.dataset.tabValue);
99
+ }
100
+ }
101
+ reset();
102
+ },
103
+ onPointerCancel: (event) => {
104
+ onPointerCancel?.(event);
105
+ reset();
106
+ },
107
+ onClickCapture: (event) => {
108
+ if (suppressClick.current) {
109
+ event.preventDefault();
110
+ event.stopPropagation();
111
+ suppressClick.current = false;
112
+ } else onClickCapture?.(event);
113
+ },
114
+ className: cn(
115
+ // `overflow-y-hidden` is not decoration. A strip only ever scrolls
116
+ // sideways, but `overflow-x: auto` on its own computes `overflow-y` to
117
+ // `auto` as well — and the active trigger's `-mb-px` rule leaves the
118
+ // content exactly one pixel taller than the box, which is enough for a
119
+ // vertical scrollbar to appear beside a row of tabs that has nothing
120
+ // to scroll.
121
+ "folio-tabs-list flex items-center overflow-x-auto overflow-y-hidden gap-1 border-b border-(--rule-2) scroll-slim",
122
+ className
123
+ ),
124
+ ...rest
125
+ }
126
+ );
127
+ }
128
+ function TabsTrigger({ className, onMouseDown, onClick, ...rest }) {
129
+ const motion = useContext(MotionContext);
130
+ return /* @__PURE__ */ jsx(
131
+ TabsPrimitive.Trigger,
132
+ {
133
+ "data-tab-value": rest.value,
134
+ onMouseDown: (event) => {
135
+ onMouseDown?.(event);
136
+ if (motion?.swipe && !event.defaultPrevented && event.button === 0) event.preventDefault();
137
+ },
138
+ onClick: (event) => {
139
+ onClick?.(event);
140
+ if (motion?.swipe && !event.defaultPrevented) {
141
+ const alreadyFocused = document.activeElement === event.currentTarget;
142
+ event.currentTarget.focus();
143
+ if (!motion.automatic || alreadyFocused) motion.change(rest.value);
144
+ }
145
+ },
146
+ className: cn(
147
+ "-mb-px min-h-(--control-h-md) shrink-0 whitespace-nowrap border-b-2 border-transparent px-3.5 py-2 text-sm text-(--ink-3-aa) transition-colors duration-(--duration-fast) hover:text-(--ink) data-[state=active]:border-(--accent) data-[state=active]:text-(--accent-on-muted)",
148
+ className
149
+ ),
150
+ ...rest
151
+ }
152
+ );
153
+ }
154
+ function TabsContent({ className, onTouchStart, onTouchEnd, onTouchCancel, ...rest }) {
155
+ const motion = useContext(MotionContext);
156
+ const start = useRef(null);
157
+ return /* @__PURE__ */ jsx(
158
+ TabsPrimitive.Content,
159
+ {
160
+ "data-folio-animated": true,
161
+ onTouchStart: (event) => {
162
+ onTouchStart?.(event);
163
+ start.current = null;
164
+ if (!motion?.swipe || event.defaultPrevented || event.touches.length !== 1 || event.target.closest(".folio-tabs") !== event.currentTarget.closest(".folio-tabs") || event.target.closest("a,button,input,textarea,select,pre,code,[contenteditable=true],[data-no-swipe]")) return;
165
+ const touch = event.touches[0];
166
+ if (touch) start.current = { x: touch.clientX, y: touch.clientY };
167
+ },
168
+ onTouchEnd: (event) => {
169
+ onTouchEnd?.(event);
170
+ const origin = start.current;
171
+ start.current = null;
172
+ if (!origin || event.defaultPrevented || !event.changedTouches[0] || window.getSelection()?.toString()) return;
173
+ const dx = event.changedTouches[0].clientX - origin.x;
174
+ const dy = event.changedTouches[0].clientY - origin.y;
175
+ if (Math.abs(dx) < 48 || Math.abs(dx) < Math.abs(dy) * 1.5) return;
176
+ const list = event.currentTarget.closest(".folio-tabs")?.querySelector("[role=tablist]");
177
+ if (!list) return;
178
+ const tabs = Array.from(list.querySelectorAll("[role=tab]:not([disabled])"));
179
+ const index = tabs.findIndex((tab) => tab.dataset.state === "active");
180
+ const rtl = getComputedStyle(list).direction === "rtl";
181
+ const next = tabs[index + (dx < 0 !== rtl ? 1 : -1)];
182
+ if (next?.dataset.tabValue) {
183
+ const alreadyFocused = document.activeElement === next;
184
+ next.focus({ preventScroll: true });
185
+ if (!motion?.automatic || alreadyFocused) motion?.change(next.dataset.tabValue);
186
+ }
187
+ },
188
+ onTouchCancel: (event) => {
189
+ start.current = null;
190
+ onTouchCancel?.(event);
191
+ },
192
+ className: cn("folio-tabs-panel pt-5", className),
193
+ ...rest
194
+ }
195
+ );
196
+ }
197
+ var Tabs_default = Tabs;
198
+ export {
199
+ Tabs,
200
+ TabsContent,
201
+ TabsList,
202
+ TabsTrigger,
203
+ Tabs_default as default
204
+ };
205
+ //# sourceMappingURL=Tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/Tabs/Tabs.tsx"],"sourcesContent":["'use client'\n\nimport * as TabsPrimitive from '@radix-ui/react-tabs'\nimport { createContext, useContext, useLayoutEffect, useRef, useState, type ComponentProps } from 'react'\nimport { cn } from '../../lib/cn'\n\nconst MotionContext = createContext<{ value?: string; change: (value: string) => void; swipe: boolean; automatic: boolean } | null>(null)\n\n/** Accessible tabs with a moving marker and optional horizontal drag gestures. */\nexport function Tabs({ value, defaultValue, onValueChange, swipe = true, orientation = 'horizontal', activationMode = 'automatic', className, ...rest }: ComponentProps<typeof TabsPrimitive.Root> & { swipe?: boolean }) {\n const [internal, setInternal] = useState(defaultValue)\n const current = value ?? internal\n const change = (next: string) => { if (value === undefined) setInternal(next); onValueChange?.(next) }\n return <MotionContext.Provider value={{ value: current, change, swipe: swipe && orientation === 'horizontal', automatic: activationMode === 'automatic' }}><TabsPrimitive.Root {...rest} activationMode={activationMode} orientation={orientation} value={current} onValueChange={change} className={cn('folio-tabs', className)} /></MotionContext.Provider>\n}\n\n/**\n * The tab strip.\n *\n * Scrolls horizontally rather than wrapping. A wrapped second row of tabs moves\n * every tab below it when the strip grows, and the reader loses the one they\n * were about to click.\n *\n * @example\n * <Tabs defaultValue=\"preview\">\n * <TabsList>\n * <TabsTrigger value=\"preview\">Preview</TabsTrigger>\n * <TabsTrigger value=\"code\">Code</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"preview\">…</TabsContent>\n * </Tabs>\n */\nexport function TabsList({ className, ref: forwardedRef, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onClickCapture, ...rest }: ComponentProps<typeof TabsPrimitive.List>) {\n const motion = useContext(MotionContext)\n const list = useRef<HTMLDivElement>(null)\n const gesture = useRef<{ x: number; y: number; id: number; dragged: boolean } | null>(null)\n const suppressClick = useRef(false)\n const previousX = useRef<number | undefined>(undefined)\n useLayoutEffect(() => {\n const element = list.current\n if (!element) return\n const measure = () => {\n const active = element.querySelector<HTMLElement>('[role=tab][data-state=active]')\n if (!active) return\n if (previousX.current !== undefined && previousX.current !== active.offsetLeft) element.closest<HTMLElement>('.folio-tabs')?.style.setProperty('--tab-enter-x', active.offsetLeft > previousX.current ? '16px' : '-16px')\n previousX.current = active.offsetLeft\n element.style.setProperty('--tab-x', `${active.offsetLeft}px`)\n element.style.setProperty('--tab-y', `${active.offsetTop}px`)\n element.style.setProperty('--tab-width', `${active.offsetWidth}px`)\n element.style.setProperty('--tab-height', `${active.offsetHeight}px`)\n element.dataset.measured = 'true'\n if (element.clientWidth > 0) {\n const viewport = element.getBoundingClientRect()\n const item = active.getBoundingClientRect()\n const delta = item.left < viewport.left ? item.left - viewport.left : item.right > viewport.right ? item.right - viewport.right : 0\n if (delta) element.scrollBy({ left: delta, behavior: window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ? 'instant' : 'smooth' })\n }\n }\n measure()\n const observer = typeof ResizeObserver === 'undefined' ? undefined : new ResizeObserver(measure)\n observer?.observe(element)\n element.querySelectorAll('[role=tab]').forEach(tab => observer?.observe(tab))\n return () => observer?.disconnect()\n }, [motion?.value])\n const reset = () => { gesture.current = null; list.current?.style.setProperty('--tab-drag-x', '0px'); list.current?.removeAttribute('data-dragging') }\n return (\n <TabsPrimitive.List\n ref={element => { list.current = element; if (typeof forwardedRef === 'function') forwardedRef(element); else if (forwardedRef) forwardedRef.current = element }}\n data-swipe={motion?.swipe || undefined}\n onPointerDown={event => {\n onPointerDown?.(event)\n if (event.defaultPrevented || !motion?.swipe || event.button !== 0 || !event.isPrimary) return\n suppressClick.current = false\n gesture.current = { x: event.clientX, y: event.clientY, id: event.pointerId, dragged: false }\n }}\n onPointerMove={event => {\n onPointerMove?.(event)\n const start = gesture.current\n if (!start || event.pointerId !== start.id) return\n const dx = event.clientX - start.x\n if (Math.abs(event.clientY - start.y) > Math.abs(dx) && !start.dragged) { reset(); return }\n if (Math.abs(dx) > 8) {\n start.dragged = true\n event.currentTarget.setPointerCapture(event.pointerId)\n event.currentTarget.dataset.dragging = 'true'\n event.currentTarget.style.setProperty('--tab-drag-x', `${Math.max(-64, Math.min(64, dx * .4))}px`)\n }\n }}\n onPointerUp={event => {\n onPointerUp?.(event)\n const start = gesture.current\n if (!start) return\n const dx = event.clientX - start.x\n suppressClick.current = start.dragged\n if (start.dragged && Math.abs(dx) >= 36) {\n const tabs = Array.from(event.currentTarget.querySelectorAll<HTMLElement>('[role=tab]:not([disabled])'))\n const index = tabs.findIndex(tab => tab.dataset.state === 'active')\n const rtl = getComputedStyle(event.currentTarget).direction === 'rtl'\n const next = tabs[index + ((dx > 0) !== rtl ? 1 : -1)]\n if (next?.dataset.tabValue) {\n const alreadyFocused = document.activeElement === next\n next.focus({ preventScroll: true })\n if (!motion?.automatic || alreadyFocused) motion?.change(next.dataset.tabValue)\n }\n }\n reset()\n }}\n onPointerCancel={event => { onPointerCancel?.(event); reset() }}\n onClickCapture={event => { if (suppressClick.current) { event.preventDefault(); event.stopPropagation(); suppressClick.current = false } else onClickCapture?.(event) }}\n className={cn(\n // `overflow-y-hidden` is not decoration. A strip only ever scrolls\n // sideways, but `overflow-x: auto` on its own computes `overflow-y` to\n // `auto` as well — and the active trigger's `-mb-px` rule leaves the\n // content exactly one pixel taller than the box, which is enough for a\n // vertical scrollbar to appear beside a row of tabs that has nothing\n // to scroll.\n 'folio-tabs-list flex items-center overflow-x-auto overflow-y-hidden gap-1 border-b border-(--rule-2) scroll-slim',\n className,\n )}\n {...rest}\n />\n )\n}\n\n/**\n * One tab.\n *\n * The active marker is a 2px ink rule pulled onto the strip's own border with\n * `-mb-px`, so the two occupy the same line instead of stacking into a 3px\n * edge. 44px tall, because a tab is a pointer target like any other.\n */\nexport function TabsTrigger({ className, onMouseDown, onClick, ...rest }: ComponentProps<typeof TabsPrimitive.Trigger>) {\n const motion = useContext(MotionContext)\n return (\n <TabsPrimitive.Trigger\n data-tab-value={rest.value}\n onMouseDown={event => { onMouseDown?.(event); if (motion?.swipe && !event.defaultPrevented && event.button === 0) event.preventDefault() }}\n onClick={event => { onClick?.(event); if (motion?.swipe && !event.defaultPrevented) { const alreadyFocused = document.activeElement === event.currentTarget; event.currentTarget.focus(); if (!motion.automatic || alreadyFocused) motion.change(rest.value) } }}\n className={cn(\n '-mb-px min-h-(--control-h-md) shrink-0 whitespace-nowrap border-b-2 border-transparent px-3.5 py-2 text-sm text-(--ink-3-aa) transition-colors duration-(--duration-fast) hover:text-(--ink) data-[state=active]:border-(--accent) data-[state=active]:text-(--accent-on-muted)',\n className,\n )}\n {...rest}\n />\n )\n}\n\n/** The panel paired to a {@link TabsTrigger} by matching `value`. */\nexport function TabsContent({ className, onTouchStart, onTouchEnd, onTouchCancel, ...rest }: ComponentProps<typeof TabsPrimitive.Content>) {\n const motion = useContext(MotionContext)\n const start = useRef<{ x: number; y: number } | null>(null)\n return (\n <TabsPrimitive.Content\n data-folio-animated\n onTouchStart={event => {\n onTouchStart?.(event)\n start.current = null\n if (!motion?.swipe || event.defaultPrevented || event.touches.length !== 1 || (event.target as HTMLElement).closest('.folio-tabs') !== event.currentTarget.closest('.folio-tabs') || (event.target as HTMLElement).closest('a,button,input,textarea,select,pre,code,[contenteditable=true],[data-no-swipe]')) return\n const touch = event.touches[0]\n if (touch) start.current = { x: touch.clientX, y: touch.clientY }\n }}\n onTouchEnd={event => {\n onTouchEnd?.(event)\n const origin = start.current\n start.current = null\n if (!origin || event.defaultPrevented || !event.changedTouches[0] || window.getSelection()?.toString()) return\n const dx = event.changedTouches[0].clientX - origin.x\n const dy = event.changedTouches[0].clientY - origin.y\n if (Math.abs(dx) < 48 || Math.abs(dx) < Math.abs(dy) * 1.5) return\n const list = event.currentTarget.closest('.folio-tabs')?.querySelector('[role=tablist]')\n if (!list) return\n const tabs = Array.from(list.querySelectorAll<HTMLElement>('[role=tab]:not([disabled])'))\n const index = tabs.findIndex(tab => tab.dataset.state === 'active')\n const rtl = getComputedStyle(list).direction === 'rtl'\n const next = tabs[index + ((dx < 0) !== rtl ? 1 : -1)]\n if (next?.dataset.tabValue) {\n const alreadyFocused = document.activeElement === next\n next.focus({ preventScroll: true })\n if (!motion?.automatic || alreadyFocused) motion?.change(next.dataset.tabValue)\n }\n }}\n onTouchCancel={event => { start.current = null; onTouchCancel?.(event) }}\n className={cn('folio-tabs-panel pt-5', className)}\n {...rest}\n />\n )\n}\n\nexport default Tabs\n"],"mappings":";AAa6J;AAX7J,YAAY,mBAAmB;AAC/B,SAAS,eAAe,YAAY,iBAAiB,QAAQ,gBAAqC;AAClG,SAAS,UAAU;AAEnB,MAAM,gBAAgB,cAA8G,IAAI;AAGjI,SAAS,KAAK,EAAE,OAAO,cAAc,eAAe,QAAQ,MAAM,cAAc,cAAc,iBAAiB,aAAa,WAAW,GAAG,KAAK,GAAoE;AACxN,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,YAAY;AACrD,QAAM,UAAU,SAAS;AACzB,QAAM,SAAS,CAAC,SAAiB;AAAE,QAAI,UAAU,OAAW,aAAY,IAAI;AAAG,oBAAgB,IAAI;AAAA,EAAE;AACrG,SAAO,oBAAC,cAAc,UAAd,EAAuB,OAAO,EAAE,OAAO,SAAS,QAAQ,OAAO,SAAS,gBAAgB,cAAc,WAAW,mBAAmB,YAAY,GAAG,8BAAC,cAAc,MAAd,EAAoB,GAAG,MAAM,gBAAgC,aAA0B,OAAO,SAAS,eAAe,QAAQ,WAAW,GAAG,cAAc,SAAS,GAAG,GAAE;AACtU;AAkBO,SAAS,SAAS,EAAE,WAAW,KAAK,cAAc,eAAe,eAAe,aAAa,iBAAiB,gBAAgB,GAAG,KAAK,GAA8C;AACzL,QAAM,SAAS,WAAW,aAAa;AACvC,QAAM,OAAO,OAAuB,IAAI;AACxC,QAAM,UAAU,OAAsE,IAAI;AAC1F,QAAM,gBAAgB,OAAO,KAAK;AAClC,QAAM,YAAY,OAA2B,MAAS;AACtD,kBAAgB,MAAM;AACpB,UAAM,UAAU,KAAK;AACrB,QAAI,CAAC,QAAS;AACd,UAAM,UAAU,MAAM;AACpB,YAAM,SAAS,QAAQ,cAA2B,+BAA+B;AACjF,UAAI,CAAC,OAAQ;AACb,UAAI,UAAU,YAAY,UAAa,UAAU,YAAY,OAAO,WAAY,SAAQ,QAAqB,aAAa,GAAG,MAAM,YAAY,iBAAiB,OAAO,aAAa,UAAU,UAAU,SAAS,OAAO;AACxN,gBAAU,UAAU,OAAO;AAC3B,cAAQ,MAAM,YAAY,WAAW,GAAG,OAAO,UAAU,IAAI;AAC7D,cAAQ,MAAM,YAAY,WAAW,GAAG,OAAO,SAAS,IAAI;AAC5D,cAAQ,MAAM,YAAY,eAAe,GAAG,OAAO,WAAW,IAAI;AAClE,cAAQ,MAAM,YAAY,gBAAgB,GAAG,OAAO,YAAY,IAAI;AACpE,cAAQ,QAAQ,WAAW;AAC3B,UAAI,QAAQ,cAAc,GAAG;AAC3B,cAAM,WAAW,QAAQ,sBAAsB;AAC/C,cAAM,OAAO,OAAO,sBAAsB;AAC1C,cAAM,QAAQ,KAAK,OAAO,SAAS,OAAO,KAAK,OAAO,SAAS,OAAO,KAAK,QAAQ,SAAS,QAAQ,KAAK,QAAQ,SAAS,QAAQ;AAClI,YAAI,MAAO,SAAQ,SAAS,EAAE,MAAM,OAAO,UAAU,OAAO,aAAa,kCAAkC,EAAE,UAAU,YAAY,SAAS,CAAC;AAAA,MAC/I;AAAA,IACF;AACA,YAAQ;AACR,UAAM,WAAW,OAAO,mBAAmB,cAAc,SAAY,IAAI,eAAe,OAAO;AAC/F,cAAU,QAAQ,OAAO;AACzB,YAAQ,iBAAiB,YAAY,EAAE,QAAQ,SAAO,UAAU,QAAQ,GAAG,CAAC;AAC5E,WAAO,MAAM,UAAU,WAAW;AAAA,EACpC,GAAG,CAAC,QAAQ,KAAK,CAAC;AAClB,QAAM,QAAQ,MAAM;AAAE,YAAQ,UAAU;AAAM,SAAK,SAAS,MAAM,YAAY,gBAAgB,KAAK;AAAG,SAAK,SAAS,gBAAgB,eAAe;AAAA,EAAE;AACrJ,SACE;AAAA,IAAC,cAAc;AAAA,IAAd;AAAA,MACC,KAAK,aAAW;AAAE,aAAK,UAAU;AAAS,YAAI,OAAO,iBAAiB,WAAY,cAAa,OAAO;AAAA,iBAAY,aAAc,cAAa,UAAU;AAAA,MAAQ;AAAA,MAC/J,cAAY,QAAQ,SAAS;AAAA,MAC7B,eAAe,WAAS;AACtB,wBAAgB,KAAK;AACrB,YAAI,MAAM,oBAAoB,CAAC,QAAQ,SAAS,MAAM,WAAW,KAAK,CAAC,MAAM,UAAW;AACxF,sBAAc,UAAU;AACxB,gBAAQ,UAAU,EAAE,GAAG,MAAM,SAAS,GAAG,MAAM,SAAS,IAAI,MAAM,WAAW,SAAS,MAAM;AAAA,MAC9F;AAAA,MACA,eAAe,WAAS;AACtB,wBAAgB,KAAK;AACrB,cAAM,QAAQ,QAAQ;AACtB,YAAI,CAAC,SAAS,MAAM,cAAc,MAAM,GAAI;AAC5C,cAAM,KAAK,MAAM,UAAU,MAAM;AACjC,YAAI,KAAK,IAAI,MAAM,UAAU,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,KAAK,CAAC,MAAM,SAAS;AAAE,gBAAM;AAAG;AAAA,QAAO;AAC1F,YAAI,KAAK,IAAI,EAAE,IAAI,GAAG;AACpB,gBAAM,UAAU;AAChB,gBAAM,cAAc,kBAAkB,MAAM,SAAS;AACrD,gBAAM,cAAc,QAAQ,WAAW;AACvC,gBAAM,cAAc,MAAM,YAAY,gBAAgB,GAAG,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,GAAE,CAAC,CAAC,IAAI;AAAA,QACnG;AAAA,MACF;AAAA,MACA,aAAa,WAAS;AACpB,sBAAc,KAAK;AACnB,cAAM,QAAQ,QAAQ;AACtB,YAAI,CAAC,MAAO;AACZ,cAAM,KAAK,MAAM,UAAU,MAAM;AACjC,sBAAc,UAAU,MAAM;AAC9B,YAAI,MAAM,WAAW,KAAK,IAAI,EAAE,KAAK,IAAI;AACvC,gBAAM,OAAO,MAAM,KAAK,MAAM,cAAc,iBAA8B,4BAA4B,CAAC;AACvG,gBAAM,QAAQ,KAAK,UAAU,SAAO,IAAI,QAAQ,UAAU,QAAQ;AAClE,gBAAM,MAAM,iBAAiB,MAAM,aAAa,EAAE,cAAc;AAChE,gBAAM,OAAO,KAAK,SAAU,KAAK,MAAO,MAAM,IAAI,GAAG;AACrD,cAAI,MAAM,QAAQ,UAAU;AAC1B,kBAAM,iBAAiB,SAAS,kBAAkB;AAClD,iBAAK,MAAM,EAAE,eAAe,KAAK,CAAC;AAClC,gBAAI,CAAC,QAAQ,aAAa,eAAgB,SAAQ,OAAO,KAAK,QAAQ,QAAQ;AAAA,UAChF;AAAA,QACF;AACA,cAAM;AAAA,MACR;AAAA,MACA,iBAAiB,WAAS;AAAE,0BAAkB,KAAK;AAAG,cAAM;AAAA,MAAE;AAAA,MAC9D,gBAAgB,WAAS;AAAE,YAAI,cAAc,SAAS;AAAE,gBAAM,eAAe;AAAG,gBAAM,gBAAgB;AAAG,wBAAc,UAAU;AAAA,QAAM,MAAO,kBAAiB,KAAK;AAAA,MAAE;AAAA,MACtK,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AASO,SAAS,YAAY,EAAE,WAAW,aAAa,SAAS,GAAG,KAAK,GAAiD;AACtH,QAAM,SAAS,WAAW,aAAa;AACvC,SACE;AAAA,IAAC,cAAc;AAAA,IAAd;AAAA,MACC,kBAAgB,KAAK;AAAA,MACrB,aAAa,WAAS;AAAE,sBAAc,KAAK;AAAG,YAAI,QAAQ,SAAS,CAAC,MAAM,oBAAoB,MAAM,WAAW,EAAG,OAAM,eAAe;AAAA,MAAE;AAAA,MACzI,SAAS,WAAS;AAAE,kBAAU,KAAK;AAAG,YAAI,QAAQ,SAAS,CAAC,MAAM,kBAAkB;AAAE,gBAAM,iBAAiB,SAAS,kBAAkB,MAAM;AAAe,gBAAM,cAAc,MAAM;AAAG,cAAI,CAAC,OAAO,aAAa,eAAgB,QAAO,OAAO,KAAK,KAAK;AAAA,QAAE;AAAA,MAAE;AAAA,MAC/P,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAGO,SAAS,YAAY,EAAE,WAAW,cAAc,YAAY,eAAe,GAAG,KAAK,GAAiD;AACzI,QAAM,SAAS,WAAW,aAAa;AACvC,QAAM,QAAQ,OAAwC,IAAI;AAC1D,SACE;AAAA,IAAC,cAAc;AAAA,IAAd;AAAA,MACC,uBAAmB;AAAA,MACnB,cAAc,WAAS;AACrB,uBAAe,KAAK;AACpB,cAAM,UAAU;AAChB,YAAI,CAAC,QAAQ,SAAS,MAAM,oBAAoB,MAAM,QAAQ,WAAW,KAAM,MAAM,OAAuB,QAAQ,aAAa,MAAM,MAAM,cAAc,QAAQ,aAAa,KAAM,MAAM,OAAuB,QAAQ,gFAAgF,EAAG;AAC9S,cAAM,QAAQ,MAAM,QAAQ,CAAC;AAC7B,YAAI,MAAO,OAAM,UAAU,EAAE,GAAG,MAAM,SAAS,GAAG,MAAM,QAAQ;AAAA,MAClE;AAAA,MACA,YAAY,WAAS;AACnB,qBAAa,KAAK;AAClB,cAAM,SAAS,MAAM;AACrB,cAAM,UAAU;AAChB,YAAI,CAAC,UAAU,MAAM,oBAAoB,CAAC,MAAM,eAAe,CAAC,KAAK,OAAO,aAAa,GAAG,SAAS,EAAG;AACxG,cAAM,KAAK,MAAM,eAAe,CAAC,EAAE,UAAU,OAAO;AACpD,cAAM,KAAK,MAAM,eAAe,CAAC,EAAE,UAAU,OAAO;AACpD,YAAI,KAAK,IAAI,EAAE,IAAI,MAAM,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,IAAK;AAC5D,cAAM,OAAO,MAAM,cAAc,QAAQ,aAAa,GAAG,cAAc,gBAAgB;AACvF,YAAI,CAAC,KAAM;AACX,cAAM,OAAO,MAAM,KAAK,KAAK,iBAA8B,4BAA4B,CAAC;AACxF,cAAM,QAAQ,KAAK,UAAU,SAAO,IAAI,QAAQ,UAAU,QAAQ;AAClE,cAAM,MAAM,iBAAiB,IAAI,EAAE,cAAc;AACjD,cAAM,OAAO,KAAK,SAAU,KAAK,MAAO,MAAM,IAAI,GAAG;AACrD,YAAI,MAAM,QAAQ,UAAU;AAC1B,gBAAM,iBAAiB,SAAS,kBAAkB;AAClD,eAAK,MAAM,EAAE,eAAe,KAAK,CAAC;AAClC,cAAI,CAAC,QAAQ,aAAa,eAAgB,SAAQ,OAAO,KAAK,QAAQ,QAAQ;AAAA,QAChF;AAAA,MACF;AAAA,MACA,eAAe,WAAS;AAAE,cAAM,UAAU;AAAM,wBAAgB,KAAK;AAAA,MAAE;AAAA,MACvE,WAAW,GAAG,yBAAyB,SAAS;AAAA,MAC/C,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,IAAO,eAAQ;","names":[]}
@@ -0,0 +1,87 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ interface TagBase extends Omit<HTMLAttributes<HTMLElement>, 'onClick'> {
5
+ children: ReactNode;
6
+ /**
7
+ * Renders the pressed/selected look, and declares the chip a toggle.
8
+ *
9
+ * An interactive chip reads `aria-pressed` off this same value, so the accent
10
+ * fill and the state a screen reader hears cannot drift apart. Leave it off
11
+ * for a chip whose `onClick` navigates or opens something: a control that is
12
+ * neither pressed nor unpressed is better announced as neither than as
13
+ * "not pressed".
14
+ */
15
+ active?: boolean;
16
+ /**
17
+ * Makes the chip ITSELF the filter control.
18
+ *
19
+ * This prop exists because the alternative did not survive contact with
20
+ * `onRemove`. The advice used to be to wrap the tag in a button at the call
21
+ * site, which is fine on its own and invalid the moment the chip is also
22
+ * removable: the remove control is a real `<button>`, so the wrapper puts a
23
+ * button inside a button — markup the parser splits into siblings, leaving a
24
+ * DOM neither the author nor the accessibility tree expects.
25
+ *
26
+ * With this the wrapper is never written. The chip carries the click, the
27
+ * focus ring and the pressed state on the element that draws them, and a
28
+ * removable filter chip renders its two controls side by side instead of one
29
+ * inside the other.
30
+ */
31
+ onClick?: () => void;
32
+ }
33
+ /**
34
+ * The removable form: a chip for one thing the reader has already chosen.
35
+ *
36
+ * `removeLabel` is required alongside `onRemove` and not optional with a
37
+ * default, because "Remove" repeated down a row of filters is eight controls a
38
+ * screen reader cannot tell apart. Write the subject into it — "Remove
39
+ * TypeScript filter".
40
+ */
41
+ interface TagRemovable {
42
+ /** Called when the reader dismisses the chip. */
43
+ onRemove: () => void;
44
+ /** The remove button's accessible name. Name the subject, not the action. */
45
+ removeLabel: string;
46
+ }
47
+ interface TagStatic {
48
+ onRemove?: never;
49
+ removeLabel?: never;
50
+ }
51
+ type TagProps = TagBase & (TagRemovable | TagStatic);
52
+ /**
53
+ * A subject label — a topic, a technology, a filter facet — that can filter
54
+ * with `onClick` and be dismissed with `onRemove`.
55
+ *
56
+ * Distinct from `Badge`, which carries a state or a count. A tag names what
57
+ * something is ABOUT, so several sit together in a row and the reader scans
58
+ * them; a badge is one fact about one record.
59
+ *
60
+ * This is where a `Token` component would have gone. It was not built: a token
61
+ * is a tag with a remove button, and the difference between the two is one
62
+ * prop, not one component. The system already ships three things that look
63
+ * alike — `Badge`, `Tag`, `StatusPill` — and a fourth whose whole distinction
64
+ * is an X on the end would be the one a call site picks by coin toss.
65
+ *
66
+ * Presentational until it is given a handler, and the component owns both
67
+ * interactive cases rather than leaving one to a wrapper at the call site.
68
+ * That is not a convenience: a wrapping `<button>` around a chip that already
69
+ * holds the remove `<button>` is a button inside a button, which no parser
70
+ * keeps and no accessibility tree reports the way it was written. Given both,
71
+ * the chip renders the label and the X as SIBLING buttons — the label takes
72
+ * the leading padding with it, so it is the whole of the chip up to the X
73
+ * rather than the words with dead padding around them.
74
+ *
75
+ * @example
76
+ * <Tag>TypeScript</Tag>
77
+ * @example
78
+ * <Tag active={on} onClick={toggle}>Rust</Tag>
79
+ * @example
80
+ * <Tag onRemove={() => drop('rust')} removeLabel="Remove Rust filter">Rust</Tag>
81
+ * @example
82
+ * // Both: a filter the reader can toggle and also take out of the row.
83
+ * <Tag active={on} onClick={toggle} onRemove={drop} removeLabel="Remove Rust filter">Rust</Tag>
84
+ */
85
+ declare function Tag({ children, active, onClick, onRemove, removeLabel, className, ...rest }: TagProps): react.JSX.Element;
86
+
87
+ export { Tag, type TagProps, Tag as default };
@@ -0,0 +1,62 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { RiCloseLine } from "@remixicon/react";
3
+ import { cn } from "../../lib/cn.js";
4
+ function Tag({ children, active, onClick, onRemove, removeLabel, className, ...rest }) {
5
+ const split = Boolean(onClick && onRemove);
6
+ const chip = cn(
7
+ "inline-flex items-center rounded-(--radius-sm) font-mono text-xs tracking-wide transition-colors duration-(--duration-fast)",
8
+ active ? "bg-(--accent) text-(--accent-foreground)" : "bg-(--stone) text-(--ink-3-aa)",
9
+ onRemove ? "gap-1 pe-1.5" : "pe-2.5",
10
+ // Handed to the label button in the split form, so the padding is part of
11
+ // the target rather than a ring of dead space around it.
12
+ !split && "py-1 ps-2.5",
13
+ className
14
+ );
15
+ const remove = onRemove ? /* @__PURE__ */ jsx(
16
+ "button",
17
+ {
18
+ type: "button",
19
+ onClick: onRemove,
20
+ "aria-label": removeLabel,
21
+ className: cn(
22
+ // The drawn box is 16px, which is under the 24px minimum a pointer
23
+ // target has to clear (WCAG 2.5.8). The inset pseudo-element takes
24
+ // the hit area out to 24 without changing what is drawn or pushing
25
+ // the chips apart — the 44px floor is for a standalone control, and
26
+ // a chip is 24 tall to begin with.
27
+ "relative inline-flex size-4 shrink-0 items-center justify-center rounded-(--radius-xs)",
28
+ "before:absolute before:inset-[-4px] before:content-['']",
29
+ "opacity-60 transition-opacity duration-(--duration-fast) hover:opacity-100 focus-visible:opacity-100"
30
+ ),
31
+ children: /* @__PURE__ */ jsx(RiCloseLine, { size: 12, "aria-hidden": true })
32
+ }
33
+ ) : null;
34
+ if (split) {
35
+ return /* @__PURE__ */ jsxs("span", { className: chip, ...rest, children: [
36
+ /* @__PURE__ */ jsx(
37
+ "button",
38
+ {
39
+ type: "button",
40
+ onClick,
41
+ "aria-pressed": active,
42
+ className: "rounded-(--radius-sm) py-1 ps-2.5 font-mono text-xs tracking-wide",
43
+ children
44
+ }
45
+ ),
46
+ remove
47
+ ] });
48
+ }
49
+ if (onClick) {
50
+ return /* @__PURE__ */ jsx("button", { type: "button", onClick, "aria-pressed": active, className: chip, ...rest, children });
51
+ }
52
+ return /* @__PURE__ */ jsxs("span", { className: chip, ...rest, children: [
53
+ children,
54
+ remove
55
+ ] });
56
+ }
57
+ var Tag_default = Tag;
58
+ export {
59
+ Tag,
60
+ Tag_default as default
61
+ };
62
+ //# sourceMappingURL=Tag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/Tag/Tag.tsx"],"sourcesContent":["import { RiCloseLine } from '@remixicon/react'\nimport type { HTMLAttributes, ReactNode } from 'react'\nimport { cn } from '../../lib/cn'\n\ninterface TagBase extends Omit<HTMLAttributes<HTMLElement>, 'onClick'> {\n children: ReactNode\n /**\n * Renders the pressed/selected look, and declares the chip a toggle.\n *\n * An interactive chip reads `aria-pressed` off this same value, so the accent\n * fill and the state a screen reader hears cannot drift apart. Leave it off\n * for a chip whose `onClick` navigates or opens something: a control that is\n * neither pressed nor unpressed is better announced as neither than as\n * \"not pressed\".\n */\n active?: boolean\n /**\n * Makes the chip ITSELF the filter control.\n *\n * This prop exists because the alternative did not survive contact with\n * `onRemove`. The advice used to be to wrap the tag in a button at the call\n * site, which is fine on its own and invalid the moment the chip is also\n * removable: the remove control is a real `<button>`, so the wrapper puts a\n * button inside a button — markup the parser splits into siblings, leaving a\n * DOM neither the author nor the accessibility tree expects.\n *\n * With this the wrapper is never written. The chip carries the click, the\n * focus ring and the pressed state on the element that draws them, and a\n * removable filter chip renders its two controls side by side instead of one\n * inside the other.\n */\n onClick?: () => void\n}\n\n/**\n * The removable form: a chip for one thing the reader has already chosen.\n *\n * `removeLabel` is required alongside `onRemove` and not optional with a\n * default, because \"Remove\" repeated down a row of filters is eight controls a\n * screen reader cannot tell apart. Write the subject into it — \"Remove\n * TypeScript filter\".\n */\ninterface TagRemovable {\n /** Called when the reader dismisses the chip. */\n onRemove: () => void\n /** The remove button's accessible name. Name the subject, not the action. */\n removeLabel: string\n}\n\ninterface TagStatic {\n onRemove?: never\n removeLabel?: never\n}\n\nexport type TagProps = TagBase & (TagRemovable | TagStatic)\n\n/**\n * A subject label — a topic, a technology, a filter facet — that can filter\n * with `onClick` and be dismissed with `onRemove`.\n *\n * Distinct from `Badge`, which carries a state or a count. A tag names what\n * something is ABOUT, so several sit together in a row and the reader scans\n * them; a badge is one fact about one record.\n *\n * This is where a `Token` component would have gone. It was not built: a token\n * is a tag with a remove button, and the difference between the two is one\n * prop, not one component. The system already ships three things that look\n * alike — `Badge`, `Tag`, `StatusPill` — and a fourth whose whole distinction\n * is an X on the end would be the one a call site picks by coin toss.\n *\n * Presentational until it is given a handler, and the component owns both\n * interactive cases rather than leaving one to a wrapper at the call site.\n * That is not a convenience: a wrapping `<button>` around a chip that already\n * holds the remove `<button>` is a button inside a button, which no parser\n * keeps and no accessibility tree reports the way it was written. Given both,\n * the chip renders the label and the X as SIBLING buttons — the label takes\n * the leading padding with it, so it is the whole of the chip up to the X\n * rather than the words with dead padding around them.\n *\n * @example\n * <Tag>TypeScript</Tag>\n * @example\n * <Tag active={on} onClick={toggle}>Rust</Tag>\n * @example\n * <Tag onRemove={() => drop('rust')} removeLabel=\"Remove Rust filter\">Rust</Tag>\n * @example\n * // Both: a filter the reader can toggle and also take out of the row.\n * <Tag active={on} onClick={toggle} onRemove={drop} removeLabel=\"Remove Rust filter\">Rust</Tag>\n */\nexport function Tag({ children, active, onClick, onRemove, removeLabel, className, ...rest }: TagProps) {\n // Two controls cannot nest, so a chip that is both a filter and a selection\n // splits its label out into a button of its own beside the remove button.\n const split = Boolean(onClick && onRemove)\n\n const chip = cn(\n 'inline-flex items-center rounded-(--radius-sm) font-mono text-xs tracking-wide transition-colors duration-(--duration-fast)',\n active ? 'bg-(--accent) text-(--accent-foreground)' : 'bg-(--stone) text-(--ink-3-aa)',\n onRemove ? 'gap-1 pe-1.5' : 'pe-2.5',\n // Handed to the label button in the split form, so the padding is part of\n // the target rather than a ring of dead space around it.\n !split && 'py-1 ps-2.5',\n className,\n )\n\n const remove = onRemove ? (\n <button\n type=\"button\"\n onClick={onRemove}\n aria-label={removeLabel}\n className={cn(\n // The drawn box is 16px, which is under the 24px minimum a pointer\n // target has to clear (WCAG 2.5.8). The inset pseudo-element takes\n // the hit area out to 24 without changing what is drawn or pushing\n // the chips apart — the 44px floor is for a standalone control, and\n // a chip is 24 tall to begin with.\n 'relative inline-flex size-4 shrink-0 items-center justify-center rounded-(--radius-xs)',\n \"before:absolute before:inset-[-4px] before:content-['']\",\n 'opacity-60 transition-opacity duration-(--duration-fast) hover:opacity-100 focus-visible:opacity-100',\n )}\n >\n <RiCloseLine size={12} aria-hidden />\n </button>\n ) : null\n\n if (split) {\n return (\n <span className={chip} {...rest}>\n <button\n type=\"button\"\n onClick={onClick}\n aria-pressed={active}\n className=\"rounded-(--radius-sm) py-1 ps-2.5 font-mono text-xs tracking-wide\"\n >\n {children}\n </button>\n {remove}\n </span>\n )\n }\n\n if (onClick) {\n return (\n <button type=\"button\" onClick={onClick} aria-pressed={active} className={chip} {...rest}>\n {children}\n </button>\n )\n }\n\n return (\n <span className={chip} {...rest}>\n {children}\n {remove}\n </span>\n )\n}\n\nexport default Tag\n"],"mappings":"AAwHM,cAMA,YANA;AAxHN,SAAS,mBAAmB;AAE5B,SAAS,UAAU;AAuFZ,SAAS,IAAI,EAAE,UAAU,QAAQ,SAAS,UAAU,aAAa,WAAW,GAAG,KAAK,GAAa;AAGtG,QAAM,QAAQ,QAAQ,WAAW,QAAQ;AAEzC,QAAM,OAAO;AAAA,IACX;AAAA,IACA,SAAS,6CAA6C;AAAA,IACtD,WAAW,iBAAiB;AAAA;AAAA;AAAA,IAG5B,CAAC,SAAS;AAAA,IACV;AAAA,EACF;AAEA,QAAM,SAAS,WACb;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,cAAY;AAAA,MACZ,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEA,8BAAC,eAAY,MAAM,IAAI,eAAW,MAAC;AAAA;AAAA,EACrC,IACE;AAEJ,MAAI,OAAO;AACT,WACE,qBAAC,UAAK,WAAW,MAAO,GAAG,MACzB;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL;AAAA,UACA,gBAAc;AAAA,UACd,WAAU;AAAA,UAET;AAAA;AAAA,MACH;AAAA,MACC;AAAA,OACH;AAAA,EAEJ;AAEA,MAAI,SAAS;AACX,WACE,oBAAC,YAAO,MAAK,UAAS,SAAkB,gBAAc,QAAQ,WAAW,MAAO,GAAG,MAChF,UACH;AAAA,EAEJ;AAEA,SACE,qBAAC,UAAK,WAAW,MAAO,GAAG,MACxB;AAAA;AAAA,IACA;AAAA,KACH;AAEJ;AAEA,IAAO,cAAQ;","names":[]}
@@ -0,0 +1,62 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ /**
5
+ * A rung of the type scale, named for what it is FOR rather than for a pixel
6
+ * value. `base` is body copy; `lead` is the standfirst that carries a piece and
7
+ * is the only step here that touches the heading ladder (`--fs-item`, its
8
+ * bottom rung). Nothing above that: a paragraph larger than a record title is a
9
+ * heading that forgot to be one.
10
+ */
11
+ type TextSize = 'xs' | 'sm' | 'base' | 'lead';
12
+ /**
13
+ * A rung of the ink ladder. Three, because the ladder has three.
14
+ *
15
+ * `muted` is `--ink-3-aa` and never `--ink-3`. The two look identical on paper
16
+ * and are not the same token: `--ink-3` is a translucent tint that inherits
17
+ * whatever is under it, so it clears AA on the page ground and quietly fails on
18
+ * a card, a plate, or a code block.
19
+ */
20
+ type TextTone = 'body' | 'strong' | 'muted';
21
+ type TextElement = 'p' | 'span' | 'div' | 'li' | 'figcaption';
22
+ interface TextProps extends HTMLAttributes<HTMLElement> {
23
+ children?: ReactNode;
24
+ /** Which rung of the type scale. See {@link TextSize}. */
25
+ size?: TextSize;
26
+ /** Which rung of the ink ladder. See {@link TextTone}. */
27
+ tone?: TextTone;
28
+ /**
29
+ * The element, and ONLY the element.
30
+ *
31
+ * Changing it changes what the markup means — a `span` inside a sentence, an
32
+ * `li` inside a list someone else opened — and changes nothing about the
33
+ * look. That separation is the whole point: the alternative is a `<p>` nested
34
+ * inside a `<p>`, which the HTML parser silently splits into two, or a
35
+ * paragraph faked out of a `<div>` because the real element brought a size
36
+ * with it.
37
+ */
38
+ as?: TextElement;
39
+ }
40
+ /**
41
+ * A paragraph, or a run of text that wants the system's voice.
42
+ *
43
+ * The step between `Article` and raw JSX. `Article` styles a whole reading
44
+ * column from element selectors and is the right answer for a post; this is for
45
+ * the single paragraph that is NOT in a column — a card's description, a
46
+ * dialog's explanation, the line under an empty state.
47
+ *
48
+ * The default tone is `body` (`--ink-2`), not `--ink`. A page whose paragraphs
49
+ * are all full-strength ink has spent the top of the ladder on its body copy
50
+ * and has nothing left for the headings, which is the single most common way a
51
+ * monochrome page loses its hierarchy.
52
+ *
53
+ * @example
54
+ * <Text>Twelve releases this quarter, none rolled back.</Text>
55
+ * @example
56
+ * <Text size="lead" tone="strong">A monochrome system for software and writing.</Text>
57
+ * @example
58
+ * <Text as="span" size="sm" tone="muted">Updated just now</Text>
59
+ */
60
+ declare function Text({ children, size, tone, as, className, ...rest }: TextProps): react.JSX.Element;
61
+
62
+ export { Text, type TextElement, type TextProps, type TextSize, type TextTone, Text as default };
@@ -0,0 +1,30 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { cn } from "../../lib/cn.js";
3
+ const SIZE = {
4
+ xs: "text-xs leading-[1.6]",
5
+ sm: "text-sm leading-[1.65]",
6
+ base: "text-base font-light leading-[1.75]",
7
+ lead: "text-[length:var(--fs-item)] font-light leading-[1.6]"
8
+ };
9
+ const TONE = {
10
+ body: "text-(--ink-2)",
11
+ strong: "text-(--ink)",
12
+ muted: "text-(--ink-3-aa)"
13
+ };
14
+ function Text({
15
+ children,
16
+ size = "base",
17
+ tone = "body",
18
+ as = "p",
19
+ className,
20
+ ...rest
21
+ }) {
22
+ const Comp = as;
23
+ return /* @__PURE__ */ jsx(Comp, { className: cn("m-0", SIZE[size], TONE[tone], className), ...rest, children });
24
+ }
25
+ var Text_default = Text;
26
+ export {
27
+ Text,
28
+ Text_default as default
29
+ };
30
+ //# sourceMappingURL=Text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/Text/Text.tsx"],"sourcesContent":["import type { ElementType, HTMLAttributes, ReactNode } from 'react'\nimport { cn } from '../../lib/cn'\n\n/**\n * A rung of the type scale, named for what it is FOR rather than for a pixel\n * value. `base` is body copy; `lead` is the standfirst that carries a piece and\n * is the only step here that touches the heading ladder (`--fs-item`, its\n * bottom rung). Nothing above that: a paragraph larger than a record title is a\n * heading that forgot to be one.\n */\nexport type TextSize = 'xs' | 'sm' | 'base' | 'lead'\n\n/**\n * A rung of the ink ladder. Three, because the ladder has three.\n *\n * `muted` is `--ink-3-aa` and never `--ink-3`. The two look identical on paper\n * and are not the same token: `--ink-3` is a translucent tint that inherits\n * whatever is under it, so it clears AA on the page ground and quietly fails on\n * a card, a plate, or a code block.\n */\nexport type TextTone = 'body' | 'strong' | 'muted'\n\nexport type TextElement = 'p' | 'span' | 'div' | 'li' | 'figcaption'\n\n/**\n * Weight travels with the size, deliberately.\n *\n * The system sets long-form copy at 300 — it is what gives a page of prose its\n * air. At 12 and 14px that same weight is a hairline: the strokes thin out\n * below the point where a light face is a choice and turn into a legibility\n * bug. So the two small steps step back up to 400, and a caller never has to\n * know that the trade exists.\n */\nconst SIZE: Record<TextSize, string> = {\n xs: 'text-xs leading-[1.6]',\n sm: 'text-sm leading-[1.65]',\n base: 'text-base font-light leading-[1.75]',\n lead: 'text-[length:var(--fs-item)] font-light leading-[1.6]',\n}\n\nconst TONE: Record<TextTone, string> = {\n body: 'text-(--ink-2)',\n strong: 'text-(--ink)',\n muted: 'text-(--ink-3-aa)',\n}\n\nexport interface TextProps extends HTMLAttributes<HTMLElement> {\n children?: ReactNode\n /** Which rung of the type scale. See {@link TextSize}. */\n size?: TextSize\n /** Which rung of the ink ladder. See {@link TextTone}. */\n tone?: TextTone\n /**\n * The element, and ONLY the element.\n *\n * Changing it changes what the markup means — a `span` inside a sentence, an\n * `li` inside a list someone else opened — and changes nothing about the\n * look. That separation is the whole point: the alternative is a `<p>` nested\n * inside a `<p>`, which the HTML parser silently splits into two, or a\n * paragraph faked out of a `<div>` because the real element brought a size\n * with it.\n */\n as?: TextElement\n}\n\n/**\n * A paragraph, or a run of text that wants the system's voice.\n *\n * The step between `Article` and raw JSX. `Article` styles a whole reading\n * column from element selectors and is the right answer for a post; this is for\n * the single paragraph that is NOT in a column — a card's description, a\n * dialog's explanation, the line under an empty state.\n *\n * The default tone is `body` (`--ink-2`), not `--ink`. A page whose paragraphs\n * are all full-strength ink has spent the top of the ladder on its body copy\n * and has nothing left for the headings, which is the single most common way a\n * monochrome page loses its hierarchy.\n *\n * @example\n * <Text>Twelve releases this quarter, none rolled back.</Text>\n * @example\n * <Text size=\"lead\" tone=\"strong\">A monochrome system for software and writing.</Text>\n * @example\n * <Text as=\"span\" size=\"sm\" tone=\"muted\">Updated just now</Text>\n */\nexport function Text({\n children,\n size = 'base',\n tone = 'body',\n as = 'p',\n className,\n ...rest\n}: TextProps) {\n const Comp = as as ElementType\n\n return (\n <Comp className={cn('m-0', SIZE[size], TONE[tone], className)} {...rest}>\n {children}\n </Comp>\n )\n}\n\nexport default Text\n"],"mappings":"AAgGI;AA/FJ,SAAS,UAAU;AAgCnB,MAAM,OAAiC;AAAA,EACrC,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AACR;AAEA,MAAM,OAAiC;AAAA,EACrC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AACT;AAyCO,SAAS,KAAK;AAAA,EACnB;AAAA,EACA,OAAO;AAAA,EACP,OAAO;AAAA,EACP,KAAK;AAAA,EACL;AAAA,EACA,GAAG;AACL,GAAc;AACZ,QAAM,OAAO;AAEb,SACE,oBAAC,QAAK,WAAW,GAAG,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,SAAS,GAAI,GAAG,MAChE,UACH;AAEJ;AAEA,IAAO,eAAQ;","names":[]}
@@ -0,0 +1,20 @@
1
+ import * as react from 'react';
2
+ import { TextareaHTMLAttributes, Ref } from 'react';
3
+
4
+ interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
5
+ /** Paints the resting border with `--danger` and reflects `aria-invalid`. */
6
+ invalid?: boolean;
7
+ ref?: Ref<HTMLTextAreaElement>;
8
+ }
9
+ /**
10
+ * Multi-line text entry.
11
+ *
12
+ * Resizes vertically only: horizontal resize lets a reader drag the control
13
+ * past the measure and past the page's own gutter.
14
+ *
15
+ * @example
16
+ * <Field label="Notes" htmlFor="notes"><Textarea id="notes" rows={4} /></Field>
17
+ */
18
+ declare function Textarea({ invalid, className, ref, 'aria-invalid': ariaInvalid, ...rest }: TextareaProps): react.JSX.Element;
19
+
20
+ export { Textarea, type TextareaProps, Textarea as default };
@@ -0,0 +1,32 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { cn } from "../../lib/cn.js";
3
+ import { CONTROL_BASE, CONTROL_BORDER, isInvalid } from "../../lib/control.js";
4
+ function Textarea({
5
+ invalid,
6
+ className,
7
+ ref,
8
+ "aria-invalid": ariaInvalid,
9
+ ...rest
10
+ }) {
11
+ const bad = isInvalid(invalid, ariaInvalid);
12
+ return /* @__PURE__ */ jsx(
13
+ "textarea",
14
+ {
15
+ ref,
16
+ "aria-invalid": ariaInvalid ?? (invalid ? true : void 0),
17
+ className: cn(
18
+ CONTROL_BASE,
19
+ "min-h-24 resize-y",
20
+ bad ? CONTROL_BORDER.invalid : CONTROL_BORDER.resting,
21
+ className
22
+ ),
23
+ ...rest
24
+ }
25
+ );
26
+ }
27
+ var Textarea_default = Textarea;
28
+ export {
29
+ Textarea,
30
+ Textarea_default as default
31
+ };
32
+ //# sourceMappingURL=Textarea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/Textarea/Textarea.tsx"],"sourcesContent":["import type { Ref, TextareaHTMLAttributes } from 'react'\nimport { cn } from '../../lib/cn'\nimport { CONTROL_BASE, CONTROL_BORDER, isInvalid } from '../../lib/control'\n\nexport interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n /** Paints the resting border with `--danger` and reflects `aria-invalid`. */\n invalid?: boolean\n ref?: Ref<HTMLTextAreaElement>\n}\n\n/**\n * Multi-line text entry.\n *\n * Resizes vertically only: horizontal resize lets a reader drag the control\n * past the measure and past the page's own gutter.\n *\n * @example\n * <Field label=\"Notes\" htmlFor=\"notes\"><Textarea id=\"notes\" rows={4} /></Field>\n */\nexport function Textarea({\n invalid,\n className,\n ref,\n 'aria-invalid': ariaInvalid,\n ...rest\n}: TextareaProps) {\n const bad = isInvalid(invalid, ariaInvalid)\n return (\n <textarea\n ref={ref}\n aria-invalid={ariaInvalid ?? (invalid ? true : undefined)}\n className={cn(\n CONTROL_BASE,\n 'min-h-24 resize-y',\n bad ? CONTROL_BORDER.invalid : CONTROL_BORDER.resting,\n className,\n )}\n {...rest}\n />\n )\n}\n\nexport default Textarea\n"],"mappings":"AA4BI;AA3BJ,SAAS,UAAU;AACnB,SAAS,cAAc,gBAAgB,iBAAiB;AAiBjD,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB,GAAG;AACL,GAAkB;AAChB,QAAM,MAAM,UAAU,SAAS,WAAW;AAC1C,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,gBAAc,gBAAgB,UAAU,OAAO;AAAA,MAC/C,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA,MAAM,eAAe,UAAU,eAAe;AAAA,QAC9C;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,IAAO,mBAAQ;","names":[]}
@@ -0,0 +1,59 @@
1
+ import * as react from 'react';
2
+ import { TimeHTMLAttributes } from 'react';
3
+
4
+ /**
5
+ * How the instant reads.
6
+ *
7
+ * `auto` is relative while the gap is small enough to be useful and absolute
8
+ * once it is not — "3 hours ago" answers the question a reader is actually
9
+ * asking about a recent record, and "2 years ago" does not.
10
+ */
11
+ type TimestampFormat = 'auto' | 'relative' | 'absolute';
12
+ interface TimestampProps extends Omit<TimeHTMLAttributes<HTMLTimeElement>, 'dateTime' | 'children'> {
13
+ /** The instant. A `Date`, an ISO string, or epoch milliseconds. */
14
+ value: Date | string | number;
15
+ /** How the instant reads. See {@link TimestampFormat}. */
16
+ format?: TimestampFormat;
17
+ /**
18
+ * How far from now `auto` still prints a relative time, in milliseconds.
19
+ * Seven days by default — past a week the calendar date is the more useful
20
+ * fact, and it is also the one that stops changing.
21
+ */
22
+ relativeWithin?: number;
23
+ /** Adds the clock time to the absolute form. */
24
+ showTime?: boolean;
25
+ }
26
+ /**
27
+ * A date or a time, rendered the one way the system renders them.
28
+ *
29
+ * Every list of records needs this, and `new Date().toLocaleString()` at the
30
+ * call site is precisely how a product ends up with four date formats on one
31
+ * screen.
32
+ *
33
+ * **On hydration.** Both halves of a formatted date are environment-dependent:
34
+ * a relative time depends on when it is read, and even an absolute one depends
35
+ * on the reader's locale and time zone, none of which a static build knows. So
36
+ * the first paint — the one the server produces and the one the client must
37
+ * reproduce exactly — is the ISO calendar date in UTC, sliced straight out of
38
+ * the ISO string with no `Intl` anywhere near it. Both sides compute it from
39
+ * the same characters, so they cannot disagree. The locale-aware and relative
40
+ * forms are applied after mount, in an effect, where there is a reader to be
41
+ * local to. This package statically exports every page, so the alternative is a
42
+ * hydration mismatch on any page with a date on it.
43
+ *
44
+ * The `datetime` attribute is the full ISO instant from the first render
45
+ * onwards and never changes, so a screen reader, a crawler, or anything else
46
+ * parsing the markup gets the exact moment whether or not the effect has run.
47
+ *
48
+ * It formats once per mount. A hundred rows each holding a ticking interval to
49
+ * keep "3 minutes ago" honest is a cost nobody asked for; a list that must tick
50
+ * should re-key or re-render from above.
51
+ *
52
+ * @example
53
+ * <Timestamp value={deploy.finishedAt} />
54
+ * @example
55
+ * <Timestamp value="2026-01-14T09:30:00Z" format="absolute" showTime />
56
+ */
57
+ declare function Timestamp({ value, format, relativeWithin, showTime, className, ...rest }: TimestampProps): react.JSX.Element;
58
+
59
+ export { Timestamp, type TimestampFormat, type TimestampProps, Timestamp as default };