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.
- package/README.md +11 -7
- package/bin/rizzo-css.js +273 -118
- package/dist/rizzo.min.css +40 -16
- package/package.json +6 -6
- package/scaffold/astro/AlertDialog.astro +86 -0
- package/scaffold/astro/AspectRatio.astro +22 -0
- package/scaffold/astro/ButtonGroup.astro +16 -0
- package/scaffold/astro/Collapsible.astro +69 -0
- package/scaffold/astro/ContextMenu.astro +58 -0
- package/scaffold/astro/CopyToClipboard.astro +4 -0
- package/scaffold/astro/Dashboard.astro +74 -0
- package/scaffold/astro/Empty.astro +23 -0
- package/scaffold/astro/HoverCard.astro +64 -0
- package/scaffold/astro/Kbd.astro +14 -0
- package/scaffold/astro/Label.astro +24 -0
- package/scaffold/astro/Modal.astro +17 -2
- package/scaffold/astro/Popover.astro +62 -0
- package/scaffold/astro/ResizableHandle.astro +16 -0
- package/scaffold/astro/ResizablePane.astro +20 -0
- package/scaffold/astro/ResizablePaneGroup.astro +84 -0
- package/scaffold/astro/ScrollArea.astro +19 -0
- package/scaffold/astro/Separator.astro +18 -0
- package/scaffold/astro/Settings.astro +10 -2
- package/scaffold/astro/Sheet.astro +90 -0
- package/scaffold/astro/Skeleton.astro +16 -0
- package/scaffold/astro/Slider.astro +75 -0
- package/scaffold/astro/SoundEffects.astro +1 -0
- package/scaffold/astro/Switch.astro +37 -0
- package/scaffold/astro/Tabs.astro +1 -1
- package/scaffold/astro/ThemeSwitcher.astro +11 -4
- package/scaffold/astro/Toggle.astro +35 -0
- package/scaffold/astro/ToggleGroup.astro +24 -0
- package/scaffold/astro/base/README-RIZZO.md +55 -0
- package/scaffold/{astro-core → astro/base}/src/pages/index.astro +1 -1
- package/scaffold/astro/variants/dashboard/src/layouts/Layout.astro +85 -0
- package/scaffold/astro/variants/dashboard/src/pages/index.astro +110 -0
- package/scaffold/astro/variants/docs/src/layouts/Layout.astro +81 -0
- package/scaffold/astro/variants/docs/src/pages/docs/getting-started.astro +36 -0
- package/scaffold/astro/variants/docs/src/pages/index.astro +38 -0
- package/scaffold/{astro-core → astro/variants/full}/README-RIZZO.md +2 -1
- package/scaffold/astro/variants/full/astro.config.mjs +5 -0
- package/scaffold/astro/variants/full/dist/_noop-middleware.mjs +3 -0
- package/scaffold/astro/variants/full/dist/chunks/astro/server_9Mzx7luy.mjs +6023 -0
- package/scaffold/astro/variants/full/dist/chunks/astro_BOYUKg7r.mjs +1 -0
- package/scaffold/astro/variants/full/dist/favicon.svg +18 -0
- package/scaffold/astro/variants/full/dist/manifest_DXpJmqSX.mjs +154 -0
- package/scaffold/astro/variants/full/dist/noop-entrypoint.mjs +3 -0
- package/scaffold/astro/variants/full/dist/pages/index.astro.mjs +87 -0
- package/scaffold/astro/variants/full/dist/renderers.mjs +3 -0
- package/scaffold/astro/variants/full/gitignore +24 -0
- package/scaffold/astro/variants/full/node_modules/.astro/data-store.json +1 -0
- package/scaffold/astro/variants/full/node_modules/.vite/deps/_metadata.json +31 -0
- package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___aria-query.js +6776 -0
- package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___aria-query.js.map +7 -0
- package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___axobject-query.js +3754 -0
- package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___axobject-query.js.map +7 -0
- package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___cssesc.js +99 -0
- package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___cssesc.js.map +7 -0
- package/scaffold/astro/variants/full/node_modules/.vite/deps/chunk-BUSYA2B4.js +8 -0
- package/scaffold/astro/variants/full/node_modules/.vite/deps/chunk-BUSYA2B4.js.map +7 -0
- package/scaffold/astro/variants/full/node_modules/.vite/deps/package.json +3 -0
- package/scaffold/astro/variants/full/package.json +13 -0
- package/scaffold/astro/variants/full/public/.gitkeep +0 -0
- package/scaffold/astro/variants/full/public/favicon.svg +18 -0
- package/scaffold/astro/variants/full/src/components/rizzo/CopyToClipboard.astro +157 -0
- package/scaffold/astro/variants/full/src/components/rizzo/icons/Check.astro +29 -0
- package/scaffold/astro/variants/full/src/components/rizzo/icons/Copy.astro +30 -0
- package/scaffold/astro/variants/full/src/layouts/Layout.astro +34 -0
- package/scaffold/astro/variants/full/src/pages/index.astro +107 -0
- package/scaffold/astro/variants/full/tsconfig.json +5 -0
- package/scaffold/landing/index.html +13 -0
- package/scaffold/shared/navbar-vanilla.html +59 -0
- package/scaffold/shared/sound-effects-inline.js +6 -1
- package/scaffold/svelte/AlertDialog.svelte +55 -0
- package/scaffold/svelte/AspectRatio.svelte +21 -0
- package/scaffold/svelte/BackToTop.svelte +1 -0
- package/scaffold/svelte/ButtonGroup.svelte +16 -0
- package/scaffold/svelte/Collapsible.svelte +57 -0
- package/scaffold/svelte/ContextMenu.svelte +60 -0
- package/scaffold/svelte/Dashboard.svelte +87 -0
- package/scaffold/svelte/Empty.svelte +36 -0
- package/scaffold/svelte/HoverCard.svelte +55 -0
- package/scaffold/svelte/Kbd.svelte +13 -0
- package/scaffold/svelte/Label.svelte +19 -0
- package/scaffold/svelte/Popover.svelte +59 -0
- package/scaffold/svelte/ResizableHandle.svelte +13 -0
- package/scaffold/svelte/ResizablePane.svelte +16 -0
- package/scaffold/svelte/ResizablePaneGroup.svelte +92 -0
- package/scaffold/svelte/ScrollArea.svelte +18 -0
- package/scaffold/svelte/Separator.svelte +14 -0
- package/scaffold/svelte/Sheet.svelte +62 -0
- package/scaffold/svelte/Skeleton.svelte +19 -0
- package/scaffold/svelte/Slider.svelte +57 -0
- package/scaffold/svelte/SoundEffects.svelte +3 -0
- package/scaffold/svelte/Switch.svelte +35 -0
- package/scaffold/svelte/Tabs.svelte +1 -1
- package/scaffold/svelte/Toggle.svelte +41 -0
- package/scaffold/svelte/ToggleGroup.svelte +30 -0
- package/scaffold/svelte/base/README-RIZZO.md +55 -0
- package/scaffold/{svelte-core → svelte/base}/src/routes/+page.svelte +1 -1
- package/scaffold/svelte/base/static/.gitkeep +0 -0
- package/scaffold/svelte/index.ts +21 -0
- package/scaffold/svelte/variants/dashboard/src/routes/+layout.svelte +64 -0
- package/scaffold/svelte/variants/dashboard/src/routes/+page.svelte +104 -0
- package/scaffold/svelte/variants/docs/src/routes/+layout.svelte +60 -0
- package/scaffold/svelte/variants/docs/src/routes/+page.svelte +34 -0
- package/scaffold/svelte/variants/docs/src/routes/docs/getting-started/+page.svelte +31 -0
- package/scaffold/{svelte-core → svelte/variants/full}/README-RIZZO.md +2 -1
- package/scaffold/svelte/variants/full/gitignore +10 -0
- package/scaffold/svelte/variants/full/package.json +20 -0
- package/scaffold/svelte/variants/full/src/app.d.ts +11 -0
- package/scaffold/svelte/variants/full/src/app.html +16 -0
- package/scaffold/svelte/variants/full/src/routes/+layout.svelte +1 -0
- package/scaffold/svelte/variants/full/src/routes/+page.svelte +105 -0
- package/scaffold/svelte/variants/full/static/.gitkeep +0 -0
- package/scaffold/svelte/variants/full/svelte.config.js +10 -0
- package/scaffold/svelte/variants/full/tsconfig.json +11 -0
- package/scaffold/vanilla/README-RIZZO.md +6 -5
- package/scaffold/vanilla/components/accordion.html +59 -64
- package/scaffold/vanilla/components/alert-dialog.html +640 -0
- package/scaffold/vanilla/components/alert.html +59 -64
- package/scaffold/vanilla/components/aspect-ratio.html +640 -0
- package/scaffold/vanilla/components/avatar.html +59 -64
- package/scaffold/vanilla/components/back-to-top.html +59 -64
- package/scaffold/vanilla/components/badge.html +59 -64
- package/scaffold/vanilla/components/breadcrumb.html +59 -64
- package/scaffold/vanilla/components/button-group.html +640 -0
- package/scaffold/vanilla/components/button.html +59 -64
- package/scaffold/vanilla/components/cards.html +59 -64
- package/scaffold/vanilla/components/collapsible.html +640 -0
- package/scaffold/vanilla/components/context-menu.html +640 -0
- package/scaffold/vanilla/components/copy-to-clipboard.html +59 -64
- package/scaffold/vanilla/components/dashboard.html +640 -0
- package/scaffold/vanilla/components/divider.html +59 -64
- package/scaffold/vanilla/components/docs-sidebar.html +59 -64
- package/scaffold/vanilla/components/dropdown.html +59 -64
- package/scaffold/vanilla/components/empty.html +640 -0
- package/scaffold/vanilla/components/font-switcher.html +59 -64
- package/scaffold/vanilla/components/footer.html +59 -64
- package/scaffold/vanilla/components/forms.html +59 -64
- package/scaffold/vanilla/components/hover-card.html +640 -0
- package/scaffold/vanilla/components/icons.html +59 -64
- package/scaffold/vanilla/components/index.html +79 -64
- package/scaffold/vanilla/components/kbd.html +640 -0
- package/scaffold/vanilla/components/label.html +640 -0
- package/scaffold/vanilla/components/modal.html +59 -64
- package/scaffold/vanilla/components/navbar.html +59 -64
- package/scaffold/vanilla/components/pagination.html +59 -64
- package/scaffold/vanilla/components/popover.html +640 -0
- package/scaffold/vanilla/components/progress-bar.html +59 -64
- package/scaffold/vanilla/components/resizable.html +640 -0
- package/scaffold/vanilla/components/scroll-area.html +640 -0
- package/scaffold/vanilla/components/search.html +59 -64
- package/scaffold/vanilla/components/separator.html +640 -0
- package/scaffold/vanilla/components/settings.html +59 -64
- package/scaffold/vanilla/components/sheet.html +640 -0
- package/scaffold/vanilla/components/skeleton.html +640 -0
- package/scaffold/vanilla/components/slider.html +640 -0
- package/scaffold/vanilla/components/sound-effects.html +59 -64
- package/scaffold/vanilla/components/spinner.html +59 -64
- package/scaffold/vanilla/components/switch.html +640 -0
- package/scaffold/vanilla/components/table.html +59 -64
- package/scaffold/vanilla/components/tabs.html +59 -64
- package/scaffold/vanilla/components/theme-switcher.html +59 -64
- package/scaffold/vanilla/components/toast.html +59 -64
- package/scaffold/vanilla/components/toggle-group.html +640 -0
- package/scaffold/vanilla/components/toggle.html +640 -0
- package/scaffold/vanilla/components/tooltip.html +59 -64
- package/scaffold/vanilla/index.html +61 -66
- package/scaffold/vanilla/variants/dashboard/index.html +45 -0
- package/scaffold/vanilla/variants/docs/index.html +36 -0
- package/scaffold/vanilla/variants/full/components/accordion.html +592 -0
- package/scaffold/vanilla/variants/full/components/alert.html +592 -0
- package/scaffold/vanilla/variants/full/components/avatar.html +592 -0
- package/scaffold/vanilla/variants/full/components/back-to-top.html +592 -0
- package/scaffold/vanilla/variants/full/components/badge.html +592 -0
- package/scaffold/vanilla/variants/full/components/breadcrumb.html +592 -0
- package/scaffold/vanilla/variants/full/components/button.html +592 -0
- package/scaffold/vanilla/variants/full/components/cards.html +592 -0
- package/scaffold/vanilla/variants/full/components/copy-to-clipboard.html +592 -0
- package/scaffold/vanilla/variants/full/components/dashboard.html +592 -0
- package/scaffold/vanilla/variants/full/components/divider.html +592 -0
- package/scaffold/vanilla/variants/full/components/docs-sidebar.html +592 -0
- package/scaffold/vanilla/variants/full/components/dropdown.html +592 -0
- package/scaffold/vanilla/variants/full/components/font-switcher.html +592 -0
- package/scaffold/vanilla/variants/full/components/footer.html +592 -0
- package/scaffold/vanilla/variants/full/components/forms.html +592 -0
- package/scaffold/vanilla/variants/full/components/icons.html +592 -0
- package/scaffold/vanilla/variants/full/components/index.html +625 -0
- package/scaffold/vanilla/variants/full/components/modal.html +592 -0
- package/scaffold/vanilla/variants/full/components/navbar.html +592 -0
- package/scaffold/vanilla/variants/full/components/pagination.html +592 -0
- package/scaffold/vanilla/variants/full/components/progress-bar.html +592 -0
- package/scaffold/vanilla/variants/full/components/search.html +592 -0
- package/scaffold/vanilla/variants/full/components/settings.html +592 -0
- package/scaffold/vanilla/variants/full/components/skeleton.html +592 -0
- package/scaffold/vanilla/variants/full/components/sound-effects.html +592 -0
- package/scaffold/vanilla/variants/full/components/spinner.html +592 -0
- package/scaffold/vanilla/variants/full/components/switch.html +592 -0
- package/scaffold/vanilla/variants/full/components/table.html +592 -0
- package/scaffold/vanilla/variants/full/components/tabs.html +592 -0
- package/scaffold/vanilla/variants/full/components/theme-switcher.html +592 -0
- package/scaffold/vanilla/variants/full/components/toast.html +592 -0
- package/scaffold/vanilla/variants/full/components/tooltip.html +592 -0
- package/scaffold/vanilla/variants/full/index.html +682 -0
- package/scaffold/vanilla/variants/full/js/main.js +989 -0
- package/scaffold/astro-core/.astro/content-assets.mjs +0 -1
- package/scaffold/astro-core/.astro/content-modules.mjs +0 -1
- package/scaffold/astro-core/.astro/content.d.ts +0 -199
- package/scaffold/astro-core/.astro/types.d.ts +0 -2
- package/scaffold/astro-core/.env.example +0 -3
- package/scaffold/svelte-core/.env.example +0 -3
- /package/scaffold/{astro-core → astro/base}/astro.config.mjs +0 -0
- /package/scaffold/{astro-core → astro/base}/dist/.gitkeep +0 -0
- /package/scaffold/{astro-core → astro/base}/dist/_noop-middleware.mjs +0 -0
- /package/scaffold/{astro-core → astro/base}/dist/chunks/astro/server_9Mzx7luy.mjs +0 -0
- /package/scaffold/{astro-core → astro/base}/dist/chunks/astro_BOYUKg7r.mjs +0 -0
- /package/scaffold/{astro-core → astro/base}/dist/favicon.svg +0 -0
- /package/scaffold/{astro-core → astro/base}/dist/manifest_DXpJmqSX.mjs +0 -0
- /package/scaffold/{astro-core → astro/base}/dist/noop-entrypoint.mjs +0 -0
- /package/scaffold/{astro-core → astro/base}/dist/pages/index.astro.mjs +0 -0
- /package/scaffold/{astro-core → astro/base}/dist/renderers.mjs +0 -0
- /package/scaffold/{astro-core → astro/base}/gitignore +0 -0
- /package/scaffold/{astro-core → astro/base}/node_modules/.astro/data-store.json +0 -0
- /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/_metadata.json +0 -0
- /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___aria-query.js +0 -0
- /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___aria-query.js.map +0 -0
- /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___axobject-query.js +0 -0
- /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___axobject-query.js.map +0 -0
- /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___cssesc.js +0 -0
- /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___cssesc.js.map +0 -0
- /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/chunk-BUSYA2B4.js +0 -0
- /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/chunk-BUSYA2B4.js.map +0 -0
- /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/package.json +0 -0
- /package/scaffold/{astro-core → astro/base}/package.json +0 -0
- /package/scaffold/{astro-core → astro/base}/public/.gitkeep +0 -0
- /package/scaffold/{astro-core → astro/base}/public/favicon.svg +0 -0
- /package/scaffold/{astro-core → astro/base}/src/components/rizzo/CopyToClipboard.astro +0 -0
- /package/scaffold/{astro-core → astro/base}/src/components/rizzo/icons/Check.astro +0 -0
- /package/scaffold/{astro-core → astro/base}/src/components/rizzo/icons/Copy.astro +0 -0
- /package/scaffold/{astro-core → astro/base}/src/layouts/Layout.astro +0 -0
- /package/scaffold/{astro-core → astro/base}/tsconfig.json +0 -0
- /package/scaffold/{svelte-core/static → astro/variants/full/dist}/.gitkeep +0 -0
- /package/scaffold/{svelte-core → svelte/base}/gitignore +0 -0
- /package/scaffold/{svelte-core → svelte/base}/package.json +0 -0
- /package/scaffold/{svelte-core → svelte/base}/src/app.d.ts +0 -0
- /package/scaffold/{svelte-core → svelte/base}/src/app.html +0 -0
- /package/scaffold/{svelte-core → svelte/base}/src/routes/+layout.svelte +0 -0
- /package/scaffold/{svelte-core → svelte/base}/svelte.config.js +0 -0
- /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>
|