rizzo-css 0.0.10 → 0.0.12
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 +20 -6
- package/bin/rizzo-css.js +13 -0
- package/dist/rizzo.min.css +34 -19
- package/package.json +1 -1
- package/scaffold/astro/CopyToClipboard.astro +37 -17
- package/scaffold/astro/FormGroup.astro +14 -6
- package/scaffold/astro/icons/Brush.astro +0 -1
- package/scaffold/astro/icons/Cake.astro +0 -1
- package/scaffold/astro/icons/Check.astro +1 -2
- package/scaffold/astro/icons/Cherry.astro +0 -1
- package/scaffold/astro/icons/ChevronDown.astro +1 -2
- package/scaffold/astro/icons/Circle.astro +1 -2
- package/scaffold/astro/icons/Close.astro +1 -2
- package/scaffold/astro/icons/Cmd.astro +26 -0
- package/scaffold/astro/icons/Copy.astro +1 -2
- package/scaffold/astro/icons/Eye.astro +1 -2
- package/scaffold/astro/icons/Filter.astro +1 -2
- package/scaffold/astro/icons/Flame.astro +0 -1
- package/scaffold/astro/icons/Flower.astro +0 -1
- package/scaffold/astro/icons/Gear.astro +1 -2
- package/scaffold/astro/icons/Heart.astro +0 -1
- package/scaffold/astro/icons/IceCream.astro +1 -2
- package/scaffold/astro/icons/Leaf.astro +0 -1
- package/scaffold/astro/icons/Lemon.astro +0 -1
- package/scaffold/astro/icons/Moon.astro +1 -2
- package/scaffold/astro/icons/Owl.astro +1 -2
- package/scaffold/astro/icons/Palette.astro +1 -2
- package/scaffold/astro/icons/Rainbow.astro +1 -2
- package/scaffold/astro/icons/Search.astro +1 -2
- package/scaffold/astro/icons/Shield.astro +0 -1
- package/scaffold/astro/icons/Snowflake.astro +1 -2
- package/scaffold/astro/icons/Sort.astro +1 -2
- package/scaffold/astro/icons/Sun.astro +0 -1
- package/scaffold/astro/icons/Sunset.astro +0 -1
- package/scaffold/astro/icons/Zap.astro +0 -1
- package/scaffold/astro/icons/devicons/Astro.astro +0 -1
- package/scaffold/astro/icons/devicons/Bash.astro +0 -1
- package/scaffold/astro/icons/devicons/Css3.astro +0 -1
- package/scaffold/astro/icons/devicons/Git.astro +0 -1
- package/scaffold/astro/icons/devicons/Html5.astro +0 -1
- package/scaffold/astro/icons/devicons/Javascript.astro +0 -1
- package/scaffold/astro/icons/devicons/Nodejs.astro +0 -1
- package/scaffold/astro/icons/devicons/Plaintext.astro +0 -1
- package/scaffold/astro/icons/devicons/React.astro +0 -1
- package/scaffold/astro/icons/devicons/Svelte.astro +0 -1
- package/scaffold/astro/icons/devicons/Vue.astro +0 -1
- package/scaffold/astro-app/README.md +32 -0
- package/scaffold/astro-app/astro.config.mjs +2 -1
- package/scaffold/astro-app/package.json +1 -1
- package/scaffold/astro-app/src/layouts/Layout.astro +4 -1
- package/scaffold/astro-app/src/pages/index.astro +4 -2
- package/scaffold/svelte/Accordion.svelte +1 -2
- package/scaffold/svelte/Alert.svelte +8 -3
- package/scaffold/svelte/Avatar.svelte +1 -1
- package/scaffold/svelte/Badge.svelte +11 -11
- package/scaffold/svelte/Breadcrumb.svelte +8 -6
- package/scaffold/svelte/Button.svelte +7 -3
- package/scaffold/svelte/Card.svelte +7 -4
- package/scaffold/svelte/CopyToClipboard.svelte +29 -29
- package/scaffold/svelte/Divider.svelte +8 -8
- package/scaffold/svelte/Dropdown.svelte +15 -18
- package/scaffold/svelte/FormGroup.svelte +14 -4
- package/scaffold/svelte/Input.svelte +7 -5
- package/scaffold/svelte/Modal.svelte +10 -6
- package/scaffold/svelte/Pagination.svelte +1 -1
- package/scaffold/svelte/ProgressBar.svelte +13 -11
- package/scaffold/svelte/Select.svelte +10 -6
- package/scaffold/svelte/Spinner.svelte +2 -2
- package/scaffold/svelte/Table.svelte +6 -7
- package/scaffold/svelte/Tabs.svelte +15 -7
- package/scaffold/svelte/Textarea.svelte +7 -5
- package/scaffold/svelte/Toast.svelte +6 -3
- package/scaffold/svelte/Tooltip.svelte +4 -4
- package/scaffold/svelte/icons/Check.svelte +17 -10
- package/scaffold/svelte/icons/ChevronDown.svelte +16 -9
- package/scaffold/svelte/icons/Circle.svelte +16 -9
- package/scaffold/svelte/icons/Close.svelte +18 -11
- package/scaffold/svelte/icons/Cmd.svelte +27 -0
- package/scaffold/svelte/icons/Copy.svelte +16 -9
- package/scaffold/svelte/icons/Eye.svelte +16 -9
- package/scaffold/svelte/icons/Filter.svelte +16 -9
- package/scaffold/svelte/icons/Gear.svelte +16 -9
- package/scaffold/svelte/icons/IceCream.svelte +16 -9
- package/scaffold/svelte/icons/Moon.svelte +16 -9
- package/scaffold/svelte/icons/Owl.svelte +16 -9
- package/scaffold/svelte/icons/Palette.svelte +16 -9
- package/scaffold/svelte/icons/Rainbow.svelte +16 -9
- package/scaffold/svelte/icons/Search.svelte +16 -9
- package/scaffold/svelte/icons/Snowflake.svelte +16 -9
- package/scaffold/svelte/icons/Sort.svelte +16 -9
- package/scaffold/svelte/icons/devicons/Astro.svelte +28 -14
- package/scaffold/svelte/icons/devicons/Bash.svelte +17 -16
- package/scaffold/svelte/icons/devicons/Css3.svelte +9 -8
- package/scaffold/svelte/icons/devicons/Git.svelte +9 -8
- package/scaffold/svelte/icons/devicons/Html5.svelte +9 -8
- package/scaffold/svelte/icons/devicons/Javascript.svelte +9 -8
- package/scaffold/svelte/icons/devicons/Nodejs.svelte +18 -14
- package/scaffold/svelte/icons/devicons/Plaintext.svelte +14 -16
- package/scaffold/svelte/icons/devicons/React.svelte +10 -9
- package/scaffold/svelte/icons/devicons/SvelteIcon.svelte +19 -0
- package/scaffold/svelte/icons/devicons/Vue.svelte +10 -9
- package/scaffold/svelte-app/README.md +4 -0
- package/scaffold/vanilla/README.md +47 -0
- package/scaffold/vanilla/icons/Brush.svg +0 -1
- package/scaffold/vanilla/icons/Cake.svg +0 -1
- package/scaffold/vanilla/icons/Check.svg +0 -1
- package/scaffold/vanilla/icons/Cherry.svg +0 -1
- package/scaffold/vanilla/icons/ChevronDown.svg +0 -1
- package/scaffold/vanilla/icons/Circle.svg +0 -1
- package/scaffold/vanilla/icons/Close.svg +0 -1
- package/scaffold/vanilla/icons/Cmd.svg +10 -0
- package/scaffold/vanilla/icons/Copy.svg +0 -1
- package/scaffold/vanilla/icons/Eye.svg +0 -1
- package/scaffold/vanilla/icons/Filter.svg +0 -1
- package/scaffold/vanilla/icons/Flame.svg +0 -1
- package/scaffold/vanilla/icons/Flower.svg +0 -1
- package/scaffold/vanilla/icons/Gear.svg +0 -1
- package/scaffold/vanilla/icons/Heart.svg +0 -1
- package/scaffold/vanilla/icons/IceCream.svg +0 -1
- package/scaffold/vanilla/icons/Leaf.svg +0 -1
- package/scaffold/vanilla/icons/Lemon.svg +0 -1
- package/scaffold/vanilla/icons/Moon.svg +0 -1
- package/scaffold/vanilla/icons/Owl.svg +0 -1
- package/scaffold/vanilla/icons/Palette.svg +0 -1
- package/scaffold/vanilla/icons/Rainbow.svg +0 -1
- package/scaffold/vanilla/icons/Search.svg +0 -1
- package/scaffold/vanilla/icons/Shield.svg +0 -1
- package/scaffold/vanilla/icons/Snowflake.svg +0 -1
- package/scaffold/vanilla/icons/Sort.svg +0 -1
- package/scaffold/vanilla/icons/Sun.svg +0 -1
- package/scaffold/vanilla/icons/Sunset.svg +0 -1
- package/scaffold/vanilla/icons/Zap.svg +0 -1
- package/scaffold/vanilla/icons/devicons/Astro.svg +0 -1
- package/scaffold/vanilla/icons/devicons/Bash.svg +0 -1
- package/scaffold/vanilla/icons/devicons/Css3.svg +0 -1
- package/scaffold/vanilla/icons/devicons/Git.svg +0 -1
- package/scaffold/vanilla/icons/devicons/Html5.svg +0 -1
- package/scaffold/vanilla/icons/devicons/Javascript.svg +0 -1
- package/scaffold/vanilla/icons/devicons/Nodejs.svg +0 -1
- package/scaffold/vanilla/icons/devicons/Plaintext.svg +0 -1
- package/scaffold/vanilla/icons/devicons/React.svg +0 -1
- package/scaffold/vanilla/icons/devicons/Svelte.svg +0 -1
- package/scaffold/vanilla/icons/devicons/Vue.svg +0 -1
- package/scaffold/vanilla/index.html +1 -277
- package/scaffold/vanilla/js/main.js +747 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Astro + Rizzo CSS
|
|
2
|
+
|
|
3
|
+
This project was scaffolded with `npx rizzo-css init` (Astro).
|
|
4
|
+
|
|
5
|
+
## First-time setup
|
|
6
|
+
|
|
7
|
+
**Install dependencies before running any Astro command:**
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm install
|
|
11
|
+
# or: npm install
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Then start the dev server:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm dev
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The theme selected during `rizzo-css init` is set in `src/layouts/Layout.astro` (`data-theme` on `<html>`) and is used on first load when you have no saved preference in the browser.
|
|
21
|
+
|
|
22
|
+
## Commands
|
|
23
|
+
|
|
24
|
+
- `pnpm dev` — Start dev server
|
|
25
|
+
- `pnpm build` — Build for production
|
|
26
|
+
- `pnpm preview` — Preview production build
|
|
27
|
+
|
|
28
|
+
## Other scaffolds
|
|
29
|
+
|
|
30
|
+
From the same **rizzo-css** package: **Vanilla** (`scaffold/vanilla/`) — single HTML file with Settings and toast; **Svelte** (`scaffold/svelte-app/`) — SvelteKit app. Use `npx rizzo-css init` and pick a different framework to create one of them.
|
|
31
|
+
|
|
32
|
+
Docs: [rizzo-css.vercel.app](https://rizzo-css.vercel.app)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"{{PROJECT_NAME}}","type":"module","version":"0.0.1","scripts":{"dev":"astro dev","build":"astro build","preview":"astro preview"},"devDependencies":{"astro":"^5.
|
|
1
|
+
{"name":"{{PROJECT_NAME}}","type":"module","version":"0.0.1","scripts":{"dev":"astro dev","build":"astro build","preview":"astro preview"},"devDependencies":{"astro":"^5.17.1"}}
|
|
@@ -3,10 +3,13 @@ interface Props {
|
|
|
3
3
|
title?: string;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
+
/* Placeholders replaced by rizzo-css CLI when scaffolding */
|
|
7
|
+
const DATA_THEME = '{{DATA_THEME}}';
|
|
8
|
+
const THEME_LIST_COMMENT = '{{THEME_LIST_COMMENT}}';
|
|
6
9
|
const { title = '{{TITLE}}' } = Astro.props;
|
|
7
10
|
---
|
|
8
11
|
<!doctype html>
|
|
9
|
-
<html lang="en" data-theme=
|
|
12
|
+
<html lang="en" data-theme={DATA_THEME}>{THEME_LIST_COMMENT}
|
|
10
13
|
<head>
|
|
11
14
|
<meta charset="UTF-8" />
|
|
12
15
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Layout from '../layouts/Layout.astro';
|
|
3
|
+
/* Placeholder replaced by rizzo-css CLI when scaffolding */
|
|
4
|
+
const TITLE = '{{TITLE}}';
|
|
3
5
|
---
|
|
4
|
-
<Layout title=
|
|
6
|
+
<Layout title={TITLE}>
|
|
5
7
|
<a href="#main-content" class="skip-link">Skip to main content</a>
|
|
6
8
|
<header class="container flex flex-wrap items-center justify-between gap-4" style="padding-top: var(--spacing-4); padding-bottom: var(--spacing-4); border-bottom: 1px solid var(--border);">
|
|
7
|
-
<a href="/" class="font-semibold" style="font-size: var(--font-size-lg); color: var(--text); text-decoration: none;">{
|
|
9
|
+
<a href="/" class="font-semibold" style="font-size: var(--font-size-lg); color: var(--text); text-decoration: none;">{TITLE}</a>
|
|
8
10
|
<a href="https://rizzo-css.vercel.app/docs/getting-started" class="btn btn-outline" target="_blank" rel="noopener noreferrer">Docs</a>
|
|
9
11
|
</header>
|
|
10
12
|
<main id="main-content" class="flex flex-col items-center justify-center text-center min-h-screen" style="padding: var(--spacing-12) var(--spacing-4); min-height: calc(100vh - 4rem);">
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
let expanded = $state<Set<string>>(getDefaultExpanded());
|
|
33
33
|
|
|
34
|
-
const classes = ['accordion', className].filter(Boolean).join(' ').trim();
|
|
34
|
+
const classes = $derived(['accordion', className].filter(Boolean).join(' ').trim());
|
|
35
35
|
|
|
36
36
|
function toggle(itemId: string) {
|
|
37
37
|
expanded = new Set(
|
|
@@ -101,7 +101,6 @@
|
|
|
101
101
|
<span class="accordion__title">{item.title}</span>
|
|
102
102
|
<span class="accordion__icon" aria-hidden="true">
|
|
103
103
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
104
|
-
<title>Expand or collapse section</title>
|
|
105
104
|
<path d="m6 9 6 6 6-6" />
|
|
106
105
|
</svg>
|
|
107
106
|
</span>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { onMount } from 'svelte';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
6
|
variant?: 'success' | 'error' | 'warning' | 'info';
|
|
@@ -7,6 +8,8 @@
|
|
|
7
8
|
autoDismiss?: number;
|
|
8
9
|
class?: string;
|
|
9
10
|
id?: string;
|
|
11
|
+
onDismiss?: () => void;
|
|
12
|
+
children?: Snippet;
|
|
10
13
|
}
|
|
11
14
|
let {
|
|
12
15
|
variant = 'info',
|
|
@@ -14,11 +17,13 @@
|
|
|
14
17
|
autoDismiss = 0,
|
|
15
18
|
class: className = '',
|
|
16
19
|
id,
|
|
20
|
+
onDismiss,
|
|
21
|
+
children,
|
|
17
22
|
}: Props = $props();
|
|
18
23
|
|
|
19
24
|
let visible = $state(true);
|
|
20
25
|
const alertId = $derived(id ?? `alert-${Math.random().toString(36).slice(2, 11)}`);
|
|
21
|
-
const classes = ['alert', `alert--${variant}`, className].filter(Boolean).join(' ').trim();
|
|
26
|
+
const classes = $derived(['alert', `alert--${variant}`, className].filter(Boolean).join(' ').trim());
|
|
22
27
|
|
|
23
28
|
const ariaLabels: Record<string, string> = {
|
|
24
29
|
success: 'Success message',
|
|
@@ -32,6 +37,7 @@
|
|
|
32
37
|
function dismiss() {
|
|
33
38
|
visible = false;
|
|
34
39
|
if (autoDismissTimeout) clearTimeout(autoDismissTimeout);
|
|
40
|
+
onDismiss?.();
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
onMount(() => {
|
|
@@ -54,7 +60,7 @@
|
|
|
54
60
|
aria-label={ariaLabels[variant]}
|
|
55
61
|
>
|
|
56
62
|
<div class="alert__content">
|
|
57
|
-
|
|
63
|
+
{@render children?.()}
|
|
58
64
|
</div>
|
|
59
65
|
{#if dismissible}
|
|
60
66
|
<button
|
|
@@ -71,7 +77,6 @@
|
|
|
71
77
|
}}
|
|
72
78
|
>
|
|
73
79
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
|
74
|
-
<title>Dismiss</title>
|
|
75
80
|
<path d="M18 6L6 18M6 6l12 12" />
|
|
76
81
|
</svg>
|
|
77
82
|
</button>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
}: Props = $props();
|
|
27
27
|
|
|
28
28
|
const displayInitials = $derived(name ? getInitials(name) : initialsProp);
|
|
29
|
-
const classes = ['avatar', `avatar--${size}`, `avatar--${shape}`, className].filter(Boolean).join(' ').trim();
|
|
29
|
+
const classes = $derived(['avatar', `avatar--${size}`, `avatar--${shape}`, className].filter(Boolean).join(' ').trim());
|
|
30
30
|
const ariaLabel = $derived(alt || name || (displayInitials ? `Avatar: ${displayInitials}` : 'Avatar'));
|
|
31
31
|
</script>
|
|
32
32
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
2
4
|
type Variant = 'primary' | 'success' | 'warning' | 'error' | 'info';
|
|
3
5
|
type Size = 'sm' | 'md' | 'lg';
|
|
4
6
|
interface Props {
|
|
@@ -6,26 +8,24 @@
|
|
|
6
8
|
size?: Size;
|
|
7
9
|
pill?: boolean;
|
|
8
10
|
class?: string;
|
|
11
|
+
children?: Snippet;
|
|
9
12
|
}
|
|
10
13
|
let {
|
|
11
14
|
variant = 'primary',
|
|
12
15
|
size = 'md',
|
|
13
16
|
pill = false,
|
|
14
17
|
class: className = '',
|
|
18
|
+
children,
|
|
15
19
|
}: Props = $props();
|
|
16
20
|
|
|
17
|
-
const classes =
|
|
18
|
-
'badge',
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
]
|
|
24
|
-
.filter(Boolean)
|
|
25
|
-
.join(' ')
|
|
26
|
-
.trim();
|
|
21
|
+
const classes = $derived(
|
|
22
|
+
['badge', `badge--${variant}`, `badge--${size}`, pill ? 'badge--pill' : '', className]
|
|
23
|
+
.filter(Boolean)
|
|
24
|
+
.join(' ')
|
|
25
|
+
.trim()
|
|
26
|
+
);
|
|
27
27
|
</script>
|
|
28
28
|
|
|
29
29
|
<span class={classes}>
|
|
30
|
-
|
|
30
|
+
{@render children?.()}
|
|
31
31
|
</span>
|
|
@@ -11,11 +11,14 @@
|
|
|
11
11
|
}
|
|
12
12
|
let { items, separator = 'chevron', class: className = '' }: Props = $props();
|
|
13
13
|
|
|
14
|
-
const separatorVariant =
|
|
15
|
-
separator === 'slash' ? 'breadcrumb--slash' : separator === 'arrow' ? 'breadcrumb--arrow' : 'breadcrumb--chevron'
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
const
|
|
14
|
+
const separatorVariant = $derived(
|
|
15
|
+
separator === 'slash' ? 'breadcrumb--slash' : separator === 'arrow' ? 'breadcrumb--arrow' : 'breadcrumb--chevron'
|
|
16
|
+
);
|
|
17
|
+
const classes = $derived(['breadcrumb', separatorVariant, className].filter(Boolean).join(' ').trim());
|
|
18
|
+
const separatorChar = $derived(
|
|
19
|
+
separator === 'slash' ? '/' : separator === 'arrow' ? '›' : typeof separator === 'string' ? separator : '›'
|
|
20
|
+
);
|
|
21
|
+
const useIcon = $derived(separator === 'chevron');
|
|
19
22
|
</script>
|
|
20
23
|
|
|
21
24
|
<nav class={classes} aria-label="Breadcrumb">
|
|
@@ -33,7 +36,6 @@
|
|
|
33
36
|
<span class="breadcrumb__separator" aria-hidden="true">
|
|
34
37
|
{#if useIcon}
|
|
35
38
|
<svg class="breadcrumb__separator-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
|
36
|
-
<title>Separator</title>
|
|
37
39
|
<path d="M6 9l6 6 6-6" />
|
|
38
40
|
</svg>
|
|
39
41
|
{:else}
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
2
4
|
type Variant = 'default' | 'primary' | 'success' | 'warning' | 'error' | 'info' | 'outline';
|
|
3
5
|
interface Props {
|
|
4
6
|
variant?: Variant;
|
|
5
7
|
disabled?: boolean;
|
|
6
8
|
type?: 'button' | 'submit' | 'reset';
|
|
7
9
|
class?: string;
|
|
10
|
+
children?: Snippet;
|
|
8
11
|
}
|
|
9
12
|
let {
|
|
10
13
|
variant = 'default',
|
|
11
14
|
disabled = false,
|
|
12
15
|
type = 'button',
|
|
13
16
|
class: className = '',
|
|
17
|
+
children,
|
|
14
18
|
...rest
|
|
15
19
|
}: Props = $props();
|
|
16
20
|
|
|
17
|
-
const variantClass = variant === 'default' ? '' : `btn-${variant}
|
|
18
|
-
const classes = ['btn', variantClass, className].filter(Boolean).join(' ');
|
|
21
|
+
const variantClass = $derived(variant === 'default' ? '' : `btn-${variant}`);
|
|
22
|
+
const classes = $derived(['btn', variantClass, className].filter(Boolean).join(' '));
|
|
19
23
|
</script>
|
|
20
24
|
|
|
21
25
|
<button {type} {disabled} class={classes} {...rest}>
|
|
22
|
-
|
|
26
|
+
{@render children?.()}
|
|
23
27
|
</button>
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
2
4
|
type Variant = 'default' | 'elevated' | 'outlined' | 'filled';
|
|
3
5
|
interface Props {
|
|
4
6
|
variant?: Variant;
|
|
5
7
|
class?: string;
|
|
8
|
+
children?: Snippet;
|
|
6
9
|
}
|
|
7
|
-
let { variant = 'default', class: className = '' }: Props = $props();
|
|
8
|
-
const variantClass = variant !== 'default' ? `card--${variant}` : '';
|
|
9
|
-
const classes = ['card', variantClass, className].filter(Boolean).join(' ').trim();
|
|
10
|
+
let { variant = 'default', class: className = '', children }: Props = $props();
|
|
11
|
+
const variantClass = $derived(variant !== 'default' ? `card--${variant}` : '');
|
|
12
|
+
const classes = $derived(['card', variantClass, className].filter(Boolean).join(' ').trim());
|
|
10
13
|
</script>
|
|
11
14
|
|
|
12
15
|
<div class={classes}>
|
|
13
|
-
|
|
16
|
+
{@render children?.()}
|
|
14
17
|
</div>
|
|
@@ -48,32 +48,32 @@
|
|
|
48
48
|
}
|
|
49
49
|
</script>
|
|
50
50
|
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
e.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
<
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
</
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
</
|
|
51
|
+
<span class="tooltip-host" data-tooltip={copied ? (format ? `Copied ${format}!` : 'Copied!') : (label ?? 'Copy to clipboard')}>
|
|
52
|
+
<button
|
|
53
|
+
type="button"
|
|
54
|
+
class={classes}
|
|
55
|
+
aria-label={copied ? (format ? `Copied ${format}!` : 'Copied!') : (label ?? `Copy ${value} to clipboard`)}
|
|
56
|
+
id={buttonId}
|
|
57
|
+
onclick={copy}
|
|
58
|
+
onkeydown={(e) => {
|
|
59
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
60
|
+
e.preventDefault();
|
|
61
|
+
copy();
|
|
62
|
+
}
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
<span class="copy-to-clipboard__text">{value}</span>
|
|
66
|
+
<span class="copy-to-clipboard__icon copy-to-clipboard__icon--copy" class:copy-to-clipboard__icon--hidden={copied} aria-hidden="true">
|
|
67
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
|
68
|
+
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
|
|
69
|
+
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
|
|
70
|
+
</svg>
|
|
71
|
+
</span>
|
|
72
|
+
<span class="copy-to-clipboard__icon copy-to-clipboard__icon--check" class:copy-to-clipboard__icon--hidden={!copied} aria-hidden="true">
|
|
73
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
|
74
|
+
<polyline points="20 6 9 17 4 12" />
|
|
75
|
+
</svg>
|
|
76
|
+
</span>
|
|
77
|
+
<span class="copy-to-clipboard__feedback" aria-live="polite">{feedbackText}</span>
|
|
78
|
+
</button>
|
|
79
|
+
</span>
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
class?: string;
|
|
6
6
|
}
|
|
7
7
|
let { orientation = 'horizontal', label, class: className = '' }: Props = $props();
|
|
8
|
-
const orientationClass = `divider--${orientation}
|
|
9
|
-
const hasLabel = typeof label === 'string' && label.trim().length > 0;
|
|
10
|
-
const labelClass = hasLabel ? 'divider--labeled' : '';
|
|
11
|
-
const classes = ['divider', orientationClass, labelClass, className].filter(Boolean).join(' ').trim();
|
|
12
|
-
const labelText = label?.trim() ?? '';
|
|
8
|
+
const orientationClass = $derived(`divider--${orientation}`);
|
|
9
|
+
const hasLabel = $derived(typeof label === 'string' && label.trim().length > 0);
|
|
10
|
+
const labelClass = $derived(hasLabel ? 'divider--labeled' : '');
|
|
11
|
+
const classes = $derived(['divider', orientationClass, labelClass, className].filter(Boolean).join(' ').trim());
|
|
12
|
+
const labelText = $derived(label?.trim() ?? '');
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
15
|
<div
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
aria-label={labelText || undefined}
|
|
20
20
|
>
|
|
21
21
|
{#if hasLabel && orientation === 'horizontal'}
|
|
22
|
-
<span class="divider__line" aria-hidden="true"
|
|
22
|
+
<span class="divider__line" aria-hidden="true"></span>
|
|
23
23
|
<span class="divider__label">{labelText}</span>
|
|
24
|
-
<span class="divider__line" aria-hidden="true"
|
|
24
|
+
<span class="divider__line" aria-hidden="true"></span>
|
|
25
25
|
{:else}
|
|
26
|
-
<span class="divider__line" aria-hidden="true"
|
|
26
|
+
<span class="divider__line" aria-hidden="true"></span>
|
|
27
27
|
{/if}
|
|
28
28
|
</div>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { onMount } from 'svelte';
|
|
3
|
+
import ChevronDown from './icons/ChevronDown.svelte';
|
|
3
4
|
|
|
4
5
|
export interface MenuItem {
|
|
5
6
|
label: string;
|
|
@@ -119,12 +120,7 @@
|
|
|
119
120
|
}}
|
|
120
121
|
>
|
|
121
122
|
<span class="dropdown__trigger-text">{trigger}</span>
|
|
122
|
-
<
|
|
123
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" role="img" aria-labelledby="{dropdownId}-trigger-icon-title">
|
|
124
|
-
<title id="{dropdownId}-trigger-icon-title">Expand menu</title>
|
|
125
|
-
<path d="m6 9 6 6 6-6" />
|
|
126
|
-
</svg>
|
|
127
|
-
</span>
|
|
123
|
+
<ChevronDown class="dropdown__icon" width={16} height={16} />
|
|
128
124
|
</button>
|
|
129
125
|
|
|
130
126
|
<div
|
|
@@ -144,10 +140,11 @@
|
|
|
144
140
|
{:else}
|
|
145
141
|
{@const hasSubmenu = item.submenu && item.submenu.length > 0}
|
|
146
142
|
{@const isSubmenuOpen = openSubmenuIndex === index}
|
|
147
|
-
<div class="dropdown__item-wrapper dropdown__item-wrapper--has-submenu={hasSubmenu}
|
|
143
|
+
<div class="dropdown__item-wrapper" class:dropdown__item-wrapper--has-submenu={hasSubmenu}>
|
|
148
144
|
{#if item.href && !hasSubmenu}
|
|
149
145
|
<a
|
|
150
|
-
class="dropdown__item
|
|
146
|
+
class="dropdown__item"
|
|
147
|
+
class:dropdown__item--disabled={item.disabled}
|
|
151
148
|
role="menuitem"
|
|
152
149
|
href={item.href}
|
|
153
150
|
aria-label={item.label}
|
|
@@ -162,7 +159,9 @@
|
|
|
162
159
|
</a>
|
|
163
160
|
{:else}
|
|
164
161
|
<div
|
|
165
|
-
class="dropdown__item
|
|
162
|
+
class="dropdown__item"
|
|
163
|
+
class:dropdown__item--disabled={item.disabled}
|
|
164
|
+
class:dropdown__item--has-submenu={hasSubmenu}
|
|
166
165
|
role="menuitem"
|
|
167
166
|
aria-disabled={item.disabled ? 'true' : undefined}
|
|
168
167
|
aria-expanded={hasSubmenu ? isSubmenuOpen : undefined}
|
|
@@ -190,18 +189,14 @@
|
|
|
190
189
|
>
|
|
191
190
|
<span>{item.label}</span>
|
|
192
191
|
{#if hasSubmenu}
|
|
193
|
-
<
|
|
194
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" role="img" aria-labelledby="{dropdownId}-submenu-arrow-{index}-title">
|
|
195
|
-
<title id="{dropdownId}-submenu-arrow-{index}-title">Expand submenu</title>
|
|
196
|
-
<path d="m6 9 6 6 6-6" />
|
|
197
|
-
</svg>
|
|
198
|
-
</span>
|
|
192
|
+
<ChevronDown class="dropdown__item-arrow" width={12} height={12} />
|
|
199
193
|
{/if}
|
|
200
194
|
</div>
|
|
201
195
|
{/if}
|
|
202
196
|
{#if hasSubmenu && item.submenu}
|
|
203
197
|
<div
|
|
204
|
-
class="dropdown__submenu
|
|
198
|
+
class="dropdown__submenu"
|
|
199
|
+
class:dropdown__submenu--open={isSubmenuOpen}
|
|
205
200
|
role="menu"
|
|
206
201
|
aria-label="{item.label} submenu"
|
|
207
202
|
aria-hidden={!isSubmenuOpen}
|
|
@@ -211,7 +206,8 @@
|
|
|
211
206
|
<div class="dropdown__separator" role="separator"></div>
|
|
212
207
|
{:else if subItem.href}
|
|
213
208
|
<a
|
|
214
|
-
class="dropdown__item dropdown__submenu-item
|
|
209
|
+
class="dropdown__item dropdown__submenu-item"
|
|
210
|
+
class:dropdown__item--disabled={subItem.disabled}
|
|
215
211
|
role="menuitem"
|
|
216
212
|
href={subItem.href}
|
|
217
213
|
aria-label={subItem.label}
|
|
@@ -225,7 +221,8 @@
|
|
|
225
221
|
</a>
|
|
226
222
|
{:else}
|
|
227
223
|
<div
|
|
228
|
-
class="dropdown__item dropdown__submenu-item
|
|
224
|
+
class="dropdown__item dropdown__submenu-item"
|
|
225
|
+
class:dropdown__item--disabled={subItem.disabled}
|
|
229
226
|
role="menuitem"
|
|
230
227
|
aria-disabled={subItem.disabled ? 'true' : undefined}
|
|
231
228
|
tabindex={open ? 0 : -1}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
2
4
|
interface Props {
|
|
3
5
|
label?: string;
|
|
4
6
|
labelFor?: string;
|
|
@@ -7,6 +9,7 @@
|
|
|
7
9
|
error?: string;
|
|
8
10
|
success?: string;
|
|
9
11
|
class?: string;
|
|
12
|
+
children?: Snippet;
|
|
10
13
|
}
|
|
11
14
|
let {
|
|
12
15
|
label,
|
|
@@ -16,6 +19,7 @@
|
|
|
16
19
|
error,
|
|
17
20
|
success,
|
|
18
21
|
class: className = '',
|
|
22
|
+
children,
|
|
19
23
|
}: Props = $props();
|
|
20
24
|
|
|
21
25
|
const errorId = $derived(labelFor && error ? `${labelFor}-error` : undefined);
|
|
@@ -24,11 +28,17 @@
|
|
|
24
28
|
|
|
25
29
|
<div class="form-group {className}">
|
|
26
30
|
{#if label}
|
|
27
|
-
|
|
28
|
-
{
|
|
29
|
-
|
|
31
|
+
{#if labelFor}
|
|
32
|
+
<label for={labelFor} class="form-group__label {required ? 'required' : ''}">
|
|
33
|
+
{label}
|
|
34
|
+
</label>
|
|
35
|
+
{:else}
|
|
36
|
+
<span class="form-group__label {required ? 'required' : ''}">
|
|
37
|
+
{label}
|
|
38
|
+
</span>
|
|
39
|
+
{/if}
|
|
30
40
|
{/if}
|
|
31
|
-
|
|
41
|
+
{@render children?.()}
|
|
32
42
|
{#if help}
|
|
33
43
|
<span id={helpId} class="form-group__help">{help}</span>
|
|
34
44
|
{/if}
|
|
@@ -34,11 +34,13 @@
|
|
|
34
34
|
ariaInvalid,
|
|
35
35
|
}: Props = $props();
|
|
36
36
|
|
|
37
|
-
const sizeClass = size !== 'md' ? `form-input--${size}` : '';
|
|
38
|
-
const errorClass = error ? 'form-input--error' : '';
|
|
39
|
-
const successClass = success ? 'form-input--success' : '';
|
|
40
|
-
const classes =
|
|
41
|
-
|
|
37
|
+
const sizeClass = $derived(size !== 'md' ? `form-input--${size}` : '');
|
|
38
|
+
const errorClass = $derived(error ? 'form-input--error' : '');
|
|
39
|
+
const successClass = $derived(success ? 'form-input--success' : '');
|
|
40
|
+
const classes = $derived(
|
|
41
|
+
['form-input', sizeClass, errorClass, successClass, className].filter(Boolean).join(' ').trim()
|
|
42
|
+
);
|
|
43
|
+
const invalid = $derived(error || ariaInvalid === true || ariaInvalid === 'true');
|
|
42
44
|
</script>
|
|
43
45
|
|
|
44
46
|
<input
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { tick } from 'svelte';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
6
|
id?: string;
|
|
@@ -9,6 +10,8 @@
|
|
|
9
10
|
closeOnOverlayClick?: boolean;
|
|
10
11
|
closeOnEscape?: boolean;
|
|
11
12
|
class?: string;
|
|
13
|
+
children?: Snippet;
|
|
14
|
+
footer?: Snippet;
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
let {
|
|
@@ -19,11 +22,13 @@
|
|
|
19
22
|
closeOnOverlayClick = true,
|
|
20
23
|
closeOnEscape = true,
|
|
21
24
|
class: className = '',
|
|
25
|
+
children,
|
|
26
|
+
footer,
|
|
22
27
|
}: Props = $props();
|
|
23
28
|
|
|
24
29
|
const modalId = $derived(id ?? `modal-${Math.random().toString(36).slice(2, 11)}`);
|
|
25
|
-
const sizeClass = size !== 'md' ? `modal--${size}` : '';
|
|
26
|
-
const classes = ['modal', sizeClass, className].filter(Boolean).join(' ').trim();
|
|
30
|
+
const sizeClass = $derived(size !== 'md' ? `modal--${size}` : '');
|
|
31
|
+
const classes = $derived(['modal', sizeClass, className].filter(Boolean).join(' ').trim());
|
|
27
32
|
|
|
28
33
|
let overlayEl: HTMLDivElement;
|
|
29
34
|
let modalEl: HTMLDivElement;
|
|
@@ -138,16 +143,15 @@
|
|
|
138
143
|
<h2 id="{modalId}-title" class="modal__title">{title}</h2>
|
|
139
144
|
<button type="button" class="modal__close" aria-label="Close modal" data-modal-close onclick={close}>
|
|
140
145
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
141
|
-
<title>Close</title>
|
|
142
146
|
<path d="M18 6L6 18" />
|
|
143
147
|
<path d="M6 6l12 12" />
|
|
144
148
|
</svg>
|
|
145
149
|
</button>
|
|
146
150
|
</div>
|
|
147
151
|
<div class="modal__body">
|
|
148
|
-
|
|
152
|
+
{@render children?.()}
|
|
149
153
|
</div>
|
|
150
154
|
<div class="modal__footer">
|
|
151
|
-
|
|
155
|
+
{@render footer?.()}
|
|
152
156
|
</div>
|
|
153
157
|
</div>
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
class: className = '',
|
|
39
39
|
}: Props = $props();
|
|
40
40
|
|
|
41
|
-
const classes = ['pagination', className].filter(Boolean).join(' ').trim();
|
|
41
|
+
const classes = $derived(['pagination', className].filter(Boolean).join(' ').trim());
|
|
42
42
|
const pageItems = $derived(getPageItems(totalPages, currentPage, maxVisible));
|
|
43
43
|
const hasPrev = $derived(currentPage > 1);
|
|
44
44
|
const hasNext = $derived(currentPage < totalPages);
|
|
@@ -24,16 +24,18 @@
|
|
|
24
24
|
const clampedValue = $derived(indeterminate ? 0 : Math.max(0, Math.min(value, safeMax)));
|
|
25
25
|
const percentage = $derived(indeterminate ? 0 : Math.round((clampedValue / safeMax) * 100));
|
|
26
26
|
|
|
27
|
-
const classes =
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
const classes = $derived(
|
|
28
|
+
[
|
|
29
|
+
'progress',
|
|
30
|
+
`progress--${variant}`,
|
|
31
|
+
`progress--${size}`,
|
|
32
|
+
indeterminate ? 'progress--indeterminate' : '',
|
|
33
|
+
className,
|
|
34
|
+
]
|
|
35
|
+
.filter(Boolean)
|
|
36
|
+
.join(' ')
|
|
37
|
+
.trim()
|
|
38
|
+
);
|
|
37
39
|
|
|
38
40
|
const barStyle = $derived(indeterminate ? {} : { width: `${percentage}%` });
|
|
39
41
|
</script>
|
|
@@ -48,7 +50,7 @@
|
|
|
48
50
|
aria-valuenow={indeterminate ? undefined : clampedValue}
|
|
49
51
|
>
|
|
50
52
|
<div class="progress__track">
|
|
51
|
-
<div class="progress__bar" style={barStyle}
|
|
53
|
+
<div class="progress__bar" style={barStyle}></div>
|
|
52
54
|
</div>
|
|
53
55
|
{#if showLabel && !indeterminate}
|
|
54
56
|
<span class="progress__label" aria-hidden="true">{percentage}%</span>
|