@dorsk/tsumikit 0.23.0 → 0.25.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.
Files changed (35) hide show
  1. package/README.md +174 -6
  2. package/dist/components/atoms/Button.svelte +1 -1
  3. package/dist/components/atoms/Card.svelte +65 -2
  4. package/dist/components/atoms/Card.svelte.d.ts +6 -0
  5. package/dist/components/atoms/Scrim.svelte +81 -0
  6. package/dist/components/atoms/Scrim.svelte.d.ts +14 -0
  7. package/dist/components/layouts/ResizablePanel.svelte +238 -120
  8. package/dist/components/layouts/ResizablePanel.svelte.d.ts +24 -8
  9. package/dist/components/layouts/resizable-panel-frame.d.ts +70 -0
  10. package/dist/components/layouts/resizable-panel-frame.js +161 -0
  11. package/dist/components/molecules/ConfirmModal.svelte +102 -0
  12. package/dist/components/molecules/ConfirmModal.svelte.d.ts +16 -0
  13. package/dist/components/molecules/KeyValue.svelte +117 -0
  14. package/dist/components/molecules/KeyValue.svelte.d.ts +20 -0
  15. package/dist/components/molecules/LoadMore.svelte +78 -0
  16. package/dist/components/molecules/LoadMore.svelte.d.ts +15 -0
  17. package/dist/components/molecules/Modal.svelte +66 -10
  18. package/dist/components/molecules/Modal.svelte.d.ts +12 -2
  19. package/dist/components/molecules/Pagination.svelte +209 -0
  20. package/dist/components/molecules/Pagination.svelte.d.ts +22 -0
  21. package/dist/components/molecules/SectionHeader.svelte +233 -0
  22. package/dist/components/molecules/SectionHeader.svelte.d.ts +29 -0
  23. package/dist/components/molecules/ThemePicker.svelte +11 -13
  24. package/dist/index.d.ts +7 -0
  25. package/dist/index.js +7 -0
  26. package/dist/stores/theme.svelte.d.ts +21 -5
  27. package/dist/stores/theme.svelte.js +48 -22
  28. package/dist/styles/app.css +7 -297
  29. package/dist/styles/reset.css +97 -0
  30. package/dist/styles/syntax.css +94 -0
  31. package/dist/styles/themes.css +729 -0
  32. package/dist/styles/tokens.css +207 -0
  33. package/dist/styles/utilities.css +111 -0
  34. package/dist/styles/variables.css +5 -926
  35. package/package.json +7 -2
package/README.md CHANGED
@@ -57,15 +57,91 @@ import { Button, Field, Input, Modal, ThemePicker } from '@dorsk/tsumikit';
57
57
 
58
58
  ## Theming
59
59
 
60
- - 17 themes ship (dark, light, sepia, **colorblind** — Okabe-Ito —, plus mocha,
61
- dracula, nord, tokyonight, gruvbox, solarized, rosepine, onedark, everforest,
62
- monokai, amoled, highcontrast).
63
- - A new theme = one entry in `THEMES` (`stores/theme.svelte.ts`) + one
64
- `[data-theme="id"]` block in `variables.css`. Nothing else changes.
60
+ - 23 themes ship (light, highcontrast, gruvboxlight, solarizedlight,
61
+ everforestlight, rosepinedawn, latte, nordlight, tokyoday, kanagawalotus,
62
+ sepia, dark, **colorblind** — Okabe-Ito —, mocha, dracula, nord, tokyonight,
63
+ gruvbox, solarized, rosepine, onedark, everforest, monokai, amoled).
65
64
  - `<ThemePicker />` and `<FontScalePicker />` wire the stores to the UI. Theme
66
65
  is persisted to `localStorage` and applied with no flash (head snippet in
67
66
  `app.html`) and updates the mobile `<meta name="theme-color">`.
68
67
 
68
+ ### Stylesheets
69
+
70
+ `@dorsk/tsumikit/styles/app.css` is a shell over five files you can import
71
+ individually, in this order:
72
+
73
+ ```css
74
+ @import '@dorsk/tsumikit/styles/tokens.css';
75
+ @import '@dorsk/tsumikit/styles/themes.css'; /* optional */
76
+ @import '@dorsk/tsumikit/styles/reset.css';
77
+ @import '@dorsk/tsumikit/styles/utilities.css';
78
+ @import '@dorsk/tsumikit/styles/syntax.css';
79
+ @import './brand.css';
80
+ ```
81
+
82
+ | export | contents |
83
+ | --- | --- |
84
+ | `styles/tokens.css` | `:root` only — every token the kit reads (`--c-*` palette, `--bg`/`--text`/`--accent` aliases, type scale, spacing, radii, shadows, fonts, `--control-height`, …). Theme-less. |
85
+ | `styles/themes.css` | the built-in `[data-theme="id"]` blocks, one per `THEMES` entry. |
86
+ | `styles/reset.css` | reset + element defaults. |
87
+ | `styles/utilities.css` | `.container`, `.stack`, `.row`, `.sr-only`, icon sizing, … |
88
+ | `styles/syntax.css` | highlight.js / Prism class → `--syn-*` mapping. |
89
+
90
+ `styles/variables.css` = `tokens.css` + `themes.css` (kept for compatibility).
91
+ Nothing is wrapped in `@layer`: kit rules are unlayered so component-scoped
92
+ styles cascade exactly as before, and a consumer stylesheet imported **after**
93
+ the kit wins on source order at equal specificity. Do not put brand overrides
94
+ inside a `@layer` of your own — layered rules lose to the kit's unlayered ones.
95
+
96
+ ### Your own theme, without vendoring
97
+
98
+ ```ts
99
+ // +layout.ts (or any module that runs before first render)
100
+ import { theme } from '@dorsk/tsumikit';
101
+ theme.register({ id: 'kusaritoi', label: 'Kusaritoi', icon: '鎖', themeColor: '#2a2a2a', mode: 'dark' });
102
+ theme.setDefault('kusaritoi');
103
+ ```
104
+
105
+ ```css
106
+ /* brand.css — imported after the kit stylesheet(s) */
107
+ @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap');
108
+ :root { --font-mono: 'JetBrains Mono', ui-monospace, monospace; }
109
+
110
+ [data-theme='kusaritoi'] {
111
+ color-scheme: dark;
112
+ --c-bg: #2a2a2a; --c-bg-elev: #323232; --c-bg-elev-2: #3a3a3a;
113
+ --c-surface: #323232; --c-border: #484848; --c-border-strong: #585858;
114
+ --c-text: #e8e8e8; --c-text-muted: #b0b0b0; --c-text-faint: #808080;
115
+ --c-accent: #5ac8c8; --c-accent-ink: #0d1f1f; --c-accent-dim: #3a8a8a;
116
+ --c-blue: #5a9fd4; --c-amber: #d9a543; --c-red: #e06060;
117
+ --c-green: #6abf69; --c-violet: #b48ef0; --c-gold: #d9a543;
118
+ --c-teal: #5ac8c8;
119
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
120
+ --shadow-md: 0 6px 20px rgba(0, 0, 0, 0.5);
121
+ --shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.6);
122
+ --mach-bg-sl: 45% 24%; --mach-fg-sl: 70% 82%; --mach-border-sl: 45% 40%;
123
+ }
124
+ ```
125
+
126
+ Contract for a `[data-theme='x']` block: all nineteen `--c-*` palette tokens,
127
+ `--shadow-sm|md|lg`, `--mach-bg-sl|fg-sl|border-sl`, and `color-scheme: light`
128
+ for a light theme (`:root` defaults to dark, so dark themes may omit it).
129
+ `--md-code-bg` is optional (derives from `--c-blue`). Everything else (`--bg`,
130
+ `--text`, `--syn-*`, …) is an alias in `tokens.css` and follows automatically.
131
+
132
+ - `theme.register(def | def[])` appends to `theme.all` (built-ins first); an
133
+ entry with a built-in `id` replaces that built-in. `icon` and `themeColor` are
134
+ optional. `ThemePicker` reads `theme.all`, so registered themes appear at once.
135
+ - `theme.setDefault(id)` is the theme used when `localStorage` holds nothing
136
+ valid — set the same id as `data-theme` in your `app.html` so the no-flash
137
+ snippet and the store agree. A persisted id that only becomes valid after
138
+ `register()` is picked up as soon as it is registered.
139
+ - Only the palette or only the fonts? Import `tokens.css` + your `brand.css`
140
+ and skip `themes.css`; or import the full `app.css` and override `:root`
141
+ tokens after it. Never copy the kit files.
142
+ - Adding a built-in theme to the kit = one entry in `THEMES`
143
+ (`stores/theme.svelte.ts`) + one block in `styles/themes.css`.
144
+
69
145
  ## Components
70
146
 
71
147
  **Atoms:** Text, Heading, Button, Input, Textarea, Select, Switch, Checkbox,
@@ -78,7 +154,8 @@ any custom SVG).
78
154
 
79
155
  **Molecules:** Field, IconButton, SelectButton, Toggle, OptionButton, Modal,
80
156
  Popover, Menu, Tabs, RadioGroup, Tooltip, Accordion, CopyButton, FileButton,
81
- Dropzone, CodeBlock, Callout, EmptyState, Toaster, ThemePicker, FontScalePicker.
157
+ Dropzone, CodeBlock, Callout, EmptyState, ConfirmModal, Pagination, Toaster,
158
+ ThemePicker, FontScalePicker, SectionHeader, KeyValue, LoadMore.
82
159
 
83
160
  **Organisms:** DataTable (generic `<T>`, typed columns + cell snippets;
84
161
  `layout="fixed"` makes column widths authoritative, `Column.truncate` /
@@ -113,6 +190,32 @@ edge-to-edge sections — inside AppShell's main column use `size="none"` instea
113
190
  Children can bleed to the column edge with
114
191
  `margin-inline: calc(-1 * var(--container-gutter))`.
115
192
 
193
+ ### ResizablePanel
194
+
195
+ Inline by default: `panel` shares the row with `children` on its `side`, drag the
196
+ edge or use the arrow keys/Home/End on the separator, collapse it with the edge
197
+ chevron; `width`/`minWidth`/`maxWidth` (px numbers or CSS lengths such as
198
+ `'12rem'`) and `widthKey` persist the width. `mode="overlay"` turns it into a
199
+ fixed non-modal drawer (`role="dialog"`) on the viewport edge: `bind:open`,
200
+ `onclose` fires on Escape, scrim click or the edge control, `scrim={false}` drops
201
+ the dim backdrop, `fullWidthBelow="960px"` makes the drawer span the viewport (no
202
+ handle, no scrim) on small screens, and `clampToViewport` (default true) keeps a
203
+ stored width inside a shrunken window. `children` is optional in overlay mode.
204
+
205
+ ```svelte
206
+ <ResizablePanel mode="overlay" side="right" label="Conversation" bind:open
207
+ width={720} minWidth={360} maxWidth="90vw" widthKey="conv-w" fullWidthBelow="960px">
208
+ {#snippet panel()}…{/snippet}
209
+ </ResizablePanel>
210
+ ```
211
+
212
+ `Scrim` (`onclose`, `hideBelow`, `z`, `label`) is the drawer's backdrop atom,
213
+ exported for custom overlays: click or Escape (document-level) calls `onclose`.
214
+ `resizeHandle` is the shared drag action behind every grip: `use:resizeHandle={{
215
+ side, min, max, step, onwidth, oncommit, onreset, onactive, measure }}` gives
216
+ any element pointer-capture + rAF-coalesced dragging, arrow/Home/End keys and
217
+ double-click reset; the width defaults to the element's parent box.
218
+
116
219
  ### Stacked distribution + legend
117
220
 
118
221
  `SegmentedProgress mode="stacked"` turns the bar into one shared track whose slice
@@ -153,6 +256,71 @@ is a live region — `role="status"`, or `role="alert"` when `tone="danger"`.
153
256
  </Callout>
154
257
  ```
155
258
 
259
+ ### Modal, ConfirmModal & Pagination
260
+
261
+ `Modal` opens on mount by default; pass `bind:open` instead to keep it mounted
262
+ and drive `showModal()`/`close()` from state (closing writes `open = false`).
263
+ `tone="danger" | "warn" | "info"` adds a title glyph and a 3px top border;
264
+ `busy` makes the body inert, shows a spinner by the title and disables Escape,
265
+ backdrop and the close button. The `footer` snippet is a right-aligned flex row
266
+ (`justify-content: flex-end; gap: var(--sp-2)`).
267
+
268
+ `ConfirmModal` wraps it as a yes/no dialog: `title`, `message` (or `children`),
269
+ `confirmLabel`/`cancelLabel`, `tone="primary" | "danger" | "warn"`, `busy`,
270
+ `onconfirm`, `oncancel`. An async `onconfirm` keeps the dialog busy until it
271
+ settles, closes only on success and shows a rejection's message (`role="alert"`)
272
+ under the body. `Button` accepts `tone="danger"` as an alias of
273
+ `variant="danger"` so the tone axis works alone.
274
+
275
+ ```svelte
276
+ <ConfirmModal bind:open title="Delete library?" tone="danger" confirmLabel="Delete"
277
+ onconfirm={() => api.deleteLibrary(id)} />
278
+ ```
279
+
280
+ `Pagination` renders `<nav aria-label>` with prev/next IconButtons, numbered
281
+ pages (`aria-current="page"`), ellipses and an optional `showRange` readout.
282
+ Page mode: `bind:page` + `pageCount`. Offset mode: `bind:offset` + `limit` +
283
+ `total` (page and count are derived, `offset` is written back). `onchange(page)`,
284
+ `siblings` (1), `showEdges` (true), `size="sm" | "md"`, `label`. Under 24rem of
285
+ container width it collapses to prev / "3 / 12" / next.
286
+
287
+ ```svelte
288
+ <Pagination bind:offset limit={20} total={412} showRange onchange={load} />
289
+ ```
290
+
291
+ ### SectionHeader, Card header/footer, KeyValue, LoadMore
292
+
293
+ `SectionHeader` is the one "title + meta + right-aligned actions" row:
294
+ `title` (or `label`), `level` 1–4 (default 2), `size`, `subtitle`, `icon`,
295
+ `count` (faint tabular figure after the title), `tone`, `hue` (0–360 swatch
296
+ chip), `uppercase` (eyebrow group label), `divider`, `sticky` (pins at
297
+ `--sticky-offset` / `--header-h` and publishes `--section-header-h` on its
298
+ parent), `collapsible` + `bind:open` (title becomes a disclosure button with
299
+ `aria-expanded`; `children` render beneath while open), `actions` snippet.
300
+
301
+ `Card` gains `header` / `footer` snippets rendered outside the padded body
302
+ behind a divider, `title` / `subtitle` / `actions` sugar that renders a
303
+ `SectionHeader` in the header slot, and `gap` to stack children as a flex
304
+ column. A Card without any of these renders exactly as before.
305
+
306
+ `KeyValue` renders `rows: { label, value: string | number | Snippet, mono?,
307
+ tone?, hint? }[]` as a semantic `<dl>` grid; `columns` 1 | 2, `dense`, `align`
308
+ start | end. `LoadMore` is the tri-state list footer: `state` idle | loading |
309
+ error | done, `onload`, `label`, `loadingLabel`, `errorLabel`, `retryLabel`,
310
+ `doneLabel`, `pill` for the compact "load older" chip.
311
+
312
+ ```svelte
313
+ <Card title="Recent sessions" subtitle="last 24h">
314
+ {#snippet actions()}<Link href="/sessions">View all</Link>{/snippet}
315
+ <KeyValue rows={[{ label: 'Running', value: 3, tone: 'ok' }, { label: 'Host', value: 'sakura', mono: true }]} />
316
+ {#snippet footer()}<LoadMore state={more} onload={loadMore} />{/snippet}
317
+ </Card>
318
+
319
+ <SectionHeader label="Blocked" count={4} uppercase hue={12} collapsible bind:open>
320
+ …group rows…
321
+ </SectionHeader>
322
+ ```
323
+
156
324
  ## Container queries
157
325
 
158
326
  AppShell's `main` and `sidebar` are query containers (`container-name: main` /
@@ -112,7 +112,7 @@
112
112
  class:btn-grow={grow}
113
113
  class:btn-primary={variant === 'primary'}
114
114
  class:btn-ghost={variant === 'ghost'}
115
- class:btn-danger={variant === 'danger'}
115
+ class:btn-danger={variant === 'danger' || (tone === 'danger' && variant === 'default')}
116
116
  class:btn-sm={size === 'sm'}
117
117
  class:btn-lg={size === 'lg'}
118
118
  class:btn-control={control}
@@ -13,7 +13,12 @@
13
13
  // keeps them on the plain border colour. `stackY`/`stackX` set the per-layer
14
14
  // vertical / horizontal offset in px (vertical spacing stays even across the
15
15
  // 3 borders); horizontal defaults to a tiny 2px peek.
16
+ //
17
+ // `header`/`footer` snippets (or the `title`/`subtitle`/`actions` sugar,
18
+ // which renders a SectionHeader) sit outside the padded body behind a
19
+ // divider; `gap` stacks children as a flex column without a wrapper.
16
20
  import type { Snippet } from 'svelte';
21
+ import SectionHeader from '../molecules/SectionHeader.svelte';
17
22
 
18
23
  type Tone = 'neutral' | 'ok' | 'warn' | 'danger' | 'info';
19
24
 
@@ -27,8 +32,14 @@
27
32
  stackTone = 'neutral',
28
33
  stackY = 8,
29
34
  stackX = 2,
35
+ title,
36
+ subtitle,
37
+ gap,
30
38
  class: klass = '',
31
39
  style = '',
40
+ header,
41
+ footer,
42
+ actions,
32
43
  children,
33
44
  ...rest
34
45
  }: {
@@ -41,8 +52,14 @@
41
52
  stackTone?: Tone;
42
53
  stackY?: number;
43
54
  stackX?: number;
55
+ title?: string;
56
+ subtitle?: string;
57
+ gap?: string;
44
58
  class?: string;
45
59
  style?: string;
60
+ header?: Snippet;
61
+ footer?: Snippet;
62
+ actions?: Snippet;
46
63
  children?: Snippet;
47
64
  [key: string]: unknown;
48
65
  } = $props();
@@ -50,6 +67,7 @@
50
67
  let stackStyle = $derived(
51
68
  stacked ? `--stack-y:${stackY}px;--stack-x:${stackX}px;` : ''
52
69
  );
70
+ const framed = $derived(!!(header || footer || title));
53
71
  </script>
54
72
 
55
73
  <svelte:element
@@ -71,18 +89,55 @@
71
89
  class:stack-warn={stacked && stackTone === 'warn'}
72
90
  class:stack-danger={stacked && stackTone === 'danger'}
73
91
  class:stack-info={stacked && stackTone === 'info'}
92
+ class:card-framed={framed}
93
+ class:card-gap={!framed && gap !== undefined}
94
+ style:--card-gap={gap}
74
95
  style={`${stackStyle}${style}`}
75
96
  {...rest}
76
97
  >
77
- {@render children?.()}
98
+ {#if framed}
99
+ {#if title}
100
+ <div class="card-head">
101
+ <SectionHeader {title} {subtitle} {actions} level={3} size="md" />
102
+ </div>
103
+ {:else if header}
104
+ <div class="card-head">{@render header()}</div>
105
+ {/if}
106
+ <div class="card-body" class:card-gap={gap !== undefined}>{@render children?.()}</div>
107
+ {#if footer}
108
+ <div class="card-foot">{@render footer()}</div>
109
+ {/if}
110
+ {:else}
111
+ {@render children?.()}
112
+ {/if}
78
113
  </svelte:element>
79
114
 
80
115
  <style>
81
116
  .card {
117
+ --card-pad: var(--sp-4);
82
118
  background: var(--bg-elevated);
83
119
  border: 1px solid var(--border);
84
120
  border-radius: var(--r-lg);
85
- padding: var(--sp-4);
121
+ padding: var(--card-pad);
122
+ }
123
+ .card-gap {
124
+ display: flex;
125
+ flex-direction: column;
126
+ gap: var(--card-gap);
127
+ }
128
+ .card-framed {
129
+ padding: 0;
130
+ }
131
+ .card-head,
132
+ .card-body,
133
+ .card-foot {
134
+ padding: var(--card-pad);
135
+ }
136
+ .card-head {
137
+ border-bottom: 1px solid var(--border);
138
+ }
139
+ .card-foot {
140
+ border-top: 1px solid var(--border);
86
141
  }
87
142
  /* Theme-aware surface shade, selected by prop so it adapts across themes
88
143
  instead of being overridden with app-level :global hacks. `base` is the
@@ -94,14 +149,22 @@
94
149
  background: var(--bg-elevated-2);
95
150
  }
96
151
  .pad-none {
152
+ --card-pad: 0;
97
153
  padding: 0;
98
154
  }
99
155
  .pad-sm {
156
+ --card-pad: var(--sp-2);
100
157
  padding: var(--sp-2);
101
158
  }
102
159
  .pad-lg {
160
+ --card-pad: var(--sp-6);
103
161
  padding: var(--sp-6);
104
162
  }
163
+ .card-framed.pad-none,
164
+ .card-framed.pad-sm,
165
+ .card-framed.pad-lg {
166
+ padding: 0;
167
+ }
105
168
  .card-tap {
106
169
  cursor: pointer;
107
170
  transition:
@@ -10,8 +10,14 @@ type $$ComponentProps = {
10
10
  stackTone?: Tone;
11
11
  stackY?: number;
12
12
  stackX?: number;
13
+ title?: string;
14
+ subtitle?: string;
15
+ gap?: string;
13
16
  class?: string;
14
17
  style?: string;
18
+ header?: Snippet;
19
+ footer?: Snippet;
20
+ actions?: Snippet;
15
21
  children?: Snippet;
16
22
  [key: string]: unknown;
17
23
  };
@@ -0,0 +1,81 @@
1
+ <script lang="ts">
2
+ import { browser } from '../../env';
3
+
4
+ let {
5
+ onclose,
6
+ hideBelow,
7
+ z = 'var(--z-drawer)',
8
+ label = 'Close'
9
+ }: {
10
+ /** Called on click anywhere on the scrim and on Escape (document-level). */
11
+ onclose?: () => void;
12
+ /** Viewport width (CSS length) under which the scrim is not rendered,
13
+ * for overlays that go full-bleed on small screens. */
14
+ hideBelow?: string;
15
+ /** z-index; defaults to the drawer layer. */
16
+ z?: string | number;
17
+ /** Accessible name of the click target. */
18
+ label?: string;
19
+ } = $props();
20
+
21
+ let hidden = $state(false);
22
+
23
+ $effect(() => {
24
+ if (!browser || !hideBelow) {
25
+ hidden = false;
26
+ return;
27
+ }
28
+ const query = matchMedia(`(max-width: ${hideBelow})`);
29
+ const sync = () => {
30
+ hidden = query.matches;
31
+ };
32
+ sync();
33
+ query.addEventListener('change', sync);
34
+ return () => query.removeEventListener('change', sync);
35
+ });
36
+
37
+ $effect(() => {
38
+ if (!browser) return;
39
+ const onKeydown = (event: KeyboardEvent) => {
40
+ if (event.key !== 'Escape' || event.defaultPrevented) return;
41
+ event.preventDefault();
42
+ onclose?.();
43
+ };
44
+ document.addEventListener('keydown', onKeydown);
45
+ return () => document.removeEventListener('keydown', onKeydown);
46
+ });
47
+ </script>
48
+
49
+ {#if !hidden}
50
+ <button
51
+ type="button"
52
+ class="scrim"
53
+ style:z-index={z}
54
+ aria-label={label}
55
+ tabindex="-1"
56
+ onclick={() => onclose?.()}
57
+ data-tsu="Scrim"
58
+ ></button>
59
+ {/if}
60
+
61
+ <style>
62
+ .scrim {
63
+ position: fixed;
64
+ inset: 0;
65
+ padding: 0;
66
+ border: 0;
67
+ background: color-mix(in srgb, var(--bg) 45%, transparent);
68
+ cursor: default;
69
+ animation: scrim-fade 0.18s var(--ease);
70
+ }
71
+ @keyframes scrim-fade {
72
+ from {
73
+ opacity: 0;
74
+ }
75
+ }
76
+ @media (prefers-reduced-motion: reduce) {
77
+ .scrim {
78
+ animation: none;
79
+ }
80
+ }
81
+ </style>
@@ -0,0 +1,14 @@
1
+ type $$ComponentProps = {
2
+ /** Called on click anywhere on the scrim and on Escape (document-level). */
3
+ onclose?: () => void;
4
+ /** Viewport width (CSS length) under which the scrim is not rendered,
5
+ * for overlays that go full-bleed on small screens. */
6
+ hideBelow?: string;
7
+ /** z-index; defaults to the drawer layer. */
8
+ z?: string | number;
9
+ /** Accessible name of the click target. */
10
+ label?: string;
11
+ };
12
+ declare const Scrim: import("svelte").Component<$$ComponentProps, {}, "">;
13
+ type Scrim = ReturnType<typeof Scrim>;
14
+ export default Scrim;