rizzo-css 0.0.54 → 0.0.55

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 (250) hide show
  1. package/README.md +11 -7
  2. package/bin/rizzo-css.js +273 -118
  3. package/dist/rizzo.min.css +40 -16
  4. package/package.json +6 -6
  5. package/scaffold/astro/AlertDialog.astro +86 -0
  6. package/scaffold/astro/AspectRatio.astro +22 -0
  7. package/scaffold/astro/ButtonGroup.astro +16 -0
  8. package/scaffold/astro/Collapsible.astro +69 -0
  9. package/scaffold/astro/ContextMenu.astro +58 -0
  10. package/scaffold/astro/CopyToClipboard.astro +4 -0
  11. package/scaffold/astro/Dashboard.astro +74 -0
  12. package/scaffold/astro/Empty.astro +23 -0
  13. package/scaffold/astro/HoverCard.astro +64 -0
  14. package/scaffold/astro/Kbd.astro +14 -0
  15. package/scaffold/astro/Label.astro +24 -0
  16. package/scaffold/astro/Modal.astro +17 -2
  17. package/scaffold/astro/Popover.astro +62 -0
  18. package/scaffold/astro/ResizableHandle.astro +16 -0
  19. package/scaffold/astro/ResizablePane.astro +20 -0
  20. package/scaffold/astro/ResizablePaneGroup.astro +84 -0
  21. package/scaffold/astro/ScrollArea.astro +19 -0
  22. package/scaffold/astro/Separator.astro +18 -0
  23. package/scaffold/astro/Settings.astro +10 -2
  24. package/scaffold/astro/Sheet.astro +90 -0
  25. package/scaffold/astro/Skeleton.astro +16 -0
  26. package/scaffold/astro/Slider.astro +75 -0
  27. package/scaffold/astro/SoundEffects.astro +1 -0
  28. package/scaffold/astro/Switch.astro +37 -0
  29. package/scaffold/astro/Tabs.astro +1 -1
  30. package/scaffold/astro/ThemeSwitcher.astro +11 -4
  31. package/scaffold/astro/Toggle.astro +35 -0
  32. package/scaffold/astro/ToggleGroup.astro +24 -0
  33. package/scaffold/astro/base/README-RIZZO.md +55 -0
  34. package/scaffold/{astro-core → astro/base}/src/pages/index.astro +1 -1
  35. package/scaffold/astro/variants/dashboard/src/layouts/Layout.astro +85 -0
  36. package/scaffold/astro/variants/dashboard/src/pages/index.astro +110 -0
  37. package/scaffold/astro/variants/docs/src/layouts/Layout.astro +81 -0
  38. package/scaffold/astro/variants/docs/src/pages/docs/getting-started.astro +36 -0
  39. package/scaffold/astro/variants/docs/src/pages/index.astro +38 -0
  40. package/scaffold/{astro-core → astro/variants/full}/README-RIZZO.md +2 -1
  41. package/scaffold/astro/variants/full/astro.config.mjs +5 -0
  42. package/scaffold/astro/variants/full/dist/_noop-middleware.mjs +3 -0
  43. package/scaffold/astro/variants/full/dist/chunks/astro/server_9Mzx7luy.mjs +6023 -0
  44. package/scaffold/astro/variants/full/dist/chunks/astro_BOYUKg7r.mjs +1 -0
  45. package/scaffold/astro/variants/full/dist/favicon.svg +18 -0
  46. package/scaffold/astro/variants/full/dist/manifest_DXpJmqSX.mjs +154 -0
  47. package/scaffold/astro/variants/full/dist/noop-entrypoint.mjs +3 -0
  48. package/scaffold/astro/variants/full/dist/pages/index.astro.mjs +87 -0
  49. package/scaffold/astro/variants/full/dist/renderers.mjs +3 -0
  50. package/scaffold/astro/variants/full/gitignore +24 -0
  51. package/scaffold/astro/variants/full/node_modules/.astro/data-store.json +1 -0
  52. package/scaffold/astro/variants/full/node_modules/.vite/deps/_metadata.json +31 -0
  53. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___aria-query.js +6776 -0
  54. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___aria-query.js.map +7 -0
  55. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___axobject-query.js +3754 -0
  56. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___axobject-query.js.map +7 -0
  57. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___cssesc.js +99 -0
  58. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___cssesc.js.map +7 -0
  59. package/scaffold/astro/variants/full/node_modules/.vite/deps/chunk-BUSYA2B4.js +8 -0
  60. package/scaffold/astro/variants/full/node_modules/.vite/deps/chunk-BUSYA2B4.js.map +7 -0
  61. package/scaffold/astro/variants/full/node_modules/.vite/deps/package.json +3 -0
  62. package/scaffold/astro/variants/full/package.json +13 -0
  63. package/scaffold/astro/variants/full/public/.gitkeep +0 -0
  64. package/scaffold/astro/variants/full/public/favicon.svg +18 -0
  65. package/scaffold/astro/variants/full/src/components/rizzo/CopyToClipboard.astro +157 -0
  66. package/scaffold/astro/variants/full/src/components/rizzo/icons/Check.astro +29 -0
  67. package/scaffold/astro/variants/full/src/components/rizzo/icons/Copy.astro +30 -0
  68. package/scaffold/astro/variants/full/src/layouts/Layout.astro +34 -0
  69. package/scaffold/astro/variants/full/src/pages/index.astro +107 -0
  70. package/scaffold/astro/variants/full/tsconfig.json +5 -0
  71. package/scaffold/landing/index.html +13 -0
  72. package/scaffold/shared/navbar-vanilla.html +59 -0
  73. package/scaffold/shared/sound-effects-inline.js +6 -1
  74. package/scaffold/svelte/AlertDialog.svelte +55 -0
  75. package/scaffold/svelte/AspectRatio.svelte +21 -0
  76. package/scaffold/svelte/BackToTop.svelte +1 -0
  77. package/scaffold/svelte/ButtonGroup.svelte +16 -0
  78. package/scaffold/svelte/Collapsible.svelte +57 -0
  79. package/scaffold/svelte/ContextMenu.svelte +60 -0
  80. package/scaffold/svelte/Dashboard.svelte +87 -0
  81. package/scaffold/svelte/Empty.svelte +36 -0
  82. package/scaffold/svelte/HoverCard.svelte +55 -0
  83. package/scaffold/svelte/Kbd.svelte +13 -0
  84. package/scaffold/svelte/Label.svelte +19 -0
  85. package/scaffold/svelte/Popover.svelte +59 -0
  86. package/scaffold/svelte/ResizableHandle.svelte +13 -0
  87. package/scaffold/svelte/ResizablePane.svelte +16 -0
  88. package/scaffold/svelte/ResizablePaneGroup.svelte +92 -0
  89. package/scaffold/svelte/ScrollArea.svelte +18 -0
  90. package/scaffold/svelte/Separator.svelte +14 -0
  91. package/scaffold/svelte/Sheet.svelte +62 -0
  92. package/scaffold/svelte/Skeleton.svelte +19 -0
  93. package/scaffold/svelte/Slider.svelte +57 -0
  94. package/scaffold/svelte/SoundEffects.svelte +3 -0
  95. package/scaffold/svelte/Switch.svelte +35 -0
  96. package/scaffold/svelte/Tabs.svelte +1 -1
  97. package/scaffold/svelte/Toggle.svelte +41 -0
  98. package/scaffold/svelte/ToggleGroup.svelte +30 -0
  99. package/scaffold/svelte/base/README-RIZZO.md +55 -0
  100. package/scaffold/{svelte-core → svelte/base}/src/routes/+page.svelte +1 -1
  101. package/scaffold/svelte/base/static/.gitkeep +0 -0
  102. package/scaffold/svelte/index.ts +21 -0
  103. package/scaffold/svelte/variants/dashboard/src/routes/+layout.svelte +64 -0
  104. package/scaffold/svelte/variants/dashboard/src/routes/+page.svelte +104 -0
  105. package/scaffold/svelte/variants/docs/src/routes/+layout.svelte +60 -0
  106. package/scaffold/svelte/variants/docs/src/routes/+page.svelte +34 -0
  107. package/scaffold/svelte/variants/docs/src/routes/docs/getting-started/+page.svelte +31 -0
  108. package/scaffold/{svelte-core → svelte/variants/full}/README-RIZZO.md +2 -1
  109. package/scaffold/svelte/variants/full/gitignore +10 -0
  110. package/scaffold/svelte/variants/full/package.json +20 -0
  111. package/scaffold/svelte/variants/full/src/app.d.ts +11 -0
  112. package/scaffold/svelte/variants/full/src/app.html +16 -0
  113. package/scaffold/svelte/variants/full/src/routes/+layout.svelte +1 -0
  114. package/scaffold/svelte/variants/full/src/routes/+page.svelte +105 -0
  115. package/scaffold/svelte/variants/full/static/.gitkeep +0 -0
  116. package/scaffold/svelte/variants/full/svelte.config.js +10 -0
  117. package/scaffold/svelte/variants/full/tsconfig.json +11 -0
  118. package/scaffold/vanilla/README-RIZZO.md +6 -5
  119. package/scaffold/vanilla/components/accordion.html +59 -64
  120. package/scaffold/vanilla/components/alert-dialog.html +640 -0
  121. package/scaffold/vanilla/components/alert.html +59 -64
  122. package/scaffold/vanilla/components/aspect-ratio.html +640 -0
  123. package/scaffold/vanilla/components/avatar.html +59 -64
  124. package/scaffold/vanilla/components/back-to-top.html +59 -64
  125. package/scaffold/vanilla/components/badge.html +59 -64
  126. package/scaffold/vanilla/components/breadcrumb.html +59 -64
  127. package/scaffold/vanilla/components/button-group.html +640 -0
  128. package/scaffold/vanilla/components/button.html +59 -64
  129. package/scaffold/vanilla/components/cards.html +59 -64
  130. package/scaffold/vanilla/components/collapsible.html +640 -0
  131. package/scaffold/vanilla/components/context-menu.html +640 -0
  132. package/scaffold/vanilla/components/copy-to-clipboard.html +59 -64
  133. package/scaffold/vanilla/components/dashboard.html +640 -0
  134. package/scaffold/vanilla/components/divider.html +59 -64
  135. package/scaffold/vanilla/components/docs-sidebar.html +59 -64
  136. package/scaffold/vanilla/components/dropdown.html +59 -64
  137. package/scaffold/vanilla/components/empty.html +640 -0
  138. package/scaffold/vanilla/components/font-switcher.html +59 -64
  139. package/scaffold/vanilla/components/footer.html +59 -64
  140. package/scaffold/vanilla/components/forms.html +59 -64
  141. package/scaffold/vanilla/components/hover-card.html +640 -0
  142. package/scaffold/vanilla/components/icons.html +59 -64
  143. package/scaffold/vanilla/components/index.html +79 -64
  144. package/scaffold/vanilla/components/kbd.html +640 -0
  145. package/scaffold/vanilla/components/label.html +640 -0
  146. package/scaffold/vanilla/components/modal.html +59 -64
  147. package/scaffold/vanilla/components/navbar.html +59 -64
  148. package/scaffold/vanilla/components/pagination.html +59 -64
  149. package/scaffold/vanilla/components/popover.html +640 -0
  150. package/scaffold/vanilla/components/progress-bar.html +59 -64
  151. package/scaffold/vanilla/components/resizable.html +640 -0
  152. package/scaffold/vanilla/components/scroll-area.html +640 -0
  153. package/scaffold/vanilla/components/search.html +59 -64
  154. package/scaffold/vanilla/components/separator.html +640 -0
  155. package/scaffold/vanilla/components/settings.html +59 -64
  156. package/scaffold/vanilla/components/sheet.html +640 -0
  157. package/scaffold/vanilla/components/skeleton.html +640 -0
  158. package/scaffold/vanilla/components/slider.html +640 -0
  159. package/scaffold/vanilla/components/sound-effects.html +59 -64
  160. package/scaffold/vanilla/components/spinner.html +59 -64
  161. package/scaffold/vanilla/components/switch.html +640 -0
  162. package/scaffold/vanilla/components/table.html +59 -64
  163. package/scaffold/vanilla/components/tabs.html +59 -64
  164. package/scaffold/vanilla/components/theme-switcher.html +59 -64
  165. package/scaffold/vanilla/components/toast.html +59 -64
  166. package/scaffold/vanilla/components/toggle-group.html +640 -0
  167. package/scaffold/vanilla/components/toggle.html +640 -0
  168. package/scaffold/vanilla/components/tooltip.html +59 -64
  169. package/scaffold/vanilla/index.html +61 -66
  170. package/scaffold/vanilla/variants/dashboard/index.html +45 -0
  171. package/scaffold/vanilla/variants/docs/index.html +36 -0
  172. package/scaffold/vanilla/variants/full/components/accordion.html +592 -0
  173. package/scaffold/vanilla/variants/full/components/alert.html +592 -0
  174. package/scaffold/vanilla/variants/full/components/avatar.html +592 -0
  175. package/scaffold/vanilla/variants/full/components/back-to-top.html +592 -0
  176. package/scaffold/vanilla/variants/full/components/badge.html +592 -0
  177. package/scaffold/vanilla/variants/full/components/breadcrumb.html +592 -0
  178. package/scaffold/vanilla/variants/full/components/button.html +592 -0
  179. package/scaffold/vanilla/variants/full/components/cards.html +592 -0
  180. package/scaffold/vanilla/variants/full/components/copy-to-clipboard.html +592 -0
  181. package/scaffold/vanilla/variants/full/components/dashboard.html +592 -0
  182. package/scaffold/vanilla/variants/full/components/divider.html +592 -0
  183. package/scaffold/vanilla/variants/full/components/docs-sidebar.html +592 -0
  184. package/scaffold/vanilla/variants/full/components/dropdown.html +592 -0
  185. package/scaffold/vanilla/variants/full/components/font-switcher.html +592 -0
  186. package/scaffold/vanilla/variants/full/components/footer.html +592 -0
  187. package/scaffold/vanilla/variants/full/components/forms.html +592 -0
  188. package/scaffold/vanilla/variants/full/components/icons.html +592 -0
  189. package/scaffold/vanilla/variants/full/components/index.html +625 -0
  190. package/scaffold/vanilla/variants/full/components/modal.html +592 -0
  191. package/scaffold/vanilla/variants/full/components/navbar.html +592 -0
  192. package/scaffold/vanilla/variants/full/components/pagination.html +592 -0
  193. package/scaffold/vanilla/variants/full/components/progress-bar.html +592 -0
  194. package/scaffold/vanilla/variants/full/components/search.html +592 -0
  195. package/scaffold/vanilla/variants/full/components/settings.html +592 -0
  196. package/scaffold/vanilla/variants/full/components/skeleton.html +592 -0
  197. package/scaffold/vanilla/variants/full/components/sound-effects.html +592 -0
  198. package/scaffold/vanilla/variants/full/components/spinner.html +592 -0
  199. package/scaffold/vanilla/variants/full/components/switch.html +592 -0
  200. package/scaffold/vanilla/variants/full/components/table.html +592 -0
  201. package/scaffold/vanilla/variants/full/components/tabs.html +592 -0
  202. package/scaffold/vanilla/variants/full/components/theme-switcher.html +592 -0
  203. package/scaffold/vanilla/variants/full/components/toast.html +592 -0
  204. package/scaffold/vanilla/variants/full/components/tooltip.html +592 -0
  205. package/scaffold/vanilla/variants/full/index.html +682 -0
  206. package/scaffold/vanilla/variants/full/js/main.js +989 -0
  207. package/scaffold/astro-core/.astro/content-assets.mjs +0 -1
  208. package/scaffold/astro-core/.astro/content-modules.mjs +0 -1
  209. package/scaffold/astro-core/.astro/content.d.ts +0 -199
  210. package/scaffold/astro-core/.astro/types.d.ts +0 -2
  211. package/scaffold/astro-core/.env.example +0 -3
  212. package/scaffold/svelte-core/.env.example +0 -3
  213. /package/scaffold/{astro-core → astro/base}/astro.config.mjs +0 -0
  214. /package/scaffold/{astro-core → astro/base}/dist/.gitkeep +0 -0
  215. /package/scaffold/{astro-core → astro/base}/dist/_noop-middleware.mjs +0 -0
  216. /package/scaffold/{astro-core → astro/base}/dist/chunks/astro/server_9Mzx7luy.mjs +0 -0
  217. /package/scaffold/{astro-core → astro/base}/dist/chunks/astro_BOYUKg7r.mjs +0 -0
  218. /package/scaffold/{astro-core → astro/base}/dist/favicon.svg +0 -0
  219. /package/scaffold/{astro-core → astro/base}/dist/manifest_DXpJmqSX.mjs +0 -0
  220. /package/scaffold/{astro-core → astro/base}/dist/noop-entrypoint.mjs +0 -0
  221. /package/scaffold/{astro-core → astro/base}/dist/pages/index.astro.mjs +0 -0
  222. /package/scaffold/{astro-core → astro/base}/dist/renderers.mjs +0 -0
  223. /package/scaffold/{astro-core → astro/base}/gitignore +0 -0
  224. /package/scaffold/{astro-core → astro/base}/node_modules/.astro/data-store.json +0 -0
  225. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/_metadata.json +0 -0
  226. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___aria-query.js +0 -0
  227. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___aria-query.js.map +0 -0
  228. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___axobject-query.js +0 -0
  229. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___axobject-query.js.map +0 -0
  230. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___cssesc.js +0 -0
  231. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___cssesc.js.map +0 -0
  232. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/chunk-BUSYA2B4.js +0 -0
  233. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/chunk-BUSYA2B4.js.map +0 -0
  234. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/package.json +0 -0
  235. /package/scaffold/{astro-core → astro/base}/package.json +0 -0
  236. /package/scaffold/{astro-core → astro/base}/public/.gitkeep +0 -0
  237. /package/scaffold/{astro-core → astro/base}/public/favicon.svg +0 -0
  238. /package/scaffold/{astro-core → astro/base}/src/components/rizzo/CopyToClipboard.astro +0 -0
  239. /package/scaffold/{astro-core → astro/base}/src/components/rizzo/icons/Check.astro +0 -0
  240. /package/scaffold/{astro-core → astro/base}/src/components/rizzo/icons/Copy.astro +0 -0
  241. /package/scaffold/{astro-core → astro/base}/src/layouts/Layout.astro +0 -0
  242. /package/scaffold/{astro-core → astro/base}/tsconfig.json +0 -0
  243. /package/scaffold/{svelte-core/static → astro/variants/full/dist}/.gitkeep +0 -0
  244. /package/scaffold/{svelte-core → svelte/base}/gitignore +0 -0
  245. /package/scaffold/{svelte-core → svelte/base}/package.json +0 -0
  246. /package/scaffold/{svelte-core → svelte/base}/src/app.d.ts +0 -0
  247. /package/scaffold/{svelte-core → svelte/base}/src/app.html +0 -0
  248. /package/scaffold/{svelte-core → svelte/base}/src/routes/+layout.svelte +0 -0
  249. /package/scaffold/{svelte-core → svelte/base}/svelte.config.js +0 -0
  250. /package/scaffold/{svelte-core → svelte/base}/tsconfig.json +0 -0
@@ -0,0 +1,60 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ id?: string;
6
+ class?: string;
7
+ children?: Snippet;
8
+ trigger?: Snippet;
9
+ }
10
+
11
+ let { id: ctxId, class: className = '', children, trigger }: Props = $props();
12
+
13
+ const id = $derived(ctxId ?? `context-menu-${Math.random().toString(36).slice(2, 9)}`);
14
+ let open = $state(false);
15
+ let x = $state(0);
16
+ let y = $state(0);
17
+ let contentEl: HTMLDivElement;
18
+
19
+ function handleContextMenu(e: MouseEvent) {
20
+ e.preventDefault();
21
+ x = e.clientX;
22
+ y = e.clientY;
23
+ open = true;
24
+ requestAnimationFrame(() => document.addEventListener('click', closeMenu));
25
+ }
26
+
27
+ function closeMenu() {
28
+ open = false;
29
+ document.removeEventListener('click', closeMenu);
30
+ }
31
+
32
+ function handleKeydown(e: KeyboardEvent) {
33
+ if (e.key === 'Escape') closeMenu();
34
+ }
35
+
36
+ $effect(() => {
37
+ if (open && contentEl) {
38
+ contentEl.style.left = `${x}px`;
39
+ contentEl.style.top = `${y}px`;
40
+ }
41
+ });
42
+ </script>
43
+
44
+ <div class="context-menu {className}" data-context-menu {id}>
45
+ <div data-context-menu-trigger oncontextmenu={handleContextMenu}>
46
+ {@render trigger?.()}
47
+ </div>
48
+ <div
49
+ bind:this={contentEl}
50
+ class="context-menu__content {open ? 'context-menu__content--open' : ''}"
51
+ role="menu"
52
+ aria-hidden={!open}
53
+ hidden={!open}
54
+ data-context-menu-content
55
+ id="{id}-content"
56
+ onkeydown={handleKeydown}
57
+ >
58
+ {@render children?.()}
59
+ </div>
60
+ </div>
@@ -0,0 +1,87 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ /** Aria-label for the sidebar (e.g. "Dashboard navigation") */
6
+ sidebarLabel?: string;
7
+ /** Optional class for the root wrapper */
8
+ class?: string;
9
+ /** Main content */
10
+ children: Snippet;
11
+ /** Optional sidebar content; if not provided, default nav links are shown */
12
+ sidebar?: Snippet;
13
+ }
14
+ let {
15
+ sidebarLabel = 'Dashboard navigation',
16
+ class: className = '',
17
+ children,
18
+ sidebar,
19
+ }: Props = $props();
20
+
21
+ const classes = $derived(['dashboard', className].filter(Boolean).join(' ').trim());
22
+ </script>
23
+
24
+ <div class={classes}>
25
+ <aside class="dashboard__sidebar" aria-label={sidebarLabel}>
26
+ {#if sidebar}
27
+ {@render sidebar()}
28
+ {:else}
29
+ <nav class="dashboard__nav">
30
+ <a href="/" class="dashboard__nav-link dashboard__nav-link--active" aria-current="page">Dashboard</a>
31
+ <a href="/" class="dashboard__nav-link">Items</a>
32
+ <a href="/" class="dashboard__nav-link">Settings</a>
33
+ </nav>
34
+ {/if}
35
+ </aside>
36
+ <main id="main-content" class="dashboard__main">
37
+ {@render children()}
38
+ </main>
39
+ </div>
40
+
41
+ <style>
42
+ .dashboard {
43
+ display: flex;
44
+ min-height: 100vh;
45
+ }
46
+ .dashboard__sidebar {
47
+ width: 16rem;
48
+ flex-shrink: 0;
49
+ border-right: 1px solid var(--border);
50
+ padding: var(--spacing-4);
51
+ background: var(--background-alt);
52
+ }
53
+ .dashboard__nav {
54
+ display: flex;
55
+ flex-direction: column;
56
+ gap: var(--spacing-1);
57
+ }
58
+ .dashboard__nav-link {
59
+ display: block;
60
+ padding: var(--spacing-2) var(--spacing-3);
61
+ border-radius: var(--radius-md);
62
+ color: var(--text);
63
+ text-decoration: none;
64
+ }
65
+ .dashboard__nav-link:hover {
66
+ background: var(--background);
67
+ }
68
+ .dashboard__nav-link--active {
69
+ background: var(--accent);
70
+ color: var(--accent-text);
71
+ }
72
+ .dashboard__main {
73
+ flex: 1;
74
+ padding: var(--spacing-6);
75
+ overflow: auto;
76
+ }
77
+ @media (max-width: 768px) {
78
+ .dashboard {
79
+ flex-direction: column;
80
+ }
81
+ .dashboard__sidebar {
82
+ width: 100%;
83
+ border-right: none;
84
+ border-bottom: 1px solid var(--border);
85
+ }
86
+ }
87
+ </style>
@@ -0,0 +1,36 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ title?: string;
6
+ description?: string;
7
+ class?: string;
8
+ icon?: Snippet;
9
+ action?: Snippet;
10
+ }
11
+
12
+ let {
13
+ title = 'No results',
14
+ description,
15
+ class: className = '',
16
+ icon,
17
+ action,
18
+ }: Props = $props();
19
+ </script>
20
+
21
+ <div class="empty {className}">
22
+ {#if icon}
23
+ <div class="empty__icon">
24
+ {@render icon()}
25
+ </div>
26
+ {/if}
27
+ <h3 class="empty__title">{title}</h3>
28
+ {#if description}
29
+ <p class="empty__description">{description}</p>
30
+ {/if}
31
+ {#if action}
32
+ <div class="empty__action">
33
+ {@render action()}
34
+ </div>
35
+ {/if}
36
+ </div>
@@ -0,0 +1,55 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ id?: string;
6
+ openDelay?: number;
7
+ closeDelay?: number;
8
+ open?: boolean;
9
+ class?: string;
10
+ children?: Snippet;
11
+ trigger?: Snippet;
12
+ }
13
+
14
+ let {
15
+ id: hoverId,
16
+ openDelay = 200,
17
+ closeDelay = 100,
18
+ open = $bindable(false),
19
+ class: className = '',
20
+ children,
21
+ trigger,
22
+ }: Props = $props();
23
+
24
+ const id = $derived(hoverId ?? `hover-card-${Math.random().toString(36).slice(2, 9)}`);
25
+ let openT: ReturnType<typeof setTimeout> | null = null;
26
+ let closeT: ReturnType<typeof setTimeout> | null = null;
27
+
28
+ function openContent() {
29
+ if (closeT) clearTimeout(closeT);
30
+ openT = setTimeout(() => (open = true), openDelay);
31
+ }
32
+
33
+ function closeContent() {
34
+ if (openT) clearTimeout(openT);
35
+ closeT = setTimeout(() => (open = false), closeDelay);
36
+ }
37
+ </script>
38
+
39
+ <div class="hover-card {className}" data-hover-card {id}>
40
+ <div data-hover-card-trigger onmouseenter={openContent} onmouseleave={closeContent}>
41
+ {@render trigger?.()}
42
+ </div>
43
+ <div
44
+ class="hover-card__content {open ? 'hover-card__content--open' : ''}"
45
+ role="dialog"
46
+ aria-hidden={!open}
47
+ hidden={!open}
48
+ data-hover-card-content
49
+ id="{id}-content"
50
+ onmouseenter={openContent}
51
+ onmouseleave={closeContent}
52
+ >
53
+ {@render children?.()}
54
+ </div>
55
+ </div>
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ class?: string;
6
+ children?: Snippet;
7
+ }
8
+
9
+ let { class: className = '', children }: Props = $props();
10
+ const classes = $derived(['kbd', className].filter(Boolean).join(' '));
11
+ </script>
12
+
13
+ <kbd class={classes}>{@render children?.()}</kbd>
@@ -0,0 +1,19 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ for?: string;
6
+ required?: boolean;
7
+ class?: string;
8
+ children?: Snippet;
9
+ }
10
+
11
+ let { for: forId, required = false, class: className = '', children }: Props = $props();
12
+ const classes = $derived(['label', required ? 'label--required' : '', className].filter(Boolean).join(' '));
13
+ </script>
14
+
15
+ {#if forId}
16
+ <label for={forId} class={classes}>{@render children?.()}</label>
17
+ {:else}
18
+ <span class={classes}>{@render children?.()}</span>
19
+ {/if}
@@ -0,0 +1,59 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ id?: string;
6
+ open?: boolean;
7
+ class?: string;
8
+ children?: Snippet;
9
+ trigger?: Snippet;
10
+ }
11
+
12
+ let {
13
+ id: popoverId,
14
+ open = $bindable(false),
15
+ class: className = '',
16
+ children,
17
+ trigger,
18
+ }: Props = $props();
19
+
20
+ const id = $derived(popoverId ?? `popover-${Math.random().toString(36).slice(2, 9)}`);
21
+
22
+ function toggle(e: MouseEvent) {
23
+ e.preventDefault();
24
+ open = !open;
25
+ }
26
+
27
+ function handleClickOutside(e: MouseEvent) {
28
+ const target = e.target as Node;
29
+ if (target && !document.getElementById(id)?.contains(target)) open = false;
30
+ }
31
+
32
+ $effect(() => {
33
+ if (open) {
34
+ const t = setTimeout(() => document.addEventListener('click', handleClickOutside), 0);
35
+ return () => {
36
+ clearTimeout(t);
37
+ document.removeEventListener('click', handleClickOutside);
38
+ };
39
+ }
40
+ });
41
+ </script>
42
+
43
+ <div class="popover {className}" data-popover id={id}>
44
+ <button type="button" data-popover-trigger onclick={toggle}>
45
+ {@render trigger?.()}
46
+ </button>
47
+ <div
48
+ class="popover__content {open ? 'popover__content--open' : ''}"
49
+ role="dialog"
50
+ aria-modal="false"
51
+ aria-hidden={!open}
52
+ hidden={!open}
53
+ data-popover-content
54
+ id={`${id}-content`}
55
+ onkeydown={(e) => e.key === 'Escape' && (open = false)}
56
+ >
57
+ {@render children?.()}
58
+ </div>
59
+ </div>
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ withHandle?: boolean;
4
+ class?: string;
5
+ }
6
+
7
+ let { withHandle = false, class: className = '' }: Props = $props();
8
+ </script>
9
+
10
+ <div
11
+ class="resizable__handle {withHandle ? 'resizable__handle--with-handle' : ''} {className}"
12
+ data-resizable-handle
13
+ ></div>
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ defaultSize?: number;
6
+ class?: string;
7
+ children?: Snippet;
8
+ }
9
+
10
+ let { defaultSize = 50, class: className = '', children }: Props = $props();
11
+ const size = Math.min(100, Math.max(0, defaultSize));
12
+ </script>
13
+
14
+ <div class="resizable__pane {className}" data-resizable-pane style="flex: 1 1 {size}%">
15
+ {@render children?.()}
16
+ </div>
@@ -0,0 +1,92 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ id?: string;
6
+ direction?: 'horizontal' | 'vertical';
7
+ class?: string;
8
+ children?: Snippet;
9
+ }
10
+
11
+ let { id: groupId, direction = 'horizontal', class: className = '', children }: Props = $props();
12
+
13
+ const id = $derived(groupId ?? `resizable-${Math.random().toString(36).slice(2, 9)}`);
14
+ let rootEl: HTMLDivElement;
15
+
16
+ function getSize(el: Element): number {
17
+ const style = getComputedStyle(el);
18
+ const basis = style.flexBasis;
19
+ if (basis?.endsWith('%')) return parseFloat(basis);
20
+ const rect = el.getBoundingClientRect();
21
+ const parent = el.parentElement;
22
+ if (!parent) return 50;
23
+ const parentRect = parent.getBoundingClientRect();
24
+ return direction === 'horizontal'
25
+ ? (rect.width / parentRect.width) * 100
26
+ : (rect.height / parentRect.height) * 100;
27
+ }
28
+
29
+ function initResize() {
30
+ const root = rootEl;
31
+ if (!root) return;
32
+ const panes = Array.from(root.querySelectorAll('[data-resizable-pane]'));
33
+ const handles = Array.from(root.querySelectorAll('[data-resizable-handle]'));
34
+ if (panes.length < 2 || handles.length !== panes.length - 1) return;
35
+
36
+ function setSizes(pct1: number, pct2: number, idx: number) {
37
+ (panes[idx] as HTMLElement).style.flex = `1 1 ${pct1}%`;
38
+ (panes[idx + 1] as HTMLElement).style.flex = `1 1 ${pct2}%`;
39
+ }
40
+
41
+ handles.forEach((handle, i) => {
42
+ let startX: number, startY: number, startPct1: number, startPct2: number;
43
+ function onMove(e: MouseEvent) {
44
+ const parent = root.getBoundingClientRect();
45
+ const delta =
46
+ direction === 'horizontal'
47
+ ? ((e.clientX - startX) / parent.width) * 100
48
+ : ((e.clientY - startY) / parent.height) * 100;
49
+ let p1 = startPct1 + delta;
50
+ let p2 = startPct2 - delta;
51
+ const min = 10;
52
+ if (p1 < min) {
53
+ p1 = min;
54
+ p2 = 100 - min;
55
+ }
56
+ if (p2 < min) {
57
+ p2 = min;
58
+ p1 = 100 - min;
59
+ }
60
+ setSizes(p1, p2, i);
61
+ }
62
+ function onUp() {
63
+ document.removeEventListener('mousemove', onMove as EventListener);
64
+ document.removeEventListener('mouseup', onUp);
65
+ }
66
+ handle.addEventListener('mousedown', (e: Event) => {
67
+ const ev = e as MouseEvent;
68
+ ev.preventDefault();
69
+ startX = ev.clientX;
70
+ startY = ev.clientY;
71
+ startPct1 = getSize(panes[i]);
72
+ startPct2 = getSize(panes[i + 1]);
73
+ document.addEventListener('mousemove', onMove as EventListener);
74
+ document.addEventListener('mouseup', onUp);
75
+ });
76
+ });
77
+ }
78
+
79
+ $effect(() => {
80
+ if (rootEl) initResize();
81
+ });
82
+ </script>
83
+
84
+ <div
85
+ bind:this={rootEl}
86
+ class="resizable__pane-group resizable__pane-group--{direction} {className}"
87
+ {id}
88
+ data-resizable-group
89
+ data-direction={direction}
90
+ >
91
+ {@render children?.()}
92
+ </div>
@@ -0,0 +1,18 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ orientation?: 'vertical' | 'horizontal';
6
+ class?: string;
7
+ children?: Snippet;
8
+ }
9
+
10
+ let { orientation = 'vertical', class: className = '', children }: Props = $props();
11
+ const horizontal = $derived(orientation === 'horizontal');
12
+ </script>
13
+
14
+ <div class="scroll-area {horizontal ? 'scroll-area--horizontal' : ''} {className}">
15
+ <div class="scroll-area__viewport" tabindex="0">
16
+ {@render children?.()}
17
+ </div>
18
+ </div>
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ orientation?: 'horizontal' | 'vertical';
4
+ class?: string;
5
+ }
6
+
7
+ let { orientation = 'horizontal', class: className = '' }: Props = $props();
8
+ </script>
9
+
10
+ <div
11
+ class="separator separator--{orientation} {className}"
12
+ role="separator"
13
+ aria-orientation={orientation}
14
+ ></div>
@@ -0,0 +1,62 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import Close from './icons/Close.svelte';
4
+
5
+ interface Props {
6
+ id?: string;
7
+ title?: string;
8
+ side?: 'top' | 'right' | 'bottom' | 'left';
9
+ open?: boolean;
10
+ class?: string;
11
+ children?: Snippet;
12
+ }
13
+
14
+ let {
15
+ id: sheetId,
16
+ title,
17
+ side = 'right',
18
+ open = $bindable(false),
19
+ class: className = '',
20
+ children,
21
+ }: Props = $props();
22
+
23
+ const id = $derived(sheetId ?? `sheet-${Math.random().toString(36).slice(2, 9)}`);
24
+
25
+ function close() {
26
+ open = false;
27
+ }
28
+ </script>
29
+
30
+ <div
31
+ class="sheet__overlay {open ? 'sheet__overlay--open' : ''}"
32
+ data-sheet-overlay
33
+ aria-hidden={!open}
34
+ id={`${id}-overlay`}
35
+ onclick={close}
36
+ role="presentation"
37
+ ></div>
38
+ <div
39
+ class="sheet sheet--{side} {open ? 'sheet--open' : ''} {className}"
40
+ role="dialog"
41
+ aria-modal="true"
42
+ aria-labelledby={title ? `${id}-title` : undefined}
43
+ aria-hidden={!open}
44
+ {id}
45
+ data-sheet
46
+ hidden={!open}
47
+ onkeydown={(e) => e.key === 'Escape' && close()}
48
+ >
49
+ <div class="sheet__content">
50
+ {#if title}
51
+ <div class="sheet__header">
52
+ <h2 id={`${id}-title`} class="sheet__title">{title}</h2>
53
+ <button type="button" class="sheet__close" aria-label="Close" onclick={close}>
54
+ <Close width={20} height={20} />
55
+ </button>
56
+ </div>
57
+ {/if}
58
+ <div class="sheet__body">
59
+ {@render children?.()}
60
+ </div>
61
+ </div>
62
+ </div>
@@ -0,0 +1,19 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ variant?: 'text' | 'circle' | 'rect' | 'default';
4
+ label?: string;
5
+ class?: string;
6
+ }
7
+ let { variant = 'default', label = 'Loading', class: className = '' }: Props = $props();
8
+ const variantClass = $derived(variant !== 'default' ? `skeleton--${variant}` : '');
9
+ const classes = $derived(['skeleton', variantClass, className].filter(Boolean).join(' ').trim());
10
+ const isDecorative = $derived(label === '');
11
+ </script>
12
+
13
+ <span
14
+ class={classes}
15
+ role={isDecorative ? undefined : 'status'}
16
+ aria-label={isDecorative ? undefined : label}
17
+ aria-busy={isDecorative ? undefined : 'true'}
18
+ aria-hidden={isDecorative ? 'true' : undefined}
19
+ ></span>
@@ -0,0 +1,57 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ id?: string;
4
+ name?: string;
5
+ min?: number;
6
+ max?: number;
7
+ step?: number;
8
+ value?: number;
9
+ disabled?: boolean;
10
+ /** Accessible name for the range input (required for axe / WCAG). */
11
+ ariaLabel?: string;
12
+ class?: string;
13
+ }
14
+
15
+ let {
16
+ id: sliderId,
17
+ name,
18
+ min = 0,
19
+ max = 100,
20
+ step = 1,
21
+ value = $bindable(min),
22
+ disabled = false,
23
+ ariaLabel,
24
+ class: className = '',
25
+ }: Props = $props();
26
+
27
+ const id = $derived(sliderId ?? `slider-${Math.random().toString(36).slice(2, 9)}`);
28
+ const pct = $derived(Math.min(100, Math.max(0, ((value - min) / (max - min)) * 100)));
29
+
30
+ function handleInput(e: Event) {
31
+ const t = e.currentTarget as HTMLInputElement;
32
+ if (t) value = parseFloat(t.value);
33
+ }
34
+ </script>
35
+
36
+ <div class="slider {className}" data-slider>
37
+ <input
38
+ type="range"
39
+ {id}
40
+ {name}
41
+ class="slider__input"
42
+ {min}
43
+ {max}
44
+ {step}
45
+ bind:value
46
+ {disabled}
47
+ aria-valuemin={min}
48
+ aria-valuemax={max}
49
+ aria-valuenow={value}
50
+ aria-label={ariaLabel}
51
+ data-slider-input
52
+ oninput={handleInput}
53
+ />
54
+ <div class="slider__track" aria-hidden="true">
55
+ <div class="slider__fill" data-slider-fill style="width: {pct}%"></div>
56
+ </div>
57
+ </div>
@@ -23,6 +23,9 @@
23
23
  if (!target) return;
24
24
  soundEffects = target.checked;
25
25
  localStorage?.setItem('soundEffects', target.checked ? 'true' : 'false');
26
+ if (target.checked && typeof window !== 'undefined') {
27
+ window.dispatchEvent(new CustomEvent('rizzo-sound-effects-change'));
28
+ }
26
29
  }
27
30
  </script>
28
31
 
@@ -0,0 +1,35 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ id?: string;
4
+ name?: string;
5
+ checked?: boolean;
6
+ disabled?: boolean;
7
+ label?: string;
8
+ class?: string;
9
+ }
10
+ let {
11
+ id,
12
+ name,
13
+ checked = $bindable(false),
14
+ disabled = false,
15
+ label,
16
+ class: className = '',
17
+ }: Props = $props();
18
+ </script>
19
+
20
+ <label class="switch {className}" for={id}>
21
+ <input
22
+ type="checkbox"
23
+ {id}
24
+ {name}
25
+ bind:checked
26
+ {disabled}
27
+ class="switch__input"
28
+ role="switch"
29
+ aria-checked={checked}
30
+ />
31
+ <span class="switch__track" aria-hidden="true">
32
+ <span class="switch__thumb"></span>
33
+ </span>
34
+ {#if label}<span class="switch__label">{label}</span>{/if}
35
+ </label>
@@ -92,7 +92,7 @@
92
92
  onkeydown={(e) => handleKeydown(e, index)}
93
93
  >
94
94
  {#if tab.icon}
95
- <img src={tab.icon} alt="" class="tabs__tab-icon" width="20" height="20" />
95
+ <img src={tab.icon} alt="" class="tabs__tab-icon" width="20" height="20" loading="lazy" aria-hidden="true" />
96
96
  {/if}
97
97
  {tab.label}
98
98
  </span>