@marianmeres/stuic 2.5.0 → 2.6.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.
@@ -0,0 +1,192 @@
1
+ # Input
2
+
3
+ A comprehensive form input system with multiple field components, validation support, and flexible layouts.
4
+
5
+ ## Components
6
+
7
+ | Component | Description |
8
+ |-----------|-------------|
9
+ | `FieldInput` | Text, email, password, number, and other input types |
10
+ | `FieldTextarea` | Multi-line text input with auto-grow |
11
+ | `FieldSelect` | Dropdown select with option groups |
12
+ | `FieldCheckbox` | Single checkbox with label |
13
+ | `FieldRadios` | Radio button group |
14
+ | `FieldSwitch` | Toggle switch field |
15
+ | `FieldFile` | File upload input |
16
+ | `FieldAssets` | Asset/image upload with preview |
17
+ | `FieldLikeButton` | Like/favorite toggle button |
18
+ | `Fieldset` | Fieldset with legend |
19
+
20
+ ## Common Props (FieldInput, FieldTextarea, FieldSelect)
21
+
22
+ | Prop | Type | Default | Description |
23
+ |------|------|---------|-------------|
24
+ | `value` | `string \| number` | - | Field value (bindable) |
25
+ | `input` | `HTMLInputElement` | - | Element reference (bindable) |
26
+ | `label` | `Snippet \| THC` | - | Field label |
27
+ | `description` | `Snippet \| THC` | - | Help text below field |
28
+ | `id` | `string` | auto | Element ID |
29
+ | `renderSize` | `"sm" \| "md" \| "lg"` | `"md"` | Visual size |
30
+ | `required` | `boolean` | `false` | Mark as required |
31
+ | `disabled` | `boolean` | `false` | Disable field |
32
+ | `validate` | `boolean \| ValidateOptions` | - | Enable validation |
33
+ | `labelLeft` | `boolean` | `false` | Position label on left |
34
+ | `labelLeftWidth` | `"normal" \| "wide"` | `"normal"` | Left label width |
35
+ | `useTrim` | `boolean` | `true` | Auto-trim whitespace |
36
+ | `class` | `string` | - | Container CSS |
37
+ | `classInput` | `string` | - | Input element CSS |
38
+ | `classLabel` | `string` | - | Label CSS |
39
+
40
+ ## Slot Props
41
+
42
+ | Prop | Type | Description |
43
+ |------|------|-------------|
44
+ | `labelAfter` | `Snippet \| THC` | Content after label |
45
+ | `inputBefore` | `Snippet \| THC` | Content before input (inside wrapper) |
46
+ | `inputAfter` | `Snippet \| THC` | Content after input (inside wrapper) |
47
+ | `inputBelow` | `Snippet \| THC` | Content below input |
48
+ | `below` | `Snippet \| THC` | Content below entire field |
49
+
50
+ ## Usage
51
+
52
+ ### Basic Text Input
53
+
54
+ ```svelte
55
+ <script lang="ts">
56
+ import { FieldInput } from 'stuic';
57
+
58
+ let name = $state('');
59
+ </script>
60
+
61
+ <FieldInput
62
+ label="Name"
63
+ bind:value={name}
64
+ placeholder="Enter your name"
65
+ required
66
+ />
67
+ ```
68
+
69
+ ### With Validation
70
+
71
+ ```svelte
72
+ <FieldInput
73
+ label="Email"
74
+ type="email"
75
+ bind:value={email}
76
+ validate
77
+ required
78
+ />
79
+ ```
80
+
81
+ ### Select Field
82
+
83
+ ```svelte
84
+ <script lang="ts">
85
+ import { FieldSelect } from 'stuic';
86
+
87
+ let country = $state('');
88
+ </script>
89
+
90
+ <FieldSelect
91
+ label="Country"
92
+ bind:value={country}
93
+ options={[
94
+ { label: 'United States', value: 'us' },
95
+ { label: 'Canada', value: 'ca' },
96
+ { label: 'Mexico', value: 'mx' }
97
+ ]}
98
+ />
99
+ ```
100
+
101
+ ### Grouped Select Options
102
+
103
+ ```svelte
104
+ <FieldSelect
105
+ label="City"
106
+ options={[
107
+ { label: 'New York', value: 'ny', optgroup: 'USA' },
108
+ { label: 'Los Angeles', value: 'la', optgroup: 'USA' },
109
+ { label: 'Toronto', value: 'to', optgroup: 'Canada' }
110
+ ]}
111
+ />
112
+ ```
113
+
114
+ ### Textarea with Auto-grow
115
+
116
+ ```svelte
117
+ <script lang="ts">
118
+ import { FieldTextarea } from 'stuic';
119
+
120
+ let message = $state('');
121
+ </script>
122
+
123
+ <FieldTextarea
124
+ label="Message"
125
+ bind:value={message}
126
+ useAutogrow
127
+ rows={3}
128
+ />
129
+ ```
130
+
131
+ ### Checkbox
132
+
133
+ ```svelte
134
+ <script lang="ts">
135
+ import { FieldCheckbox } from 'stuic';
136
+
137
+ let agreed = $state(false);
138
+ </script>
139
+
140
+ <FieldCheckbox
141
+ label="I agree to the terms"
142
+ bind:checked={agreed}
143
+ required
144
+ />
145
+ ```
146
+
147
+ ### Input with Addons
148
+
149
+ ```svelte
150
+ <FieldInput
151
+ label="Price"
152
+ type="number"
153
+ bind:value={price}
154
+ >
155
+ {#snippet inputBefore()}
156
+ <span class="px-3 text-gray-500">$</span>
157
+ {/snippet}
158
+ {#snippet inputAfter()}
159
+ <span class="px-3 text-gray-500">.00</span>
160
+ {/snippet}
161
+ </FieldInput>
162
+ ```
163
+
164
+ ### Left-aligned Label
165
+
166
+ ```svelte
167
+ <FieldInput
168
+ label="Username"
169
+ bind:value={username}
170
+ labelLeft
171
+ labelLeftWidth="wide"
172
+ />
173
+ ```
174
+
175
+ ## Validation
176
+
177
+ Validation is handled by the `validate` action. Pass `validate={true}` for default HTML5 validation, or pass options:
178
+
179
+ ```svelte
180
+ <FieldInput
181
+ label="Custom"
182
+ bind:value={val}
183
+ validate={{
184
+ validatorFn: (el) => {
185
+ if (el.value.length < 3) {
186
+ return { valid: false, message: 'Min 3 characters' };
187
+ }
188
+ return { valid: true };
189
+ }
190
+ }}
191
+ />
192
+ ```
@@ -0,0 +1,81 @@
1
+ # KbdShortcut
2
+
3
+ Display keyboard shortcuts with platform-aware modifier key symbols. Automatically shows the correct symbols for macOS (⌘, ⌥, ⇧) vs Windows/Linux (Win, Ctrl, Alt).
4
+
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `keys` | `string` | - | The key(s) to display (e.g., `"K"`, `"Enter"`) |
10
+ | `metas` | `KnownMeta[]` | `[]` | Array of modifier keys |
11
+ | `forcedOs` | `"mac" \| "win" \| "linux"` | - | Force specific OS symbols |
12
+ | `class` | `string` | - | CSS classes |
13
+
14
+ ## Meta Keys
15
+
16
+ | Meta | macOS | Windows/Linux |
17
+ |------|-------|---------------|
18
+ | `cmd` | ⌘ | ⊞ |
19
+ | `meta` | ⌘ | ⊞ |
20
+ | `win` | ⌘ | ⊞ |
21
+ | `opt` | ⌥ | Alt |
22
+ | `alt` | ⌥ | Alt |
23
+ | `shift` | ⇧ | ⇧ |
24
+ | `ctrl` | ⌃ | Ctrl |
25
+
26
+ ## Usage
27
+
28
+ ### Basic Shortcut
29
+
30
+ ```svelte
31
+ <script lang="ts">
32
+ import { KbdShortcut } from 'stuic';
33
+ </script>
34
+
35
+ <KbdShortcut metas={['cmd']} keys="K" />
36
+ <!-- macOS: ⌘K -->
37
+ <!-- Windows: ⊞K -->
38
+ ```
39
+
40
+ ### Multiple Modifiers
41
+
42
+ ```svelte
43
+ <KbdShortcut metas={['cmd', 'shift']} keys="P" />
44
+ <!-- macOS: ⌘⇧P -->
45
+ <!-- Windows: ⊞⇧P -->
46
+ ```
47
+
48
+ ### Key Only
49
+
50
+ ```svelte
51
+ <KbdShortcut keys="Enter" />
52
+ <!-- Displays: Enter -->
53
+ ```
54
+
55
+ ### Force Specific OS
56
+
57
+ ```svelte
58
+ <KbdShortcut metas={['cmd']} keys="S" forcedOs="mac" />
59
+ <!-- Always shows: ⌘S -->
60
+
61
+ <KbdShortcut metas={['cmd']} keys="S" forcedOs="win" />
62
+ <!-- Always shows: ⊞S -->
63
+ ```
64
+
65
+ ### In Context
66
+
67
+ ```svelte
68
+ <p>
69
+ Press <KbdShortcut metas={['cmd']} keys="K" /> to open search
70
+ </p>
71
+ ```
72
+
73
+ ### Custom Styling
74
+
75
+ ```svelte
76
+ <KbdShortcut
77
+ metas={['cmd', 'shift']}
78
+ keys="Z"
79
+ class="bg-gray-100 px-2 py-1"
80
+ />
81
+ ```
@@ -0,0 +1,117 @@
1
+ # Modal
2
+
3
+ A centered modal dialog with optional header and footer sections. Built on top of `Backdrop` with focus trap and scroll locking.
4
+
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `visible` | `boolean` | `false` | Controls visibility (bindable) |
10
+ | `focusTrap` | `boolean \| FocusTrapOptions` | `true` | Enable focus trapping |
11
+ | `transitionDuration` | `number` | `100` | Fade transition duration (ms) |
12
+ | `onEscape` | `() => void` | - | Callback on Escape key |
13
+ | `noScrollLock` | `boolean` | `false` | Disable body scroll lock |
14
+ | `classBackdrop` | `string` | - | CSS for backdrop overlay |
15
+ | `classInner` | `string` | - | CSS for inner width container |
16
+ | `class` | `string` | - | CSS for modal box |
17
+ | `classHeader` | `string` | - | CSS for header section |
18
+ | `classMain` | `string` | - | CSS for main content |
19
+ | `classFooter` | `string` | - | CSS for footer section |
20
+ | `labelledby` | `string` | - | ARIA labelledby ID |
21
+ | `describedby` | `string` | - | ARIA describedby ID |
22
+ | `el` | `HTMLDivElement` | - | Modal element reference (bindable) |
23
+ | `elBackdrop` | `HTMLDivElement` | - | Backdrop element reference (bindable) |
24
+
25
+ ## Snippets
26
+
27
+ | Snippet | Description |
28
+ |---------|-------------|
29
+ | `header` | Optional header section |
30
+ | `children` | Main modal content |
31
+ | `footer` | Optional footer section |
32
+
33
+ ## Methods
34
+
35
+ | Method | Description |
36
+ |--------|-------------|
37
+ | `open(opener?)` | Open modal, optionally track opener element |
38
+ | `close()` | Close modal |
39
+ | `setOpener(el)` | Set element to refocus when closed |
40
+ | `visibility()` | Returns object with `visible` getter |
41
+
42
+ ## Usage
43
+
44
+ ### Basic Modal
45
+
46
+ ```svelte
47
+ <script lang="ts">
48
+ import { Modal } from 'stuic';
49
+
50
+ let modal: Modal;
51
+ </script>
52
+
53
+ <button onclick={(e) => modal.open(e)}>Open Modal</button>
54
+
55
+ <Modal
56
+ bind:this={modal}
57
+ onEscape={() => modal.close()}
58
+ >
59
+ <div class="p-6">
60
+ <h2>Modal Title</h2>
61
+ <p>Modal content goes here.</p>
62
+ <button onclick={() => modal.close()}>Close</button>
63
+ </div>
64
+ </Modal>
65
+ ```
66
+
67
+ ### With Header and Footer
68
+
69
+ ```svelte
70
+ <Modal bind:this={modal} onEscape={() => modal.close()}>
71
+ {#snippet header()}
72
+ <div class="p-4 border-b">
73
+ <h2>Confirm Action</h2>
74
+ </div>
75
+ {/snippet}
76
+
77
+ <div class="p-6">
78
+ Are you sure you want to proceed?
79
+ </div>
80
+
81
+ {#snippet footer()}
82
+ <div class="p-4 border-t flex justify-end gap-2">
83
+ <button onclick={() => modal.close()}>Cancel</button>
84
+ <button onclick={handleConfirm}>Confirm</button>
85
+ </div>
86
+ {/snippet}
87
+ </Modal>
88
+ ```
89
+
90
+ ### With Visibility Binding
91
+
92
+ ```svelte
93
+ <script lang="ts">
94
+ let visible = $state(false);
95
+ </script>
96
+
97
+ <button onclick={() => visible = true}>Open</button>
98
+
99
+ <Modal
100
+ bind:visible
101
+ onEscape={() => visible = false}
102
+ >
103
+ <div class="p-6">Content</div>
104
+ </Modal>
105
+ ```
106
+
107
+ ### Custom Sizing
108
+
109
+ ```svelte
110
+ <Modal
111
+ bind:this={modal}
112
+ classInner="max-w-lg"
113
+ class="rounded-lg"
114
+ >
115
+ <div class="p-6">Smaller modal</div>
116
+ </Modal>
117
+ ```
@@ -0,0 +1,103 @@
1
+ # ModalDialog
2
+
3
+ A modal component using the native HTML `<dialog>` element with `showModal()`. Provides built-in backdrop, focus management, and accessibility.
4
+
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `noClickOutsideClose` | `boolean` | `false` | Disable close on outside click |
10
+ | `noEscapeClose` | `boolean` | `false` | Disable close on Escape key |
11
+ | `preEscapeClose` | `() => any` | - | Hook before Escape close (return `false` to prevent) |
12
+ | `preClose` | `() => any` | - | Hook before any close (return `false` to prevent) |
13
+ | `type` | `string` | - | Optional UI hint (added as `data-type` attribute) |
14
+ | `class` | `string` | - | CSS for content box |
15
+ | `classDialog` | `string` | - | CSS for dialog element |
16
+
17
+ ## Methods
18
+
19
+ | Method | Description |
20
+ |--------|-------------|
21
+ | `open(opener?)` | Open modal with `showModal()`, optionally track opener |
22
+ | `close()` | Close modal |
23
+ | `setOpener(el)` | Set element to refocus when closed |
24
+
25
+ ## Usage
26
+
27
+ ### Basic Dialog
28
+
29
+ ```svelte
30
+ <script lang="ts">
31
+ import { ModalDialog } from 'stuic';
32
+
33
+ let dialog: ModalDialog;
34
+ </script>
35
+
36
+ <button onclick={(e) => dialog.open(e)}>Open Dialog</button>
37
+
38
+ <ModalDialog bind:this={dialog} class="p-6 rounded-lg max-w-md">
39
+ <h2>Dialog Title</h2>
40
+ <p>This uses the native dialog element.</p>
41
+ <button onclick={() => dialog.close()}>Close</button>
42
+ </ModalDialog>
43
+ ```
44
+
45
+ ### With Pre-close Validation
46
+
47
+ ```svelte
48
+ <script lang="ts">
49
+ let hasUnsavedChanges = $state(false);
50
+ </script>
51
+
52
+ <ModalDialog
53
+ bind:this={dialog}
54
+ preClose={() => {
55
+ if (hasUnsavedChanges) {
56
+ return confirm('Discard unsaved changes?');
57
+ }
58
+ }}
59
+ class="p-6 rounded-lg"
60
+ >
61
+ <form>
62
+ <input oninput={() => hasUnsavedChanges = true} />
63
+ <button type="button" onclick={() => dialog.close()}>Close</button>
64
+ </form>
65
+ </ModalDialog>
66
+ ```
67
+
68
+ ### Prevent Outside Click Close
69
+
70
+ ```svelte
71
+ <ModalDialog
72
+ bind:this={dialog}
73
+ noClickOutsideClose
74
+ class="p-6 rounded-lg"
75
+ >
76
+ <p>Click outside won't close this dialog.</p>
77
+ <button onclick={() => dialog.close()}>Close</button>
78
+ </ModalDialog>
79
+ ```
80
+
81
+ ### Async Pre-close Hook
82
+
83
+ ```svelte
84
+ <ModalDialog
85
+ bind:this={dialog}
86
+ preEscapeClose={async () => {
87
+ const shouldClose = await confirmAction();
88
+ return shouldClose;
89
+ }}
90
+ >
91
+ Content
92
+ </ModalDialog>
93
+ ```
94
+
95
+ ## Differences from Modal
96
+
97
+ | Feature | Modal | ModalDialog |
98
+ |---------|-------|-------------|
99
+ | Implementation | Custom backdrop | Native `<dialog>` |
100
+ | Backdrop | Via `Backdrop` component | Native `::backdrop` |
101
+ | Browser support | All modern | Requires `<dialog>` support |
102
+ | Stacking | Manual z-index | Top layer (always on top) |
103
+ | Accessibility | Manual ARIA | Built-in |
@@ -0,0 +1,144 @@
1
+ # Notifications
2
+
3
+ A toast notification system with auto-disposal, deduplication, progress indicators, and flexible positioning.
4
+
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `notifications` | `NotificationsStack` | - | Stack instance (required) |
10
+ | `posX` | `"left" \| "center" \| "right"` | `"right"` | Horizontal position (desktop) |
11
+ | `posY` | `"top" \| "center" \| "bottom"` | `"top"` | Vertical position (desktop) |
12
+ | `posXMobile` | `"left" \| "center" \| "right"` | `"center"` | Horizontal position (mobile) |
13
+ | `posYMobile` | `"top" \| "center" \| "bottom"` | `"top"` | Vertical position (mobile) |
14
+ | `themeInfo` | `TW_COLORS` | `"neutral"` | Color theme for info notifications |
15
+ | `themeError` | `TW_COLORS` | `"red"` | Color theme for error notifications |
16
+ | `themeWarn` | `TW_COLORS` | `"yellow"` | Color theme for warning notifications |
17
+ | `themeSuccess` | `TW_COLORS` | `"green"` | Color theme for success notifications |
18
+ | `noTheme` | `boolean` | `false` | Disable color theming |
19
+ | `noIcons` | `boolean` | `false` | Hide notification icons |
20
+ | `noProgress` | `boolean` | `false` | Hide TTL progress bar |
21
+ | `noXButton` | `boolean` | `false` | Hide close button |
22
+ | `duration` | `number` | `200` | Fade transition duration (ms) |
23
+ | `forceAsHtml` | `boolean` | - | Render content as HTML |
24
+ | `iconFns` | `Record<type, () => string>` | - | Custom icon functions |
25
+
26
+ ## NotificationsStack API
27
+
28
+ ### Constructor Options
29
+
30
+ | Option | Type | Default | Description |
31
+ |--------|------|---------|-------------|
32
+ | `maxCapacity` | `number` | `5` | Maximum notifications in queue |
33
+ | `defaultTtl` | `number` | `3000` | Default time-to-live (ms) |
34
+ | `extraTtlPerChar` | `number` | `20` | Extra TTL per content character |
35
+ | `sortOrder` | `"asc" \| "desc"` | `"asc"` | Stack sort order |
36
+ | `disposeInterval` | `number` | `500` | Auto-dispose check interval (ms) |
37
+
38
+ ### Methods
39
+
40
+ | Method | Description |
41
+ |--------|-------------|
42
+ | `info(content, opts?)` | Add info notification |
43
+ | `success(content, opts?)` | Add success notification |
44
+ | `warn(content, opts?)` | Add warning notification |
45
+ | `error(content, opts?)` | Add error notification |
46
+ | `removeById(id)` | Remove notification by ID |
47
+ | `reset()` | Clear all notifications |
48
+ | `destroy()` | Cleanup and stop ticker |
49
+
50
+ ### Notification Options
51
+
52
+ | Option | Type | Description |
53
+ |--------|------|-------------|
54
+ | `id` | `string \| number` | Unique ID (auto-generated from content if omitted) |
55
+ | `ttl` | `number` | Time-to-live in ms (0 = no auto-dismiss) |
56
+ | `iconFn` | `(() => string) \| false` | Custom icon or `false` to hide |
57
+ | `forceAsHtml` | `boolean` | Render content as HTML |
58
+
59
+ ## Usage
60
+
61
+ ### Basic Setup
62
+
63
+ ```svelte
64
+ <script lang="ts">
65
+ import { Notifications, NotificationsStack } from 'stuic';
66
+
67
+ const notifications = new NotificationsStack();
68
+ </script>
69
+
70
+ <Notifications {notifications} />
71
+
72
+ <button onclick={() => notifications.info('Hello!')}>
73
+ Show Info
74
+ </button>
75
+ ```
76
+
77
+ ### Different Types
78
+
79
+ ```svelte
80
+ <script lang="ts">
81
+ notifications.info('Information message');
82
+ notifications.success('Operation successful!');
83
+ notifications.warn('Warning: check this');
84
+ notifications.error('An error occurred');
85
+ </script>
86
+ ```
87
+
88
+ ### Custom TTL
89
+
90
+ ```svelte
91
+ <script lang="ts">
92
+ // Auto-dismiss after 10 seconds
93
+ notifications.info('Long message', { ttl: 10000 });
94
+
95
+ // Never auto-dismiss
96
+ notifications.error('Critical error', { ttl: 0 });
97
+ </script>
98
+ ```
99
+
100
+ ### Deduplication
101
+
102
+ ```svelte
103
+ <script lang="ts">
104
+ // Same content = same ID = increments count instead of duplicating
105
+ notifications.info('Save completed');
106
+ notifications.info('Save completed'); // Shows "2" badge
107
+ </script>
108
+ ```
109
+
110
+ ### Custom Positioning
111
+
112
+ ```svelte
113
+ <Notifications
114
+ {notifications}
115
+ posX="left"
116
+ posY="bottom"
117
+ posXMobile="center"
118
+ posYMobile="bottom"
119
+ />
120
+ ```
121
+
122
+ ### Custom Stack Options
123
+
124
+ ```svelte
125
+ <script lang="ts">
126
+ const notifications = new NotificationsStack([], {
127
+ maxCapacity: 3,
128
+ defaultTtl: 5000,
129
+ sortOrder: 'desc'
130
+ });
131
+ </script>
132
+ ```
133
+
134
+ ## Cleanup
135
+
136
+ ```svelte
137
+ <script lang="ts">
138
+ import { onDestroy } from 'svelte';
139
+
140
+ const notifications = new NotificationsStack();
141
+
142
+ onDestroy(() => notifications.destroy());
143
+ </script>
144
+ ```
@@ -0,0 +1,71 @@
1
+ # Progress
2
+
3
+ A progress indicator available as either a horizontal bar or circular display.
4
+
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `type` | `"bar" \| "circle"` | `"bar"` | Display type |
10
+ | `progress` | `number` | `0` | Progress value (0-100) |
11
+ | `class` | `string` | - | CSS for container |
12
+ | `classBar` | `string` | - | CSS for progress bar fill (bar type only) |
13
+ | `styleBar` | `string` | - | Inline styles for bar fill |
14
+
15
+ ## Usage
16
+
17
+ ### Basic Bar
18
+
19
+ ```svelte
20
+ <script lang="ts">
21
+ import { Progress } from 'stuic';
22
+
23
+ let progress = $state(0);
24
+ </script>
25
+
26
+ <Progress {progress} />
27
+ ```
28
+
29
+ ### Circle Progress
30
+
31
+ ```svelte
32
+ <Progress type="circle" progress={75} class="size-16" />
33
+ ```
34
+
35
+ ### Animated Progress
36
+
37
+ ```svelte
38
+ <script lang="ts">
39
+ let progress = $state(0);
40
+
41
+ function start() {
42
+ progress = 0;
43
+ const interval = setInterval(() => {
44
+ progress += 10;
45
+ if (progress >= 100) clearInterval(interval);
46
+ }, 300);
47
+ }
48
+ </script>
49
+
50
+ <Progress {progress} />
51
+ <button onclick={start}>Start</button>
52
+ ```
53
+
54
+ ### Custom Styling
55
+
56
+ ```svelte
57
+ <Progress
58
+ progress={60}
59
+ class="h-2 bg-gray-200 rounded-full"
60
+ classBar="bg-blue-500 rounded-full"
61
+ />
62
+ ```
63
+
64
+ ### With Transition
65
+
66
+ ```svelte
67
+ <Progress
68
+ progress={value}
69
+ classBar="transition-all duration-300"
70
+ />
71
+ ```