rizzo-css 0.0.17 → 0.0.19

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 (261) hide show
  1. package/README.md +4 -4
  2. package/bin/rizzo-css.js +329 -118
  3. package/dist/rizzo.min.css +3 -3
  4. package/package.json +7 -3
  5. package/scaffold/astro-minimal/.env.example +3 -0
  6. package/scaffold/astro-minimal/README.md +36 -0
  7. package/scaffold/astro-minimal/package.json +13 -0
  8. package/scaffold/astro-minimal/src/layouts/Layout.astro +28 -0
  9. package/scaffold/astro-minimal/src/pages/index.astro +10 -0
  10. package/scaffold/svelte-minimal/.env.example +3 -0
  11. package/scaffold/svelte-minimal/README.md +37 -0
  12. package/scaffold/svelte-minimal/package.json +20 -0
  13. package/scaffold/svelte-minimal/src/app.d.ts +11 -0
  14. package/scaffold/svelte-minimal/src/app.html +15 -0
  15. package/scaffold/svelte-minimal/src/routes/+layout.svelte +1 -0
  16. package/scaffold/svelte-minimal/src/routes/+page.svelte +5 -0
  17. package/scaffold/svelte-minimal/svelte.config.js +10 -0
  18. package/scaffold/svelte-minimal/tsconfig.json +11 -0
  19. package/scaffold/vanilla/README.md +4 -4
  20. package/scaffold/vanilla/components/accordion.html +18 -0
  21. package/scaffold/vanilla/components/alert.html +18 -0
  22. package/scaffold/vanilla/components/avatar.html +18 -0
  23. package/scaffold/vanilla/components/badge.html +18 -0
  24. package/scaffold/vanilla/components/breadcrumb.html +18 -0
  25. package/scaffold/vanilla/components/button.html +18 -0
  26. package/scaffold/vanilla/components/cards.html +18 -0
  27. package/scaffold/vanilla/components/copy-to-clipboard.html +18 -0
  28. package/scaffold/vanilla/components/divider.html +18 -0
  29. package/scaffold/vanilla/components/dropdown.html +18 -0
  30. package/scaffold/vanilla/components/forms.html +18 -0
  31. package/scaffold/vanilla/components/icons.html +18 -0
  32. package/scaffold/vanilla/components/index.html +18 -0
  33. package/scaffold/vanilla/components/modal.html +18 -0
  34. package/scaffold/vanilla/components/navbar.html +18 -0
  35. package/scaffold/vanilla/components/pagination.html +18 -0
  36. package/scaffold/vanilla/components/progress-bar.html +18 -0
  37. package/scaffold/vanilla/components/search.html +18 -0
  38. package/scaffold/vanilla/components/settings.html +18 -0
  39. package/scaffold/vanilla/components/spinner.html +18 -0
  40. package/scaffold/vanilla/components/table.html +18 -0
  41. package/scaffold/vanilla/components/tabs.html +18 -0
  42. package/scaffold/vanilla/components/theme-switcher.html +18 -0
  43. package/scaffold/vanilla/components/toast.html +18 -0
  44. package/scaffold/vanilla/components/tooltip.html +18 -0
  45. package/scaffold/vanilla/index.html +18 -0
  46. package/scaffold/astro-app/README.md +0 -43
  47. package/scaffold/astro-app/package.json +0 -1
  48. package/scaffold/astro-app/src/components/Accordion.astro +0 -178
  49. package/scaffold/astro-app/src/components/Alert.astro +0 -131
  50. package/scaffold/astro-app/src/components/Avatar.astro +0 -59
  51. package/scaffold/astro-app/src/components/Badge.astro +0 -24
  52. package/scaffold/astro-app/src/components/Breadcrumb.astro +0 -61
  53. package/scaffold/astro-app/src/components/Button.astro +0 -3
  54. package/scaffold/astro-app/src/components/Card.astro +0 -18
  55. package/scaffold/astro-app/src/components/Checkbox.astro +0 -38
  56. package/scaffold/astro-app/src/components/CliCommandTabs.astro +0 -90
  57. package/scaffold/astro-app/src/components/CodeBlock.astro +0 -393
  58. package/scaffold/astro-app/src/components/CopyToClipboard.astro +0 -219
  59. package/scaffold/astro-app/src/components/Divider.astro +0 -37
  60. package/scaffold/astro-app/src/components/DocsSidebar.astro +0 -51
  61. package/scaffold/astro-app/src/components/Dropdown.astro +0 -807
  62. package/scaffold/astro-app/src/components/FormGroup.astro +0 -59
  63. package/scaffold/astro-app/src/components/FrameworkSwitcher.astro +0 -72
  64. package/scaffold/astro-app/src/components/Input.astro +0 -59
  65. package/scaffold/astro-app/src/components/Modal.astro +0 -212
  66. package/scaffold/astro-app/src/components/Navbar.astro +0 -623
  67. package/scaffold/astro-app/src/components/PackageInstallTabs.astro +0 -87
  68. package/scaffold/astro-app/src/components/Pagination.astro +0 -240
  69. package/scaffold/astro-app/src/components/ProgressBar.astro +0 -65
  70. package/scaffold/astro-app/src/components/Radio.astro +0 -38
  71. package/scaffold/astro-app/src/components/Search.astro +0 -1259
  72. package/scaffold/astro-app/src/components/Select.astro +0 -49
  73. package/scaffold/astro-app/src/components/Settings.astro +0 -382
  74. package/scaffold/astro-app/src/components/Spinner.astro +0 -30
  75. package/scaffold/astro-app/src/components/Table.astro +0 -181
  76. package/scaffold/astro-app/src/components/Tabs.astro +0 -223
  77. package/scaffold/astro-app/src/components/Textarea.astro +0 -58
  78. package/scaffold/astro-app/src/components/ThemeIcon.astro +0 -50
  79. package/scaffold/astro-app/src/components/ThemeSwitcher.astro +0 -504
  80. package/scaffold/astro-app/src/components/Toast.astro +0 -30
  81. package/scaffold/astro-app/src/components/Tooltip.astro +0 -32
  82. package/scaffold/astro-app/src/components/icons/Brush.astro +0 -10
  83. package/scaffold/astro-app/src/components/icons/Cake.astro +0 -11
  84. package/scaffold/astro-app/src/components/icons/Check.astro +0 -29
  85. package/scaffold/astro-app/src/components/icons/Cherry.astro +0 -11
  86. package/scaffold/astro-app/src/components/icons/ChevronDown.astro +0 -29
  87. package/scaffold/astro-app/src/components/icons/Circle.astro +0 -29
  88. package/scaffold/astro-app/src/components/icons/Close.astro +0 -30
  89. package/scaffold/astro-app/src/components/icons/Cmd.astro +0 -26
  90. package/scaffold/astro-app/src/components/icons/Copy.astro +0 -30
  91. package/scaffold/astro-app/src/components/icons/Eye.astro +0 -30
  92. package/scaffold/astro-app/src/components/icons/Filter.astro +0 -29
  93. package/scaffold/astro-app/src/components/icons/Flame.astro +0 -28
  94. package/scaffold/astro-app/src/components/icons/Flower.astro +0 -11
  95. package/scaffold/astro-app/src/components/icons/Gear.astro +0 -30
  96. package/scaffold/astro-app/src/components/icons/Heart.astro +0 -28
  97. package/scaffold/astro-app/src/components/icons/IceCream.astro +0 -31
  98. package/scaffold/astro-app/src/components/icons/Leaf.astro +0 -29
  99. package/scaffold/astro-app/src/components/icons/Lemon.astro +0 -11
  100. package/scaffold/astro-app/src/components/icons/Moon.astro +0 -29
  101. package/scaffold/astro-app/src/components/icons/Owl.astro +0 -34
  102. package/scaffold/astro-app/src/components/icons/Palette.astro +0 -33
  103. package/scaffold/astro-app/src/components/icons/Rainbow.astro +0 -31
  104. package/scaffold/astro-app/src/components/icons/Search.astro +0 -30
  105. package/scaffold/astro-app/src/components/icons/Shield.astro +0 -28
  106. package/scaffold/astro-app/src/components/icons/Snowflake.astro +0 -34
  107. package/scaffold/astro-app/src/components/icons/Sort.astro +0 -30
  108. package/scaffold/astro-app/src/components/icons/Sun.astro +0 -29
  109. package/scaffold/astro-app/src/components/icons/Sunset.astro +0 -10
  110. package/scaffold/astro-app/src/components/icons/Zap.astro +0 -9
  111. package/scaffold/astro-app/src/components/icons/devicons/Astro.astro +0 -53
  112. package/scaffold/astro-app/src/components/icons/devicons/Bash.astro +0 -34
  113. package/scaffold/astro-app/src/components/icons/devicons/Css3.astro +0 -29
  114. package/scaffold/astro-app/src/components/icons/devicons/Git.astro +0 -24
  115. package/scaffold/astro-app/src/components/icons/devicons/Html5.astro +0 -27
  116. package/scaffold/astro-app/src/components/icons/devicons/Javascript.astro +0 -25
  117. package/scaffold/astro-app/src/components/icons/devicons/Nodejs.astro +0 -47
  118. package/scaffold/astro-app/src/components/icons/devicons/Plaintext.astro +0 -33
  119. package/scaffold/astro-app/src/components/icons/devicons/React.astro +0 -27
  120. package/scaffold/astro-app/src/components/icons/devicons/Svelte.astro +0 -25
  121. package/scaffold/astro-app/src/components/icons/devicons/Vue.astro +0 -26
  122. package/scaffold/astro-app/src/config/frameworks.ts +0 -26
  123. package/scaffold/astro-app/src/config/themes.ts +0 -54
  124. package/scaffold/astro-app/src/layouts/DocsLayout.astro +0 -263
  125. package/scaffold/astro-app/src/layouts/Layout.astro +0 -41
  126. package/scaffold/astro-app/src/pages/components/accordion.astro +0 -172
  127. package/scaffold/astro-app/src/pages/components/alert.astro +0 -250
  128. package/scaffold/astro-app/src/pages/components/avatar.astro +0 -102
  129. package/scaffold/astro-app/src/pages/components/badge.astro +0 -119
  130. package/scaffold/astro-app/src/pages/components/breadcrumb.astro +0 -124
  131. package/scaffold/astro-app/src/pages/components/button.astro +0 -74
  132. package/scaffold/astro-app/src/pages/components/cards.astro +0 -247
  133. package/scaffold/astro-app/src/pages/components/copy-to-clipboard.astro +0 -49
  134. package/scaffold/astro-app/src/pages/components/divider.astro +0 -74
  135. package/scaffold/astro-app/src/pages/components/dropdown.astro +0 -394
  136. package/scaffold/astro-app/src/pages/components/forms.astro +0 -367
  137. package/scaffold/astro-app/src/pages/components/icons.astro +0 -246
  138. package/scaffold/astro-app/src/pages/components/modal.astro +0 -152
  139. package/scaffold/astro-app/src/pages/components/navbar.astro +0 -80
  140. package/scaffold/astro-app/src/pages/components/pagination.astro +0 -126
  141. package/scaffold/astro-app/src/pages/components/progress-bar.astro +0 -94
  142. package/scaffold/astro-app/src/pages/components/search.astro +0 -155
  143. package/scaffold/astro-app/src/pages/components/settings.astro +0 -78
  144. package/scaffold/astro-app/src/pages/components/spinner.astro +0 -81
  145. package/scaffold/astro-app/src/pages/components/table.astro +0 -144
  146. package/scaffold/astro-app/src/pages/components/tabs.astro +0 -220
  147. package/scaffold/astro-app/src/pages/components/theme-switcher.astro +0 -69
  148. package/scaffold/astro-app/src/pages/components/toast.astro +0 -157
  149. package/scaffold/astro-app/src/pages/components/tooltip.astro +0 -209
  150. package/scaffold/astro-app/src/pages/components.astro +0 -290
  151. package/scaffold/astro-app/src/pages/docs/accessibility.astro +0 -9
  152. package/scaffold/astro-app/src/pages/docs/colors.astro +0 -9
  153. package/scaffold/astro-app/src/pages/docs/design-system.astro +0 -9
  154. package/scaffold/astro-app/src/pages/docs/getting-started.astro +0 -9
  155. package/scaffold/astro-app/src/pages/docs/index.astro +0 -15
  156. package/scaffold/astro-app/src/pages/docs/themes/[theme].astro +0 -14
  157. package/scaffold/astro-app/src/pages/docs/theming.astro +0 -10
  158. package/scaffold/astro-app/src/pages/index.astro +0 -24
  159. package/scaffold/svelte-app/README.md +0 -39
  160. package/scaffold/svelte-app/package.json +0 -22
  161. package/scaffold/svelte-app/src/app.d.ts +0 -28
  162. package/scaffold/svelte-app/src/app.html +0 -21
  163. package/scaffold/svelte-app/src/lib/assets/favicon.svg +0 -1
  164. package/scaffold/svelte-app/src/lib/rizzo/Accordion.svelte +0 -128
  165. package/scaffold/svelte-app/src/lib/rizzo/Alert.svelte +0 -85
  166. package/scaffold/svelte-app/src/lib/rizzo/Avatar.svelte +0 -39
  167. package/scaffold/svelte-app/src/lib/rizzo/Badge.svelte +0 -31
  168. package/scaffold/svelte-app/src/lib/rizzo/Breadcrumb.svelte +0 -49
  169. package/scaffold/svelte-app/src/lib/rizzo/Button.svelte +0 -27
  170. package/scaffold/svelte-app/src/lib/rizzo/Card.svelte +0 -17
  171. package/scaffold/svelte-app/src/lib/rizzo/Checkbox.svelte +0 -37
  172. package/scaffold/svelte-app/src/lib/rizzo/CopyToClipboard.svelte +0 -79
  173. package/scaffold/svelte-app/src/lib/rizzo/Divider.svelte +0 -28
  174. package/scaffold/svelte-app/src/lib/rizzo/Dropdown.svelte +0 -254
  175. package/scaffold/svelte-app/src/lib/rizzo/FormGroup.svelte +0 -51
  176. package/scaffold/svelte-app/src/lib/rizzo/Input.svelte +0 -59
  177. package/scaffold/svelte-app/src/lib/rizzo/Modal.svelte +0 -157
  178. package/scaffold/svelte-app/src/lib/rizzo/Pagination.svelte +0 -93
  179. package/scaffold/svelte-app/src/lib/rizzo/ProgressBar.svelte +0 -58
  180. package/scaffold/svelte-app/src/lib/rizzo/Radio.svelte +0 -38
  181. package/scaffold/svelte-app/src/lib/rizzo/Select.svelte +0 -51
  182. package/scaffold/svelte-app/src/lib/rizzo/Spinner.svelte +0 -14
  183. package/scaffold/svelte-app/src/lib/rizzo/Table.svelte +0 -158
  184. package/scaffold/svelte-app/src/lib/rizzo/Tabs.svelte +0 -117
  185. package/scaffold/svelte-app/src/lib/rizzo/Textarea.svelte +0 -59
  186. package/scaffold/svelte-app/src/lib/rizzo/ThemeIcon.svelte +0 -54
  187. package/scaffold/svelte-app/src/lib/rizzo/ThemeSwitcher.svelte +0 -315
  188. package/scaffold/svelte-app/src/lib/rizzo/Toast.svelte +0 -33
  189. package/scaffold/svelte-app/src/lib/rizzo/Tooltip.svelte +0 -19
  190. package/scaffold/svelte-app/src/lib/rizzo/icons/Check.svelte +0 -29
  191. package/scaffold/svelte-app/src/lib/rizzo/icons/ChevronDown.svelte +0 -29
  192. package/scaffold/svelte-app/src/lib/rizzo/icons/Circle.svelte +0 -29
  193. package/scaffold/svelte-app/src/lib/rizzo/icons/Close.svelte +0 -30
  194. package/scaffold/svelte-app/src/lib/rizzo/icons/Cmd.svelte +0 -27
  195. package/scaffold/svelte-app/src/lib/rizzo/icons/Copy.svelte +0 -30
  196. package/scaffold/svelte-app/src/lib/rizzo/icons/Eye.svelte +0 -30
  197. package/scaffold/svelte-app/src/lib/rizzo/icons/Filter.svelte +0 -29
  198. package/scaffold/svelte-app/src/lib/rizzo/icons/Gear.svelte +0 -30
  199. package/scaffold/svelte-app/src/lib/rizzo/icons/IceCream.svelte +0 -31
  200. package/scaffold/svelte-app/src/lib/rizzo/icons/Moon.svelte +0 -29
  201. package/scaffold/svelte-app/src/lib/rizzo/icons/Owl.svelte +0 -34
  202. package/scaffold/svelte-app/src/lib/rizzo/icons/Palette.svelte +0 -33
  203. package/scaffold/svelte-app/src/lib/rizzo/icons/Rainbow.svelte +0 -31
  204. package/scaffold/svelte-app/src/lib/rizzo/icons/Search.svelte +0 -30
  205. package/scaffold/svelte-app/src/lib/rizzo/icons/Snowflake.svelte +0 -34
  206. package/scaffold/svelte-app/src/lib/rizzo/icons/Sort.svelte +0 -30
  207. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Astro.svelte +0 -45
  208. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Bash.svelte +0 -28
  209. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Css3.svelte +0 -23
  210. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Git.svelte +0 -18
  211. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Html5.svelte +0 -21
  212. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Javascript.svelte +0 -19
  213. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Nodejs.svelte +0 -44
  214. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Plaintext.svelte +0 -24
  215. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/React.svelte +0 -21
  216. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/SvelteIcon.svelte +0 -19
  217. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Vue.svelte +0 -20
  218. package/scaffold/svelte-app/src/lib/rizzo/index.ts +0 -35
  219. package/scaffold/svelte-app/src/lib/rizzo-docs/CodeBlock.svelte +0 -239
  220. package/scaffold/svelte-app/src/lib/rizzo-docs/SvelteDocPage.svelte +0 -99
  221. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/AccordionDoc.svelte +0 -53
  222. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/AlertDoc.svelte +0 -114
  223. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/AvatarDoc.svelte +0 -92
  224. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/BadgeDoc.svelte +0 -60
  225. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/BreadcrumbDoc.svelte +0 -55
  226. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ButtonDoc.svelte +0 -55
  227. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/CardsDoc.svelte +0 -173
  228. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ComingSoon.svelte +0 -12
  229. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ComponentsOverview.svelte +0 -92
  230. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/CopyToClipboardDoc.svelte +0 -26
  231. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/DividerDoc.svelte +0 -105
  232. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/DropdownDoc.svelte +0 -161
  233. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/FormsDoc.svelte +0 -375
  234. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/IconsDoc.svelte +0 -246
  235. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/Index.svelte +0 -8
  236. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ModalDoc.svelte +0 -50
  237. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/NavbarDoc.svelte +0 -79
  238. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/PaginationDoc.svelte +0 -44
  239. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ProgressBarDoc.svelte +0 -95
  240. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/SearchDoc.svelte +0 -147
  241. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/SettingsDoc.svelte +0 -158
  242. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/SpinnerDoc.svelte +0 -41
  243. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/TableDoc.svelte +0 -116
  244. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/TabsDoc.svelte +0 -152
  245. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ThemeSwitcherDoc.svelte +0 -189
  246. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/Theming.svelte +0 -6
  247. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ToastDoc.svelte +0 -136
  248. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/TooltipDoc.svelte +0 -57
  249. package/scaffold/svelte-app/src/routes/+layout.svelte +0 -10
  250. package/scaffold/svelte-app/src/routes/+page.svelte +0 -31
  251. package/scaffold/svelte-app/src/routes/components/+page.svelte +0 -4
  252. package/scaffold/svelte-app/src/routes/components/[slug]/+page.svelte +0 -7
  253. package/scaffold/svelte-app/static/robots.txt +0 -3
  254. package/scaffold/svelte-app/svelte.config.js +0 -13
  255. package/scaffold/svelte-app/tsconfig.json +0 -21
  256. package/scaffold/svelte-app/vite.config.ts +0 -6
  257. /package/scaffold/{astro-app → astro-minimal}/astro.config.mjs +0 -0
  258. /package/scaffold/{astro-app → astro-minimal}/public/.gitkeep +0 -0
  259. /package/scaffold/{astro-app → astro-minimal}/public/favicon.svg +0 -0
  260. /package/scaffold/{astro-app → astro-minimal}/tsconfig.json +0 -0
  261. /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>