@dryui/ui 0.5.2 → 1.0.0
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/dist/alert/{alert-root.svelte → alert.svelte} +78 -20
- package/dist/alert/alert.svelte.d.ts +15 -0
- package/dist/alert/index.d.ts +15 -14
- package/dist/alert/index.js +3 -12
- package/dist/breadcrumb/breadcrumb-link.svelte +1 -1
- package/dist/button/button.svelte +1 -1
- package/dist/card/card-root.svelte +2 -2
- package/dist/chromatic-shift/chromatic-shift.svelte +2 -2
- package/dist/code-block/code-block-button.svelte +1 -1
- package/dist/color-picker/color-picker-area.svelte +2 -2
- package/dist/color-picker/color-picker-channel-input.svelte +2 -2
- package/dist/color-picker/color-picker-input-alpha-slider.svelte +2 -2
- package/dist/color-picker/color-picker-input-hue-slider.svelte +2 -2
- package/dist/color-picker/color-picker-input.svelte +9 -9
- package/dist/color-picker/color-picker-swatch.svelte +2 -2
- package/dist/combobox/combobox-input.svelte +9 -9
- package/dist/command-palette/command-palette-item.svelte +1 -1
- package/dist/data-grid/data-grid-button-input-column.svelte +1 -1
- package/dist/diagram/diagram.svelte +222 -32
- package/dist/diagram/diagram.svelte.d.ts +1 -0
- package/dist/diagram/edge-routing.d.ts +63 -1
- package/dist/diagram/edge-routing.js +316 -26
- package/dist/diagram/layout.js +633 -62
- package/dist/diagram/types.d.ts +58 -0
- package/dist/drag-and-drop/drag-and-drop-handle.svelte +1 -1
- package/dist/drag-and-drop/drag-and-drop-item.svelte +1 -1
- package/dist/file-select/file-select-root.svelte +2 -2
- package/dist/file-upload/file-upload-dropzone.svelte +2 -2
- package/dist/gauge/gauge.svelte +1 -1
- package/dist/image-comparison/image-comparison.svelte +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/input/input.svelte +10 -11
- package/dist/label/label.svelte +1 -1
- package/dist/link/link.svelte +1 -1
- package/dist/list/list-item.svelte +2 -2
- package/dist/multi-select-combobox/multi-select-combobox-selection-item.svelte +9 -3
- package/dist/multi-select-combobox/multi-select-combobox-selection-remove-button.svelte +2 -0
- package/dist/navigation-menu/navigation-menu-link.svelte +1 -1
- package/dist/notification-center/notification-center-item.svelte +1 -1
- package/dist/number-input/number-input-button.svelte +3 -3
- package/dist/option-picker/context.svelte.d.ts +9 -0
- package/dist/option-picker/context.svelte.js +2 -0
- package/dist/option-picker/option-picker-item.svelte +31 -4
- package/dist/option-picker/option-picker-preview.svelte +2 -2
- package/dist/option-picker/option-picker-root.svelte +2 -2
- package/dist/phone-input/phone-input-select.svelte +2 -2
- package/dist/pin-input/pin-input-cell.svelte +1 -1
- package/dist/pin-input/pin-input-root.svelte +1 -1
- package/dist/progress/progress.svelte +1 -1
- package/dist/scroll-area/scroll-area.svelte +1 -1
- package/dist/shimmer/index.d.ts +8 -0
- package/dist/shimmer/index.js +1 -0
- package/dist/shimmer/shimmer.svelte +87 -0
- package/dist/shimmer/shimmer.svelte.d.ts +10 -0
- package/dist/sidebar/sidebar-item.svelte +1 -1
- package/dist/slider/slider-input.svelte +2 -2
- package/dist/splitter/splitter-handle.svelte +1 -1
- package/dist/table-of-contents/table-of-contents-item.svelte +1 -1
- package/dist/table-of-contents/table-of-contents-list.svelte +1 -1
- package/dist/tags-input/tags-input-root.svelte +1 -1
- package/dist/tags-input/tags-input-tag-delete-button.svelte +2 -0
- package/dist/tags-input/tags-input-tag.svelte +9 -3
- package/dist/textarea/textarea.svelte +11 -11
- package/dist/themes/default.css +31 -0
- package/dist/toast/toast-root.svelte +1 -1
- package/dist/tour/tour-root.css +3 -3
- package/dist/tree/tree-item-children.svelte +1 -1
- package/dist/tree/tree-item-label.svelte +1 -1
- package/dist/video-embed/video-embed-button.svelte +1 -1
- package/package.json +11 -750
- package/skills/dryui/SKILL.md +26 -21
- package/skills/dryui/rules/compound-components.md +3 -3
- package/skills/dryui/rules/theming.md +1 -1
- package/dist/alert/alert-button-close.svelte +0 -29
- package/dist/alert/alert-button-close.svelte.d.ts +0 -8
- package/dist/alert/alert-description.svelte +0 -28
- package/dist/alert/alert-description.svelte.d.ts +0 -8
- package/dist/alert/alert-icon.svelte +0 -26
- package/dist/alert/alert-icon.svelte.d.ts +0 -8
- package/dist/alert/alert-root.svelte.d.ts +0 -12
- package/dist/alert/alert-title.svelte +0 -29
- package/dist/alert/alert-title.svelte.d.ts +0 -8
- package/dist/alert/context.svelte.d.ts +0 -9
- package/dist/alert/context.svelte.js +0 -10
- package/dist/option-swatch-group/context.svelte.d.ts +0 -9
- package/dist/option-swatch-group/context.svelte.js +0 -2
- package/dist/option-swatch-group/index.d.ts +0 -29
- package/dist/option-swatch-group/index.js +0 -12
- package/dist/option-swatch-group/option-swatch-group-item-button.svelte +0 -214
- package/dist/option-swatch-group/option-swatch-group-item-button.svelte.d.ts +0 -12
- package/dist/option-swatch-group/option-swatch-group-label.svelte +0 -24
- package/dist/option-swatch-group/option-swatch-group-label.svelte.d.ts +0 -8
- package/dist/option-swatch-group/option-swatch-group-meta.svelte +0 -24
- package/dist/option-swatch-group/option-swatch-group-meta.svelte.d.ts +0 -8
- package/dist/option-swatch-group/option-swatch-group-root.svelte +0 -81
- package/dist/option-swatch-group/option-swatch-group-root.svelte.d.ts +0 -12
- package/dist/option-swatch-group/option-swatch-group-swatch.svelte +0 -52
- package/dist/option-swatch-group/option-swatch-group-swatch.svelte.d.ts +0 -10
package/skills/dryui/SKILL.md
CHANGED
|
@@ -33,9 +33,9 @@ Most DryUI components are compound — they require `<Card.Root>`, not `<Card>`.
|
|
|
33
33
|
<Card.Root>content</Card.Root>
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
Compound components
|
|
36
|
+
Compound components are tracked in the manifest at `packages/mcp/src/component-catalog.ts`. Verify with `info` before you assume a bare name works, then use `.Root` and wrap the parts inside it.
|
|
37
37
|
|
|
38
|
-
The test: every compound component in your markup uses `.Root`, and its parts are wrapped inside it. See `rules/compound-components.md` for the
|
|
38
|
+
The test: every compound component in your markup uses `.Root`, and its parts are wrapped inside it. See `rules/compound-components.md` for the parts reference.
|
|
39
39
|
|
|
40
40
|
## 3. Let the Theme Do Its Job
|
|
41
41
|
|
|
@@ -126,20 +126,23 @@ The test: search your markup for raw `<input`, `<select>`, `<dialog>`, `<button>
|
|
|
126
126
|
- Codex: public install today is `$skill-installer install https://github.com/rob-balfre/dryui/tree/main/packages/ui/skills/dryui` then `codex mcp add dryui -- npx -y @dryui/mcp`. If you're working inside the DryUI repo itself, install the repo-local plugin from `/plugins` via `.agents/plugins/marketplace.json`.
|
|
127
127
|
- Copilot/Cursor/Windsurf: `npx degit rob-balfre/dryui/packages/ui/skills/dryui .agents/skills/dryui` + add MCP config (see https://dryui.dev/tools)
|
|
128
128
|
|
|
129
|
-
**3.
|
|
129
|
+
**3. Install the CLI** so every subsequent command is short and fast:
|
|
130
130
|
|
|
131
|
-
```
|
|
132
|
-
|
|
131
|
+
```bash
|
|
132
|
+
bun install -g @dryui/cli # or: npm install -g @dryui/cli
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
**
|
|
135
|
+
**4. Bootstrap the project** — `init` detects your project state and applies whatever is missing:
|
|
136
136
|
|
|
137
|
+
```bash
|
|
138
|
+
dryui init # existing project
|
|
139
|
+
dryui init my-app # new project — scaffolds SvelteKit + DryUI in one step
|
|
140
|
+
cd my-app && bun run dev
|
|
137
141
|
```
|
|
138
|
-
npx -y @dryui/cli init my-app
|
|
139
|
-
cd my-app && npm run dev
|
|
140
|
-
```
|
|
141
142
|
|
|
142
|
-
This works for greenfield (empty directory), brownfield (existing non-SvelteKit project), and existing SvelteKit projects. Verify: `
|
|
143
|
+
This works for greenfield (empty directory), brownfield (existing non-SvelteKit project), and existing SvelteKit projects. Verify: `dryui detect` should show `project: ready`.
|
|
144
|
+
|
|
145
|
+
> **No global install?** `bunx @dryui/cli <cmd>` and `npx -y @dryui/cli <cmd>` work anywhere without installing — same commands, just slower (re-fetches on each call).
|
|
143
146
|
|
|
144
147
|
### Manual setup
|
|
145
148
|
|
|
@@ -185,21 +188,23 @@ Use these to look up APIs, discover components, plan setup, and validate code.
|
|
|
185
188
|
|
|
186
189
|
### CLI fallback
|
|
187
190
|
|
|
188
|
-
|
|
191
|
+
Install once with `bun install -g @dryui/cli` (or `npm install -g @dryui/cli`), then use the short form below. Every command outputs TOON (token-optimized, agent-friendly) by default. Pass `--text` for human-readable plain text, `--json` where supported, or `--full` to disable truncation.
|
|
189
192
|
|
|
190
193
|
```bash
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
194
|
+
dryui init [path] [--pm bun] # Bootstrap SvelteKit + DryUI project
|
|
195
|
+
dryui info <component> # Look up component API
|
|
196
|
+
dryui compose "date input" # Composition guidance
|
|
197
|
+
dryui detect [path] # Check project setup
|
|
198
|
+
dryui install [path] # Print install plan
|
|
199
|
+
dryui review <file.svelte> # Validate component
|
|
200
|
+
dryui diagnose <file.css> # Validate theme CSS
|
|
201
|
+
dryui doctor [path] # Audit workspace
|
|
202
|
+
dryui lint [path] # Deterministic findings
|
|
203
|
+
dryui list # List components
|
|
201
204
|
```
|
|
202
205
|
|
|
206
|
+
Without a global install, prefix any command with `bunx @dryui/cli …` or `npx -y @dryui/cli …` — same behaviour, just slower (re-fetches on each call).
|
|
207
|
+
|
|
203
208
|
Categories: action, input, form, layout, navigation, overlay, display, feedback, interaction, utility
|
|
204
209
|
|
|
205
210
|
## Rule Files
|
|
@@ -18,7 +18,7 @@ Every compound component uses `.Root` as the container. Never use the bare name.
|
|
|
18
18
|
|
|
19
19
|
## Parts Reference
|
|
20
20
|
|
|
21
|
-
Below are the parts for the most commonly used compound components. Always run `
|
|
21
|
+
Below are the parts for the most commonly used compound components. Always run `dryui info <name>` for the full, up-to-date parts list.
|
|
22
22
|
|
|
23
23
|
### Card
|
|
24
24
|
|
|
@@ -311,6 +311,6 @@ Parts: Root, Input, Content, Item, Empty
|
|
|
311
311
|
|
|
312
312
|
## Full Compound Component List
|
|
313
313
|
|
|
314
|
-
Run `
|
|
314
|
+
Run `dryui info <name>` for any component's complete parts list:
|
|
315
315
|
|
|
316
|
-
Accordion,
|
|
316
|
+
Accordion, AlertDialog, Breadcrumb, Card, Collapsible, ColorPicker, Combobox, CommandPalette, ContextMenu, DataGrid, DatePicker, Dialog, DragAndDrop, Drawer, DropdownMenu, EmptyState, Field, FileUpload, FloatButton, Pagination, Popover, RadioGroup, RichTextEditor, Select, Splitter, Stepper, Table, Tabs, TagsInput, Toast, ToggleGroup, Toolbar, Tooltip, Tour, Transfer
|
|
@@ -271,7 +271,7 @@ Ensure sufficient contrast between text and background.
|
|
|
271
271
|
Run the CLI diagnose command to catch theme issues:
|
|
272
272
|
|
|
273
273
|
```bash
|
|
274
|
-
|
|
274
|
+
dryui diagnose src/styles/global.css
|
|
275
275
|
```
|
|
276
276
|
|
|
277
277
|
Common diagnostic codes:
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
4
|
-
import CloseButtonBase from '../internal/close-button-base.svelte';
|
|
5
|
-
import { getAlertCtx } from './context.svelte.js';
|
|
6
|
-
|
|
7
|
-
interface Props extends HTMLButtonAttributes {
|
|
8
|
-
children?: Snippet;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
let { children, ...rest }: Props = $props();
|
|
12
|
-
|
|
13
|
-
const ctx = getAlertCtx();
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
<span class="alert-close-slot">
|
|
17
|
-
<CloseButtonBase aria-label="Dismiss alert" {...rest} onclick={() => ctx.dismiss()}>
|
|
18
|
-
{#if children}{@render children()}{/if}
|
|
19
|
-
</CloseButtonBase>
|
|
20
|
-
</span>
|
|
21
|
-
|
|
22
|
-
<style>
|
|
23
|
-
.alert-close-slot {
|
|
24
|
-
display: inline-grid;
|
|
25
|
-
grid-column: -2 / -1;
|
|
26
|
-
grid-row: 1 / 3;
|
|
27
|
-
align-self: start;
|
|
28
|
-
}
|
|
29
|
-
</style>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
-
interface Props extends HTMLButtonAttributes {
|
|
4
|
-
children?: Snippet;
|
|
5
|
-
}
|
|
6
|
-
declare const AlertButtonClose: import("svelte").Component<Props, {}, "">;
|
|
7
|
-
type AlertButtonClose = ReturnType<typeof AlertButtonClose>;
|
|
8
|
-
export default AlertButtonClose;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
-
import { markDirectChild } from './context.svelte.js';
|
|
5
|
-
|
|
6
|
-
interface Props extends HTMLAttributes<HTMLParagraphElement> {
|
|
7
|
-
children: Snippet;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
let { class: className, children, ...rest }: Props = $props();
|
|
11
|
-
</script>
|
|
12
|
-
|
|
13
|
-
<p data-alert-description {@attach markDirectChild} class={className} {...rest}>
|
|
14
|
-
{@render children()}
|
|
15
|
-
</p>
|
|
16
|
-
|
|
17
|
-
<style>
|
|
18
|
-
[data-alert-description][data-alert-direct-child] {
|
|
19
|
-
grid-column: 2;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
[data-alert-description] {
|
|
23
|
-
font-size: var(--dry-type-small-size);
|
|
24
|
-
line-height: var(--dry-type-small-leading);
|
|
25
|
-
color: var(--dry-color-text-weak);
|
|
26
|
-
margin: 0;
|
|
27
|
-
}
|
|
28
|
-
</style>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
interface Props extends HTMLAttributes<HTMLParagraphElement> {
|
|
4
|
-
children: Snippet;
|
|
5
|
-
}
|
|
6
|
-
declare const AlertDescription: import("svelte").Component<Props, {}, "">;
|
|
7
|
-
type AlertDescription = ReturnType<typeof AlertDescription>;
|
|
8
|
-
export default AlertDescription;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
-
|
|
5
|
-
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
6
|
-
children: Snippet;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let { class: className, children, ...rest }: Props = $props();
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<span aria-hidden="true" data-alert-icon class={className} {...rest}>
|
|
13
|
-
{@render children()}
|
|
14
|
-
</span>
|
|
15
|
-
|
|
16
|
-
<style>
|
|
17
|
-
[data-alert-icon] {
|
|
18
|
-
grid-column: 1;
|
|
19
|
-
grid-row: 1 / 3;
|
|
20
|
-
color: var(--dry-alert-icon-color);
|
|
21
|
-
display: grid;
|
|
22
|
-
align-items: center;
|
|
23
|
-
margin-top: var(--dry-space-0_5);
|
|
24
|
-
padding-inline-end: var(--dry-alert-gap, var(--dry-space-3));
|
|
25
|
-
}
|
|
26
|
-
</style>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
4
|
-
children: Snippet;
|
|
5
|
-
}
|
|
6
|
-
declare const AlertIcon: import("svelte").Component<Props, {}, "">;
|
|
7
|
-
type AlertIcon = ReturnType<typeof AlertIcon>;
|
|
8
|
-
export default AlertIcon;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import { type AlertVariant } from './context.svelte.js';
|
|
4
|
-
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
-
variant?: AlertVariant;
|
|
6
|
-
dismissible?: boolean;
|
|
7
|
-
onDismiss?: () => void;
|
|
8
|
-
children: Snippet;
|
|
9
|
-
}
|
|
10
|
-
declare const AlertRoot: import("svelte").Component<Props, {}, "">;
|
|
11
|
-
type AlertRoot = ReturnType<typeof AlertRoot>;
|
|
12
|
-
export default AlertRoot;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
-
import { markDirectChild } from './context.svelte.js';
|
|
5
|
-
|
|
6
|
-
interface Props extends HTMLAttributes<HTMLHeadingElement> {
|
|
7
|
-
children: Snippet;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
let { class: className, children, ...rest }: Props = $props();
|
|
11
|
-
</script>
|
|
12
|
-
|
|
13
|
-
<h5 data-alert-title {@attach markDirectChild} class={className} {...rest}>
|
|
14
|
-
{@render children()}
|
|
15
|
-
</h5>
|
|
16
|
-
|
|
17
|
-
<style>
|
|
18
|
-
[data-alert-title][data-alert-direct-child] {
|
|
19
|
-
grid-column: 2;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
[data-alert-title] {
|
|
23
|
-
font-size: var(--dry-type-heading-4-size);
|
|
24
|
-
font-weight: 600;
|
|
25
|
-
line-height: var(--dry-type-small-leading);
|
|
26
|
-
color: var(--dry-color-text-strong);
|
|
27
|
-
margin: 0;
|
|
28
|
-
}
|
|
29
|
-
</style>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
interface Props extends HTMLAttributes<HTMLHeadingElement> {
|
|
4
|
-
children: Snippet;
|
|
5
|
-
}
|
|
6
|
-
declare const AlertTitle: import("svelte").Component<Props, {}, "">;
|
|
7
|
-
type AlertTitle = ReturnType<typeof AlertTitle>;
|
|
8
|
-
export default AlertTitle;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export type AlertVariant = 'info' | 'success' | 'warning' | 'error';
|
|
2
|
-
interface AlertContext {
|
|
3
|
-
readonly variant: AlertVariant;
|
|
4
|
-
readonly isDismissed: boolean;
|
|
5
|
-
dismiss: () => void;
|
|
6
|
-
}
|
|
7
|
-
export declare const setAlertCtx: (ctx: AlertContext) => AlertContext, getAlertCtx: () => AlertContext;
|
|
8
|
-
export declare function markDirectChild(node: HTMLElement): () => void;
|
|
9
|
-
export {};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { createContext } from '@dryui/primitives';
|
|
2
|
-
export const [setAlertCtx, getAlertCtx] = createContext('alert');
|
|
3
|
-
export function markDirectChild(node) {
|
|
4
|
-
if (node.parentElement?.hasAttribute('data-alert')) {
|
|
5
|
-
node.setAttribute('data-alert-direct-child', '');
|
|
6
|
-
}
|
|
7
|
-
return () => {
|
|
8
|
-
node.removeAttribute('data-alert-direct-child');
|
|
9
|
-
};
|
|
10
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
interface SelectableTileGroupContext {
|
|
2
|
-
readonly value: string;
|
|
3
|
-
readonly disabled: boolean;
|
|
4
|
-
readonly orientation: 'horizontal' | 'vertical';
|
|
5
|
-
select: (value: string) => void;
|
|
6
|
-
isSelected: (value: string) => boolean;
|
|
7
|
-
}
|
|
8
|
-
export declare const setSelectableTileGroupCtx: (ctx: SelectableTileGroupContext) => SelectableTileGroupContext, getSelectableTileGroupCtx: () => SelectableTileGroupContext;
|
|
9
|
-
export {};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import type { SelectableTileGroupItemProps as PrimitiveOptionSwatchGroupItemProps, SelectableTileGroupRootProps as PrimitiveOptionSwatchGroupRootProps } from '@dryui/primitives';
|
|
4
|
-
export type { SelectableTileGroupLabelProps as OptionSwatchGroupLabelProps } from '@dryui/primitives';
|
|
5
|
-
export type { SelectableTileGroupMetaProps as OptionSwatchGroupMetaProps } from '@dryui/primitives';
|
|
6
|
-
export interface OptionSwatchGroupRootProps extends PrimitiveOptionSwatchGroupRootProps {
|
|
7
|
-
columns?: 1 | 2 | 3 | 4;
|
|
8
|
-
}
|
|
9
|
-
export interface OptionSwatchGroupItemProps extends PrimitiveOptionSwatchGroupItemProps {
|
|
10
|
-
size?: 'default' | 'compact';
|
|
11
|
-
unavailable?: boolean;
|
|
12
|
-
}
|
|
13
|
-
export interface OptionSwatchGroupSwatchProps extends HTMLAttributes<HTMLSpanElement> {
|
|
14
|
-
color?: string;
|
|
15
|
-
shape?: 'circle' | 'rounded';
|
|
16
|
-
children?: Snippet;
|
|
17
|
-
}
|
|
18
|
-
import OptionSwatchGroupRoot from './option-swatch-group-root.svelte';
|
|
19
|
-
import OptionSwatchGroupItem from './option-swatch-group-item-button.svelte';
|
|
20
|
-
import OptionSwatchGroupSwatch from './option-swatch-group-swatch.svelte';
|
|
21
|
-
import OptionSwatchGroupLabel from './option-swatch-group-label.svelte';
|
|
22
|
-
import OptionSwatchGroupMeta from './option-swatch-group-meta.svelte';
|
|
23
|
-
export declare const OptionSwatchGroup: {
|
|
24
|
-
Root: typeof OptionSwatchGroupRoot;
|
|
25
|
-
Item: typeof OptionSwatchGroupItem;
|
|
26
|
-
Swatch: typeof OptionSwatchGroupSwatch;
|
|
27
|
-
Label: typeof OptionSwatchGroupLabel;
|
|
28
|
-
Meta: typeof OptionSwatchGroupMeta;
|
|
29
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import OptionSwatchGroupRoot from './option-swatch-group-root.svelte';
|
|
2
|
-
import OptionSwatchGroupItem from './option-swatch-group-item-button.svelte';
|
|
3
|
-
import OptionSwatchGroupSwatch from './option-swatch-group-swatch.svelte';
|
|
4
|
-
import OptionSwatchGroupLabel from './option-swatch-group-label.svelte';
|
|
5
|
-
import OptionSwatchGroupMeta from './option-swatch-group-meta.svelte';
|
|
6
|
-
export const OptionSwatchGroup = {
|
|
7
|
-
Root: OptionSwatchGroupRoot,
|
|
8
|
-
Item: OptionSwatchGroupItem,
|
|
9
|
-
Swatch: OptionSwatchGroupSwatch,
|
|
10
|
-
Label: OptionSwatchGroupLabel,
|
|
11
|
-
Meta: OptionSwatchGroupMeta
|
|
12
|
-
};
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
4
|
-
import Button from '../button/button.svelte';
|
|
5
|
-
import { getSelectableTileGroupCtx } from './context.svelte.js';
|
|
6
|
-
|
|
7
|
-
interface Props extends Omit<HTMLButtonAttributes, 'value'> {
|
|
8
|
-
value: string;
|
|
9
|
-
disabled?: boolean;
|
|
10
|
-
unavailable?: boolean;
|
|
11
|
-
size?: 'default' | 'compact';
|
|
12
|
-
children: Snippet;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let {
|
|
16
|
-
value,
|
|
17
|
-
disabled = false,
|
|
18
|
-
unavailable = false,
|
|
19
|
-
size = 'default',
|
|
20
|
-
children,
|
|
21
|
-
...rest
|
|
22
|
-
}: Props = $props();
|
|
23
|
-
|
|
24
|
-
const ctx = getSelectableTileGroupCtx();
|
|
25
|
-
const isDisabled = $derived(disabled || unavailable || ctx.disabled);
|
|
26
|
-
const isSelected = $derived(ctx.isSelected(value));
|
|
27
|
-
|
|
28
|
-
function moveFocus(current: HTMLButtonElement, direction: -1 | 1) {
|
|
29
|
-
const group = current.closest('[role="radiogroup"]');
|
|
30
|
-
if (!(group instanceof HTMLElement)) return;
|
|
31
|
-
|
|
32
|
-
const items = Array.from(
|
|
33
|
-
group.querySelectorAll<HTMLButtonElement>('[role="radio"]:not([disabled])')
|
|
34
|
-
);
|
|
35
|
-
const index = items.indexOf(current);
|
|
36
|
-
if (index === -1) return;
|
|
37
|
-
|
|
38
|
-
const target = items[(index + direction + items.length) % items.length];
|
|
39
|
-
target?.focus();
|
|
40
|
-
const nextValue = target?.dataset.value;
|
|
41
|
-
if (nextValue) ctx.select(nextValue);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function handleKeydown(event: KeyboardEvent) {
|
|
45
|
-
if (isDisabled || !(event.currentTarget instanceof HTMLButtonElement)) return;
|
|
46
|
-
|
|
47
|
-
const isHorizontal = ctx.orientation === 'horizontal';
|
|
48
|
-
if (
|
|
49
|
-
(isHorizontal && event.key === 'ArrowRight') ||
|
|
50
|
-
(!isHorizontal && event.key === 'ArrowDown')
|
|
51
|
-
) {
|
|
52
|
-
event.preventDefault();
|
|
53
|
-
moveFocus(event.currentTarget, 1);
|
|
54
|
-
}
|
|
55
|
-
if ((isHorizontal && event.key === 'ArrowLeft') || (!isHorizontal && event.key === 'ArrowUp')) {
|
|
56
|
-
event.preventDefault();
|
|
57
|
-
moveFocus(event.currentTarget, -1);
|
|
58
|
-
}
|
|
59
|
-
if (event.key === ' ' || event.key === 'Enter') {
|
|
60
|
-
event.preventDefault();
|
|
61
|
-
ctx.select(value);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
</script>
|
|
65
|
-
|
|
66
|
-
<span
|
|
67
|
-
class="root"
|
|
68
|
-
data-size={size !== 'default' ? size : undefined}
|
|
69
|
-
data-state={isSelected ? 'checked' : 'unchecked'}
|
|
70
|
-
data-selected={isSelected ? '' : undefined}
|
|
71
|
-
data-disabled={isDisabled || undefined}
|
|
72
|
-
data-unavailable={unavailable || undefined}
|
|
73
|
-
>
|
|
74
|
-
<Button
|
|
75
|
-
variant="bare"
|
|
76
|
-
type="button"
|
|
77
|
-
role="radio"
|
|
78
|
-
aria-checked={isSelected}
|
|
79
|
-
disabled={isDisabled}
|
|
80
|
-
data-option-swatch-group-item
|
|
81
|
-
data-state={isSelected ? 'checked' : 'unchecked'}
|
|
82
|
-
data-selected={isSelected ? '' : undefined}
|
|
83
|
-
data-unavailable={unavailable || undefined}
|
|
84
|
-
data-value={value}
|
|
85
|
-
tabindex={isSelected ? 0 : -1}
|
|
86
|
-
{...rest}
|
|
87
|
-
onclick={() => {
|
|
88
|
-
if (!isDisabled) ctx.select(value);
|
|
89
|
-
}}
|
|
90
|
-
onkeydown={handleKeydown}
|
|
91
|
-
>
|
|
92
|
-
<span class="content">
|
|
93
|
-
{@render children()}
|
|
94
|
-
</span>
|
|
95
|
-
</Button>
|
|
96
|
-
</span>
|
|
97
|
-
|
|
98
|
-
<style>
|
|
99
|
-
.root {
|
|
100
|
-
--_swatch-item-selected-bg: var(
|
|
101
|
-
--dry-option-swatch-group-selected-bg,
|
|
102
|
-
color-mix(in srgb, var(--dry-color-fill-selected) 12%, var(--dry-color-bg-raised) 88%)
|
|
103
|
-
);
|
|
104
|
-
--_swatch-item-selected-bg-hover: var(
|
|
105
|
-
--dry-option-swatch-group-selected-bg-hover,
|
|
106
|
-
color-mix(in srgb, var(--dry-color-fill-selected) 16%, var(--dry-color-bg-raised) 84%)
|
|
107
|
-
);
|
|
108
|
-
--_swatch-item-selected-border: var(
|
|
109
|
-
--dry-option-swatch-group-selected-border,
|
|
110
|
-
var(--dry-color-stroke-selected)
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
display: grid;
|
|
114
|
-
background: var(--dry-option-swatch-group-bg, var(--dry-color-bg-base));
|
|
115
|
-
border: 1px solid var(--dry-option-swatch-group-border, var(--dry-color-stroke-weak));
|
|
116
|
-
border-radius: var(--dry-option-swatch-group-radius, var(--dry-radius-lg));
|
|
117
|
-
box-shadow: var(--dry-option-swatch-group-shadow, none);
|
|
118
|
-
transition:
|
|
119
|
-
background var(--dry-duration-fast, 100ms) ease,
|
|
120
|
-
border-color var(--dry-duration-fast, 100ms) ease,
|
|
121
|
-
box-shadow var(--dry-duration-fast, 100ms) ease,
|
|
122
|
-
transform var(--dry-duration-fast, 100ms) ease;
|
|
123
|
-
|
|
124
|
-
--dry-btn-bg: transparent;
|
|
125
|
-
--dry-btn-border: transparent;
|
|
126
|
-
--dry-btn-color: var(--dry-option-swatch-group-color, var(--dry-color-text-strong));
|
|
127
|
-
--dry-btn-padding-x: 0;
|
|
128
|
-
--dry-btn-padding-y: 0;
|
|
129
|
-
--dry-btn-radius: var(--dry-option-swatch-group-radius, var(--dry-radius-lg));
|
|
130
|
-
--dry-btn-justify: stretch;
|
|
131
|
-
--dry-btn-align: stretch;
|
|
132
|
-
--dry-btn-min-height: 0;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
.root:hover:not([data-disabled]) {
|
|
136
|
-
border-color: color-mix(
|
|
137
|
-
in srgb,
|
|
138
|
-
var(--dry-color-stroke-strong) 72%,
|
|
139
|
-
var(--dry-color-stroke-weak) 28%
|
|
140
|
-
);
|
|
141
|
-
background: var(
|
|
142
|
-
--dry-option-swatch-group-bg-hover,
|
|
143
|
-
color-mix(in srgb, var(--dry-color-bg-raised) 92%, var(--dry-color-fill-selected) 8%)
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.root[data-state='checked'] {
|
|
148
|
-
border-color: var(--_swatch-item-selected-border);
|
|
149
|
-
background: var(--_swatch-item-selected-bg);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.root[data-state='checked']:hover:not([data-disabled]) {
|
|
153
|
-
background: var(--_swatch-item-selected-bg-hover);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
.root:focus-within {
|
|
157
|
-
outline: 2px solid var(--dry-color-focus-ring);
|
|
158
|
-
outline-offset: 2px;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
.content {
|
|
162
|
-
display: grid;
|
|
163
|
-
grid-template-columns: auto minmax(0, 1fr);
|
|
164
|
-
align-items: center;
|
|
165
|
-
justify-items: start;
|
|
166
|
-
gap: var(--dry-option-swatch-group-item-gap, var(--dry-space-2_5));
|
|
167
|
-
padding: var(--dry-option-swatch-group-padding-y, var(--dry-space-2))
|
|
168
|
-
var(--dry-option-swatch-group-padding-x, var(--dry-space-2_5));
|
|
169
|
-
min-block-size: var(--dry-option-swatch-group-min-block-size, 3rem);
|
|
170
|
-
text-align: left;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
.root[data-size='compact'] .content {
|
|
174
|
-
grid-template-columns: auto;
|
|
175
|
-
justify-items: center;
|
|
176
|
-
gap: 0;
|
|
177
|
-
min-block-size: 0;
|
|
178
|
-
padding: var(--dry-option-swatch-group-compact-padding, var(--dry-space-0_5));
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
.root[data-size='compact'] {
|
|
182
|
-
background: transparent;
|
|
183
|
-
border-color: transparent;
|
|
184
|
-
border-radius: 999px;
|
|
185
|
-
box-shadow: none;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
.root[data-size='compact']:hover:not([data-disabled]) {
|
|
189
|
-
background: color-mix(in srgb, var(--dry-color-fill-selected) 6%, transparent);
|
|
190
|
-
border-color: transparent;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
.root[data-size='compact'][data-state='checked'] {
|
|
194
|
-
--dry-option-swatch-group-swatch-border: color-mix(
|
|
195
|
-
in srgb,
|
|
196
|
-
var(--_swatch-item-selected-border) 34%,
|
|
197
|
-
var(--dry-color-stroke-weak) 66%
|
|
198
|
-
);
|
|
199
|
-
|
|
200
|
-
background: color-mix(in srgb, var(--dry-color-fill-selected) 6%, transparent);
|
|
201
|
-
border-color: transparent;
|
|
202
|
-
box-shadow: 0 0 0 1px var(--_swatch-item-selected-border);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
.root[data-size='compact'][data-state='checked']:hover:not([data-disabled]) {
|
|
206
|
-
background: color-mix(in srgb, var(--dry-color-fill-selected) 8%, transparent);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.root[data-disabled] {
|
|
210
|
-
opacity: 0.6;
|
|
211
|
-
border-color: var(--dry-color-stroke-disabled);
|
|
212
|
-
box-shadow: none;
|
|
213
|
-
}
|
|
214
|
-
</style>
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
-
interface Props extends Omit<HTMLButtonAttributes, 'value'> {
|
|
4
|
-
value: string;
|
|
5
|
-
disabled?: boolean;
|
|
6
|
-
unavailable?: boolean;
|
|
7
|
-
size?: 'default' | 'compact';
|
|
8
|
-
children: Snippet;
|
|
9
|
-
}
|
|
10
|
-
declare const OptionSwatchGroupItemButton: import("svelte").Component<Props, {}, "">;
|
|
11
|
-
type OptionSwatchGroupItemButton = ReturnType<typeof OptionSwatchGroupItemButton>;
|
|
12
|
-
export default OptionSwatchGroupItemButton;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import type { Snippet } from 'svelte';
|
|
4
|
-
|
|
5
|
-
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
6
|
-
children?: Snippet;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let { class: className, children, ...rest }: Props = $props();
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<span data-part="label" data-option-swatch-group-label class={className} {...rest}
|
|
13
|
-
>{@render children?.()}</span
|
|
14
|
-
>
|
|
15
|
-
|
|
16
|
-
<style>
|
|
17
|
-
[data-option-swatch-group-label] {
|
|
18
|
-
grid-column: 2;
|
|
19
|
-
grid-row: 1;
|
|
20
|
-
font-size: var(--dry-type-small-size);
|
|
21
|
-
font-weight: 600;
|
|
22
|
-
line-height: 1.2;
|
|
23
|
-
}
|
|
24
|
-
</style>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
4
|
-
children?: Snippet;
|
|
5
|
-
}
|
|
6
|
-
declare const OptionSwatchGroupLabel: import("svelte").Component<Props, {}, "">;
|
|
7
|
-
type OptionSwatchGroupLabel = ReturnType<typeof OptionSwatchGroupLabel>;
|
|
8
|
-
export default OptionSwatchGroupLabel;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import type { Snippet } from 'svelte';
|
|
4
|
-
|
|
5
|
-
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
6
|
-
children?: Snippet;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let { class: className, children, ...rest }: Props = $props();
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<span data-part="meta" data-option-swatch-group-meta class={className} {...rest}
|
|
13
|
-
>{@render children?.()}</span
|
|
14
|
-
>
|
|
15
|
-
|
|
16
|
-
<style>
|
|
17
|
-
[data-option-swatch-group-meta] {
|
|
18
|
-
grid-column: 2;
|
|
19
|
-
grid-row: 2;
|
|
20
|
-
color: var(--dry-option-swatch-muted);
|
|
21
|
-
font-size: var(--dry-type-tiny-size);
|
|
22
|
-
line-height: 1.2;
|
|
23
|
-
}
|
|
24
|
-
</style>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
4
|
-
children?: Snippet;
|
|
5
|
-
}
|
|
6
|
-
declare const OptionSwatchGroupMeta: import("svelte").Component<Props, {}, "">;
|
|
7
|
-
type OptionSwatchGroupMeta = ReturnType<typeof OptionSwatchGroupMeta>;
|
|
8
|
-
export default OptionSwatchGroupMeta;
|