@ciderpress/ui 1.0.0-rc.1

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 (428) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +23 -0
  3. package/dist/0~142.js +2 -0
  4. package/dist/0~164.js +2 -0
  5. package/dist/0~2.js +2 -0
  6. package/dist/0~225.js +2 -0
  7. package/dist/0~288.js +2 -0
  8. package/dist/0~299.js +2 -0
  9. package/dist/0~3.js +2 -0
  10. package/dist/0~301.js +2 -0
  11. package/dist/0~311.js +2 -0
  12. package/dist/0~326.js +2 -0
  13. package/dist/0~40.js +2 -0
  14. package/dist/0~43.js +2 -0
  15. package/dist/0~433.js +2 -0
  16. package/dist/0~453.js +2 -0
  17. package/dist/0~457.js +2 -0
  18. package/dist/0~497.js +2 -0
  19. package/dist/0~511.js +2 -0
  20. package/dist/0~603.js +2 -0
  21. package/dist/0~616.js +2 -0
  22. package/dist/0~659.js +2 -0
  23. package/dist/0~670.js +2 -0
  24. package/dist/0~687.js +2 -0
  25. package/dist/0~706.js +2 -0
  26. package/dist/0~729.js +2 -0
  27. package/dist/0~768.js +2 -0
  28. package/dist/0~819.js +2 -0
  29. package/dist/0~830.js +2 -0
  30. package/dist/0~854.js +2 -0
  31. package/dist/0~863.js +2 -0
  32. package/dist/0~879.js +2 -0
  33. package/dist/0~96.js +2 -0
  34. package/dist/0~97.js +2 -0
  35. package/dist/components/FileTree/FileTree.css +90 -0
  36. package/dist/components/FileTree/FileTree.d.ts +7 -0
  37. package/dist/components/FileTree/FileTree.js +531 -0
  38. package/dist/components/FileTree/FileTreeItem.d.ts +8 -0
  39. package/dist/components/FileTree/RemoteSvgIcon.d.ts +11 -0
  40. package/dist/components/FileTree/index.d.ts +4 -0
  41. package/dist/components/folder-icons.d.ts +32 -0
  42. package/dist/components/languages.d.ts +7 -0
  43. package/dist/components/tree-parser/tree-parser.d.ts +12 -0
  44. package/dist/components/tree-parser/types.d.ts +11 -0
  45. package/dist/head/css/loader-apple.css +1 -0
  46. package/dist/head/css/loader-backdrop.css +1 -0
  47. package/dist/head/css/loader-dots.css +1 -0
  48. package/dist/head/css/themes/amber.css +1 -0
  49. package/dist/head/css/themes/arcade.css +1 -0
  50. package/dist/head/css/themes/grannysmith.css +1 -0
  51. package/dist/head/css/themes/honeycrisp.css +1 -0
  52. package/dist/head/css/themes/midnight.css +1 -0
  53. package/dist/head/css/themes/mulled.css +1 -0
  54. package/dist/head/js/loader-dots.js +1 -0
  55. package/dist/head/js/vscode-nav.js +1 -0
  56. package/dist/index.d.ts +43 -0
  57. package/dist/index.mjs +40 -0
  58. package/dist/node.d.ts +81 -0
  59. package/dist/node.mjs +17762 -0
  60. package/dist/plugins/mermaid/MermaidRenderer.tsx +480 -0
  61. package/dist/plugins/mermaid/mermaid.css +199 -0
  62. package/dist/theme/components/announcement/announcement-bar.css +103 -0
  63. package/dist/theme/components/announcement/announcement-bar.tsx +173 -0
  64. package/dist/theme/components/ask-ai/ask-ai-button.css +52 -0
  65. package/dist/theme/components/ask-ai/ask-ai-button.tsx +56 -0
  66. package/dist/theme/components/content-footer/content-footer-portal.tsx +70 -0
  67. package/dist/theme/components/content-footer/feedback.css +47 -0
  68. package/dist/theme/components/content-footer/feedback.tsx +96 -0
  69. package/dist/theme/components/content-footer/meta-actions.css +25 -0
  70. package/dist/theme/components/content-footer/meta-actions.tsx +57 -0
  71. package/dist/theme/components/content-footer/page-pager.css +61 -0
  72. package/dist/theme/components/content-footer/page-pager.tsx +110 -0
  73. package/dist/theme/components/edit-source-button.tsx +97 -0
  74. package/dist/theme/components/footer/site-footer.css +179 -0
  75. package/dist/theme/components/footer/site-footer.tsx +115 -0
  76. package/dist/theme/components/home/cta.css +67 -0
  77. package/dist/theme/components/home/cta.tsx +77 -0
  78. package/dist/theme/components/home/feature-card.css +52 -0
  79. package/dist/theme/components/home/feature-card.tsx +131 -0
  80. package/dist/theme/components/home/feature.tsx +79 -0
  81. package/dist/theme/components/home/hero-demo.css +66 -0
  82. package/dist/theme/components/home/hero-demo.tsx +46 -0
  83. package/dist/theme/components/home/hero.css +96 -0
  84. package/dist/theme/components/home/hero.tsx +111 -0
  85. package/dist/theme/components/home/layout.tsx +183 -0
  86. package/dist/theme/components/home/page-rail.css +21 -0
  87. package/dist/theme/components/home/page-rail.tsx +19 -0
  88. package/dist/theme/components/home/split.css +148 -0
  89. package/dist/theme/components/home/split.tsx +120 -0
  90. package/dist/theme/components/home/trust-strip.css +33 -0
  91. package/dist/theme/components/home/trust-strip.tsx +43 -0
  92. package/dist/theme/components/home/workspaces.tsx +71 -0
  93. package/dist/theme/components/nav/branch-tag.css +54 -0
  94. package/dist/theme/components/nav/branch-tag.tsx +101 -0
  95. package/dist/theme/components/nav/ciderpress-doc-layout.tsx +247 -0
  96. package/dist/theme/components/nav/ciderpress-docs-bar.css +505 -0
  97. package/dist/theme/components/nav/ciderpress-docs-bar.tsx +426 -0
  98. package/dist/theme/components/nav/ciderpress-header.css +172 -0
  99. package/dist/theme/components/nav/ciderpress-header.tsx +113 -0
  100. package/dist/theme/components/nav/ciderpress-layout-context.tsx +49 -0
  101. package/dist/theme/components/nav/ciderpress-nav-hamburger.css +193 -0
  102. package/dist/theme/components/nav/ciderpress-nav-hamburger.tsx +112 -0
  103. package/dist/theme/components/nav/ciderpress-nav-menu.css +130 -0
  104. package/dist/theme/components/nav/ciderpress-nav-menu.tsx +372 -0
  105. package/dist/theme/components/nav/ciderpress-nav-search.css +73 -0
  106. package/dist/theme/components/nav/ciderpress-nav-search.tsx +55 -0
  107. package/dist/theme/components/nav/ciderpress-nav-social-links.css +35 -0
  108. package/dist/theme/components/nav/ciderpress-nav-social-links.tsx +87 -0
  109. package/dist/theme/components/nav/floating-branch-indicator.css +106 -0
  110. package/dist/theme/components/nav/floating-branch-indicator.tsx +109 -0
  111. package/dist/theme/components/nav/layout.tsx +268 -0
  112. package/dist/theme/components/nav/mobile-nav-cta.tsx +79 -0
  113. package/dist/theme/components/nav/nav-divider.css +15 -0
  114. package/dist/theme/components/nav/nav-divider.tsx +19 -0
  115. package/dist/theme/components/nav/nav-logo.css +42 -0
  116. package/dist/theme/components/nav/nav-logo.tsx +262 -0
  117. package/dist/theme/components/nav/theme-switcher.css +92 -0
  118. package/dist/theme/components/nav/theme-switcher.tsx +298 -0
  119. package/dist/theme/components/nav/topbar-cta.css +45 -0
  120. package/dist/theme/components/nav/topbar-cta.tsx +39 -0
  121. package/dist/theme/components/nav/variant-toggle.css +70 -0
  122. package/dist/theme/components/nav/variant-toggle.tsx +83 -0
  123. package/dist/theme/components/nav/version-chip.css +31 -0
  124. package/dist/theme/components/nav/version-chip.tsx +45 -0
  125. package/dist/theme/components/nav/vscode-tag.css +32 -0
  126. package/dist/theme/components/nav/vscode-tag.tsx +20 -0
  127. package/dist/theme/components/openapi/code-sample.tsx +341 -0
  128. package/dist/theme/components/openapi/copy-markdown-button.tsx +41 -0
  129. package/dist/theme/components/openapi/icons.tsx +45 -0
  130. package/dist/theme/components/openapi/index.ts +6 -0
  131. package/dist/theme/components/openapi/method-badge.tsx +24 -0
  132. package/dist/theme/components/openapi/openapi.css +665 -0
  133. package/dist/theme/components/openapi/operation.tsx +200 -0
  134. package/dist/theme/components/openapi/overview.tsx +207 -0
  135. package/dist/theme/components/openapi/parameters-table.tsx +149 -0
  136. package/dist/theme/components/openapi/request-body.tsx +90 -0
  137. package/dist/theme/components/openapi/response-list.tsx +112 -0
  138. package/dist/theme/components/openapi/schema-viewer.tsx +277 -0
  139. package/dist/theme/components/openapi/security-badges.tsx +63 -0
  140. package/dist/theme/components/openapi/spec-utils.ts +122 -0
  141. package/dist/theme/components/shared/accordion.css +118 -0
  142. package/dist/theme/components/shared/accordion.stories.tsx +96 -0
  143. package/dist/theme/components/shared/accordion.tsx +191 -0
  144. package/dist/theme/components/shared/brand-logo.stories.tsx +49 -0
  145. package/dist/theme/components/shared/brand-mark.stories.tsx +53 -0
  146. package/dist/theme/components/shared/browser-window.css +1 -0
  147. package/dist/theme/components/shared/browser-window.stories.tsx +100 -0
  148. package/dist/theme/components/shared/browser-window.tsx +2 -0
  149. package/dist/theme/components/shared/card.stories.tsx +50 -0
  150. package/dist/theme/components/shared/card.tsx +35 -0
  151. package/dist/theme/components/shared/ciderpress-logo.tsx +93 -0
  152. package/dist/theme/components/shared/ciderpress-mark.tsx +77 -0
  153. package/dist/theme/components/shared/color.css +56 -0
  154. package/dist/theme/components/shared/color.stories.tsx +47 -0
  155. package/dist/theme/components/shared/color.tsx +69 -0
  156. package/dist/theme/components/shared/columns.css +37 -0
  157. package/dist/theme/components/shared/columns.stories.tsx +91 -0
  158. package/dist/theme/components/shared/columns.tsx +50 -0
  159. package/dist/theme/components/shared/desktop-window.css +339 -0
  160. package/dist/theme/components/shared/desktop-window.tsx +535 -0
  161. package/dist/theme/components/shared/field.css +158 -0
  162. package/dist/theme/components/shared/field.stories.tsx +100 -0
  163. package/dist/theme/components/shared/field.tsx +186 -0
  164. package/dist/theme/components/shared/frame.css +39 -0
  165. package/dist/theme/components/shared/frame.stories.tsx +49 -0
  166. package/dist/theme/components/shared/frame.tsx +76 -0
  167. package/dist/theme/components/shared/icon.stories.tsx +90 -0
  168. package/dist/theme/components/shared/icon.tsx +41 -0
  169. package/dist/theme/components/shared/prompt.css +178 -0
  170. package/dist/theme/components/shared/prompt.stories.tsx +57 -0
  171. package/dist/theme/components/shared/prompt.tsx +369 -0
  172. package/dist/theme/components/shared/resolve-card-icon.ts +28 -0
  173. package/dist/theme/components/shared/section-card.stories.tsx +51 -0
  174. package/dist/theme/components/shared/section-card.tsx +44 -0
  175. package/dist/theme/components/shared/section-grid.stories.tsx +46 -0
  176. package/dist/theme/components/shared/section-grid.tsx +15 -0
  177. package/dist/theme/components/shared/status-badge.css +37 -0
  178. package/dist/theme/components/shared/status-badge.stories.tsx +61 -0
  179. package/dist/theme/components/shared/status-badge.tsx +74 -0
  180. package/dist/theme/components/shared/steps.css +88 -0
  181. package/dist/theme/components/shared/steps.stories.tsx +68 -0
  182. package/dist/theme/components/shared/steps.tsx +100 -0
  183. package/dist/theme/components/shared/tech-icon-table.stories.tsx +29 -0
  184. package/dist/theme/components/shared/tech-icon-table.tsx +71 -0
  185. package/dist/theme/components/shared/tech-tag.stories.tsx +40 -0
  186. package/dist/theme/components/shared/tech-tag.tsx +31 -0
  187. package/dist/theme/components/shared/theme-color-palette.css +80 -0
  188. package/dist/theme/components/shared/theme-color-palette.stories.tsx +52 -0
  189. package/dist/theme/components/shared/theme-color-palette.tsx +275 -0
  190. package/dist/theme/components/shared/tooltip.css +69 -0
  191. package/dist/theme/components/shared/tooltip.stories.tsx +72 -0
  192. package/dist/theme/components/shared/tooltip.tsx +77 -0
  193. package/dist/theme/components/sidebar/framework-picker.css +77 -0
  194. package/dist/theme/components/sidebar/framework-picker.tsx +78 -0
  195. package/dist/theme/components/sidebar/sidebar-filter.test.ts +140 -0
  196. package/dist/theme/components/sidebar/sidebar-filter.ts +79 -0
  197. package/dist/theme/components/sidebar/sidebar-links.css +102 -0
  198. package/dist/theme/components/sidebar/sidebar-links.tsx +122 -0
  199. package/dist/theme/components/sidebar/sidebar-promo.css +42 -0
  200. package/dist/theme/components/sidebar/sidebar-promo.tsx +52 -0
  201. package/dist/theme/components/sidebar/sidebar-scope.tsx +151 -0
  202. package/dist/theme/components/sidebar/sidebar-toggle.css +181 -0
  203. package/dist/theme/components/sidebar/sidebar-toggle.tsx +127 -0
  204. package/dist/theme/components/theme-provider.tsx +637 -0
  205. package/dist/theme/components/workspaces/card.css +151 -0
  206. package/dist/theme/components/workspaces/card.tsx +166 -0
  207. package/dist/theme/components/workspaces/grid.tsx +62 -0
  208. package/dist/theme/css.d.ts +1 -0
  209. package/dist/theme/env.d.ts +12 -0
  210. package/dist/theme/fonts/GeistMono-Variable.woff2 +0 -0
  211. package/dist/theme/fonts/GeistPixel-Square.woff2 +0 -0
  212. package/dist/theme/fonts/GeistSans-Variable.woff2 +0 -0
  213. package/dist/theme/hooks/use-ciderpress.ts +61 -0
  214. package/dist/theme/hooks/use-nav-items.ts +76 -0
  215. package/dist/theme/icons/index.ts +2 -0
  216. package/dist/theme/icons/tech-map.ts +228 -0
  217. package/dist/theme/index.tsx +180 -0
  218. package/dist/theme/lib/read-social-links.ts +27 -0
  219. package/dist/theme/lib/route-link.tsx +126 -0
  220. package/dist/theme/lib/safe-url.test.ts +0 -0
  221. package/dist/theme/lib/safe-url.ts +68 -0
  222. package/dist/theme/lib/theme-favicon.ts +125 -0
  223. package/dist/theme/lib/user-config-stub.ts +12 -0
  224. package/dist/theme/styles/layers.css +32 -0
  225. package/dist/theme/styles/overrides/badge.css +26 -0
  226. package/dist/theme/styles/overrides/content-footer.css +80 -0
  227. package/dist/theme/styles/overrides/details.css +61 -0
  228. package/dist/theme/styles/overrides/fonts.css +32 -0
  229. package/dist/theme/styles/overrides/home-card.css +133 -0
  230. package/dist/theme/styles/overrides/home.css +243 -0
  231. package/dist/theme/styles/overrides/rail.css +337 -0
  232. package/dist/theme/styles/overrides/rspress.css +62 -0
  233. package/dist/theme/styles/overrides/scrollbar.css +25 -0
  234. package/dist/theme/styles/overrides/section-card.css +114 -0
  235. package/dist/theme/styles/overrides/sidebar.css +144 -0
  236. package/dist/theme/styles/overrides/tokens.css +288 -0
  237. package/dist/theme/styles/overrides/vscode.css +88 -0
  238. package/dist/theme/styles/themes/amber.css +545 -0
  239. package/dist/theme/styles/themes/arcade-fx.css +366 -0
  240. package/dist/theme/styles/themes/arcade.css +273 -0
  241. package/dist/theme/styles/themes/grannysmith.css +545 -0
  242. package/dist/theme/styles/themes/honeycrisp.css +545 -0
  243. package/dist/theme/styles/themes/midnight.css +273 -0
  244. package/dist/theme/styles/themes/mulled.css +817 -0
  245. package/package.json +103 -0
  246. package/src/theme/components/announcement/announcement-bar.css +103 -0
  247. package/src/theme/components/announcement/announcement-bar.tsx +173 -0
  248. package/src/theme/components/ask-ai/ask-ai-button.css +52 -0
  249. package/src/theme/components/ask-ai/ask-ai-button.tsx +56 -0
  250. package/src/theme/components/content-footer/content-footer-portal.tsx +70 -0
  251. package/src/theme/components/content-footer/feedback.css +47 -0
  252. package/src/theme/components/content-footer/feedback.tsx +96 -0
  253. package/src/theme/components/content-footer/meta-actions.css +25 -0
  254. package/src/theme/components/content-footer/meta-actions.tsx +57 -0
  255. package/src/theme/components/content-footer/page-pager.css +61 -0
  256. package/src/theme/components/content-footer/page-pager.tsx +110 -0
  257. package/src/theme/components/edit-source-button.tsx +97 -0
  258. package/src/theme/components/footer/site-footer.css +179 -0
  259. package/src/theme/components/footer/site-footer.tsx +115 -0
  260. package/src/theme/components/home/cta.css +67 -0
  261. package/src/theme/components/home/cta.tsx +77 -0
  262. package/src/theme/components/home/feature-card.css +52 -0
  263. package/src/theme/components/home/feature-card.tsx +131 -0
  264. package/src/theme/components/home/feature.tsx +79 -0
  265. package/src/theme/components/home/hero-demo.css +66 -0
  266. package/src/theme/components/home/hero-demo.tsx +46 -0
  267. package/src/theme/components/home/hero.css +96 -0
  268. package/src/theme/components/home/hero.tsx +111 -0
  269. package/src/theme/components/home/layout.tsx +183 -0
  270. package/src/theme/components/home/page-rail.css +21 -0
  271. package/src/theme/components/home/page-rail.tsx +19 -0
  272. package/src/theme/components/home/split.css +148 -0
  273. package/src/theme/components/home/split.tsx +120 -0
  274. package/src/theme/components/home/trust-strip.css +33 -0
  275. package/src/theme/components/home/trust-strip.tsx +43 -0
  276. package/src/theme/components/home/workspaces.tsx +71 -0
  277. package/src/theme/components/nav/branch-tag.css +54 -0
  278. package/src/theme/components/nav/branch-tag.tsx +101 -0
  279. package/src/theme/components/nav/ciderpress-doc-layout.tsx +247 -0
  280. package/src/theme/components/nav/ciderpress-docs-bar.css +505 -0
  281. package/src/theme/components/nav/ciderpress-docs-bar.tsx +426 -0
  282. package/src/theme/components/nav/ciderpress-header.css +172 -0
  283. package/src/theme/components/nav/ciderpress-header.tsx +113 -0
  284. package/src/theme/components/nav/ciderpress-layout-context.tsx +49 -0
  285. package/src/theme/components/nav/ciderpress-nav-hamburger.css +193 -0
  286. package/src/theme/components/nav/ciderpress-nav-hamburger.tsx +112 -0
  287. package/src/theme/components/nav/ciderpress-nav-menu.css +130 -0
  288. package/src/theme/components/nav/ciderpress-nav-menu.tsx +372 -0
  289. package/src/theme/components/nav/ciderpress-nav-search.css +73 -0
  290. package/src/theme/components/nav/ciderpress-nav-search.tsx +55 -0
  291. package/src/theme/components/nav/ciderpress-nav-social-links.css +35 -0
  292. package/src/theme/components/nav/ciderpress-nav-social-links.tsx +87 -0
  293. package/src/theme/components/nav/floating-branch-indicator.css +106 -0
  294. package/src/theme/components/nav/floating-branch-indicator.tsx +109 -0
  295. package/src/theme/components/nav/layout.tsx +268 -0
  296. package/src/theme/components/nav/mobile-nav-cta.tsx +79 -0
  297. package/src/theme/components/nav/nav-divider.css +15 -0
  298. package/src/theme/components/nav/nav-divider.tsx +19 -0
  299. package/src/theme/components/nav/nav-logo.css +42 -0
  300. package/src/theme/components/nav/nav-logo.tsx +262 -0
  301. package/src/theme/components/nav/theme-switcher.css +92 -0
  302. package/src/theme/components/nav/theme-switcher.tsx +298 -0
  303. package/src/theme/components/nav/topbar-cta.css +45 -0
  304. package/src/theme/components/nav/topbar-cta.tsx +39 -0
  305. package/src/theme/components/nav/variant-toggle.css +70 -0
  306. package/src/theme/components/nav/variant-toggle.tsx +83 -0
  307. package/src/theme/components/nav/version-chip.css +31 -0
  308. package/src/theme/components/nav/version-chip.tsx +45 -0
  309. package/src/theme/components/nav/vscode-tag.css +32 -0
  310. package/src/theme/components/nav/vscode-tag.tsx +20 -0
  311. package/src/theme/components/openapi/code-sample.tsx +341 -0
  312. package/src/theme/components/openapi/copy-markdown-button.tsx +41 -0
  313. package/src/theme/components/openapi/icons.tsx +45 -0
  314. package/src/theme/components/openapi/index.ts +6 -0
  315. package/src/theme/components/openapi/method-badge.tsx +24 -0
  316. package/src/theme/components/openapi/openapi.css +665 -0
  317. package/src/theme/components/openapi/operation.tsx +200 -0
  318. package/src/theme/components/openapi/overview.tsx +207 -0
  319. package/src/theme/components/openapi/parameters-table.tsx +149 -0
  320. package/src/theme/components/openapi/request-body.tsx +90 -0
  321. package/src/theme/components/openapi/response-list.tsx +112 -0
  322. package/src/theme/components/openapi/schema-viewer.tsx +277 -0
  323. package/src/theme/components/openapi/security-badges.tsx +63 -0
  324. package/src/theme/components/openapi/spec-utils.ts +122 -0
  325. package/src/theme/components/shared/accordion.css +118 -0
  326. package/src/theme/components/shared/accordion.stories.tsx +96 -0
  327. package/src/theme/components/shared/accordion.tsx +191 -0
  328. package/src/theme/components/shared/brand-logo.stories.tsx +49 -0
  329. package/src/theme/components/shared/brand-mark.stories.tsx +53 -0
  330. package/src/theme/components/shared/browser-window.css +1 -0
  331. package/src/theme/components/shared/browser-window.stories.tsx +100 -0
  332. package/src/theme/components/shared/browser-window.tsx +2 -0
  333. package/src/theme/components/shared/card.stories.tsx +50 -0
  334. package/src/theme/components/shared/card.tsx +35 -0
  335. package/src/theme/components/shared/ciderpress-logo.tsx +93 -0
  336. package/src/theme/components/shared/ciderpress-mark.tsx +77 -0
  337. package/src/theme/components/shared/color.css +56 -0
  338. package/src/theme/components/shared/color.stories.tsx +47 -0
  339. package/src/theme/components/shared/color.tsx +69 -0
  340. package/src/theme/components/shared/columns.css +37 -0
  341. package/src/theme/components/shared/columns.stories.tsx +91 -0
  342. package/src/theme/components/shared/columns.tsx +50 -0
  343. package/src/theme/components/shared/desktop-window.css +339 -0
  344. package/src/theme/components/shared/desktop-window.tsx +535 -0
  345. package/src/theme/components/shared/field.css +158 -0
  346. package/src/theme/components/shared/field.stories.tsx +100 -0
  347. package/src/theme/components/shared/field.tsx +186 -0
  348. package/src/theme/components/shared/frame.css +39 -0
  349. package/src/theme/components/shared/frame.stories.tsx +49 -0
  350. package/src/theme/components/shared/frame.tsx +76 -0
  351. package/src/theme/components/shared/icon.stories.tsx +90 -0
  352. package/src/theme/components/shared/icon.tsx +41 -0
  353. package/src/theme/components/shared/prompt.css +178 -0
  354. package/src/theme/components/shared/prompt.stories.tsx +57 -0
  355. package/src/theme/components/shared/prompt.tsx +369 -0
  356. package/src/theme/components/shared/resolve-card-icon.ts +28 -0
  357. package/src/theme/components/shared/section-card.stories.tsx +51 -0
  358. package/src/theme/components/shared/section-card.tsx +44 -0
  359. package/src/theme/components/shared/section-grid.stories.tsx +46 -0
  360. package/src/theme/components/shared/section-grid.tsx +15 -0
  361. package/src/theme/components/shared/status-badge.css +37 -0
  362. package/src/theme/components/shared/status-badge.stories.tsx +61 -0
  363. package/src/theme/components/shared/status-badge.tsx +74 -0
  364. package/src/theme/components/shared/steps.css +88 -0
  365. package/src/theme/components/shared/steps.stories.tsx +68 -0
  366. package/src/theme/components/shared/steps.tsx +100 -0
  367. package/src/theme/components/shared/tech-icon-table.stories.tsx +29 -0
  368. package/src/theme/components/shared/tech-icon-table.tsx +71 -0
  369. package/src/theme/components/shared/tech-tag.stories.tsx +40 -0
  370. package/src/theme/components/shared/tech-tag.tsx +31 -0
  371. package/src/theme/components/shared/theme-color-palette.css +80 -0
  372. package/src/theme/components/shared/theme-color-palette.stories.tsx +52 -0
  373. package/src/theme/components/shared/theme-color-palette.tsx +275 -0
  374. package/src/theme/components/shared/tooltip.css +69 -0
  375. package/src/theme/components/shared/tooltip.stories.tsx +72 -0
  376. package/src/theme/components/shared/tooltip.tsx +77 -0
  377. package/src/theme/components/sidebar/framework-picker.css +77 -0
  378. package/src/theme/components/sidebar/framework-picker.tsx +78 -0
  379. package/src/theme/components/sidebar/sidebar-filter.test.ts +140 -0
  380. package/src/theme/components/sidebar/sidebar-filter.ts +79 -0
  381. package/src/theme/components/sidebar/sidebar-links.css +102 -0
  382. package/src/theme/components/sidebar/sidebar-links.tsx +122 -0
  383. package/src/theme/components/sidebar/sidebar-promo.css +42 -0
  384. package/src/theme/components/sidebar/sidebar-promo.tsx +52 -0
  385. package/src/theme/components/sidebar/sidebar-scope.tsx +151 -0
  386. package/src/theme/components/sidebar/sidebar-toggle.css +181 -0
  387. package/src/theme/components/sidebar/sidebar-toggle.tsx +127 -0
  388. package/src/theme/components/theme-provider.tsx +637 -0
  389. package/src/theme/components/workspaces/card.css +151 -0
  390. package/src/theme/components/workspaces/card.tsx +166 -0
  391. package/src/theme/components/workspaces/grid.tsx +62 -0
  392. package/src/theme/css.d.ts +1 -0
  393. package/src/theme/env.d.ts +12 -0
  394. package/src/theme/fonts/GeistMono-Variable.woff2 +0 -0
  395. package/src/theme/fonts/GeistPixel-Square.woff2 +0 -0
  396. package/src/theme/fonts/GeistSans-Variable.woff2 +0 -0
  397. package/src/theme/hooks/use-ciderpress.ts +61 -0
  398. package/src/theme/hooks/use-nav-items.ts +76 -0
  399. package/src/theme/icons/index.ts +2 -0
  400. package/src/theme/icons/tech-map.ts +228 -0
  401. package/src/theme/index.tsx +180 -0
  402. package/src/theme/lib/read-social-links.ts +27 -0
  403. package/src/theme/lib/route-link.tsx +126 -0
  404. package/src/theme/lib/safe-url.test.ts +0 -0
  405. package/src/theme/lib/safe-url.ts +68 -0
  406. package/src/theme/lib/theme-favicon.ts +125 -0
  407. package/src/theme/lib/user-config-stub.ts +12 -0
  408. package/src/theme/styles/layers.css +32 -0
  409. package/src/theme/styles/overrides/badge.css +26 -0
  410. package/src/theme/styles/overrides/content-footer.css +80 -0
  411. package/src/theme/styles/overrides/details.css +61 -0
  412. package/src/theme/styles/overrides/fonts.css +32 -0
  413. package/src/theme/styles/overrides/home-card.css +133 -0
  414. package/src/theme/styles/overrides/home.css +243 -0
  415. package/src/theme/styles/overrides/rail.css +337 -0
  416. package/src/theme/styles/overrides/rspress.css +62 -0
  417. package/src/theme/styles/overrides/scrollbar.css +25 -0
  418. package/src/theme/styles/overrides/section-card.css +114 -0
  419. package/src/theme/styles/overrides/sidebar.css +144 -0
  420. package/src/theme/styles/overrides/tokens.css +288 -0
  421. package/src/theme/styles/overrides/vscode.css +88 -0
  422. package/src/theme/styles/themes/amber.css +545 -0
  423. package/src/theme/styles/themes/arcade-fx.css +366 -0
  424. package/src/theme/styles/themes/arcade.css +273 -0
  425. package/src/theme/styles/themes/grannysmith.css +545 -0
  426. package/src/theme/styles/themes/honeycrisp.css +545 -0
  427. package/src/theme/styles/themes/midnight.css +273 -0
  428. package/src/theme/styles/themes/mulled.css +817 -0
@@ -0,0 +1,44 @@
1
+ import { match, P } from 'massaman/match'
2
+ import type React from 'react'
3
+
4
+ import { Card } from './card'
5
+ import { Icon } from './icon'
6
+ import { resolveCardIcon } from './resolve-card-icon'
7
+
8
+ export interface SectionCardProps {
9
+ readonly href: string
10
+ readonly title: string
11
+ readonly description?: string
12
+ readonly icon?: string | { readonly id: string; readonly color: string }
13
+ }
14
+
15
+ /**
16
+ * Section card — simple icon + title + description link card
17
+ * used on auto-generated section landing pages.
18
+ *
19
+ * @param props - Props with href, title, optional description and icon
20
+ * @returns React element with a linked section card
21
+ */
22
+ export function SectionCard({
23
+ href,
24
+ title,
25
+ description,
26
+ icon = 'pixelarticons:file',
27
+ }: SectionCardProps): React.ReactElement {
28
+ const resolved = resolveCardIcon(icon) ?? { id: 'pixelarticons:file', color: 'purple' }
29
+ const descEl = match(description)
30
+ .with(P.nonNullable, (d) => <span className="cp-section-card__desc">{d}</span>)
31
+ .otherwise(() => null)
32
+
33
+ return (
34
+ <Card href={href} className="cp-section-card">
35
+ <div className="cp-section-card__header">
36
+ <span className={`cp-section-card__icon cp-section-card__icon--${resolved.color}`}>
37
+ <Icon icon={resolved.id} />
38
+ </span>
39
+ <span className="cp-section-card__title">{title}</span>
40
+ </div>
41
+ {descEl}
42
+ </Card>
43
+ )
44
+ }
@@ -0,0 +1,46 @@
1
+ import type { Story } from '@ladle/react'
2
+
3
+ import { SectionCard } from './section-card.tsx'
4
+ import { SectionGrid } from './section-grid.tsx'
5
+
6
+ const meta = {
7
+ title: 'Layout / Section Grid',
8
+ }
9
+
10
+ export default meta
11
+
12
+ /**
13
+ * Section grid populated with the same SectionCards used on auto-
14
+ * generated landing pages.
15
+ *
16
+ * @returns Grid wrapping four section cards
17
+ */
18
+ // oxlint-disable-next-line func-style -- Ladle stories use `export const`
19
+ export const Default: Story = () => (
20
+ <SectionGrid>
21
+ <SectionCard
22
+ href="/guides/getting-started"
23
+ title="Getting started"
24
+ description="Spin up a docs site against your existing markdown."
25
+ icon={{ id: 'pixelarticons:flag', color: 'purple' }}
26
+ />
27
+ <SectionCard
28
+ href="/concepts"
29
+ title="Concepts"
30
+ description="How the sync engine and theme cascade fit together."
31
+ icon={{ id: 'pixelarticons:bulb', color: 'amber' }}
32
+ />
33
+ <SectionCard
34
+ href="/references/cli"
35
+ title="CLI reference"
36
+ description="Every command, flag, and config option."
37
+ icon={{ id: 'pixelarticons:command', color: 'blue' }}
38
+ />
39
+ <SectionCard
40
+ href="/examples"
41
+ title="Examples"
42
+ description="Real-world Ciderpress sites you can copy from."
43
+ icon={{ id: 'pixelarticons:layout', color: 'green' }}
44
+ />
45
+ </SectionGrid>
46
+ )
@@ -0,0 +1,15 @@
1
+ import type React from 'react'
2
+
3
+ export interface SectionGridProps {
4
+ readonly children: React.ReactNode
5
+ }
6
+
7
+ /**
8
+ * Grid container for section cards on landing pages.
9
+ *
10
+ * @param props - Props with children to render inside the grid
11
+ * @returns React element wrapping children in a section grid
12
+ */
13
+ export function SectionGrid({ children }: SectionGridProps): React.ReactElement {
14
+ return <div className="cp-section-grid">{children}</div>
15
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Badge — inline labels with semantic variants and custom colors.
3
+ */
4
+
5
+ .cp-badge {
6
+ display: inline-flex;
7
+ align-items: center;
8
+ padding: var(--cp-s-1) var(--cp-s-8);
9
+ border-radius: var(--cp-radius-pill);
10
+ font-size: var(--cp-fs-badge);
11
+ font-weight: 600;
12
+ line-height: var(--cp-lh-relaxed);
13
+ letter-spacing: var(--cp-letter-wide);
14
+ text-transform: uppercase;
15
+ white-space: nowrap;
16
+ vertical-align: middle;
17
+ }
18
+
19
+ .cp-badge--info {
20
+ background: var(--cp-c-badge-info-bg);
21
+ color: var(--cp-c-badge-info-fg);
22
+ }
23
+
24
+ .cp-badge--success {
25
+ background: var(--cp-c-badge-success-bg);
26
+ color: var(--cp-c-badge-success-fg);
27
+ }
28
+
29
+ .cp-badge--warning {
30
+ background: var(--cp-c-badge-warning-bg);
31
+ color: var(--cp-c-badge-warning-fg);
32
+ }
33
+
34
+ .cp-badge--error {
35
+ background: var(--cp-c-badge-error-bg);
36
+ color: var(--cp-c-badge-error-fg);
37
+ }
@@ -0,0 +1,61 @@
1
+ import type { Story } from '@ladle/react'
2
+
3
+ import { Badge } from './status-badge.tsx'
4
+ import type { BadgeProps } from './status-badge.tsx'
5
+
6
+ const meta = {
7
+ title: 'Data Display / Status Badge',
8
+ }
9
+
10
+ export default meta
11
+
12
+ /**
13
+ * Default badge — info variant.
14
+ *
15
+ * @param args - Badge props driven by Ladle controls
16
+ * @returns Rendered badge
17
+ */
18
+ // oxlint-disable-next-line func-style -- Ladle stories use `export const`
19
+ export const Default: Story<BadgeProps> = (args) => <Badge {...args}>{args.children}</Badge>
20
+
21
+ Default.args = {
22
+ children: 'Beta',
23
+ variant: 'info',
24
+ }
25
+
26
+ Default.argTypes = {
27
+ variant: {
28
+ control: { type: 'radio' },
29
+ options: ['info', 'success', 'warning', 'error'],
30
+ defaultValue: 'info',
31
+ },
32
+ }
33
+
34
+ /**
35
+ * One badge per semantic variant for at-a-glance review.
36
+ *
37
+ * @returns Variant gallery
38
+ */
39
+ // oxlint-disable-next-line func-style -- Ladle stories use `export const`
40
+ export const Variants: Story = () => (
41
+ <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
42
+ <Badge variant="info">Info</Badge>
43
+ <Badge variant="success">Success</Badge>
44
+ <Badge variant="warning">Warning</Badge>
45
+ <Badge variant="error">Error</Badge>
46
+ </div>
47
+ )
48
+
49
+ /**
50
+ * Badge driven by a free-form custom color.
51
+ *
52
+ * @returns Custom-colored badge
53
+ */
54
+ // oxlint-disable-next-line func-style -- Ladle stories use `export const`
55
+ export const CustomColor: Story = () => (
56
+ <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
57
+ <Badge color="#7c3aed">Violet</Badge>
58
+ <Badge color="#0ea5e9">Sky</Badge>
59
+ <Badge color="#f472b6">Pink</Badge>
60
+ </div>
61
+ )
@@ -0,0 +1,74 @@
1
+ import { match, P } from 'massaman/match'
2
+ import type React from 'react'
3
+
4
+ export type BadgeVariant = 'info' | 'success' | 'warning' | 'error'
5
+
6
+ export interface BadgeProps {
7
+ /**
8
+ * Semantic variant controlling color. Defaults to 'info'.
9
+ * Ignored when `color` is provided.
10
+ */
11
+ readonly variant?: BadgeVariant
12
+ /**
13
+ * Custom color (hex, rgb, hsl). Overrides `variant` when set.
14
+ * Used as the text color with a 12% opacity background tint.
15
+ */
16
+ readonly color?: string
17
+ /**
18
+ * Badge label text.
19
+ */
20
+ readonly children: React.ReactNode
21
+ }
22
+
23
+ /**
24
+ * Inline badge for labeling features, endpoints, or sections.
25
+ * Supports semantic variants (info, success, warning, error) and
26
+ * arbitrary custom colors.
27
+ *
28
+ * @param props - Badge variant or custom color and label content
29
+ * @returns React element with styled inline badge
30
+ */
31
+ export function Badge({ variant = 'info', color, children }: BadgeProps): React.ReactElement {
32
+ return match(color)
33
+ .with(P.nonNullable, (c) => (
34
+ <span className="cp-badge" style={{ color: c, backgroundColor: hexToTint(c) }}>
35
+ {children}
36
+ </span>
37
+ ))
38
+ .otherwise(() => {
39
+ const className = match(variant)
40
+ .with('info', () => 'cp-badge cp-badge--info')
41
+ .with('success', () => 'cp-badge cp-badge--success')
42
+ .with('warning', () => 'cp-badge cp-badge--warning')
43
+ .with('error', () => 'cp-badge cp-badge--error')
44
+ .exhaustive()
45
+
46
+ return <span className={className}>{children}</span>
47
+ })
48
+ }
49
+
50
+ /**
51
+ * Convert a hex color to an rgba tint at 12% opacity for the badge background.
52
+ * Falls back to a simple rgba wrapper for non-hex values.
53
+ *
54
+ * @private
55
+ * @param color - CSS color value
56
+ * @returns rgba string at 12% opacity
57
+ */
58
+ function hexToTint(color: string): string {
59
+ const hex = color.replaceAll('#', '')
60
+
61
+ if (hex.length !== 6 && hex.length !== 3) {
62
+ return `color-mix(in srgb, ${color} 12%, transparent)`
63
+ }
64
+
65
+ const fullHex = match(hex.length)
66
+ .with(3, () => [...hex].map((c) => `${c}${c}`).join(''))
67
+ .otherwise(() => hex)
68
+
69
+ const r = Number.parseInt(fullHex.slice(0, 2), 16)
70
+ const g = Number.parseInt(fullHex.slice(2, 4), 16)
71
+ const b = Number.parseInt(fullHex.slice(4, 6), 16)
72
+
73
+ return `rgba(${String(r)}, ${String(g)}, ${String(b)}, 0.12)`
74
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Steps — vertical timeline stepper with numbered circles and connecting lines.
3
+ */
4
+
5
+ .cp-steps {
6
+ display: flex;
7
+ flex-direction: column;
8
+ padding: 0;
9
+ margin: 16px 0;
10
+ }
11
+
12
+ .cp-step {
13
+ display: flex;
14
+ gap: 16px;
15
+ }
16
+
17
+ .cp-step__rail {
18
+ display: flex;
19
+ flex-direction: column;
20
+ align-items: center;
21
+ flex-shrink: 0;
22
+ }
23
+
24
+ .cp-step__indicator {
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ width: 36px;
29
+ height: 36px;
30
+ border-radius: 50%;
31
+ border: 1px solid var(--cp-c-border);
32
+ background: var(--cp-c-bg-soft);
33
+ color: var(--cp-c-text-1);
34
+ font-size: 12px;
35
+ font-weight: 600;
36
+ line-height: 1;
37
+ flex-shrink: 0;
38
+ }
39
+
40
+ .cp-step__connector {
41
+ margin-top: 4px;
42
+ margin-bottom: 4px;
43
+ width: 2px;
44
+ flex: 1;
45
+ background: var(--cp-c-border);
46
+ min-height: 16px;
47
+ }
48
+
49
+ .cp-step:last-child .cp-step__connector {
50
+ background: linear-gradient(to bottom, var(--cp-c-border) 50%, transparent);
51
+ }
52
+
53
+ .cp-step__body {
54
+ padding-bottom: 24px;
55
+ min-width: 0;
56
+ flex: 1;
57
+ }
58
+
59
+ .cp-step:last-child .cp-step__body {
60
+ padding-bottom: 0;
61
+ }
62
+
63
+ .cp-step__title {
64
+ margin-top: 0 !important;
65
+ font-size: 16px;
66
+ font-weight: 600;
67
+ line-height: 24px;
68
+ color: var(--cp-c-text-1);
69
+ }
70
+
71
+ h2.cp-step__title {
72
+ font-size: 20px;
73
+ line-height: 24px;
74
+ }
75
+
76
+ p.cp-step__title {
77
+ font-size: 14px;
78
+ font-weight: 500;
79
+ line-height: 24px;
80
+ }
81
+
82
+ .cp-step__content {
83
+ margin-top: 8px;
84
+ }
85
+
86
+ .cp-step__content:empty {
87
+ display: none;
88
+ }
@@ -0,0 +1,68 @@
1
+ import type { Story } from '@ladle/react'
2
+
3
+ import { Step, Steps } from './steps.tsx'
4
+
5
+ const meta = {
6
+ title: 'Data Display / Steps',
7
+ }
8
+
9
+ export default meta
10
+
11
+ /**
12
+ * Default — three numbered steps in the standard h3 title size.
13
+ *
14
+ * @returns Steps with numbered indicators
15
+ */
16
+ // oxlint-disable-next-line func-style -- Ladle stories use `export const`
17
+ export const Default: Story = () => (
18
+ <Steps>
19
+ <Step title="Install">
20
+ <p>Add Ciderpress to your monorepo:</p>
21
+ <code>pnpm add ciderpress</code>
22
+ </Step>
23
+ <Step title="Configure">
24
+ <p>Create `ciderpress.config.ts` at the repo root and point it at your docs directory.</p>
25
+ </Step>
26
+ <Step title="Run">
27
+ <p>Start the dev server and open the printed URL.</p>
28
+ </Step>
29
+ </Steps>
30
+ )
31
+
32
+ /**
33
+ * Icon indicators — each step's circle is replaced with the supplied
34
+ * Iconify icon instead of a number.
35
+ *
36
+ * @returns Steps with icon indicators
37
+ */
38
+ // oxlint-disable-next-line func-style -- Ladle stories use `export const`
39
+ export const WithIcons: Story = () => (
40
+ <Steps>
41
+ <Step title="Author" icon="pixelarticons:edit">
42
+ <p>Write your docs as plain markdown — no special directives required.</p>
43
+ </Step>
44
+ <Step title="Sync" icon="pixelarticons:sync">
45
+ <p>The sync engine mirrors your structure into the Rspress-expected layout.</p>
46
+ </Step>
47
+ <Step title="Ship" icon="pixelarticons:cloud-upload">
48
+ <p>`pnpm cider build` produces a static site ready to deploy anywhere.</p>
49
+ </Step>
50
+ </Steps>
51
+ )
52
+
53
+ /**
54
+ * Smaller title size — useful for nested steps or sidebar callouts.
55
+ *
56
+ * @returns Steps with paragraph-sized titles
57
+ */
58
+ // oxlint-disable-next-line func-style -- Ladle stories use `export const`
59
+ export const ParagraphTitles: Story = () => (
60
+ <Steps titleSize="p">
61
+ <Step title="First check">
62
+ <p>Verify Node 24+ is installed.</p>
63
+ </Step>
64
+ <Step title="Second check">
65
+ <p>Confirm pnpm is on a recent version.</p>
66
+ </Step>
67
+ </Steps>
68
+ )
@@ -0,0 +1,100 @@
1
+ import { match, P } from 'massaman/match'
2
+ import React from 'react'
3
+
4
+ import { Icon } from './icon'
5
+
6
+ export interface StepsProps {
7
+ /**
8
+ * Heading level for step titles.
9
+ */
10
+ readonly titleSize?: 'h2' | 'h3' | 'p'
11
+ /**
12
+ * Step children to render in a vertical timeline.
13
+ */
14
+ readonly children: React.ReactNode
15
+ }
16
+
17
+ /**
18
+ * Vertical timeline stepper that renders numbered Step children
19
+ * with connecting lines between them.
20
+ *
21
+ * @param props - Steps configuration with optional title size
22
+ * @returns React element wrapping Step children in a timeline layout
23
+ */
24
+ export function Steps({ titleSize = 'h3', children }: StepsProps): React.ReactElement {
25
+ const mapped = React.Children.map(children, (child, index) =>
26
+ match(child)
27
+ .with(
28
+ P.when((c): c is React.ReactElement => React.isValidElement(c)),
29
+ (el) => React.cloneElement(el, { stepNumber: index + 1, titleSize } as Partial<StepProps>)
30
+ )
31
+ .otherwise(() => child)
32
+ )
33
+
34
+ return <div className="cp-steps">{mapped}</div>
35
+ }
36
+
37
+ export interface StepProps {
38
+ /**
39
+ * Title displayed next to the step indicator.
40
+ */
41
+ readonly title: string
42
+ /**
43
+ * Optional Iconify icon ID that replaces the step number in the circle.
44
+ */
45
+ readonly icon?: string
46
+ /**
47
+ * Explicit step number override. Injected automatically by Steps.
48
+ */
49
+ readonly stepNumber?: number
50
+ /**
51
+ * Heading level for the title. Injected automatically by Steps.
52
+ */
53
+ readonly titleSize?: 'h2' | 'h3' | 'p'
54
+ /**
55
+ * Arbitrary MDX content for this step.
56
+ */
57
+ readonly children: React.ReactNode
58
+ }
59
+
60
+ /**
61
+ * Individual step within a Steps timeline, rendering a numbered circle
62
+ * indicator (or icon), connecting line, title, and body content.
63
+ *
64
+ * @param props - Step configuration with title, optional icon, and content
65
+ * @returns React element for a single timeline step
66
+ */
67
+ export function Step({
68
+ title,
69
+ icon,
70
+ stepNumber = 1,
71
+ titleSize = 'h3',
72
+ children,
73
+ }: StepProps): React.ReactElement {
74
+ const indicator = match(icon)
75
+ .with(P.nonNullable, (i) => (
76
+ <span className="cp-step__indicator">
77
+ <Icon icon={i} />
78
+ </span>
79
+ ))
80
+ .otherwise(() => <span className="cp-step__indicator">{stepNumber}</span>)
81
+
82
+ const titleEl = match(titleSize)
83
+ .with('h2', () => <h2 className="cp-step__title">{title}</h2>)
84
+ .with('h3', () => <h3 className="cp-step__title">{title}</h3>)
85
+ .with('p', () => <p className="cp-step__title">{title}</p>)
86
+ .exhaustive()
87
+
88
+ return (
89
+ <div className="cp-step">
90
+ <div className="cp-step__rail">
91
+ {indicator}
92
+ <div className="cp-step__connector" />
93
+ </div>
94
+ <div className="cp-step__body">
95
+ {titleEl}
96
+ <div className="cp-step__content">{children}</div>
97
+ </div>
98
+ </div>
99
+ )
100
+ }
@@ -0,0 +1,29 @@
1
+ import type { Story } from '@ladle/react'
2
+
3
+ import { TechIconTable } from './tech-icon-table.tsx'
4
+
5
+ const meta = {
6
+ title: 'Icons / Tech Icon Table',
7
+ }
8
+
9
+ export default meta
10
+
11
+ /**
12
+ * Default — table of language icons matching what auto-generated
13
+ * reference docs render.
14
+ *
15
+ * @returns Tech-icon table with 6 entries
16
+ */
17
+ // oxlint-disable-next-line func-style -- Ladle stories use `export const`
18
+ export const Default: Story = () => (
19
+ <TechIconTable
20
+ entries={[
21
+ { tag: 'typescript', icon: 'devicon:typescript', label: 'TypeScript' },
22
+ { tag: 'javascript', icon: 'devicon:javascript', label: 'JavaScript' },
23
+ { tag: 'python', icon: 'devicon:python', label: 'Python' },
24
+ { tag: 'rust', icon: 'devicon:rust', label: 'Rust' },
25
+ { tag: 'go', icon: 'devicon:go', label: 'Go' },
26
+ { tag: 'java', icon: 'devicon:java', label: 'Java' },
27
+ ]}
28
+ />
29
+ )
@@ -0,0 +1,71 @@
1
+ import type React from 'react'
2
+
3
+ import { Icon } from './icon'
4
+
5
+ export interface TechIconEntry {
6
+ readonly tag: string
7
+ readonly icon: string
8
+ readonly label: string
9
+ }
10
+
11
+ export interface TechIconTableProps {
12
+ readonly entries: readonly TechIconEntry[]
13
+ }
14
+
15
+ const tableStyle: React.CSSProperties = {
16
+ width: '100%',
17
+ }
18
+
19
+ const iconCellStyle: React.CSSProperties = {
20
+ width: 48,
21
+ textAlign: 'center' as const,
22
+ }
23
+
24
+ const iconWrapperStyle: React.CSSProperties = {
25
+ display: 'inline-flex',
26
+ alignItems: 'center',
27
+ justifyContent: 'center',
28
+ width: 36,
29
+ height: 36,
30
+ background: 'var(--cp-c-bg-icon)',
31
+ }
32
+
33
+ /**
34
+ * Renders a table of technology icons with tag, label, and identifier columns.
35
+ * Used in generated icon reference docs.
36
+ *
37
+ * @param props - Props with an array of tech icon entries to render
38
+ * @returns React element with an icon reference table
39
+ */
40
+ export function TechIconTable({ entries }: TechIconTableProps): React.ReactElement {
41
+ return (
42
+ <table style={tableStyle}>
43
+ <thead>
44
+ <tr>
45
+ <th style={iconCellStyle} />
46
+ <th>Tag</th>
47
+ <th>Label</th>
48
+ <th>Identifier</th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+ {entries.map((entry) => (
53
+ <tr key={entry.tag}>
54
+ <td style={iconCellStyle}>
55
+ <div style={iconWrapperStyle}>
56
+ <Icon icon={entry.icon} width={20} height={20} />
57
+ </div>
58
+ </td>
59
+ <td>
60
+ <code>{entry.tag}</code>
61
+ </td>
62
+ <td>{entry.label}</td>
63
+ <td>
64
+ <code>{entry.icon}</code>
65
+ </td>
66
+ </tr>
67
+ ))}
68
+ </tbody>
69
+ </table>
70
+ )
71
+ }
@@ -0,0 +1,40 @@
1
+ import type { Story } from '@ladle/react'
2
+
3
+ import { TechTag } from './tech-tag.tsx'
4
+
5
+ const meta = {
6
+ title: 'Icons / Tech Tag',
7
+ }
8
+
9
+ export default meta
10
+
11
+ /**
12
+ * Default — resolves `typescript` against the TECH_ICONS map and
13
+ * renders the icon + label pair.
14
+ *
15
+ * @returns Single tech tag
16
+ */
17
+ // oxlint-disable-next-line func-style -- Ladle stories use `export const`
18
+ export const Default: Story = () => <TechTag name="typescript" />
19
+
20
+ /**
21
+ * Several common language tags laid out inline.
22
+ *
23
+ * @returns Inline list of tags
24
+ */
25
+ // oxlint-disable-next-line func-style -- Ladle stories use `export const`
26
+ export const Languages: Story = () => (
27
+ <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
28
+ {['typescript', 'javascript', 'python', 'rust', 'go', 'java', 'ruby', 'php'].map((n) => (
29
+ <TechTag key={n} name={n} />
30
+ ))}
31
+ </div>
32
+ )
33
+
34
+ /**
35
+ * Unknown tag — falls back to the raw name without an icon.
36
+ *
37
+ * @returns Tag without an icon
38
+ */
39
+ // oxlint-disable-next-line func-style -- Ladle stories use `export const`
40
+ export const Fallback: Story = () => <TechTag name="not-a-real-tech-name" />