@spaethtech/svelte-ui 0.3.0 → 0.3.1-dev.10.ff03a8d

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.
@@ -0,0 +1,255 @@
1
+ # Component Reference
2
+
3
+ Complete reference for all svelte-ui components. The exported set is whatever
4
+ `src/lib/index.ts` re-exports — this doc tracks it.
5
+
6
+ Icons are **MDI via `unplugin-icons`** — there is **no `Icon` component**. You render an icon by
7
+ importing an MDI component (`import IconHome from '~icons/mdi/home'`) and passing it into a
8
+ component's `icon` **snippet**. See `docs/usage.md`.
9
+
10
+ ## Cross-cutting axes
11
+
12
+ Most sizeable/themeable components share two props (defined in `types/variants.ts` /
13
+ `types/sizes.ts`):
14
+
15
+ - **`variant`** — color/style: `primary`, `secondary`, `danger`, `info`, `success`, `warning`,
16
+ `ghost`, `plain`. `plain` is borderless/transparent — for dense icon controls.
17
+ - **`size`** — `sm` (24px), `md` (32px, **default**), `lg` (40px). Tied to the theme's
18
+ `--ui-height-sm` / `--ui-height` / `--ui-height-lg`.
19
+
20
+ ## Form Components
21
+
22
+ ### Button
23
+
24
+ Flexible button/anchor component.
25
+
26
+ - **Location**: `src/lib/components/Button.svelte`
27
+ - **Axes**: `variant`, `size`
28
+ - **Props**: `text`, `icon` (snippet), `href` (renders an `<a>`), `disabled`, `onclick`, `title`,
29
+ plus native button/anchor attributes
30
+ - **Features**: icon-only sizing, themed tooltip driven from `title` (via `use:tooltip`),
31
+ TypeScript discriminated union for button-vs-anchor
32
+ - **Accessibility**: ARIA attributes, focus-visible outlines
33
+
34
+ ### Input
35
+
36
+ Text input with an icon slot, trailing actions, and validation.
37
+
38
+ - **Location**: `src/lib/components/Input.svelte`
39
+ - **Axes**: `size`
40
+ - **Props**: `value` (bindable), `icon` (snippet), `iconPosition` (`'left' | 'right'`, default
41
+ `'right'`), `iconClickable`, `onIconClick`, `actions` (snippet — trailing controls inside the
42
+ frame), `validate`, `valid`/`touched` (bindable), plus native input attributes
43
+ - **Note**: a single `icon` snippet positioned by `iconPosition` — there is no
44
+ `iconLeft`/`iconRight`.
45
+
46
+ ### Select
47
+
48
+ Custom dropdown built on `Input` + `List`.
49
+
50
+ - **Location**: `src/lib/components/Select.svelte`
51
+ - **Axes**: `size`
52
+ - **Props**: `options` (`{ value, label, ... }[]`), `value` (bindable), `multiSelect`,
53
+ `placeholder`, `itemSnippet`, plus API props (`url`, `searchParam`, `transform`, `debounceMs`,
54
+ `maxResults`, `headers`, `searchTerm`)
55
+ - **Modes**: static `options` or search-as-you-type against `url`
56
+
57
+ ### List
58
+
59
+ Standalone selectable list (Select's dropdown body).
60
+
61
+ - **Location**: `src/lib/components/List.svelte`
62
+ - **Axes**: `size`
63
+ - **Props**: `options` (`{ value, label, ... }[]`), `value` (bindable), `multiSelect`,
64
+ `showCheckboxes`, `maxVisibleItems`, `itemSnippet`, plus the same API props as `Select`
65
+
66
+ ### TextArea
67
+
68
+ Multi-line text input with optional auto-resize.
69
+
70
+ - **Location**: `src/lib/components/TextArea.svelte`
71
+ - **Axes**: `size`
72
+ - **Props**: `value` (bindable), `minRows`, `maxRows`, `lineHeightRem`, `allowCopy` (built-in copy
73
+ control), `validate`, `valid`/`touched`, plus native textarea attributes
74
+ - **Modes**: fixed height (`minRows === maxRows`) or auto-sizing
75
+
76
+ ### Checkbox
77
+
78
+ Small themed checkbox (native control tinted via `accent-color`).
79
+
80
+ - **Location**: `src/lib/components/Checkbox.svelte`
81
+ - **Axes**: `size`
82
+ - **Props**: `checked` (bindable), `indeterminate`, `disabled`, plus native input attributes
83
+
84
+ ### Rating
85
+
86
+ Read-only star-rating display (5-star, from a 10-point average).
87
+
88
+ - **Location**: `src/lib/components/Rating.svelte`
89
+ - **Props**: `average` (number), `count` (number)
90
+
91
+ ## Specialized Input Components
92
+
93
+ Thin wrappers over `Input`, each preconfigured with an MDI icon (rendered into Input's snippet).
94
+
95
+ ### PasswordInput
96
+
97
+ - **Location**: `src/lib/components/PasswordInput.svelte`
98
+ - **Features**: built-in visibility toggle (eye / eye-off MDI icons)
99
+
100
+ ### EmailInput
101
+
102
+ - **Location**: `src/lib/components/EmailInput.svelte`
103
+ - **Features**: email validation, envelope icon
104
+
105
+ ### SearchInput
106
+
107
+ - **Location**: `src/lib/components/SearchInput.svelte`
108
+ - **Features**: search (magnify) icon, clear button when typing
109
+
110
+ ### NumberInput
111
+
112
+ - **Location**: `src/lib/components/NumberInput.svelte`
113
+ - **Features**: number formatting and validation
114
+
115
+ ## Data Components
116
+
117
+ These pair with the headless **`@spaethtech/svelte-ui/data`** layer (query-language parser/AST, `createGrid`,
118
+ `DataSet`). See `docs/usage.md`.
119
+
120
+ ### DataTable
121
+
122
+ Config-driven, responsive 12-column data table over a `DataGrid`.
123
+
124
+ - **Location**: `src/lib/components/DataTable.svelte`
125
+ - **Props**: `grid` (`DataGrid<T>` from `@spaethtech/svelte-ui/data`), `selectable`, `expandable`, `expanded`
126
+ (snippet), `rowActions` (`(row) => MenuItem[]`), `bulkActions`
127
+ - **Features**: selectable + expandable rows, sortable headers, per-row & bulk action menus
128
+ (via `Menu`/`Popup`), paginated footer. A **compound component** — all controls are
129
+ `<Button variant="plain" size="sm">` / `<Select size="sm">` / `<Checkbox>`.
130
+
131
+ ### Query
132
+
133
+ Filter bar over a `DataSet` — monospace input with `$column` + enum-value autocomplete and a help
134
+ dialog.
135
+
136
+ - **Location**: `src/lib/components/Query.svelte`
137
+ - **Props**: `dataset` (`DataSet`), `placeholder`
138
+ - **Note**: URL sync is intentionally not built in — observe `dataset.applied` and sync yourself.
139
+ Built on `Input` + `Button` + `Popup` + `Dialog`.
140
+
141
+ ## Overlays
142
+
143
+ ### Dialog
144
+
145
+ **Pure modal shell** — the mechanics only, no imposed content. Put a `Card` (or anything) inside via
146
+ `children`. For the common confirm pattern use `ConfirmDialog` (below).
147
+
148
+ - **Location**: `src/lib/components/Dialog.svelte`
149
+ - **Props**: `isOpen` (bindable), `width` (any CSS value — `'80%'`, `'80vw'`, `'400px'`; default
150
+ auto, capped at `min(32rem, …)`), `height` (any CSS value; default auto), `dismissible` (default
151
+ `true`), `onClose`, `class`, `children` (snippet). Extra attributes (e.g. `aria-label`) spread onto
152
+ the panel.
153
+ - **Features**: portals to `<body>`, background scroll-lock (scrollbar-width compensated), backdrop
154
+ + Escape dismiss, **focus trap** (initial focus in, Tab wraps, focus restored on close),
155
+ `role="dialog"` + `aria-modal`.
156
+
157
+ ### ConfirmDialog
158
+
159
+ The common title + message + Confirm/Cancel modal, composed from a `Card` on top of the `Dialog`
160
+ shell.
161
+
162
+ - **Location**: `src/lib/components/ConfirmDialog.svelte`
163
+ - **Props**: `isOpen` (bindable), `title`, `message`, `confirmText`, `cancelText`, `onConfirm`,
164
+ `onCancel`, `variant` (`'normal' | 'danger'`), `size`, `showConfirm`, `showCancel`, `dismissible`,
165
+ `width`/`height` (forwarded to the shell), `children` (snippet — replaces `message` as the body).
166
+
167
+ ### Popup
168
+
169
+ Interactive popover anchored to a trigger, rendered in the browser top layer (Popover API) so it's
170
+ never clipped by overflow/stacking contexts. Placement via the shared `anchored` engine.
171
+
172
+ - **Location**: `src/lib/components/Popup.svelte`
173
+ - **Props**: `anchor` (trigger element), `open` (bindable), `side`, `align`, `boundary`
174
+ (`'viewport'` or an element/selector), `offset`, `matchWidth`, `onclose`, `children` (snippet)
175
+ - **Features**: flips against the boundary, dismisses on Escape + outside pointerdown
176
+
177
+ ### Menu
178
+
179
+ Keyboard-navigable action menu rendered inside a `Popup`.
180
+
181
+ - **Location**: `src/lib/components/Menu.svelte`
182
+ - **Props**: `anchor`, `open` (bindable), `items` (`MenuItem[]` from `@spaethtech/svelte-ui/data`), `side`,
183
+ `align`, `boundary`
184
+ - **Features**: renders all items always and disables the invalid ones; aligns labels when any
185
+ item has an icon
186
+
187
+ ### tooltip (action)
188
+
189
+ Themed tooltips as a Svelte action — `use:tooltip` — built on `anchored`. No global handler.
190
+
191
+ - **Location**: `src/lib/positioning/tooltip.ts`
192
+ - **Options** (`TooltipOptions`): `text` (defaults to the element's `title`, which is then
193
+ suppressed), `side` (default `top`), `align`, `offset`, `delay`, `disabled`
194
+ - **Note**: `Button` feeds this from its `title`, so native `title` tooltips are replaced wherever
195
+ a Button is used. Mirrors text to `aria-label` when the element has no accessible name.
196
+
197
+ ## Positioning
198
+
199
+ ### anchored (engine)
200
+
201
+ Shared placement engine — a Svelte action plus `computePlacement` / `resolveBoundary` — used by
202
+ `Popup`, `Menu`, and `tooltip`.
203
+
204
+ - **Location**: `src/lib/positioning/anchored.ts`
205
+ - **Exports**: `anchored`, `computePlacement`, `resolveBoundary`, and the types `Side`, `Align`,
206
+ `Boundary`, `PlaceOptions`, `Placement`, `AnchoredParams`
207
+
208
+ ## Display / Theme
209
+
210
+ ### Badge
211
+
212
+ Status indicator / label.
213
+
214
+ - **Location**: `src/lib/components/Badge/Badge.svelte`
215
+ - **Axes**: `size`
216
+ - **Variants**: `default`, `primary`, `success`, `warning`, `danger`, `info`
217
+ - **Props**: `text`, `variant`, `size`, `dismissible`, `rounded`, `children`; dispatches `dismiss`
218
+
219
+ ### NotesEditor
220
+
221
+ - **Location**: `src/lib/components/NotesEditor.svelte`
222
+
223
+ ### ThemeSelector
224
+
225
+ Theme switcher (Auto / Light / Dark), built on `Select`.
226
+
227
+ - **Location**: `src/lib/components/ThemeSelector.svelte`
228
+ - **Features**: applies `.theme-light` / `.theme-dark` to `<html>`/`<body>`, `auto` follows the
229
+ system preference, persists to `localStorage` (`svelte-ui-theme`)
230
+
231
+ ## Import Pattern
232
+
233
+ ```typescript
234
+ import { Button, Input, Select, DataTable, tooltip } from "@spaethtech/svelte-ui";
235
+ import { createGrid } from "@spaethtech/svelte-ui/data";
236
+ import "@spaethtech/svelte-ui/theme.css"; // via @import in your app.css
237
+ ```
238
+
239
+ ## Component Structure
240
+
241
+ ### Colocated Components
242
+
243
+ ```
244
+ src/lib/components/ComponentName/
245
+ ├── ComponentName.svelte # Implementation
246
+ ├── ComponentName.spec.md # Specification
247
+ ├── ComponentName.test.ts # Tests
248
+ └── index.ts # Export
249
+ ```
250
+
251
+ ### Simple Components
252
+
253
+ ```
254
+ src/lib/components/ComponentName.svelte
255
+ ```
@@ -0,0 +1,323 @@
1
+ # Demo Page Standards
2
+
3
+ This document defines the unified format for all component demo pages in the svelte-ui library.
4
+ The live demo runs at **http://localhost:5173** (`npm run dev`).
5
+
6
+ ## Current State Analysis
7
+
8
+ ### Consistent Elements Found:
9
+
10
+ - **Back navigation** - Button linking to main page
11
+ - **Theme selector** - ThemeSelector component in header
12
+ - **Component sections** - Grouped examples (variants, sizes, states)
13
+ - **Code examples** - TextArea components showing code snippets
14
+
15
+ ### Inconsistencies Found:
16
+
17
+ - **Import patterns** - Mixed usage of imports
18
+ - **Layout structure** - Different container classes and layouts
19
+ - **Header positioning** - Theme selector and back button placement varies
20
+ - **Section organization** - Inconsistent section naming and ordering
21
+ - **Code formatting** - Different TextArea configurations
22
+ - **Missing elements** - Some pages lack back buttons or theme selectors
23
+
24
+ ## Standard Template
25
+
26
+ All demo pages should follow this structure:
27
+
28
+ ### File Location
29
+
30
+ ```
31
+ src/routes/[component-name]/+page.svelte
32
+ ```
33
+
34
+ ### Standard Template Structure
35
+
36
+ ```svelte
37
+ <script lang="ts">
38
+ // IMPORTS - Use consistent library imports
39
+ import { ComponentName, Button, ThemeSelector, TextArea } from "$lib/index.js";
40
+ // Icons are MDI via unplugin-icons — import the ones this page uses.
41
+ import IconArrowLeft from "~icons/mdi/arrow-left";
42
+
43
+ // DEMO STATE - Component-specific state variables
44
+ let demoState = $state("initial");
45
+
46
+ // DEMO DATA - Static data for examples
47
+ const exampleData = [
48
+ { id: "1", name: "Example 1" },
49
+ { id: "2", name: "Example 2" },
50
+ ];
51
+ </script>
52
+
53
+ <!-- PAGE CONTAINER -->
54
+ <div class="p-8 max-w-4xl mx-auto space-y-8">
55
+ <!-- HEADER -->
56
+ <div class="flex items-center justify-between flex-col sm:flex-row gap-4 mb-6">
57
+ <Button href="/" variant="ghost" text="Back to Components">
58
+ {#snippet icon()}<IconArrowLeft />{/snippet}
59
+ </Button>
60
+ <ThemeSelector />
61
+ </div>
62
+
63
+ <!-- PAGE TITLE -->
64
+ <h1 class="text-3xl font-bold mb-8">ComponentName Component</h1>
65
+
66
+ <!-- SECTION: Basic Usage -->
67
+ <section>
68
+ <h2 class="text-2xl font-semibold mb-4">Basic Usage</h2>
69
+ <div class="mb-6">
70
+ <!-- Example components -->
71
+ <ComponentName prop="value" />
72
+ </div>
73
+
74
+ <TextArea
75
+ value={`import { ComponentName } from '@spaethtech/svelte-ui';
76
+
77
+ <ComponentName prop="value" />`}
78
+ readonly
79
+ textareaClass="font-mono text-sm"
80
+ />
81
+ </section>
82
+
83
+ <!-- SECTION: Variants (if applicable) -->
84
+ <section>
85
+ <h2 class="text-2xl font-semibold mb-4">Variants</h2>
86
+ <div class="flex gap-4 flex-wrap mb-6">
87
+ <ComponentName variant="primary" />
88
+ <ComponentName variant="secondary" />
89
+ </div>
90
+
91
+ <TextArea
92
+ value={`<ComponentName variant="primary" />
93
+ <ComponentName variant="secondary" />`}
94
+ readonly
95
+ textareaClass="font-mono text-sm"
96
+ />
97
+ </section>
98
+
99
+ <!-- SECTION: Sizes (if applicable) -->
100
+ <section>
101
+ <h2 class="text-2xl font-semibold mb-4">Sizes</h2>
102
+ <div class="flex items-center gap-2 mb-6">
103
+ <ComponentName size="sm" />
104
+ <ComponentName size="md" />
105
+ <ComponentName size="lg" />
106
+ </div>
107
+
108
+ <TextArea
109
+ value={`<ComponentName size="sm" />
110
+ <ComponentName size="md" />
111
+ <ComponentName size="lg" />`}
112
+ readonly
113
+ textareaClass="font-mono text-sm"
114
+ />
115
+ </section>
116
+
117
+ <!-- SECTION: Interactive Examples -->
118
+ <section>
119
+ <h2 class="text-2xl font-semibold mb-4">Interactive Examples</h2>
120
+ <div class="mb-6">
121
+ <ComponentName bind:value={demoState} />
122
+ </div>
123
+
124
+ <TextArea
125
+ value={`<script>
126
+ let value = $state('');
127
+ </script>
128
+
129
+ <ComponentName bind:value />`}
130
+ readonly
131
+ textareaClass="font-mono text-sm"
132
+ />
133
+ </section>
134
+
135
+ <!-- SECTION: Advanced Features (if applicable) -->
136
+ <section>
137
+ <h2 class="text-2xl font-semibold mb-4">Advanced Features</h2>
138
+ <div class="mb-6">
139
+ <!-- Advanced examples -->
140
+ </div>
141
+
142
+ <TextArea value={`<!-- Advanced usage code -->`} readonly textareaClass="font-mono text-sm" />
143
+ </section>
144
+ </div>
145
+ ```
146
+
147
+ ## Required Elements
148
+
149
+ ### 1. Container Structure
150
+
151
+ ```svelte
152
+ <div class="p-8 max-w-4xl mx-auto space-y-8">
153
+ ```
154
+
155
+ - **Padding**: `p-8` for consistent spacing
156
+ - **Max width**: `max-w-4xl` for readability
157
+ - **Centering**: `mx-auto` to center content
158
+ - **Spacing**: `space-y-8` between sections
159
+
160
+ ### 2. Header Layout
161
+
162
+ ```svelte
163
+ <div class="flex items-center justify-between flex-col sm:flex-row gap-4 mb-6">
164
+ <Button href="/" variant="ghost" text="Back to Components">
165
+ {#snippet icon()}<IconArrowLeft />{/snippet}
166
+ </Button>
167
+ <ThemeSelector />
168
+ </div>
169
+ ```
170
+
171
+ - **Responsive**: Stacks on mobile (`flex-col sm:flex-row`)
172
+ - **Back button**: Links to main page with consistent styling
173
+ - **Theme selector**: Always in top-right area
174
+
175
+ ### 3. Page Title
176
+
177
+ ```svelte
178
+ <h1 class="text-3xl font-bold mb-8">ComponentName Component</h1>
179
+ ```
180
+
181
+ - **Size**: `text-3xl` for prominence
182
+ - **Weight**: `font-bold` for emphasis
183
+ - **Spacing**: `mb-8` for separation
184
+
185
+ ### 4. Section Structure
186
+
187
+ ```svelte
188
+ <section>
189
+ <h2 class="text-2xl font-semibold mb-4">Section Name</h2>
190
+ <div class="mb-6">
191
+ <!-- Examples -->
192
+ </div>
193
+
194
+ <TextArea value={`code example`} readonly textareaClass="font-mono text-sm" />
195
+ </section>
196
+ ```
197
+
198
+ ### 5. Code Examples
199
+
200
+ - **Always include** corresponding code for each example
201
+ - **Use TextArea** component for code display
202
+ - **Readonly**: Always `readonly`
203
+ - **Styling**: `textareaClass="font-mono text-sm"`
204
+ - **Import format**: Use `'@spaethtech/svelte-ui'` (not internal paths)
205
+
206
+ ## Standard Sections (in order)
207
+
208
+ 1. **Basic Usage** - Simplest implementation
209
+ 2. **Variants** - Different visual styles (if applicable)
210
+ 3. **Sizes** - Different size options (if applicable)
211
+ 4. **States** - Disabled, loading, error states (if applicable)
212
+ 5. **Interactive Examples** - Functional examples with state
213
+ 6. **Advanced Features** - Complex usage patterns
214
+ 7. **Accessibility** - A11y features demonstration (if notable)
215
+
216
+ ## Import Standards
217
+
218
+ ### Consistent Library Imports
219
+
220
+ ```svelte
221
+ import {(ComponentName, Button, ThemeSelector, TextArea)} from '$lib/index.js';
222
+ ```
223
+
224
+ ### MDI Icons (unplugin-icons)
225
+
226
+ Icons are MDI components imported from `~icons/mdi/*` and rendered into a component's `icon`
227
+ snippet — there is no `Icon` component.
228
+
229
+ ```svelte
230
+ import IconArrowLeft from '~icons/mdi/arrow-left'; import IconPencil from '~icons/mdi/pencil';
231
+ ```
232
+
233
+ ### Code Example Imports
234
+
235
+ In TextArea code examples, always show:
236
+
237
+ ```javascript
238
+ import { ComponentName } from "@spaethtech/svelte-ui";
239
+ ```
240
+
241
+ ## Responsive Design
242
+
243
+ ### Container Breakpoints
244
+
245
+ - **Mobile**: Full width with padding
246
+ - **Desktop**: Max-width container centered
247
+
248
+ ### Header Layout
249
+
250
+ - **Mobile**: Stack vertically (back button top, theme selector bottom)
251
+ - **Desktop**: Horizontal layout (back button left, theme selector right)
252
+
253
+ ### Example Layout
254
+
255
+ - **Flex wrapping**: Use `flex-wrap` for button/badge groups
256
+ - **Grid layouts**: Use responsive grids for complex examples
257
+
258
+ ## Code Example Best Practices
259
+
260
+ ### 1. Realistic Examples
261
+
262
+ - Use meaningful prop values
263
+ - Show practical use cases
264
+ - Include realistic data
265
+
266
+ ### 2. Progressive Complexity
267
+
268
+ - Start with simplest usage
269
+ - Build up to more complex examples
270
+ - Show common patterns
271
+
272
+ ### 3. Complete Code Snippets
273
+
274
+ - Include necessary imports
275
+ - Show complete functional examples
276
+ - Include state management when relevant
277
+
278
+ ### 4. Consistent Formatting
279
+
280
+ - Use 2-space indentation
281
+ - Keep lines under 80 characters when possible
282
+ - Use clear prop names
283
+
284
+ ## Component-Specific Guidelines
285
+
286
+ ### Form Components
287
+
288
+ - Show validation examples
289
+ - Demonstrate error states
290
+ - Include accessibility attributes
291
+
292
+ ### Interactive Components
293
+
294
+ - Show event handling
295
+ - Demonstrate state binding
296
+ - Include keyboard navigation
297
+
298
+ ### Layout Components
299
+
300
+ - Show responsive behavior
301
+ - Demonstrate different content types
302
+ - Include slot usage
303
+
304
+ ### Theme Integration
305
+
306
+ - Show theme-aware styling
307
+ - Demonstrate CSS variable usage
308
+ - Include light/dark mode examples
309
+
310
+ ## Quality Checklist
311
+
312
+ Before considering a demo page complete:
313
+
314
+ - [ ] Header with back button and theme selector
315
+ - [ ] Consistent import statements
316
+ - [ ] All major features demonstrated
317
+ - [ ] Code examples for every visual example
318
+ - [ ] Responsive layout tested
319
+ - [ ] Accessibility considerations shown
320
+ - [ ] Error-free TypeScript
321
+ - [ ] Consistent styling and spacing
322
+ - [ ] Realistic example data
323
+ - [ ] Progressive complexity in examples