@dryui/ui 1.1.3 → 1.1.5
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/border-beam/border-beam.svelte +42 -0
- package/dist/border-beam/border-beam.svelte.d.ts +4 -0
- package/dist/border-beam/index.d.ts +3 -0
- package/dist/border-beam/index.js +1 -0
- package/dist/button/button.svelte +2 -1
- package/dist/dialog/dialog-body.svelte +1 -1
- package/dist/dialog/dialog-content.svelte +7 -3
- package/dist/drawer/drawer-body.svelte +1 -0
- package/dist/drawer/drawer-dialog-content.svelte +20 -18
- package/dist/drawer/drawer-footer.svelte +1 -0
- package/dist/drawer/drawer-header.svelte +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/slider/index.d.ts +7 -0
- package/dist/slider/slider-input.svelte +94 -2
- package/dist/slider/slider-input.svelte.d.ts +6 -0
- package/package.json +7 -2
- package/skills/dryui/SKILL.md +35 -29
- package/skills/dryui/rules/composition.md +3 -3
- package/skills/dryui/rules/compound-components.md +2 -2
- package/skills/dryui/rules/theming.md +2 -2
- package/dist/internal/overlay-base.svelte +0 -25
- package/dist/internal/overlay-base.svelte.d.ts +0 -6
- package/dist/internal/section-body.svelte +0 -22
- package/dist/internal/section-body.svelte.d.ts +0 -8
- package/dist/internal/section-footer.svelte +0 -26
- package/dist/internal/section-footer.svelte.d.ts +0 -8
- package/dist/internal/section-header.svelte +0 -21
- package/dist/internal/section-header.svelte.d.ts +0 -8
- package/dist/themes/practical-ui-foundation-map.md +0 -46
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
BorderBeam as BorderBeamPrimitive,
|
|
4
|
+
type BorderBeamProps
|
|
5
|
+
} from '@dryui/primitives/border-beam';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
size,
|
|
9
|
+
colorVariant,
|
|
10
|
+
theme,
|
|
11
|
+
staticColors,
|
|
12
|
+
duration,
|
|
13
|
+
active,
|
|
14
|
+
borderRadius,
|
|
15
|
+
brightness,
|
|
16
|
+
saturation,
|
|
17
|
+
hueRange,
|
|
18
|
+
strength,
|
|
19
|
+
onActivate,
|
|
20
|
+
onDeactivate,
|
|
21
|
+
children,
|
|
22
|
+
...rest
|
|
23
|
+
}: BorderBeamProps = $props();
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<BorderBeamPrimitive
|
|
27
|
+
{size}
|
|
28
|
+
{colorVariant}
|
|
29
|
+
{theme}
|
|
30
|
+
{staticColors}
|
|
31
|
+
{duration}
|
|
32
|
+
{active}
|
|
33
|
+
{borderRadius}
|
|
34
|
+
{brightness}
|
|
35
|
+
{saturation}
|
|
36
|
+
{hueRange}
|
|
37
|
+
{strength}
|
|
38
|
+
{onActivate}
|
|
39
|
+
{onDeactivate}
|
|
40
|
+
{children}
|
|
41
|
+
{...rest}
|
|
42
|
+
/>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { BorderBeamProps, BorderBeamColorVariant, BorderBeamSize, BorderBeamTheme } from '@dryui/primitives/border-beam';
|
|
2
|
+
export type { BorderBeamProps, BorderBeamColorVariant, BorderBeamSize, BorderBeamTheme };
|
|
3
|
+
export { default as BorderBeam } from './border-beam.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as BorderBeam } from './border-beam.svelte';
|
|
@@ -410,7 +410,8 @@
|
|
|
410
410
|
--_dry-btn-color: var(--dry-btn-color, var(--dry-color-text-strong));
|
|
411
411
|
}
|
|
412
412
|
|
|
413
|
-
&[aria-pressed='true']
|
|
413
|
+
&[aria-pressed='true'],
|
|
414
|
+
&[aria-pressed='true']:hover:not([data-disabled]) {
|
|
414
415
|
--_dry-btn-bg: var(--dry-btn-bg, var(--dry-color-fill-brand));
|
|
415
416
|
--_dry-btn-color: var(--dry-btn-color, var(--dry-color-on-brand));
|
|
416
417
|
}
|
|
@@ -46,6 +46,10 @@
|
|
|
46
46
|
[data-dialog-content] {
|
|
47
47
|
position: fixed;
|
|
48
48
|
inset: 0;
|
|
49
|
+
/* dryui-allow width */
|
|
50
|
+
width: 100vw;
|
|
51
|
+
/* dryui-allow width */
|
|
52
|
+
max-width: none;
|
|
49
53
|
height: 100vh;
|
|
50
54
|
height: 100dvh;
|
|
51
55
|
max-height: none;
|
|
@@ -53,9 +57,9 @@
|
|
|
53
57
|
background: transparent;
|
|
54
58
|
color: var(--dry-color-text-strong);
|
|
55
59
|
padding: 0;
|
|
56
|
-
margin: 0;
|
|
57
60
|
display: grid;
|
|
58
61
|
grid-template-columns: min(90vw, var(--dry-dialog-max-width, 32rem));
|
|
62
|
+
place-content: center;
|
|
59
63
|
place-items: center;
|
|
60
64
|
overflow: visible;
|
|
61
65
|
}
|
|
@@ -89,9 +93,9 @@
|
|
|
89
93
|
color: var(--dry-color-text-strong);
|
|
90
94
|
box-shadow: var(--dry-dialog-shadow, var(--dry-overlay-shadow, var(--dry-shadow-overlay)));
|
|
91
95
|
padding: 0;
|
|
92
|
-
max-
|
|
96
|
+
max-block-size: var(--dry-dialog-max-block-size, 85vh);
|
|
93
97
|
display: grid;
|
|
94
|
-
overflow: auto;
|
|
98
|
+
overflow: var(--dry-dialog-overflow, auto);
|
|
95
99
|
|
|
96
100
|
transition:
|
|
97
101
|
opacity var(--dry-duration-normal) var(--dry-ease-spring-snappy),
|
|
@@ -14,10 +14,15 @@
|
|
|
14
14
|
let dialogEl = $state<HTMLDialogElement>();
|
|
15
15
|
|
|
16
16
|
$effect(() => {
|
|
17
|
-
if (
|
|
17
|
+
if (!dialogEl) return;
|
|
18
|
+
|
|
19
|
+
// Native <dialog> applies a max-width that leaves a strip beside edge drawers.
|
|
20
|
+
dialogEl.style.setProperty('max-width', 'none');
|
|
21
|
+
|
|
22
|
+
if (ctx.open && !dialogEl.open) {
|
|
18
23
|
dialogEl.showModal();
|
|
19
24
|
}
|
|
20
|
-
if (!ctx.open && dialogEl
|
|
25
|
+
if (!ctx.open && dialogEl.open) {
|
|
21
26
|
dialogEl.close();
|
|
22
27
|
}
|
|
23
28
|
});
|
|
@@ -55,7 +60,6 @@
|
|
|
55
60
|
background: transparent;
|
|
56
61
|
color: var(--dry-color-text-strong);
|
|
57
62
|
padding: 0;
|
|
58
|
-
margin: 0;
|
|
59
63
|
box-sizing: border-box;
|
|
60
64
|
display: grid;
|
|
61
65
|
grid-template-columns: minmax(0, 1fr);
|
|
@@ -102,6 +106,8 @@
|
|
|
102
106
|
--dry-drawer-bg: var(--dry-color-bg-overlay);
|
|
103
107
|
--dry-drawer-border: var(--dry-color-stroke-weak);
|
|
104
108
|
--dry-drawer-size: 25rem;
|
|
109
|
+
--_drawer-rest-transform: translateX(0);
|
|
110
|
+
--_drawer-enter-transform: translateX(100%);
|
|
105
111
|
|
|
106
112
|
background: var(--dry-drawer-bg);
|
|
107
113
|
color: var(--dry-color-text-strong);
|
|
@@ -110,6 +116,9 @@
|
|
|
110
116
|
display: grid;
|
|
111
117
|
grid-template-rows: max-content minmax(0, 1fr) max-content;
|
|
112
118
|
overflow: hidden;
|
|
119
|
+
opacity: 1;
|
|
120
|
+
transform: var(--_drawer-rest-transform);
|
|
121
|
+
will-change: transform, opacity;
|
|
113
122
|
|
|
114
123
|
transition:
|
|
115
124
|
transform var(--dry-duration-slow) var(--dry-ease-spring-snappy),
|
|
@@ -123,44 +132,37 @@
|
|
|
123
132
|
}
|
|
124
133
|
|
|
125
134
|
[data-drawer-content][data-side='left'] [data-drawer-panel] {
|
|
135
|
+
--_drawer-enter-transform: translateX(-100%);
|
|
126
136
|
grid-column: 1;
|
|
127
137
|
height: 100%;
|
|
128
138
|
border-right: 1px solid var(--dry-drawer-border);
|
|
129
139
|
}
|
|
130
140
|
|
|
131
141
|
[data-drawer-content][data-side='top'] [data-drawer-panel] {
|
|
142
|
+
--_drawer-rest-transform: translateY(0);
|
|
143
|
+
--_drawer-enter-transform: translateY(-100%);
|
|
132
144
|
grid-row: 1;
|
|
133
145
|
height: var(--dry-drawer-size);
|
|
134
146
|
border-bottom: 1px solid var(--dry-drawer-border);
|
|
135
147
|
}
|
|
136
148
|
|
|
137
149
|
[data-drawer-content][data-side='bottom'] [data-drawer-panel] {
|
|
150
|
+
--_drawer-rest-transform: translateY(0);
|
|
151
|
+
--_drawer-enter-transform: translateY(100%);
|
|
138
152
|
grid-row: 2;
|
|
139
153
|
height: var(--dry-drawer-size);
|
|
140
154
|
border-top: 1px solid var(--dry-drawer-border);
|
|
141
155
|
}
|
|
142
156
|
|
|
143
157
|
@starting-style {
|
|
144
|
-
[data-drawer-content][
|
|
145
|
-
opacity: 0;
|
|
146
|
-
transform: translateX(100%);
|
|
147
|
-
}
|
|
148
|
-
[data-drawer-content][data-side='left'][open] [data-drawer-panel] {
|
|
149
|
-
opacity: 0;
|
|
150
|
-
transform: translateX(-100%);
|
|
151
|
-
}
|
|
152
|
-
[data-drawer-content][data-side='top'][open] [data-drawer-panel] {
|
|
153
|
-
opacity: 0;
|
|
154
|
-
transform: translateY(-100%);
|
|
155
|
-
}
|
|
156
|
-
[data-drawer-content][data-side='bottom'][open] [data-drawer-panel] {
|
|
158
|
+
[data-drawer-content][open] [data-drawer-panel] {
|
|
157
159
|
opacity: 0;
|
|
158
|
-
transform:
|
|
160
|
+
transform: var(--_drawer-enter-transform);
|
|
159
161
|
}
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
[data-drawer-content][data-state='open'] [data-drawer-panel] {
|
|
163
165
|
opacity: 1;
|
|
164
|
-
transform:
|
|
166
|
+
transform: var(--_drawer-rest-transform);
|
|
165
167
|
}
|
|
166
168
|
</style>
|
package/dist/index.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export type { MultiSelectComboboxRootProps, MultiSelectComboboxInputProps, Multi
|
|
|
47
47
|
export { SegmentedControl } from './segmented-control/index.js';
|
|
48
48
|
export type { SegmentedControlRootProps, SegmentedControlItemProps } from './segmented-control/index.js';
|
|
49
49
|
export { Slider } from './slider/index.js';
|
|
50
|
-
export type { SliderProps } from './slider/index.js';
|
|
50
|
+
export type { SliderProps, SliderVariant } from './slider/index.js';
|
|
51
51
|
export { Toggle } from './toggle/index.js';
|
|
52
52
|
export type { ToggleProps } from './toggle/index.js';
|
|
53
53
|
export { ToggleGroup } from './toggle-group/index.js';
|
|
@@ -270,6 +270,8 @@ export { AlphaSlider } from './alpha-slider/index.js';
|
|
|
270
270
|
export type { AlphaSliderProps } from './alpha-slider/index.js';
|
|
271
271
|
export { Beam } from './beam/index.js';
|
|
272
272
|
export type { BeamProps } from './beam/index.js';
|
|
273
|
+
export { BorderBeam } from './border-beam/index.js';
|
|
274
|
+
export type { BorderBeamProps } from './border-beam/index.js';
|
|
273
275
|
export { Shimmer } from './shimmer/index.js';
|
|
274
276
|
export type { ShimmerProps } from './shimmer/index.js';
|
|
275
277
|
export { Glass } from './glass/index.js';
|
package/dist/index.js
CHANGED
|
@@ -139,6 +139,7 @@ export { Glow } from './glow/index.js';
|
|
|
139
139
|
export { Adjust } from './adjust/index.js';
|
|
140
140
|
export { AlphaSlider } from './alpha-slider/index.js';
|
|
141
141
|
export { Beam } from './beam/index.js';
|
|
142
|
+
export { BorderBeam } from './border-beam/index.js';
|
|
142
143
|
export { Shimmer } from './shimmer/index.js';
|
|
143
144
|
export { Glass } from './glass/index.js';
|
|
144
145
|
export { GodRays } from './god-rays/index.js';
|
package/dist/slider/index.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import type { SliderProps as PrimitiveSliderProps } from '@dryui/primitives';
|
|
3
|
+
export type SliderVariant = 'default' | 'pill';
|
|
2
4
|
export interface SliderProps extends Omit<PrimitiveSliderProps, 'size'> {
|
|
3
5
|
size?: 'sm' | 'md' | 'lg';
|
|
6
|
+
variant?: SliderVariant;
|
|
7
|
+
valueLabel?: Snippet<[{
|
|
8
|
+
value: number;
|
|
9
|
+
percentage: number;
|
|
10
|
+
}]>;
|
|
4
11
|
}
|
|
5
12
|
export { default as Slider } from './slider-input.svelte';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
4
|
import { getFormControlCtx } from '@dryui/primitives';
|
|
4
5
|
|
|
@@ -8,8 +9,10 @@
|
|
|
8
9
|
max?: number;
|
|
9
10
|
step?: number;
|
|
10
11
|
size?: 'sm' | 'md' | 'lg';
|
|
12
|
+
variant?: 'default' | 'pill';
|
|
11
13
|
disabled?: boolean;
|
|
12
14
|
orientation?: 'horizontal' | 'vertical';
|
|
15
|
+
valueLabel?: Snippet<[{ value: number; percentage: number }]>;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
let {
|
|
@@ -18,8 +21,10 @@
|
|
|
18
21
|
max = 100,
|
|
19
22
|
step = 1,
|
|
20
23
|
size = 'md',
|
|
24
|
+
variant = 'default',
|
|
21
25
|
disabled = false,
|
|
22
26
|
orientation = 'horizontal',
|
|
27
|
+
valueLabel,
|
|
23
28
|
class: className,
|
|
24
29
|
...rest
|
|
25
30
|
}: Props = $props();
|
|
@@ -28,6 +33,7 @@
|
|
|
28
33
|
const isDisabled = $derived(disabled || ctx?.disabled || false);
|
|
29
34
|
|
|
30
35
|
let progress = $derived(((value - min) / (max - min)) * 100);
|
|
36
|
+
let isPill = $derived(variant === 'pill');
|
|
31
37
|
|
|
32
38
|
function applyStyles(node: HTMLElement) {
|
|
33
39
|
$effect(() => {
|
|
@@ -36,7 +42,7 @@
|
|
|
36
42
|
}
|
|
37
43
|
</script>
|
|
38
44
|
|
|
39
|
-
<span class="wrapper">
|
|
45
|
+
<span class="wrapper" data-variant={variant} data-size={size} use:applyStyles>
|
|
40
46
|
<input
|
|
41
47
|
type="range"
|
|
42
48
|
bind:value
|
|
@@ -51,11 +57,20 @@
|
|
|
51
57
|
aria-errormessage={ctx?.errorMessageId}
|
|
52
58
|
data-disabled={isDisabled || undefined}
|
|
53
59
|
data-orientation={orientation}
|
|
60
|
+
data-variant={variant}
|
|
54
61
|
data-size={size}
|
|
55
62
|
class={className}
|
|
56
|
-
use:applyStyles
|
|
57
63
|
{...rest}
|
|
58
64
|
/>
|
|
65
|
+
{#if isPill}
|
|
66
|
+
<span data-part="value-label" aria-hidden="true">
|
|
67
|
+
{#if valueLabel}
|
|
68
|
+
{@render valueLabel({ value, percentage: progress })}
|
|
69
|
+
{:else}
|
|
70
|
+
{Math.round(progress)}%
|
|
71
|
+
{/if}
|
|
72
|
+
</span>
|
|
73
|
+
{/if}
|
|
59
74
|
</span>
|
|
60
75
|
|
|
61
76
|
<style>
|
|
@@ -181,4 +196,81 @@
|
|
|
181
196
|
--dry-slider-track-height: 8px;
|
|
182
197
|
--dry-slider-thumb-size: 28px;
|
|
183
198
|
}
|
|
199
|
+
|
|
200
|
+
/* ── Pill variant ── */
|
|
201
|
+
|
|
202
|
+
.wrapper[data-variant='pill'] input,
|
|
203
|
+
.wrapper[data-variant='pill'] [data-part='value-label'] {
|
|
204
|
+
grid-area: 1 / 1;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
input[data-variant='pill'][data-size='sm'] {
|
|
208
|
+
--dry-slider-track-height: 32px;
|
|
209
|
+
--dry-slider-thumb-size: 32px;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
input[data-variant='pill'][data-size='md'] {
|
|
213
|
+
--dry-slider-track-height: 40px;
|
|
214
|
+
--dry-slider-thumb-size: 40px;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
input[data-variant='pill'][data-size='lg'] {
|
|
218
|
+
--dry-slider-track-height: 48px;
|
|
219
|
+
--dry-slider-thumb-size: 48px;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
input[data-variant='pill']::-webkit-slider-thumb {
|
|
223
|
+
background: transparent;
|
|
224
|
+
border: none;
|
|
225
|
+
box-shadow: none;
|
|
226
|
+
margin-top: 0;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
input[data-variant='pill']::-moz-range-thumb {
|
|
230
|
+
background: transparent;
|
|
231
|
+
border: none;
|
|
232
|
+
box-shadow: none;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
input[data-variant='pill']:hover:not([data-disabled])::-webkit-slider-thumb,
|
|
236
|
+
input[data-variant='pill']:active:not([data-disabled])::-webkit-slider-thumb {
|
|
237
|
+
transform: none;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
input[data-variant='pill']:hover:not([data-disabled])::-moz-range-thumb,
|
|
241
|
+
input[data-variant='pill']:active:not([data-disabled])::-moz-range-thumb {
|
|
242
|
+
transform: none;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/* Pill value label */
|
|
246
|
+
.wrapper[data-variant='pill'] [data-part='value-label'] {
|
|
247
|
+
pointer-events: none;
|
|
248
|
+
display: grid;
|
|
249
|
+
align-items: center;
|
|
250
|
+
padding-inline: var(--dry-space-4);
|
|
251
|
+
font-size: var(--dry-text-sm-size, 0.875rem);
|
|
252
|
+
font-weight: 600;
|
|
253
|
+
color: var(--dry-color-text);
|
|
254
|
+
clip-path: inset(
|
|
255
|
+
0 calc(100% - var(--dry-slider-progress, 50%)) 0 0 round var(--dry-radius-full)
|
|
256
|
+
);
|
|
257
|
+
transition: clip-path var(--dry-duration-fast) var(--dry-ease-default);
|
|
258
|
+
z-index: 1;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.wrapper[data-variant='pill'][data-size='sm'] [data-part='value-label'] {
|
|
262
|
+
font-size: var(--dry-text-xs-size, 0.75rem);
|
|
263
|
+
padding-inline: var(--dry-space-3);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.wrapper[data-variant='pill'][data-size='lg'] [data-part='value-label'] {
|
|
267
|
+
font-size: var(--dry-text-base-size, 1rem);
|
|
268
|
+
padding-inline: var(--dry-space-5);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
@media (prefers-reduced-motion: reduce) {
|
|
272
|
+
.wrapper[data-variant='pill'] [data-part='value-label'] {
|
|
273
|
+
transition: none;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
184
276
|
</style>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
3
|
interface Props extends Omit<HTMLInputAttributes, 'size'> {
|
|
3
4
|
value?: number;
|
|
@@ -5,8 +6,13 @@ interface Props extends Omit<HTMLInputAttributes, 'size'> {
|
|
|
5
6
|
max?: number;
|
|
6
7
|
step?: number;
|
|
7
8
|
size?: 'sm' | 'md' | 'lg';
|
|
9
|
+
variant?: 'default' | 'pill';
|
|
8
10
|
disabled?: boolean;
|
|
9
11
|
orientation?: 'horizontal' | 'vertical';
|
|
12
|
+
valueLabel?: Snippet<[{
|
|
13
|
+
value: number;
|
|
14
|
+
percentage: number;
|
|
15
|
+
}]>;
|
|
10
16
|
}
|
|
11
17
|
declare const SliderInput: import("svelte").Component<Props, {}, "value">;
|
|
12
18
|
type SliderInput = ReturnType<typeof SliderInput>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dryui/ui",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"author": "Rob Balfre",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -76,6 +76,11 @@
|
|
|
76
76
|
"svelte": "./dist/beam/index.js",
|
|
77
77
|
"default": "./dist/beam/index.js"
|
|
78
78
|
},
|
|
79
|
+
"./border-beam": {
|
|
80
|
+
"types": "./dist/border-beam/index.d.ts",
|
|
81
|
+
"svelte": "./dist/border-beam/index.js",
|
|
82
|
+
"default": "./dist/border-beam/index.js"
|
|
83
|
+
},
|
|
79
84
|
"./breadcrumb": {
|
|
80
85
|
"types": "./dist/breadcrumb/index.d.ts",
|
|
81
86
|
"svelte": "./dist/breadcrumb/index.js",
|
|
@@ -770,7 +775,7 @@
|
|
|
770
775
|
"postpack": "bun ../../scripts/postpack-exports.ts"
|
|
771
776
|
},
|
|
772
777
|
"dependencies": {
|
|
773
|
-
"@dryui/primitives": "^1.1.
|
|
778
|
+
"@dryui/primitives": "^1.1.5"
|
|
774
779
|
},
|
|
775
780
|
"peerDependencies": {
|
|
776
781
|
"svelte": "^5.55.1"
|
package/skills/dryui/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dryui
|
|
3
|
-
description: 'Use when building UIs with DryUI (@dryui/ui) Svelte 5 components. Teaches correct patterns for compound components, theming, forms, and accessibility. Use
|
|
3
|
+
description: 'Use when building UIs with DryUI (@dryui/ui) Svelte 5 components. Teaches correct patterns for compound components, theming, forms, and accessibility. Use the CLI as the default entry point; MCP mirrors the same workflow when available.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# DryUI
|
|
@@ -13,18 +13,18 @@ Zero-dependency Svelte 5 components. All imports from `@dryui/ui`. Requires a th
|
|
|
13
13
|
|
|
14
14
|
**Never guess a component API. Always verify first.**
|
|
15
15
|
|
|
16
|
-
- Call `
|
|
16
|
+
- Call `dryui info <component>` or `dryui compose "<query>"` before using any component for the first time. If MCP is available, `ask --scope component` and `ask --scope recipe` are equivalent.
|
|
17
17
|
- Component APIs vary — `bind:value`, `bind:open`, `bind:checked` are NOT interchangeable
|
|
18
18
|
- Compound vs simple, required parts, available props — all differ per component
|
|
19
19
|
- If you skip the lookup, you'll write plausible-looking code that silently breaks
|
|
20
20
|
|
|
21
|
-
The test: can you point to
|
|
21
|
+
The test: can you point to a `dryui info`, `dryui compose`, or `ask` call for every component or pattern in your output?
|
|
22
22
|
|
|
23
23
|
## 2. Everything is Compound Until Proven Otherwise
|
|
24
24
|
|
|
25
25
|
**Use `.Root`. Always check.**
|
|
26
26
|
|
|
27
|
-
Most DryUI components are compound — they require `<Card.Root>`, not `<Card>`. The bare name silently fails or renders wrong. Assume compound; verify with `ask --scope component`.
|
|
27
|
+
Most DryUI components are compound — they require `<Card.Root>`, not `<Card>`. The bare name silently fails or renders wrong. Assume compound; verify with `dryui info <Component>` or `ask --scope component`.
|
|
28
28
|
|
|
29
29
|
```svelte
|
|
30
30
|
<!-- Wrong -->
|
|
@@ -33,7 +33,7 @@ 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 are tracked in the manifest at `packages/mcp/src/component-catalog.ts`. Verify with `ask --scope component` before you assume a bare name works, then use `.Root` and wrap the parts inside it.
|
|
36
|
+
Compound components are tracked in the manifest at `packages/mcp/src/component-catalog.ts`. Verify with `dryui info <Component>` or `ask --scope component` before you assume a bare name works, then use `.Root` and wrap the parts inside it.
|
|
37
37
|
|
|
38
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
|
|
|
@@ -118,21 +118,19 @@ The test: search your markup for raw `<input`, `<select>`, `<dialog>`, `<button>
|
|
|
118
118
|
|
|
119
119
|
## Quick Start
|
|
120
120
|
|
|
121
|
-
**1. Install
|
|
121
|
+
**1. Install the CLI** so every subsequent command is short and fast:
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
- Copilot/Cursor/Windsurf: `npx degit rob-balfre/dryui/packages/ui/skills/dryui .agents/skills/dryui` + add MCP config (see https://dryui.dev/tools)
|
|
123
|
+
```bash
|
|
124
|
+
bun install -g @dryui/cli@latest # or: npm install -g @dryui/cli@latest
|
|
125
|
+
```
|
|
128
126
|
|
|
129
|
-
**
|
|
127
|
+
**2. Start with bare `dryui`** when you want editor integration and feedback:
|
|
130
128
|
|
|
131
129
|
```bash
|
|
132
|
-
|
|
130
|
+
dryui
|
|
133
131
|
```
|
|
134
132
|
|
|
135
|
-
**
|
|
133
|
+
**3. Bootstrap or inspect the project** with the CLI:
|
|
136
134
|
|
|
137
135
|
```bash
|
|
138
136
|
dryui init # existing project
|
|
@@ -140,10 +138,16 @@ dryui init my-app # new project — scaffolds SvelteKit + DryUI in one step
|
|
|
140
138
|
cd my-app && bun run dev
|
|
141
139
|
```
|
|
142
140
|
|
|
143
|
-
This works for greenfield (empty directory), brownfield (existing non-SvelteKit project), and existing SvelteKit projects.
|
|
141
|
+
This works for greenfield (empty directory), brownfield (existing non-SvelteKit project), and existing SvelteKit projects. On existing projects, `dryui install` prints the ordered plan and `dryui detect` verifies that setup is complete.
|
|
144
142
|
|
|
145
143
|
> **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).
|
|
146
144
|
|
|
145
|
+
**4. Add the agent integration layer manually** if you do not want to use `dryui` / `dryui setup`:
|
|
146
|
+
|
|
147
|
+
- Claude Code: `claude plugin marketplace add rob-balfre/dryui && claude plugin install dryui@dryui` (installs skill + MCP in one step)
|
|
148
|
+
- Codex (0.121.0+): `codex marketplace add rob-balfre/dryui`, then start `codex`, run `/plugins`, and install `DryUI` (installs skill + MCP in one step). Manual fallback: `codex mcp add dryui -- npx -y @dryui/mcp` + copy the skill from `packages/ui/skills/dryui`.
|
|
149
|
+
- Copilot/Cursor/Windsurf: `npx degit rob-balfre/dryui/packages/ui/skills/dryui .agents/skills/dryui` + add MCP config (see https://dryui.dev/tools)
|
|
150
|
+
|
|
147
151
|
### Manual setup
|
|
148
152
|
|
|
149
153
|
1. `bun add @dryui/ui`
|
|
@@ -181,7 +185,7 @@ This works for greenfield (empty directory), brownfield (existing non-SvelteKit
|
|
|
181
185
|
|
|
182
186
|
## Bindable Props — Common Confusion
|
|
183
187
|
|
|
184
|
-
Always verify with `ask --scope component`, but these are the most common mistakes:
|
|
188
|
+
Always verify with `dryui info <Component>` or `ask --scope component`, but these are the most common mistakes:
|
|
185
189
|
|
|
186
190
|
- `bind:value` (Input, Select, Tabs...) vs `bind:checked` (Checkbox, Switch) vs `bind:pressed` (Toggle) vs `bind:open` (Dialog, Popover, Drawer...)
|
|
187
191
|
- Select and Combobox support both `bind:value` and `bind:open`
|
|
@@ -194,25 +198,18 @@ Use these to look up APIs, discover components, plan setup, and validate code.
|
|
|
194
198
|
|
|
195
199
|
### Recommended workflow
|
|
196
200
|
|
|
197
|
-
1. `
|
|
201
|
+
1. `dryui info <Component>` or `dryui compose "<query>"` before writing so you confirm kind, required parts, bindables, and canonical usage. If MCP is available, `ask --scope component` and `ask --scope recipe` are the equivalent surface.
|
|
198
202
|
2. Build the route or component with raw CSS grid, `Container` for constrained width, and `@container` for responsive layout.
|
|
199
|
-
3. `
|
|
203
|
+
3. `dryui review`, `dryui diagnose`, or `dryui doctor` after implementation to catch composition drift, layout violations, and accessibility regressions. If MCP is available, `check` is the equivalent surface.
|
|
200
204
|
4. Never guess component shape from memory. DryUI is intentionally strict, and the lookup cost is lower than rework.
|
|
201
205
|
|
|
202
|
-
###
|
|
206
|
+
### CLI (default entry point)
|
|
203
207
|
|
|
204
|
-
|
|
205
|
-
| -------------------- | ----------------------------------------------------------------- |
|
|
206
|
-
| Project setup | `ask --scope setup ""` |
|
|
207
|
-
| Lookup & composition | `ask --scope component`, `ask --scope recipe`, `ask --scope list` |
|
|
208
|
-
| Validation | `check <file.svelte>`, `check <theme.css>` |
|
|
209
|
-
| Audit | `check`, `check <directory>` |
|
|
210
|
-
|
|
211
|
-
### CLI fallback
|
|
212
|
-
|
|
213
|
-
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.
|
|
208
|
+
Install once with `bun install -g @dryui/cli@latest` (or `npm install -g @dryui/cli@latest`), 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.
|
|
214
209
|
|
|
215
210
|
```bash
|
|
211
|
+
dryui # default onboarding entry point
|
|
212
|
+
dryui setup # explicit onboarding subcommand
|
|
216
213
|
dryui init [path] [--pm bun] # Bootstrap SvelteKit + DryUI project
|
|
217
214
|
dryui info <component> # Look up component API
|
|
218
215
|
dryui compose "date input" # Composition guidance
|
|
@@ -227,6 +224,15 @@ dryui list # List components
|
|
|
227
224
|
|
|
228
225
|
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).
|
|
229
226
|
|
|
227
|
+
### MCP tools (same workflow in-editor)
|
|
228
|
+
|
|
229
|
+
| Workflow | Tools |
|
|
230
|
+
| -------------------- | ----------------------------------------------------------------- |
|
|
231
|
+
| Project setup | `ask --scope setup ""` |
|
|
232
|
+
| Lookup & composition | `ask --scope component`, `ask --scope recipe`, `ask --scope list` |
|
|
233
|
+
| Validation | `check <file.svelte>`, `check <theme.css>` |
|
|
234
|
+
| Audit | `check`, `check <directory>` |
|
|
235
|
+
|
|
230
236
|
Categories: action, input, form, layout, navigation, overlay, display, feedback, interaction, utility
|
|
231
237
|
|
|
232
238
|
## Rule Files
|
|
@@ -398,7 +398,7 @@ Use Field.Error to show validation messages.
|
|
|
398
398
|
|
|
399
399
|
## Component Selection Quick Reference
|
|
400
400
|
|
|
401
|
-
Before using any component, call `
|
|
401
|
+
Before using any component, call `dryui compose "<query>"` or `dryui info <Component>` to get the correct component and usage snippet. If MCP is available, `ask --scope recipe` and `ask --scope component` are equivalent. This table is a quick reference — the CLI and MCP surfaces both return the fuller snippets and anti-patterns.
|
|
402
402
|
|
|
403
403
|
| UI Need | Use This | NOT This |
|
|
404
404
|
| ----------------- | -------------------------------------- | ---------------------------- |
|
|
@@ -431,7 +431,7 @@ Before using any component, call `ask --scope recipe` or `ask --scope component`
|
|
|
431
431
|
|
|
432
432
|
## Composition Recipes
|
|
433
433
|
|
|
434
|
-
Call `
|
|
434
|
+
Call `dryui compose "<recipe>"` with any recipe name to get a full working snippet. If MCP is available, `ask --scope recipe "<recipe>"` is equivalent.
|
|
435
435
|
|
|
436
436
|
| Recipe | Description | Key Components |
|
|
437
437
|
| ------------------------- | ------------------------- | -------------------------------------- |
|
|
@@ -457,7 +457,7 @@ DryUI is a presentation and accessibility system, not a workflow engine. For dep
|
|
|
457
457
|
- Normalize route/session state in script before rendering DryUI inputs.
|
|
458
458
|
- Reset dependent `Select.Root` values when their parent choice changes; do not rely on stale child state surviving domain changes.
|
|
459
459
|
- Use raw CSS grid to lay out planner sections, and keep orchestration logic in route-level stores or derived state.
|
|
460
|
-
- Run `
|
|
460
|
+
- Run `dryui info <Component>` or `dryui compose "<pattern>"` before introducing a new field shape, then run `dryui review` or `dryui doctor` after the flow is wired. If MCP is available, `ask` / `check` are equivalent.
|
|
461
461
|
|
|
462
462
|
```svelte
|
|
463
463
|
<script lang="ts">
|
|
@@ -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.
|
|
21
|
+
Below are the parts for the most commonly used compound components. Prefer `dryui info <name>` for the full, up-to-date parts list; if MCP is available, `ask --scope component "<name>"` is equivalent.
|
|
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. If MCP is available, `ask --scope component "<name>"` is equivalent:
|
|
315
315
|
|
|
316
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
|
|
@@ -268,11 +268,11 @@ Ensure sufficient contrast between text and background.
|
|
|
268
268
|
|
|
269
269
|
## Validating Theme CSS
|
|
270
270
|
|
|
271
|
-
Run `
|
|
271
|
+
Run `dryui diagnose <theme.css>` to catch theme issues. If MCP is available, `check <theme.css>` is equivalent:
|
|
272
272
|
|
|
273
273
|
```bash
|
|
274
|
-
check src/styles/global.css
|
|
275
274
|
dryui diagnose src/styles/global.css
|
|
275
|
+
check src/styles/global.css
|
|
276
276
|
```
|
|
277
277
|
|
|
278
278
|
Common diagnostic codes:
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
|
|
4
|
-
interface Props extends HTMLAttributes<HTMLDivElement> {}
|
|
5
|
-
|
|
6
|
-
let { class: className, ...rest }: Props = $props();
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<div class={className} {...rest}></div>
|
|
10
|
-
|
|
11
|
-
<style>
|
|
12
|
-
div {
|
|
13
|
-
position: fixed;
|
|
14
|
-
inset: 0;
|
|
15
|
-
background: var(--dry-overlay-bg, var(--dry-color-overlay-backdrop));
|
|
16
|
-
backdrop-filter: blur(var(--dry-overlay-blur, 12px));
|
|
17
|
-
-webkit-backdrop-filter: blur(var(--dry-overlay-blur, 12px));
|
|
18
|
-
z-index: var(--dry-layer-overlay);
|
|
19
|
-
will-change: opacity;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
div[data-state='closed'] {
|
|
23
|
-
display: none;
|
|
24
|
-
}
|
|
25
|
-
</style>
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
-
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
-
}
|
|
4
|
-
declare const OverlayBase: import("svelte").Component<Props, {}, "">;
|
|
5
|
-
type OverlayBase = ReturnType<typeof OverlayBase>;
|
|
6
|
-
export default OverlayBase;
|
|
@@ -1,22 +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<HTMLDivElement> {
|
|
6
|
-
children: Snippet;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let { children, class: className, ...rest }: Props = $props();
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<div class={className} {...rest}>
|
|
13
|
-
{@render children()}
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
<style>
|
|
17
|
-
div {
|
|
18
|
-
padding: var(--dry-section-padding);
|
|
19
|
-
overflow-y: auto;
|
|
20
|
-
min-height: 0;
|
|
21
|
-
}
|
|
22
|
-
</style>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
-
children: Snippet;
|
|
5
|
-
}
|
|
6
|
-
declare const SectionBody: import("svelte").Component<Props, {}, "">;
|
|
7
|
-
type SectionBody = ReturnType<typeof SectionBody>;
|
|
8
|
-
export default SectionBody;
|
|
@@ -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<HTMLDivElement> {
|
|
6
|
-
children: Snippet;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let { children, class: className, ...rest }: Props = $props();
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<div class={className} {...rest}>
|
|
13
|
-
{@render children()}
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
<style>
|
|
17
|
-
div {
|
|
18
|
-
padding: var(--dry-section-padding);
|
|
19
|
-
border-top: 1px solid var(--dry-section-border);
|
|
20
|
-
display: grid;
|
|
21
|
-
grid-auto-flow: column;
|
|
22
|
-
grid-auto-columns: max-content;
|
|
23
|
-
justify-items: var(--dry-section-footer-justify, start);
|
|
24
|
-
gap: var(--dry-section-footer-gap, var(--dry-space-4));
|
|
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<HTMLDivElement> {
|
|
4
|
-
children: Snippet;
|
|
5
|
-
}
|
|
6
|
-
declare const SectionFooter: import("svelte").Component<Props, {}, "">;
|
|
7
|
-
type SectionFooter = ReturnType<typeof SectionFooter>;
|
|
8
|
-
export default SectionFooter;
|
|
@@ -1,21 +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<HTMLDivElement> {
|
|
6
|
-
children: Snippet;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let { children, class: className, ...rest }: Props = $props();
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<div class={className} {...rest}>
|
|
13
|
-
{@render children()}
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
<style>
|
|
17
|
-
div {
|
|
18
|
-
padding: var(--dry-section-padding);
|
|
19
|
-
border-bottom: 1px solid var(--dry-section-border);
|
|
20
|
-
}
|
|
21
|
-
</style>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
-
children: Snippet;
|
|
5
|
-
}
|
|
6
|
-
declare const SectionHeader: import("svelte").Component<Props, {}, "">;
|
|
7
|
-
type SectionHeader = ReturnType<typeof SectionHeader>;
|
|
8
|
-
export default SectionHeader;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# Practical UI Foundation Map
|
|
2
|
-
|
|
3
|
-
> Living note for [docs/research/practical-ui-figma-extraction.md](./docs/research/practical-ui-figma-extraction.md). Extracted from the Practical UI design system file on 2026-03-25.
|
|
4
|
-
|
|
5
|
-
## Foundation Rules
|
|
6
|
-
|
|
7
|
-
- Colour tokens are organized as semantic roles first, then tone, emphasis, and state.
|
|
8
|
-
- Background surfaces use `base`, `sunken`, `raised`, and `overlay`.
|
|
9
|
-
- Practical UI’s public neutral text and fill system is transparent, not solid.
|
|
10
|
-
- Elevation is expressed with both surface colour and shadow.
|
|
11
|
-
- Spacing is a fixed 4px-based ladder, not ad hoc values.
|
|
12
|
-
- Typography is centered on Inter with a small named scale.
|
|
13
|
-
|
|
14
|
-
## DryUI Mapping
|
|
15
|
-
|
|
16
|
-
| Figma | DryUI |
|
|
17
|
-
| -------------------- | --------------------------- |
|
|
18
|
-
| `Background/Base` | `--dry-color-bg-base` |
|
|
19
|
-
| `Background/Sunken` | `--dry-color-bg-sunken` |
|
|
20
|
-
| `Background/Raised` | `--dry-color-bg-raised` |
|
|
21
|
-
| `Background/Overlay` | `--dry-color-bg-overlay` |
|
|
22
|
-
| `Background/Inverse` | `--dry-color-bg-inverse` |
|
|
23
|
-
| `Text/Strong` | `--dry-color-text-strong` |
|
|
24
|
-
| `Text/Weak` | `--dry-color-text-weak` |
|
|
25
|
-
| `Text/Disabled` | `--dry-color-text-disabled` |
|
|
26
|
-
| `Stroke/Strong` | `--dry-color-stroke-strong` |
|
|
27
|
-
| `Stroke/Weak` | `--dry-color-stroke-weak` |
|
|
28
|
-
| `Stroke/Focus` | `--dry-color-stroke-focus` |
|
|
29
|
-
| `Fill/Strong` | `--dry-color-fill-strong` |
|
|
30
|
-
| `Fill/Weak` | `--dry-color-fill-weak` |
|
|
31
|
-
| `Fill/Hover` | `--dry-color-fill-hover` |
|
|
32
|
-
| `Fill/Press` | `--dry-color-fill-active` |
|
|
33
|
-
| `Fill/Selected` | `--dry-color-fill-selected` |
|
|
34
|
-
| `Fill/Inverse` | `--dry-color-fill-inverse` |
|
|
35
|
-
| `Information` | `info` |
|
|
36
|
-
|
|
37
|
-
## Published Scales
|
|
38
|
-
|
|
39
|
-
- Spacing: `0`, `4`, `8`, `12`, `16`, `20`, `24`, `32`, `40`, `48`, `56`, `64`, `80`, `96`, `128`, `192`, `256`
|
|
40
|
-
- Desktop typography: `Display 56/64`, `Heading 1 40/48`, `Heading 2 32/40`, `Heading 3 24/32`, `Heading 4 20/28`, `Small 16/24`, `Tiny 14/20`
|
|
41
|
-
- Mobile typography: `Display 40/48`, `Heading 1 36/44`, `Heading 2 28/36`, `Heading 3 24/32`, `Heading 4 20/28`, `Small 16/24`, `Tiny 14/20`
|
|
42
|
-
|
|
43
|
-
## Notes
|
|
44
|
-
|
|
45
|
-
- Keep [`default.css`](./packages/ui/src/themes/default.css) and [`dark.css`](./packages/ui/src/themes/dark.css) synchronized with the extracted foundation ladder.
|
|
46
|
-
- The inverse fill family in Dark mode follows the same transparent-neutral logic as the rest of the semantic layer.
|