rizzo-css 0.0.17 → 0.0.18

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 (260) hide show
  1. package/README.md +4 -4
  2. package/bin/rizzo-css.js +151 -103
  3. package/package.json +7 -3
  4. package/scaffold/astro-minimal/.env.example +3 -0
  5. package/scaffold/astro-minimal/README.md +36 -0
  6. package/scaffold/astro-minimal/package.json +13 -0
  7. package/scaffold/astro-minimal/src/layouts/Layout.astro +28 -0
  8. package/scaffold/astro-minimal/src/pages/index.astro +10 -0
  9. package/scaffold/svelte-minimal/.env.example +3 -0
  10. package/scaffold/svelte-minimal/README.md +37 -0
  11. package/scaffold/svelte-minimal/package.json +20 -0
  12. package/scaffold/svelte-minimal/src/app.d.ts +11 -0
  13. package/scaffold/svelte-minimal/src/app.html +15 -0
  14. package/scaffold/svelte-minimal/src/routes/+layout.svelte +1 -0
  15. package/scaffold/svelte-minimal/src/routes/+page.svelte +5 -0
  16. package/scaffold/svelte-minimal/svelte.config.js +10 -0
  17. package/scaffold/svelte-minimal/tsconfig.json +11 -0
  18. package/scaffold/vanilla/README.md +4 -4
  19. package/scaffold/vanilla/components/accordion.html +8 -0
  20. package/scaffold/vanilla/components/alert.html +8 -0
  21. package/scaffold/vanilla/components/avatar.html +8 -0
  22. package/scaffold/vanilla/components/badge.html +8 -0
  23. package/scaffold/vanilla/components/breadcrumb.html +8 -0
  24. package/scaffold/vanilla/components/button.html +8 -0
  25. package/scaffold/vanilla/components/cards.html +8 -0
  26. package/scaffold/vanilla/components/copy-to-clipboard.html +8 -0
  27. package/scaffold/vanilla/components/divider.html +8 -0
  28. package/scaffold/vanilla/components/dropdown.html +8 -0
  29. package/scaffold/vanilla/components/forms.html +8 -0
  30. package/scaffold/vanilla/components/icons.html +8 -0
  31. package/scaffold/vanilla/components/index.html +8 -0
  32. package/scaffold/vanilla/components/modal.html +8 -0
  33. package/scaffold/vanilla/components/navbar.html +8 -0
  34. package/scaffold/vanilla/components/pagination.html +8 -0
  35. package/scaffold/vanilla/components/progress-bar.html +8 -0
  36. package/scaffold/vanilla/components/search.html +8 -0
  37. package/scaffold/vanilla/components/settings.html +8 -0
  38. package/scaffold/vanilla/components/spinner.html +8 -0
  39. package/scaffold/vanilla/components/table.html +8 -0
  40. package/scaffold/vanilla/components/tabs.html +8 -0
  41. package/scaffold/vanilla/components/theme-switcher.html +8 -0
  42. package/scaffold/vanilla/components/toast.html +8 -0
  43. package/scaffold/vanilla/components/tooltip.html +8 -0
  44. package/scaffold/vanilla/index.html +8 -0
  45. package/scaffold/astro-app/README.md +0 -43
  46. package/scaffold/astro-app/package.json +0 -1
  47. package/scaffold/astro-app/src/components/Accordion.astro +0 -178
  48. package/scaffold/astro-app/src/components/Alert.astro +0 -131
  49. package/scaffold/astro-app/src/components/Avatar.astro +0 -59
  50. package/scaffold/astro-app/src/components/Badge.astro +0 -24
  51. package/scaffold/astro-app/src/components/Breadcrumb.astro +0 -61
  52. package/scaffold/astro-app/src/components/Button.astro +0 -3
  53. package/scaffold/astro-app/src/components/Card.astro +0 -18
  54. package/scaffold/astro-app/src/components/Checkbox.astro +0 -38
  55. package/scaffold/astro-app/src/components/CliCommandTabs.astro +0 -90
  56. package/scaffold/astro-app/src/components/CodeBlock.astro +0 -393
  57. package/scaffold/astro-app/src/components/CopyToClipboard.astro +0 -219
  58. package/scaffold/astro-app/src/components/Divider.astro +0 -37
  59. package/scaffold/astro-app/src/components/DocsSidebar.astro +0 -51
  60. package/scaffold/astro-app/src/components/Dropdown.astro +0 -807
  61. package/scaffold/astro-app/src/components/FormGroup.astro +0 -59
  62. package/scaffold/astro-app/src/components/FrameworkSwitcher.astro +0 -72
  63. package/scaffold/astro-app/src/components/Input.astro +0 -59
  64. package/scaffold/astro-app/src/components/Modal.astro +0 -212
  65. package/scaffold/astro-app/src/components/Navbar.astro +0 -623
  66. package/scaffold/astro-app/src/components/PackageInstallTabs.astro +0 -87
  67. package/scaffold/astro-app/src/components/Pagination.astro +0 -240
  68. package/scaffold/astro-app/src/components/ProgressBar.astro +0 -65
  69. package/scaffold/astro-app/src/components/Radio.astro +0 -38
  70. package/scaffold/astro-app/src/components/Search.astro +0 -1259
  71. package/scaffold/astro-app/src/components/Select.astro +0 -49
  72. package/scaffold/astro-app/src/components/Settings.astro +0 -382
  73. package/scaffold/astro-app/src/components/Spinner.astro +0 -30
  74. package/scaffold/astro-app/src/components/Table.astro +0 -181
  75. package/scaffold/astro-app/src/components/Tabs.astro +0 -223
  76. package/scaffold/astro-app/src/components/Textarea.astro +0 -58
  77. package/scaffold/astro-app/src/components/ThemeIcon.astro +0 -50
  78. package/scaffold/astro-app/src/components/ThemeSwitcher.astro +0 -504
  79. package/scaffold/astro-app/src/components/Toast.astro +0 -30
  80. package/scaffold/astro-app/src/components/Tooltip.astro +0 -32
  81. package/scaffold/astro-app/src/components/icons/Brush.astro +0 -10
  82. package/scaffold/astro-app/src/components/icons/Cake.astro +0 -11
  83. package/scaffold/astro-app/src/components/icons/Check.astro +0 -29
  84. package/scaffold/astro-app/src/components/icons/Cherry.astro +0 -11
  85. package/scaffold/astro-app/src/components/icons/ChevronDown.astro +0 -29
  86. package/scaffold/astro-app/src/components/icons/Circle.astro +0 -29
  87. package/scaffold/astro-app/src/components/icons/Close.astro +0 -30
  88. package/scaffold/astro-app/src/components/icons/Cmd.astro +0 -26
  89. package/scaffold/astro-app/src/components/icons/Copy.astro +0 -30
  90. package/scaffold/astro-app/src/components/icons/Eye.astro +0 -30
  91. package/scaffold/astro-app/src/components/icons/Filter.astro +0 -29
  92. package/scaffold/astro-app/src/components/icons/Flame.astro +0 -28
  93. package/scaffold/astro-app/src/components/icons/Flower.astro +0 -11
  94. package/scaffold/astro-app/src/components/icons/Gear.astro +0 -30
  95. package/scaffold/astro-app/src/components/icons/Heart.astro +0 -28
  96. package/scaffold/astro-app/src/components/icons/IceCream.astro +0 -31
  97. package/scaffold/astro-app/src/components/icons/Leaf.astro +0 -29
  98. package/scaffold/astro-app/src/components/icons/Lemon.astro +0 -11
  99. package/scaffold/astro-app/src/components/icons/Moon.astro +0 -29
  100. package/scaffold/astro-app/src/components/icons/Owl.astro +0 -34
  101. package/scaffold/astro-app/src/components/icons/Palette.astro +0 -33
  102. package/scaffold/astro-app/src/components/icons/Rainbow.astro +0 -31
  103. package/scaffold/astro-app/src/components/icons/Search.astro +0 -30
  104. package/scaffold/astro-app/src/components/icons/Shield.astro +0 -28
  105. package/scaffold/astro-app/src/components/icons/Snowflake.astro +0 -34
  106. package/scaffold/astro-app/src/components/icons/Sort.astro +0 -30
  107. package/scaffold/astro-app/src/components/icons/Sun.astro +0 -29
  108. package/scaffold/astro-app/src/components/icons/Sunset.astro +0 -10
  109. package/scaffold/astro-app/src/components/icons/Zap.astro +0 -9
  110. package/scaffold/astro-app/src/components/icons/devicons/Astro.astro +0 -53
  111. package/scaffold/astro-app/src/components/icons/devicons/Bash.astro +0 -34
  112. package/scaffold/astro-app/src/components/icons/devicons/Css3.astro +0 -29
  113. package/scaffold/astro-app/src/components/icons/devicons/Git.astro +0 -24
  114. package/scaffold/astro-app/src/components/icons/devicons/Html5.astro +0 -27
  115. package/scaffold/astro-app/src/components/icons/devicons/Javascript.astro +0 -25
  116. package/scaffold/astro-app/src/components/icons/devicons/Nodejs.astro +0 -47
  117. package/scaffold/astro-app/src/components/icons/devicons/Plaintext.astro +0 -33
  118. package/scaffold/astro-app/src/components/icons/devicons/React.astro +0 -27
  119. package/scaffold/astro-app/src/components/icons/devicons/Svelte.astro +0 -25
  120. package/scaffold/astro-app/src/components/icons/devicons/Vue.astro +0 -26
  121. package/scaffold/astro-app/src/config/frameworks.ts +0 -26
  122. package/scaffold/astro-app/src/config/themes.ts +0 -54
  123. package/scaffold/astro-app/src/layouts/DocsLayout.astro +0 -263
  124. package/scaffold/astro-app/src/layouts/Layout.astro +0 -41
  125. package/scaffold/astro-app/src/pages/components/accordion.astro +0 -172
  126. package/scaffold/astro-app/src/pages/components/alert.astro +0 -250
  127. package/scaffold/astro-app/src/pages/components/avatar.astro +0 -102
  128. package/scaffold/astro-app/src/pages/components/badge.astro +0 -119
  129. package/scaffold/astro-app/src/pages/components/breadcrumb.astro +0 -124
  130. package/scaffold/astro-app/src/pages/components/button.astro +0 -74
  131. package/scaffold/astro-app/src/pages/components/cards.astro +0 -247
  132. package/scaffold/astro-app/src/pages/components/copy-to-clipboard.astro +0 -49
  133. package/scaffold/astro-app/src/pages/components/divider.astro +0 -74
  134. package/scaffold/astro-app/src/pages/components/dropdown.astro +0 -394
  135. package/scaffold/astro-app/src/pages/components/forms.astro +0 -367
  136. package/scaffold/astro-app/src/pages/components/icons.astro +0 -246
  137. package/scaffold/astro-app/src/pages/components/modal.astro +0 -152
  138. package/scaffold/astro-app/src/pages/components/navbar.astro +0 -80
  139. package/scaffold/astro-app/src/pages/components/pagination.astro +0 -126
  140. package/scaffold/astro-app/src/pages/components/progress-bar.astro +0 -94
  141. package/scaffold/astro-app/src/pages/components/search.astro +0 -155
  142. package/scaffold/astro-app/src/pages/components/settings.astro +0 -78
  143. package/scaffold/astro-app/src/pages/components/spinner.astro +0 -81
  144. package/scaffold/astro-app/src/pages/components/table.astro +0 -144
  145. package/scaffold/astro-app/src/pages/components/tabs.astro +0 -220
  146. package/scaffold/astro-app/src/pages/components/theme-switcher.astro +0 -69
  147. package/scaffold/astro-app/src/pages/components/toast.astro +0 -157
  148. package/scaffold/astro-app/src/pages/components/tooltip.astro +0 -209
  149. package/scaffold/astro-app/src/pages/components.astro +0 -290
  150. package/scaffold/astro-app/src/pages/docs/accessibility.astro +0 -9
  151. package/scaffold/astro-app/src/pages/docs/colors.astro +0 -9
  152. package/scaffold/astro-app/src/pages/docs/design-system.astro +0 -9
  153. package/scaffold/astro-app/src/pages/docs/getting-started.astro +0 -9
  154. package/scaffold/astro-app/src/pages/docs/index.astro +0 -15
  155. package/scaffold/astro-app/src/pages/docs/themes/[theme].astro +0 -14
  156. package/scaffold/astro-app/src/pages/docs/theming.astro +0 -10
  157. package/scaffold/astro-app/src/pages/index.astro +0 -24
  158. package/scaffold/svelte-app/README.md +0 -39
  159. package/scaffold/svelte-app/package.json +0 -22
  160. package/scaffold/svelte-app/src/app.d.ts +0 -28
  161. package/scaffold/svelte-app/src/app.html +0 -21
  162. package/scaffold/svelte-app/src/lib/assets/favicon.svg +0 -1
  163. package/scaffold/svelte-app/src/lib/rizzo/Accordion.svelte +0 -128
  164. package/scaffold/svelte-app/src/lib/rizzo/Alert.svelte +0 -85
  165. package/scaffold/svelte-app/src/lib/rizzo/Avatar.svelte +0 -39
  166. package/scaffold/svelte-app/src/lib/rizzo/Badge.svelte +0 -31
  167. package/scaffold/svelte-app/src/lib/rizzo/Breadcrumb.svelte +0 -49
  168. package/scaffold/svelte-app/src/lib/rizzo/Button.svelte +0 -27
  169. package/scaffold/svelte-app/src/lib/rizzo/Card.svelte +0 -17
  170. package/scaffold/svelte-app/src/lib/rizzo/Checkbox.svelte +0 -37
  171. package/scaffold/svelte-app/src/lib/rizzo/CopyToClipboard.svelte +0 -79
  172. package/scaffold/svelte-app/src/lib/rizzo/Divider.svelte +0 -28
  173. package/scaffold/svelte-app/src/lib/rizzo/Dropdown.svelte +0 -254
  174. package/scaffold/svelte-app/src/lib/rizzo/FormGroup.svelte +0 -51
  175. package/scaffold/svelte-app/src/lib/rizzo/Input.svelte +0 -59
  176. package/scaffold/svelte-app/src/lib/rizzo/Modal.svelte +0 -157
  177. package/scaffold/svelte-app/src/lib/rizzo/Pagination.svelte +0 -93
  178. package/scaffold/svelte-app/src/lib/rizzo/ProgressBar.svelte +0 -58
  179. package/scaffold/svelte-app/src/lib/rizzo/Radio.svelte +0 -38
  180. package/scaffold/svelte-app/src/lib/rizzo/Select.svelte +0 -51
  181. package/scaffold/svelte-app/src/lib/rizzo/Spinner.svelte +0 -14
  182. package/scaffold/svelte-app/src/lib/rizzo/Table.svelte +0 -158
  183. package/scaffold/svelte-app/src/lib/rizzo/Tabs.svelte +0 -117
  184. package/scaffold/svelte-app/src/lib/rizzo/Textarea.svelte +0 -59
  185. package/scaffold/svelte-app/src/lib/rizzo/ThemeIcon.svelte +0 -54
  186. package/scaffold/svelte-app/src/lib/rizzo/ThemeSwitcher.svelte +0 -315
  187. package/scaffold/svelte-app/src/lib/rizzo/Toast.svelte +0 -33
  188. package/scaffold/svelte-app/src/lib/rizzo/Tooltip.svelte +0 -19
  189. package/scaffold/svelte-app/src/lib/rizzo/icons/Check.svelte +0 -29
  190. package/scaffold/svelte-app/src/lib/rizzo/icons/ChevronDown.svelte +0 -29
  191. package/scaffold/svelte-app/src/lib/rizzo/icons/Circle.svelte +0 -29
  192. package/scaffold/svelte-app/src/lib/rizzo/icons/Close.svelte +0 -30
  193. package/scaffold/svelte-app/src/lib/rizzo/icons/Cmd.svelte +0 -27
  194. package/scaffold/svelte-app/src/lib/rizzo/icons/Copy.svelte +0 -30
  195. package/scaffold/svelte-app/src/lib/rizzo/icons/Eye.svelte +0 -30
  196. package/scaffold/svelte-app/src/lib/rizzo/icons/Filter.svelte +0 -29
  197. package/scaffold/svelte-app/src/lib/rizzo/icons/Gear.svelte +0 -30
  198. package/scaffold/svelte-app/src/lib/rizzo/icons/IceCream.svelte +0 -31
  199. package/scaffold/svelte-app/src/lib/rizzo/icons/Moon.svelte +0 -29
  200. package/scaffold/svelte-app/src/lib/rizzo/icons/Owl.svelte +0 -34
  201. package/scaffold/svelte-app/src/lib/rizzo/icons/Palette.svelte +0 -33
  202. package/scaffold/svelte-app/src/lib/rizzo/icons/Rainbow.svelte +0 -31
  203. package/scaffold/svelte-app/src/lib/rizzo/icons/Search.svelte +0 -30
  204. package/scaffold/svelte-app/src/lib/rizzo/icons/Snowflake.svelte +0 -34
  205. package/scaffold/svelte-app/src/lib/rizzo/icons/Sort.svelte +0 -30
  206. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Astro.svelte +0 -45
  207. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Bash.svelte +0 -28
  208. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Css3.svelte +0 -23
  209. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Git.svelte +0 -18
  210. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Html5.svelte +0 -21
  211. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Javascript.svelte +0 -19
  212. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Nodejs.svelte +0 -44
  213. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Plaintext.svelte +0 -24
  214. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/React.svelte +0 -21
  215. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/SvelteIcon.svelte +0 -19
  216. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Vue.svelte +0 -20
  217. package/scaffold/svelte-app/src/lib/rizzo/index.ts +0 -35
  218. package/scaffold/svelte-app/src/lib/rizzo-docs/CodeBlock.svelte +0 -239
  219. package/scaffold/svelte-app/src/lib/rizzo-docs/SvelteDocPage.svelte +0 -99
  220. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/AccordionDoc.svelte +0 -53
  221. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/AlertDoc.svelte +0 -114
  222. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/AvatarDoc.svelte +0 -92
  223. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/BadgeDoc.svelte +0 -60
  224. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/BreadcrumbDoc.svelte +0 -55
  225. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ButtonDoc.svelte +0 -55
  226. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/CardsDoc.svelte +0 -173
  227. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ComingSoon.svelte +0 -12
  228. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ComponentsOverview.svelte +0 -92
  229. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/CopyToClipboardDoc.svelte +0 -26
  230. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/DividerDoc.svelte +0 -105
  231. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/DropdownDoc.svelte +0 -161
  232. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/FormsDoc.svelte +0 -375
  233. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/IconsDoc.svelte +0 -246
  234. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/Index.svelte +0 -8
  235. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ModalDoc.svelte +0 -50
  236. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/NavbarDoc.svelte +0 -79
  237. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/PaginationDoc.svelte +0 -44
  238. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ProgressBarDoc.svelte +0 -95
  239. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/SearchDoc.svelte +0 -147
  240. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/SettingsDoc.svelte +0 -158
  241. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/SpinnerDoc.svelte +0 -41
  242. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/TableDoc.svelte +0 -116
  243. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/TabsDoc.svelte +0 -152
  244. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ThemeSwitcherDoc.svelte +0 -189
  245. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/Theming.svelte +0 -6
  246. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ToastDoc.svelte +0 -136
  247. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/TooltipDoc.svelte +0 -57
  248. package/scaffold/svelte-app/src/routes/+layout.svelte +0 -10
  249. package/scaffold/svelte-app/src/routes/+page.svelte +0 -31
  250. package/scaffold/svelte-app/src/routes/components/+page.svelte +0 -4
  251. package/scaffold/svelte-app/src/routes/components/[slug]/+page.svelte +0 -7
  252. package/scaffold/svelte-app/static/robots.txt +0 -3
  253. package/scaffold/svelte-app/svelte.config.js +0 -13
  254. package/scaffold/svelte-app/tsconfig.json +0 -21
  255. package/scaffold/svelte-app/vite.config.ts +0 -6
  256. /package/scaffold/{astro-app → astro-minimal}/astro.config.mjs +0 -0
  257. /package/scaffold/{astro-app → astro-minimal}/public/.gitkeep +0 -0
  258. /package/scaffold/{astro-app → astro-minimal}/public/favicon.svg +0 -0
  259. /package/scaffold/{astro-app → astro-minimal}/tsconfig.json +0 -0
  260. /package/scaffold/{svelte-app → svelte-minimal}/static/.gitkeep +0 -0
@@ -1,623 +0,0 @@
1
- ---
2
- import Gear from './icons/Gear.astro';
3
- import Search from './Search.astro';
4
- import { getFrameworkFromPath } from '../config/frameworks.js';
5
- import { DOCS_NAV } from '../config/docsNav';
6
-
7
- // Extend Window interface for openSettings
8
- declare global {
9
- interface Window {
10
- openSettings?: () => void;
11
- }
12
- }
13
-
14
- interface Props {
15
- siteName?: string;
16
- logo?: string;
17
- }
18
-
19
- const { siteName = 'Rizzo CSS', logo } = Astro.props;
20
-
21
- // Get current URL pathname and framework for component links only
22
- const currentPath = Astro.url.pathname;
23
- const { framework } = getFrameworkFromPath(currentPath);
24
- const docsPrefix = framework.pathPrefix;
25
-
26
- /** Use only for component routes; docs and themes are general (no framework prefix). */
27
- function componentHref(path: string): string {
28
- if (!path.startsWith('/docs')) return path;
29
- return docsPrefix + path.slice('/docs'.length) || docsPrefix || '/';
30
- }
31
-
32
- // Navigation links with optional sub-links (doc paths are rewritten by docHref)
33
- interface NavLink {
34
- href: string;
35
- label: string;
36
- subLinks?: Array<{ href: string; label: string }>;
37
- /** Docs dropdown: grouped sections (Introduction, Foundations) */
38
- docsMenu?: {
39
- groups: Array<{ label: string; links: Array<{ href: string; label: string }> }>;
40
- };
41
- /** Components dropdown: overview full width, then two columns of links */
42
- componentsMenu?: {
43
- overview: { href: string; label: string };
44
- links: Array<{ href: string; label: string }>;
45
- };
46
- }
47
-
48
- // Build docs menu from DOCS_NAV (Introduction + Foundations only; Components has its own nav menu)
49
- const docsMenuGroups = DOCS_NAV.filter((group) => group.label !== 'Components').map((group) => ({
50
- label: group.label,
51
- links: group.links.map((link) => ({
52
- href: link.frameworkOnly ? `${docsPrefix}/${link.href}` : `/docs/${link.href}`,
53
- label: link.label,
54
- })),
55
- }));
56
-
57
- const navLinks: NavLink[] = [
58
- { href: '/', label: 'Home' },
59
- {
60
- href: '/docs/getting-started',
61
- label: 'Docs',
62
- docsMenu: { groups: docsMenuGroups },
63
- },
64
- {
65
- href: componentHref('/docs/components'),
66
- label: 'Components',
67
- componentsMenu: {
68
- overview: { href: componentHref('/docs/components'), label: 'Overview' },
69
- links: [
70
- { href: componentHref('/docs/components/accordion'), label: 'Accordion' },
71
- { href: componentHref('/docs/components/alert'), label: 'Alert' },
72
- { href: componentHref('/docs/components/avatar'), label: 'Avatar' },
73
- { href: componentHref('/docs/components/badge'), label: 'Badge' },
74
- { href: componentHref('/docs/components/breadcrumb'), label: 'Breadcrumb' },
75
- { href: componentHref('/docs/components/button'), label: 'Button' },
76
- { href: componentHref('/docs/components/cards'), label: 'Cards' },
77
- { href: componentHref('/docs/components/copy-to-clipboard'), label: 'CopyToClipboard' },
78
- { href: componentHref('/docs/components/divider'), label: 'Divider' },
79
- { href: componentHref('/docs/components/dropdown'), label: 'Dropdown' },
80
- { href: componentHref('/docs/components/forms'), label: 'Forms' },
81
- { href: componentHref('/docs/components/icons'), label: 'Icons' },
82
- { href: componentHref('/docs/components/modal'), label: 'Modal' },
83
- { href: componentHref('/docs/components/navbar'), label: 'Navbar' },
84
- { href: componentHref('/docs/components/pagination'), label: 'Pagination' },
85
- { href: componentHref('/docs/components/progress-bar'), label: 'Progress Bar' },
86
- { href: componentHref('/docs/components/search'), label: 'Search' },
87
- { href: componentHref('/docs/components/settings'), label: 'Settings' },
88
- { href: componentHref('/docs/components/spinner'), label: 'Spinner' },
89
- { href: componentHref('/docs/components/table'), label: 'Table' },
90
- { href: componentHref('/docs/components/tabs'), label: 'Tabs' },
91
- { href: componentHref('/docs/components/theme-switcher'), label: 'Theme Switcher' },
92
- { href: componentHref('/docs/components/toast'), label: 'Toast' },
93
- { href: componentHref('/docs/components/tooltip'), label: 'Tooltip' },
94
- ],
95
- },
96
- },
97
- ];
98
- ---
99
-
100
- <nav class="navbar" role="navigation" aria-label="Main navigation">
101
- <div class="navbar__container">
102
- <div class="navbar__brand">
103
- {logo && (
104
- <img src={logo} alt={`${siteName} logo`} class="navbar__logo" />
105
- )}
106
- <a href="/" class="navbar__brand-link" aria-label={`${siteName} home`}>
107
- {siteName}
108
- </a>
109
- </div>
110
-
111
- <div class="navbar__actions-desktop">
112
- <Search />
113
- <div class="tooltip-wrapper" aria-describedby="navbar-settings-tooltip">
114
- <button
115
- class="navbar__settings-btn"
116
- type="button"
117
- aria-label="Open settings"
118
- onclick="window.openSettings && window.openSettings()"
119
- >
120
- <Gear class="navbar__settings-icon" width={20} height={20} />
121
- <span class="navbar__settings-label">Settings</span>
122
- </button>
123
- <span class="tooltip tooltip--bottom" id="navbar-settings-tooltip" role="tooltip" aria-hidden="true">Settings</span>
124
- </div>
125
- </div>
126
-
127
- <button
128
- class="navbar__toggle"
129
- type="button"
130
- aria-expanded="false"
131
- aria-controls="navbar-menu"
132
- aria-label="Toggle navigation menu"
133
- id="navbar-toggle"
134
- >
135
- <span class="sr-only">Menu</span>
136
- <span class="navbar__toggle-icon" aria-hidden="true">
137
- <span></span>
138
- <span></span>
139
- <span></span>
140
- </span>
141
- </button>
142
-
143
- <div class="navbar__menu" id="navbar-menu" role="menu">
144
- {navLinks.map((link) => {
145
- const isActive = currentPath === link.href || (link.href !== '/' && currentPath.startsWith(link.href));
146
- const hasSubLinks = (link.subLinks && link.subLinks.length > 0) || !!link.docsMenu || !!link.componentsMenu;
147
- const subLinkId = hasSubLinks ? `navbar-submenu-${link.label.toLowerCase().replace(/\s+/g, '-')}` : undefined;
148
-
149
- return (
150
- <div class={`navbar__item ${hasSubLinks ? 'navbar__item--has-dropdown' : ''}`}>
151
- {hasSubLinks ? (
152
- <div
153
- class="navbar__link"
154
- role="menuitem"
155
- tabindex={0}
156
- aria-label={link.label}
157
- aria-expanded="false"
158
- aria-haspopup="true"
159
- aria-controls={subLinkId}
160
- data-dropdown-toggle={subLinkId}
161
- data-dropdown-href={link.href}
162
- >
163
- {link.label}
164
- <svg class="navbar__dropdown-icon" width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
165
- <path d="M2 4l4 4 4-4"/>
166
- </svg>
167
- </div>
168
- ) : (
169
- <div
170
- class="navbar__link"
171
- role="menuitem"
172
- tabindex={0}
173
- aria-label={link.label}
174
- aria-current={isActive ? 'page' : undefined}
175
- data-nav-href={link.href}
176
- >
177
- {link.label}
178
- </div>
179
- )}
180
- {link.docsMenu ? (
181
- <ul class="navbar__submenu navbar__submenu--docs" id={subLinkId} role="menu" aria-label={`${link.label} submenu`}>
182
- {link.docsMenu.groups.map((group) => (
183
- <li class="navbar__submenu-group" role="none">
184
- <span class="navbar__submenu-group-label" aria-hidden="true">{group.label}</span>
185
- <ul class="navbar__submenu-list" role="group" aria-label={group.label}>
186
- {group.links.map((subLink) => {
187
- const isSubActive = currentPath === subLink.href;
188
- return (
189
- <li role="none">
190
- <div
191
- class="navbar__sublink"
192
- role="menuitem"
193
- tabindex={-1}
194
- aria-label={subLink.label}
195
- aria-current={isSubActive ? 'page' : undefined}
196
- data-nav-href={subLink.href}
197
- >
198
- {subLink.label}
199
- </div>
200
- </li>
201
- );
202
- })}
203
- </ul>
204
- </li>
205
- ))}
206
- </ul>
207
- ) : link.componentsMenu ? (
208
- <ul class="navbar__submenu navbar__submenu--components" id={subLinkId} role="menu" aria-label={`${link.label} submenu`}>
209
- <li class="navbar__submenu-overview" role="none">
210
- <div
211
- class="navbar__sublink navbar__sublink--overview"
212
- role="menuitem"
213
- tabindex={-1}
214
- aria-label={link.componentsMenu.overview.label}
215
- aria-current={currentPath === link.componentsMenu.overview.href ? 'page' : undefined}
216
- data-nav-href={link.componentsMenu.overview.href}
217
- >
218
- {link.componentsMenu.overview.label}
219
- </div>
220
- </li>
221
- <li class="navbar__submenu-components-grid" role="none">
222
- <div class="navbar__submenu-column">
223
- {link.componentsMenu.links.slice(0, Math.ceil(link.componentsMenu.links.length / 2)).map((subLink) => {
224
- const isSubActive = currentPath === subLink.href;
225
- return (
226
- <div
227
- class="navbar__sublink"
228
- role="menuitem"
229
- tabindex={-1}
230
- aria-label={subLink.label}
231
- aria-current={isSubActive ? 'page' : undefined}
232
- data-nav-href={subLink.href}
233
- >
234
- {subLink.label}
235
- </div>
236
- );
237
- })}
238
- </div>
239
- <div class="navbar__submenu-column">
240
- {link.componentsMenu.links.slice(Math.ceil(link.componentsMenu.links.length / 2)).map((subLink) => {
241
- const isSubActive = currentPath === subLink.href;
242
- return (
243
- <div
244
- class="navbar__sublink"
245
- role="menuitem"
246
- tabindex={-1}
247
- aria-label={subLink.label}
248
- aria-current={isSubActive ? 'page' : undefined}
249
- data-nav-href={subLink.href}
250
- >
251
- {subLink.label}
252
- </div>
253
- );
254
- })}
255
- </div>
256
- </li>
257
- </ul>
258
- ) : hasSubLinks && link.subLinks ? (
259
- <ul class="navbar__submenu" id={subLinkId} role="menu" aria-label={`${link.label} submenu`}>
260
- {link.subLinks.map((subLink) => {
261
- const isSubActive = currentPath === subLink.href;
262
- return (
263
- <li role="none">
264
- <div
265
- class="navbar__sublink"
266
- role="menuitem"
267
- tabindex={-1}
268
- aria-label={subLink.label}
269
- aria-current={isSubActive ? 'page' : undefined}
270
- data-nav-href={subLink.href}
271
- >
272
- {subLink.label}
273
- </div>
274
- </li>
275
- );
276
- })}
277
- </ul>
278
- ) : null}
279
- </div>
280
- );
281
- })}
282
- </div>
283
- </div>
284
- </nav>
285
-
286
- <script>
287
- (function initNavbar() {
288
- const navbar = document.querySelector('.navbar');
289
- if (!navbar) return;
290
-
291
- const menuToggleBtn = document.getElementById('navbar-toggle');
292
- const menu = navbar.querySelector('.navbar__menu');
293
-
294
- if (!menuToggleBtn || !menu) return;
295
-
296
- const toggleMenu = (open?: boolean) => {
297
- const isOpen = open !== undefined ? open : menu.classList.contains('navbar__menu--open');
298
- const willBeOpen = !isOpen;
299
-
300
- // On mobile, close search if it's open when opening menu
301
- const isMobile = window.innerWidth <= 1023;
302
- if (isMobile && !isOpen) {
303
- // Menu is about to open, close any open search instance
304
- document.querySelectorAll('[data-search]').forEach((search) => {
305
- const panel = search.querySelector('.search__panel');
306
- if (panel?.getAttribute('aria-hidden') === 'false') {
307
- const el = search as Element & { __searchInstance?: { closeSearch?: () => void } };
308
- if (el?.__searchInstance?.closeSearch) {
309
- el.__searchInstance.closeSearch();
310
- } else {
311
- const overlay = search.querySelector('[data-search-overlay]');
312
- if (overlay instanceof HTMLElement) overlay.click();
313
- }
314
- }
315
- });
316
- }
317
-
318
- // Toggle class on navbar to hide/show bottom border
319
- if (willBeOpen) {
320
- navbar.classList.add('navbar--menu-open');
321
- } else {
322
- navbar.classList.remove('navbar--menu-open');
323
- }
324
-
325
- menu.classList.toggle('navbar__menu--open', !isOpen);
326
- menuToggleBtn.setAttribute('aria-expanded', (!isOpen).toString());
327
- };
328
-
329
- menuToggleBtn.addEventListener('click', (e) => {
330
- const target = e.target as Element;
331
- // Only skip if click was inside the menu (e.g. dropdown toggle) - not when clicking the hamburger
332
- if (target.closest('#navbar-menu') && target.closest('[data-dropdown-toggle]')) {
333
- return;
334
- }
335
- toggleMenu();
336
- });
337
-
338
- // Navigate when activating menu items that use data-nav-href (non-interactive element with role=menuitem)
339
- const navHrefHandler = (e: Event) => {
340
- const target = (e.target as Element).closest('[data-nav-href]');
341
- if (target && target instanceof HTMLElement) {
342
- const href = target.getAttribute('data-nav-href');
343
- if (href) {
344
- e.preventDefault();
345
- window.location.href = href;
346
- }
347
- }
348
- };
349
- navbar.addEventListener('click', navHrefHandler);
350
- navbar.addEventListener('keydown', (e: Event) => {
351
- const keyEvent = e as KeyboardEvent;
352
- if (keyEvent.key === 'Enter' || keyEvent.key === ' ') {
353
- const target = (keyEvent.target as Element).closest('[data-nav-href]');
354
- if (target && target instanceof HTMLElement) {
355
- const href = target.getAttribute('data-nav-href');
356
- if (href) {
357
- keyEvent.preventDefault();
358
- window.location.href = href;
359
- }
360
- }
361
- }
362
- });
363
-
364
- // Dropdown menu handling
365
- const dropdownToggles = navbar.querySelectorAll('[data-dropdown-toggle]');
366
- dropdownToggles.forEach((dropdownToggleBtn) => {
367
- const item = dropdownToggleBtn.closest('.navbar__item--has-dropdown');
368
- if (!item) return;
369
-
370
- const submenu = item.querySelector('.navbar__submenu');
371
- const sublinks = submenu ? Array.from(submenu.querySelectorAll('.navbar__sublink')) : [];
372
-
373
- // Adjust dropdown alignment to prevent overflow
374
- const adjustDropdownPosition = () => {
375
- if (!submenu || window.innerWidth <= 1023) return; // Skip on mobile
376
-
377
- const submenuEl = submenu as HTMLElement;
378
-
379
- // Temporarily make visible to measure
380
- const wasVisible = submenuEl.style.visibility !== 'hidden';
381
- if (!wasVisible) {
382
- submenuEl.style.visibility = 'hidden';
383
- submenuEl.style.opacity = '1';
384
- submenuEl.style.display = 'block';
385
- }
386
-
387
- const itemRect = item.getBoundingClientRect();
388
- const submenuWidth = submenuEl.offsetWidth || submenuEl.scrollWidth;
389
- const viewportWidth = window.innerWidth;
390
- const padding = 16; // Viewport padding
391
-
392
- // Check if dropdown would overflow on the right
393
- if (itemRect.left + submenuWidth > viewportWidth - padding) {
394
- // Align to right edge of parent item
395
- submenuEl.style.left = 'auto';
396
- submenuEl.style.right = '0';
397
- } else {
398
- // Default: align to left edge
399
- submenuEl.style.left = '0';
400
- submenuEl.style.right = 'auto';
401
- }
402
-
403
- // Restore visibility state
404
- if (!wasVisible) {
405
- submenuEl.style.visibility = '';
406
- submenuEl.style.opacity = '';
407
- submenuEl.style.display = '';
408
- }
409
- };
410
-
411
- const handleToggle = (e: Event) => {
412
- e.preventDefault();
413
- e.stopPropagation();
414
- e.stopImmediatePropagation();
415
-
416
- const isMobile = window.innerWidth <= 1023;
417
- const isExpanded = item.getAttribute('aria-expanded') === 'true';
418
-
419
- // On mobile, preserve scroll position to prevent jarring
420
- let scrollTop = 0;
421
- if (isMobile && menu) {
422
- scrollTop = (menu as HTMLElement).scrollTop;
423
- }
424
-
425
- item.setAttribute('aria-expanded', (!isExpanded).toString());
426
-
427
- // Adjust position when opening
428
- if (!isExpanded) {
429
- setTimeout(() => {
430
- adjustDropdownPosition();
431
-
432
- // Restore scroll position on mobile to prevent jarring
433
- if (isMobile && menu) {
434
- (menu as HTMLElement).scrollTop = scrollTop;
435
- }
436
- }, 0);
437
- }
438
-
439
- // Focus management: when opening, focus first sublink (desktop and mobile)
440
- if (!isExpanded && sublinks.length > 0) {
441
- setTimeout(() => (sublinks[0] as HTMLElement).focus(), 0);
442
- }
443
- };
444
-
445
- // Always use capture phase to ensure we handle it before any other listeners
446
- dropdownToggleBtn.addEventListener('click', handleToggle, true);
447
-
448
- // Keyboard navigation on dropdown toggle
449
- dropdownToggleBtn.addEventListener('keydown', (e: Event) => {
450
- const keyEvent = e as KeyboardEvent;
451
- if (keyEvent.key === 'Enter' || keyEvent.key === ' ') {
452
- keyEvent.preventDefault();
453
- handleToggle(e);
454
- } else if (keyEvent.key === 'ArrowDown' && sublinks.length > 0) {
455
- keyEvent.preventDefault();
456
- const isExpanded = item.getAttribute('aria-expanded') === 'true';
457
- if (!isExpanded) {
458
- item.setAttribute('aria-expanded', 'true');
459
- adjustDropdownPosition();
460
- }
461
- setTimeout(() => (sublinks[0] as HTMLElement).focus(), 0);
462
- } else if (keyEvent.key === 'ArrowUp' && sublinks.length > 0) {
463
- keyEvent.preventDefault();
464
- const isExpanded = item.getAttribute('aria-expanded') === 'true';
465
- if (!isExpanded) {
466
- item.setAttribute('aria-expanded', 'true');
467
- adjustDropdownPosition();
468
- }
469
- // Focus last item when ArrowUp from toggle
470
- setTimeout(() => (sublinks[sublinks.length - 1] as HTMLElement).focus(), 0);
471
- } else if (keyEvent.key === 'Escape') {
472
- keyEvent.preventDefault();
473
- item.setAttribute('aria-expanded', 'false');
474
- }
475
- });
476
-
477
- // Keyboard navigation within submenu
478
- if (submenu) {
479
- submenu.addEventListener('keydown', (e: Event) => {
480
- const keyEvent = e as KeyboardEvent;
481
- const currentIndex = sublinks.findIndex(link => link === document.activeElement);
482
-
483
- if (keyEvent.key === 'Escape') {
484
- keyEvent.preventDefault();
485
- item.setAttribute('aria-expanded', 'false');
486
- (dropdownToggleBtn as HTMLElement).focus();
487
- } else if (keyEvent.key === 'ArrowDown') {
488
- keyEvent.preventDefault();
489
- const nextIndex = (currentIndex + 1) % sublinks.length;
490
- (sublinks[nextIndex] as HTMLElement).focus();
491
- } else if (keyEvent.key === 'ArrowUp') {
492
- keyEvent.preventDefault();
493
- const prevIndex = currentIndex <= 0 ? sublinks.length - 1 : currentIndex - 1;
494
- (sublinks[prevIndex] as HTMLElement).focus();
495
- } else if (keyEvent.key === 'Home') {
496
- keyEvent.preventDefault();
497
- (sublinks[0] as HTMLElement).focus();
498
- } else if (keyEvent.key === 'End') {
499
- keyEvent.preventDefault();
500
- (sublinks[sublinks.length - 1] as HTMLElement).focus();
501
- } else if (keyEvent.key === 'Tab') {
502
- // Close dropdown when Tab is pressed (allows natural tab flow)
503
- item.setAttribute('aria-expanded', 'false');
504
- } else if (keyEvent.key === 'Enter' || keyEvent.key === ' ') {
505
- // Allow Enter/Space to activate links naturally
506
- // The click handler will handle navigation
507
- }
508
- });
509
- }
510
-
511
- // Adjust on hover (for desktop)
512
- if (window.innerWidth > 1023) {
513
- item.addEventListener('mouseenter', () => {
514
- // Small delay to ensure submenu is rendered
515
- requestAnimationFrame(() => {
516
- requestAnimationFrame(() => {
517
- adjustDropdownPosition();
518
- });
519
- });
520
- });
521
- }
522
-
523
- // Adjust on window resize
524
- window.addEventListener('resize', adjustDropdownPosition);
525
-
526
- // Close on outside click
527
- document.addEventListener('click', (e) => {
528
- const target = e.target;
529
- // Don't close if clicking on the dropdown toggle or its children
530
- const clickedToggle = target && target instanceof Element && (
531
- target === dropdownToggleBtn ||
532
- target.closest('[data-dropdown-toggle]') === dropdownToggleBtn
533
- );
534
- if (target && target instanceof Node && !item.contains(target) && !clickedToggle) {
535
- item.setAttribute('aria-expanded', 'false');
536
- }
537
- });
538
- });
539
-
540
- // Close menu on outside click
541
- document.addEventListener('click', (e) => {
542
- const target = e.target as Node | null;
543
- // Don't close if clicking inside the navbar (including dropdown toggles and their children)
544
- if (target && navbar.contains(target as Node)) {
545
- // Also check if it's specifically a dropdown toggle or submenu item
546
- const element = target as Element;
547
- if (element && (
548
- element.closest('[data-dropdown-toggle]') ||
549
- element.closest('.navbar__submenu') ||
550
- element.closest('.navbar__sublink')
551
- )) {
552
- return; // Click is on dropdown-related element, don't close menu
553
- }
554
- return; // Click is inside navbar, don't close menu
555
- }
556
- // Only close if clicking completely outside the navbar
557
- if (target && !navbar.contains(target as Node)) {
558
- menu.classList.remove('navbar__menu--open');
559
- menuToggleBtn.setAttribute('aria-expanded', 'false');
560
- // Close all dropdowns
561
- dropdownToggles.forEach((dt) => {
562
- const item = dt.closest('.navbar__item--has-dropdown');
563
- if (item) item.setAttribute('aria-expanded', 'false');
564
- });
565
- }
566
- });
567
-
568
- // Close menu on Escape key
569
- document.addEventListener('keydown', (e: Event) => {
570
- const keyEvent = e as KeyboardEvent;
571
- if (keyEvent.key === 'Escape') {
572
- if (menu.classList.contains('navbar__menu--open')) {
573
- toggleMenu(false);
574
- menuToggleBtn.focus();
575
- }
576
- // Close all dropdowns
577
- dropdownToggles.forEach((dt) => {
578
- const item = dt.closest('.navbar__item--has-dropdown');
579
- if (item) {
580
- item.setAttribute('aria-expanded', 'false');
581
- (dt as HTMLElement).focus();
582
- }
583
- });
584
- }
585
- });
586
-
587
- // Settings button keyboard handler
588
- const settingsBtn = navbar.querySelector('.navbar__settings-btn');
589
- if (settingsBtn) {
590
- settingsBtn.addEventListener('click', () => {
591
- if (window.openSettings) {
592
- window.openSettings();
593
- }
594
- });
595
- settingsBtn.addEventListener('keydown', (e: Event) => {
596
- const keyEvent = e as KeyboardEvent;
597
- if (keyEvent.key === 'Enter' || keyEvent.key === ' ') {
598
- keyEvent.preventDefault();
599
- if (window.openSettings) {
600
- window.openSettings();
601
- }
602
- }
603
- });
604
- }
605
-
606
- // Handle window resize
607
- let resizeTimer: ReturnType<typeof setTimeout> | undefined;
608
- window.addEventListener('resize', () => {
609
- if (resizeTimer) clearTimeout(resizeTimer);
610
- resizeTimer = setTimeout(() => {
611
- if (window.innerWidth >= 1024) {
612
- menu.classList.remove('navbar__menu--open');
613
- menuToggleBtn.setAttribute('aria-expanded', 'false');
614
- // Close all dropdowns
615
- dropdownToggles.forEach((dt) => {
616
- const item = dt.closest('.navbar__item--has-dropdown');
617
- if (item) item.setAttribute('aria-expanded', 'false');
618
- });
619
- }
620
- }, 250);
621
- });
622
- })();
623
- </script>