@marianmeres/stuic 2.66.0 → 3.0.1

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 (208) hide show
  1. package/README.md +292 -4
  2. package/dist/README.md +41 -18
  3. package/dist/actions/index.d.ts +1 -0
  4. package/dist/actions/index.js +1 -0
  5. package/dist/actions/popover/README.md +19 -0
  6. package/dist/actions/popover/index.css +6 -9
  7. package/dist/actions/popover/popover.svelte.js +2 -2
  8. package/dist/actions/tooltip/README.md +18 -0
  9. package/dist/actions/tooltip/index.css +5 -8
  10. package/dist/actions/tooltip/tooltip.svelte.js +1 -1
  11. package/dist/actions/typeahead.svelte.d.ts +53 -0
  12. package/dist/actions/typeahead.svelte.js +328 -0
  13. package/dist/base.css +17 -0
  14. package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte +10 -10
  15. package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte.d.ts +4 -3
  16. package/dist/components/AlertConfirmPrompt/Current.svelte +15 -18
  17. package/dist/components/AlertConfirmPrompt/Current.svelte.d.ts +4 -3
  18. package/dist/components/AlertConfirmPrompt/acp-icons.js +5 -4
  19. package/dist/components/AlertConfirmPrompt/index.css +66 -0
  20. package/dist/components/AssetsPreview/AssetsPreview.svelte +91 -73
  21. package/dist/components/AssetsPreview/index.css +61 -0
  22. package/dist/components/Avatar/Avatar.svelte +31 -18
  23. package/dist/components/Avatar/README.md +166 -0
  24. package/dist/components/Avatar/index.css +130 -0
  25. package/dist/components/Backdrop/Backdrop.svelte +7 -2
  26. package/dist/components/Backdrop/README.md +71 -6
  27. package/dist/components/Backdrop/index.css +31 -0
  28. package/dist/components/Button/Button.svelte +116 -124
  29. package/dist/components/Button/Button.svelte.d.ts +35 -24
  30. package/dist/components/Button/README.md +87 -21
  31. package/dist/components/Button/index.css +475 -9
  32. package/dist/components/Button/index.d.ts +1 -1
  33. package/dist/components/Button/index.js +1 -1
  34. package/dist/components/ButtonGroupRadio/ButtonGroupRadio.svelte +7 -39
  35. package/dist/components/ButtonGroupRadio/ButtonGroupRadio.svelte.d.ts +0 -1
  36. package/dist/components/ButtonGroupRadio/README.md +82 -4
  37. package/dist/components/ButtonGroupRadio/index.css +158 -14
  38. package/dist/components/Collapsible/Collapsible.svelte +7 -7
  39. package/dist/components/Collapsible/Collapsible.svelte.d.ts +2 -2
  40. package/dist/components/Collapsible/README.md +34 -2
  41. package/dist/components/Collapsible/index.css +40 -0
  42. package/dist/components/CommandMenu/CommandMenu.svelte +18 -26
  43. package/dist/components/CommandMenu/CommandMenu.svelte.d.ts +0 -1
  44. package/dist/components/CommandMenu/README.md +39 -0
  45. package/dist/components/CommandMenu/index.css +47 -2
  46. package/dist/components/DismissibleMessage/DismissibleMessage.svelte +53 -51
  47. package/dist/components/DismissibleMessage/DismissibleMessage.svelte.d.ts +6 -6
  48. package/dist/components/DismissibleMessage/README.md +93 -11
  49. package/dist/components/DismissibleMessage/index.css +128 -8
  50. package/dist/components/DismissibleMessage/index.d.ts +1 -1
  51. package/dist/components/DropdownMenu/DropdownMenu.svelte +14 -51
  52. package/dist/components/DropdownMenu/DropdownMenu.svelte.d.ts +6 -7
  53. package/dist/components/DropdownMenu/README.md +132 -0
  54. package/dist/components/DropdownMenu/index.css +258 -52
  55. package/dist/components/Input/FieldAssets.svelte +8 -5
  56. package/dist/components/Input/FieldCheckbox.svelte +7 -44
  57. package/dist/components/Input/FieldFile.svelte +1 -6
  58. package/dist/components/Input/FieldInput.svelte +9 -1
  59. package/dist/components/Input/FieldInput.svelte.d.ts +2 -0
  60. package/dist/components/Input/FieldOptions.svelte +42 -39
  61. package/dist/components/Input/FieldRadios.svelte +7 -16
  62. package/dist/components/Input/FieldSelect.svelte +1 -1
  63. package/dist/components/Input/FieldSwitch.svelte +1 -5
  64. package/dist/components/Input/FieldTextarea.svelte +1 -1
  65. package/dist/components/Input/README.md +194 -0
  66. package/dist/components/Input/_internal/FieldRadioInternal.svelte +2 -40
  67. package/dist/components/Input/_internal/InputWrap.svelte +8 -48
  68. package/dist/components/Input/index.css +524 -116
  69. package/dist/components/KbdShortcut/KbdShortcut.svelte +4 -12
  70. package/dist/components/KbdShortcut/README.md +34 -0
  71. package/dist/components/KbdShortcut/index.css +55 -0
  72. package/dist/components/ListItemButton/ListItemButton.svelte +37 -74
  73. package/dist/components/ListItemButton/ListItemButton.svelte.d.ts +1 -10
  74. package/dist/components/ListItemButton/README.md +100 -45
  75. package/dist/components/ListItemButton/index.css +173 -52
  76. package/dist/components/ListItemButton/index.d.ts +1 -1
  77. package/dist/components/ListItemButton/index.js +1 -1
  78. package/dist/components/Modal/Modal.svelte +1 -8
  79. package/dist/components/Modal/README.md +29 -0
  80. package/dist/components/Modal/index.css +38 -0
  81. package/dist/components/ModalDialog/ModalDialog.svelte +2 -21
  82. package/dist/components/ModalDialog/README.md +35 -0
  83. package/dist/components/ModalDialog/index.css +59 -0
  84. package/dist/components/Nav/Nav.svelte +732 -0
  85. package/dist/components/Nav/Nav.svelte.d.ts +110 -0
  86. package/dist/components/Nav/README.md +334 -0
  87. package/dist/components/Nav/index.css +318 -0
  88. package/dist/components/Nav/index.d.ts +1 -0
  89. package/dist/components/Nav/index.js +1 -0
  90. package/dist/components/Notifications/Notifications.svelte +44 -129
  91. package/dist/components/Notifications/Notifications.svelte.d.ts +9 -18
  92. package/dist/components/Notifications/README.md +186 -70
  93. package/dist/components/Notifications/index.css +212 -15
  94. package/dist/components/Notifications/notifications-stack.svelte.d.ts +4 -0
  95. package/dist/components/Notifications/notifications-stack.svelte.js +8 -0
  96. package/dist/components/Progress/Progress.svelte +4 -2
  97. package/dist/components/Progress/Progress.svelte.d.ts +1 -0
  98. package/dist/components/Progress/README.md +97 -11
  99. package/dist/components/Progress/_internal/Bar.svelte +4 -15
  100. package/dist/components/Progress/_internal/Bar.svelte.d.ts +1 -1
  101. package/dist/components/Progress/_internal/Circle.svelte +30 -2
  102. package/dist/components/Progress/_internal/Circle.svelte.d.ts +1 -0
  103. package/dist/components/Progress/index.css +50 -4
  104. package/dist/components/Skeleton/README.md +152 -0
  105. package/dist/components/Skeleton/Skeleton.svelte +9 -9
  106. package/dist/components/Skeleton/Skeleton.svelte.d.ts +0 -1
  107. package/dist/components/Skeleton/index.css +72 -45
  108. package/dist/components/Spinner/README.md +149 -37
  109. package/dist/components/Spinner/Spinner.svelte +14 -38
  110. package/dist/components/Spinner/Spinner.svelte.d.ts +2 -1
  111. package/dist/components/Spinner/SpinnerCircle.svelte +6 -34
  112. package/dist/components/Spinner/SpinnerCircle.svelte.d.ts +1 -0
  113. package/dist/components/Spinner/SpinnerCircleOscillate.svelte +10 -5
  114. package/dist/components/Spinner/SpinnerUnicode.svelte +3 -1
  115. package/dist/components/Spinner/SpinnerUnicode.svelte.d.ts +1 -0
  116. package/dist/components/Spinner/index.css +104 -0
  117. package/dist/components/Switch/README.md +45 -14
  118. package/dist/components/Switch/Switch.svelte +23 -48
  119. package/dist/components/Switch/Switch.svelte.d.ts +4 -2
  120. package/dist/components/Switch/index.css +121 -4
  121. package/dist/components/Switch/index.d.ts +1 -2
  122. package/dist/components/Switch/index.js +1 -2
  123. package/dist/components/TabbedMenu/README.md +37 -21
  124. package/dist/components/TabbedMenu/TabbedMenu.svelte +5 -46
  125. package/dist/components/TabbedMenu/TabbedMenu.svelte.d.ts +0 -1
  126. package/dist/components/TabbedMenu/index.css +84 -17
  127. package/dist/components/ThemePreview/README.md +289 -0
  128. package/dist/components/ThemePreview/ThemePreview.svelte +394 -0
  129. package/dist/components/ThemePreview/ThemePreview.svelte.d.ts +35 -0
  130. package/dist/components/ThemePreview/index.css +509 -0
  131. package/dist/components/ThemePreview/index.d.ts +1 -0
  132. package/dist/components/ThemePreview/index.js +1 -0
  133. package/dist/components/TwCheck/README.md +32 -13
  134. package/dist/components/TwCheck/TwCheck.svelte +11 -9
  135. package/dist/components/TwCheck/TwCheck.svelte.d.ts +0 -1
  136. package/dist/components/TwCheck/index.css +17 -2
  137. package/dist/components/TypeaheadInput/TypeaheadInput.svelte +20 -188
  138. package/dist/components/TypeaheadInput/TypeaheadInput.svelte.d.ts +4 -2
  139. package/dist/components/X/X.svelte +12 -5
  140. package/dist/components/X/X.svelte.d.ts +1 -0
  141. package/dist/icons/index.d.ts +1 -0
  142. package/dist/icons/index.js +1 -0
  143. package/dist/index.css +46 -26
  144. package/dist/index.d.ts +2 -0
  145. package/dist/index.js +2 -0
  146. package/dist/themes/blue-orange.css +217 -0
  147. package/dist/themes/blue-orange.d.ts +6 -0
  148. package/dist/themes/blue-orange.js +175 -0
  149. package/dist/themes/cyan-red.css +217 -0
  150. package/dist/themes/cyan-red.d.ts +6 -0
  151. package/dist/themes/cyan-red.js +175 -0
  152. package/dist/themes/cyan-slate.css +217 -0
  153. package/dist/themes/cyan-slate.d.ts +6 -0
  154. package/dist/themes/cyan-slate.js +175 -0
  155. package/dist/themes/emerald-pink.css +217 -0
  156. package/dist/themes/emerald-pink.d.ts +6 -0
  157. package/dist/themes/emerald-pink.js +175 -0
  158. package/dist/themes/fuchsia-emerald.css +217 -0
  159. package/dist/themes/fuchsia-emerald.d.ts +6 -0
  160. package/dist/themes/fuchsia-emerald.js +175 -0
  161. package/dist/themes/gray.css +217 -0
  162. package/dist/themes/gray.d.ts +6 -0
  163. package/dist/themes/gray.js +175 -0
  164. package/dist/themes/indigo-amber.css +217 -0
  165. package/dist/themes/indigo-amber.d.ts +6 -0
  166. package/dist/themes/indigo-amber.js +175 -0
  167. package/dist/themes/neutral.css +217 -0
  168. package/dist/themes/neutral.d.ts +6 -0
  169. package/dist/themes/neutral.js +175 -0
  170. package/dist/themes/pink-emerald.css +217 -0
  171. package/dist/themes/pink-emerald.d.ts +6 -0
  172. package/dist/themes/pink-emerald.js +175 -0
  173. package/dist/themes/purple-yellow.css +217 -0
  174. package/dist/themes/purple-yellow.d.ts +6 -0
  175. package/dist/themes/purple-yellow.js +175 -0
  176. package/dist/themes/rainbow.css +217 -0
  177. package/dist/themes/rainbow.d.ts +6 -0
  178. package/dist/themes/rainbow.js +180 -0
  179. package/dist/themes/red-blue.css +217 -0
  180. package/dist/themes/red-blue.d.ts +6 -0
  181. package/dist/themes/red-blue.js +175 -0
  182. package/dist/themes/red-cyan.css +217 -0
  183. package/dist/themes/red-cyan.d.ts +6 -0
  184. package/dist/themes/red-cyan.js +175 -0
  185. package/dist/themes/rose-teal.css +217 -0
  186. package/dist/themes/rose-teal.d.ts +6 -0
  187. package/dist/themes/rose-teal.js +175 -0
  188. package/dist/themes/sky-amber.css +217 -0
  189. package/dist/themes/sky-amber.d.ts +6 -0
  190. package/dist/themes/sky-amber.js +175 -0
  191. package/dist/themes/slate-cyan.css +217 -0
  192. package/dist/themes/slate-cyan.d.ts +6 -0
  193. package/dist/themes/slate-cyan.js +175 -0
  194. package/dist/themes/tailwind-color-pairs.md +31 -0
  195. package/dist/themes/teal-rose.css +217 -0
  196. package/dist/themes/teal-rose.d.ts +6 -0
  197. package/dist/themes/teal-rose.js +175 -0
  198. package/dist/themes/violet-lime.css +217 -0
  199. package/dist/themes/violet-lime.d.ts +6 -0
  200. package/dist/themes/violet-lime.js +175 -0
  201. package/dist/utils/design-tokens.d.ts +43 -0
  202. package/dist/utils/design-tokens.js +127 -0
  203. package/dist/utils/index.d.ts +1 -0
  204. package/dist/utils/index.js +1 -0
  205. package/dist/utils/storage-abstraction.js +1 -1
  206. package/package.json +14 -11
  207. package/dist/components/Switch/SwitchButton.svelte +0 -135
  208. package/dist/components/Switch/SwitchButton.svelte.d.ts +0 -21
@@ -1,60 +1,6 @@
1
1
  # Notifications
2
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 |
3
+ A toast notification system with automatic stacking, progress indicators, and type-based theming using design tokens.
58
4
 
59
5
  ## Usage
60
6
 
@@ -62,7 +8,7 @@ A toast notification system with auto-disposal, deduplication, progress indicato
62
8
 
63
9
  ```svelte
64
10
  <script lang="ts">
65
- import { Notifications, NotificationsStack } from 'stuic';
11
+ import { Notifications, NotificationsStack } from '@marianmeres/stuic';
66
12
 
67
13
  const notifications = new NotificationsStack();
68
14
  </script>
@@ -70,11 +16,11 @@ A toast notification system with auto-disposal, deduplication, progress indicato
70
16
  <Notifications {notifications} />
71
17
 
72
18
  <button onclick={() => notifications.info('Hello!')}>
73
- Show Info
19
+ Show notification
74
20
  </button>
75
21
  ```
76
22
 
77
- ### Different Types
23
+ ### Notification Types
78
24
 
79
25
  ```svelte
80
26
  <script lang="ts">
@@ -85,14 +31,14 @@ A toast notification system with auto-disposal, deduplication, progress indicato
85
31
  </script>
86
32
  ```
87
33
 
88
- ### Custom TTL
34
+ ### Custom TTL (Time to Live)
89
35
 
90
36
  ```svelte
91
37
  <script lang="ts">
92
38
  // Auto-dismiss after 10 seconds
93
- notifications.info('Long message', { ttl: 10000 });
39
+ notifications.info('Long notification', { ttl: 10000 });
94
40
 
95
- // Never auto-dismiss
41
+ // No auto-dismiss (sticky)
96
42
  notifications.error('Critical error', { ttl: 0 });
97
43
  </script>
98
44
  ```
@@ -107,30 +53,193 @@ A toast notification system with auto-disposal, deduplication, progress indicato
107
53
  </script>
108
54
  ```
109
55
 
110
- ### Custom Positioning
56
+ ### Positioning
111
57
 
112
58
  ```svelte
59
+ <!-- Top right (default) -->
60
+ <Notifications {notifications} />
61
+
62
+ <!-- Bottom center -->
63
+ <Notifications {notifications} posX="center" posY="bottom" />
64
+
65
+ <!-- Different positions for mobile vs desktop -->
113
66
  <Notifications
114
67
  {notifications}
115
- posX="left"
116
- posY="bottom"
68
+ posX="right"
117
69
  posXMobile="center"
70
+ posY="top"
118
71
  posYMobile="bottom"
119
72
  />
120
73
  ```
121
74
 
122
- ### Custom Stack Options
75
+ ### Without Icons or Progress
76
+
77
+ ```svelte
78
+ <Notifications {notifications} noIcons />
79
+ <Notifications {notifications} noProgress />
80
+ <Notifications {notifications} noXButton />
81
+ ```
82
+
83
+ ### Custom Icons
123
84
 
124
85
  ```svelte
125
86
  <script lang="ts">
126
- const notifications = new NotificationsStack([], {
127
- maxCapacity: 3,
128
- defaultTtl: 5000,
129
- sortOrder: 'desc'
130
- });
87
+ const customIcons = {
88
+ info: () => '<svg>...</svg>',
89
+ success: () => '<svg>...</svg>',
90
+ warn: () => '<svg>...</svg>',
91
+ error: () => '<svg>...</svg>',
92
+ };
131
93
  </script>
94
+
95
+ <Notifications {notifications} iconFns={customIcons} />
132
96
  ```
133
97
 
98
+ ## Props
99
+
100
+ | Prop | Type | Default | Description |
101
+ |------|------|---------|-------------|
102
+ | `notifications` | `NotificationsStack` | required | The notifications stack instance |
103
+ | `posX` | `"left" \| "center" \| "right"` | `"right"` | Horizontal position (desktop) |
104
+ | `posXMobile` | `"left" \| "center" \| "right"` | `"center"` | Horizontal position (mobile) |
105
+ | `posY` | `"top" \| "center" \| "bottom"` | `"top"` | Vertical position (desktop) |
106
+ | `posYMobile` | `"top" \| "center" \| "bottom"` | `"top"` | Vertical position (mobile) |
107
+ | `noIcons` | `boolean` | `false` | Hide notification icons |
108
+ | `noProgress` | `boolean` | `false` | Hide TTL progress bar |
109
+ | `noXButton` | `boolean` | `false` | Hide close button |
110
+ | `forceAsHtml` | `boolean` | `false` | Render content as HTML |
111
+ | `ariaCloseLabel` | `string` | `"Close"` | Accessibility label for close button |
112
+ | `duration` | `number` | `200` | Fade transition duration (ms) |
113
+ | `iconFns` | `Record<type, () => string>` | - | Custom icon render functions |
114
+ | `class` | `string` | - | Additional CSS classes for notification box |
115
+ | `classWrapX` | `string` | - | Additional CSS classes for horizontal wrapper |
116
+ | `classWrapY` | `string` | - | Additional CSS classes for vertical wrapper |
117
+ | `classNotifCount` | `string` | - | Additional CSS classes for count badge |
118
+ | `classNotifIcon` | `string` | - | Additional CSS classes for icon |
119
+ | `classNotifContent` | `string` | - | Additional CSS classes for content |
120
+ | `classProgress` | `string` | - | Additional CSS classes for progress container |
121
+ | `classProgressBar` | `string` | - | Additional CSS classes for progress bar |
122
+ | `el` | `HTMLDivElement` | - | Bindable element reference |
123
+
124
+ ## CSS Variables
125
+
126
+ ### Component Tokens
127
+
128
+ Override globally in `:root` or locally via `style` attribute:
129
+
130
+ ```css
131
+ :root {
132
+ /* Layout */
133
+ --stuic-notification-max-width: var(--container-sm); /* 24rem */
134
+ --stuic-notification-radius: var(--radius-lg); /* 0.5rem */
135
+ --stuic-notification-padding-x: calc(var(--spacing) * 4); /* 1rem */
136
+ --stuic-notification-padding-y: calc(var(--spacing) * 3); /* 0.75rem */
137
+ --stuic-notification-gap: calc(var(--spacing) * 4); /* 1rem */
138
+
139
+ /* Typography */
140
+ --stuic-notification-font-size: var(--text-sm);
141
+
142
+ /* Animation */
143
+ --stuic-notification-transition: 200ms;
144
+
145
+ /* Shadow */
146
+ --stuic-notification-shadow: var(--shadow-lg);
147
+
148
+ /* Icon */
149
+ --stuic-notification-icon-size: calc(var(--spacing) * 6); /* 1.5rem */
150
+
151
+ /* Counter badge */
152
+ --stuic-notification-badge-font-size: var(--text-xs);
153
+ --stuic-notification-badge-padding-x: calc(var(--spacing) * 2);
154
+ --stuic-notification-badge-padding-y: calc(var(--spacing) * 1);
155
+ --stuic-notification-badge-radius: 9999px;
156
+ --stuic-notification-badge-bg: var(--color-neutral-950);
157
+ --stuic-notification-badge-text: var(--color-neutral-50);
158
+
159
+ /* Progress bar */
160
+ --stuic-notification-progress-opacity: 0.1;
161
+ }
162
+ ```
163
+
164
+ ### Example Override
165
+
166
+ ```css
167
+ /* Make notifications more compact */
168
+ :root {
169
+ --stuic-notification-padding-x: calc(var(--spacing) * 3);
170
+ --stuic-notification-padding-y: calc(var(--spacing) * 2);
171
+ --stuic-notification-radius: var(--radius-md);
172
+ }
173
+ ```
174
+
175
+ ```svelte
176
+ <!-- Local override -->
177
+ <Notifications
178
+ {notifications}
179
+ style="--stuic-notification-radius: 9999px;"
180
+ />
181
+ ```
182
+
183
+ ### Type Colors
184
+
185
+ Notification types use the global STUIC design tokens:
186
+
187
+ | Type | Background | Foreground | Border |
188
+ |------|------------|------------|--------|
189
+ | `info` | `--stuic-color-info` | `--stuic-color-info-foreground` | `--stuic-color-info-hover` |
190
+ | `success` | `--stuic-color-success` | `--stuic-color-success-foreground` | `--stuic-color-success-hover` |
191
+ | `warn` | `--stuic-color-warning` | `--stuic-color-warning-foreground` | `--stuic-color-warning-hover` |
192
+ | `error` | `--stuic-color-destructive` | `--stuic-color-destructive-foreground` | `--stuic-color-destructive-hover` |
193
+
194
+ To customize type colors, override the global intent tokens:
195
+
196
+ ```css
197
+ :root {
198
+ --stuic-color-info: var(--color-blue-600);
199
+ --stuic-color-info-foreground: var(--color-white);
200
+ --stuic-color-info-hover: var(--color-blue-700);
201
+ }
202
+ ```
203
+
204
+ ## Data Attributes
205
+
206
+ The notification box uses data attributes for type-based styling:
207
+
208
+ - `data-type` - The notification type (`info`, `success`, `warn`, `error`)
209
+
210
+ ## NotificationsStack API
211
+
212
+ ### Constructor Options
213
+
214
+ | Option | Type | Default | Description |
215
+ |--------|------|---------|-------------|
216
+ | `maxCapacity` | `number` | `5` | Maximum notifications in queue |
217
+ | `defaultTtl` | `number` | `3000` | Default time-to-live (ms) |
218
+ | `extraTtlPerChar` | `number` | `20` | Extra TTL per content character |
219
+ | `sortOrder` | `"asc" \| "desc"` | `"asc"` | Stack sort order |
220
+ | `disposeInterval` | `number` | `500` | Auto-dispose check interval (ms) |
221
+
222
+ ### Methods
223
+
224
+ | Method | Description |
225
+ |--------|-------------|
226
+ | `info(content, opts?)` | Add info notification |
227
+ | `success(content, opts?)` | Add success notification |
228
+ | `warn(content, opts?)` | Add warning notification |
229
+ | `error(content, opts?)` | Add error notification |
230
+ | `removeById(id)` | Remove notification by ID |
231
+ | `reset()` | Clear all notifications |
232
+ | `destroy()` | Cleanup and stop ticker |
233
+
234
+ ### Notification Options
235
+
236
+ | Option | Type | Description |
237
+ |--------|------|-------------|
238
+ | `id` | `string \| number` | Unique ID (auto-generated from content if omitted) |
239
+ | `ttl` | `number` | Time-to-live in ms (0 = no auto-dismiss) |
240
+ | `iconFn` | `(() => string) \| false` | Custom icon or `false` to hide |
241
+ | `forceAsHtml` | `boolean` | Render content as HTML |
242
+
134
243
  ## Cleanup
135
244
 
136
245
  ```svelte
@@ -142,3 +251,10 @@ A toast notification system with auto-disposal, deduplication, progress indicato
142
251
  onDestroy(() => notifications.destroy());
143
252
  </script>
144
253
  ```
254
+
255
+ ## Accessibility
256
+
257
+ - Uses `role="alert"` for screen reader announcements
258
+ - Uses `aria-live="assertive"` on the container
259
+ - Close button has configurable `aria-label`
260
+ - Renders in a popover layer for proper stacking context
@@ -1,20 +1,217 @@
1
- /*
2
- When defining theme variables that reference other variables, use the inline option.
1
+ /* ============================================================================
2
+ NOTIFICATION COMPONENT TOKENS
3
+ Override globally: :root { --stuic-notification-radius: 0; }
4
+ Override locally: <Notifications style="--stuic-notification-radius: 9999px;">
5
+ ============================================================================ */
3
6
 
4
- Using the inline option, the utility class will use the theme variable value instead
5
- of referencing the actual theme variable.
7
+ :root {
8
+ /* Layout */
9
+ --stuic-notification-max-width: var(--container-sm); /* 24rem */
10
+ --stuic-notification-radius: var(--radius-lg); /* 0.5rem */
11
+ --stuic-notification-padding-x: calc(var(--spacing) * 4); /* 1rem */
12
+ --stuic-notification-padding-y: calc(var(--spacing) * 3); /* 0.75rem */
13
+ --stuic-notification-gap: calc(
14
+ var(--spacing) * 4
15
+ ); /* 1rem - gap between notifications */
6
16
 
7
- Without using inline, your utility classes might resolve to unexpected values because
8
- of how variables are resolved in CSS.
9
- */
17
+ /* Typography */
18
+ --stuic-notification-font-size: var(--text-base);
10
19
 
11
- /* prettier-ignore */
12
- @theme inline {
13
- --color-notif-bg: var(--color-notif-bg, var(--color-neutral-700));
14
- --color-notif-text: var(--color-notif-text, var(--color-neutral-50));
15
- --color-notif-border: var(--color-notif-border, var(--color-neutral-900));
20
+ /* Animation */
21
+ --stuic-notification-transition: 200ms;
16
22
 
17
- --color-notif-bg-dark: var(--color-notif-bg-dark, var(--color-neutral-950));
18
- --color-notif-text-dark: var(--color-notif-text-dark, var(--color-neutral-200));
19
- --color-notif-border-dark: var(--color-notif-border-dark, var(--color-neutral-500));
23
+ /* Shadow */
24
+ --stuic-notification-shadow: var(--shadow-lg);
25
+
26
+ /* Icon */
27
+ --stuic-notification-icon-size: calc(var(--spacing) * 6); /* 1.5rem */
28
+
29
+ /* Counter badge */
30
+ --stuic-notification-badge-font-size: var(--text-xs);
31
+ --stuic-notification-badge-padding-x: calc(var(--spacing) * 2);
32
+ --stuic-notification-badge-padding-y: calc(var(--spacing) * 1);
33
+ --stuic-notification-badge-radius: 9999px;
34
+ --stuic-notification-badge-bg: var(--color-neutral-950);
35
+ --stuic-notification-badge-text: var(--color-neutral-50);
36
+
37
+ /* Progress bar */
38
+ /* --stuic-notification-progress-opacity: 0.1; */
39
+ }
40
+
41
+ @layer components {
42
+ /* ============================================================================
43
+ TYPE-BASED COLOR MAPPING
44
+ Each type sets the color palette via internal CSS vars.
45
+ ============================================================================ */
46
+
47
+ /* Default / info */
48
+ .stuic-notification {
49
+ --_bg: var(--stuic-color-info);
50
+ --_text: var(--stuic-color-info-foreground);
51
+ --_border: var(--stuic-color-info-hover);
52
+ }
53
+
54
+ .stuic-notification[data-type="success"] {
55
+ --_bg: var(--stuic-color-success);
56
+ --_text: var(--stuic-color-success-foreground);
57
+ --_border: var(--stuic-color-success-hover);
58
+ }
59
+
60
+ .stuic-notification[data-type="warn"] {
61
+ --_bg: var(--stuic-color-warning);
62
+ --_text: var(--stuic-color-warning-foreground);
63
+ --_border: var(--stuic-color-warning-hover);
64
+ }
65
+
66
+ .stuic-notification[data-type="error"] {
67
+ --_bg: var(--stuic-color-destructive);
68
+ --_text: var(--stuic-color-destructive-foreground);
69
+ --_border: var(--stuic-color-destructive-hover);
70
+ }
71
+
72
+ /* ============================================================================
73
+ BASE STYLES
74
+ ============================================================================ */
75
+
76
+ .stuic-notification {
77
+ /* Layout */
78
+ position: relative;
79
+ display: flex;
80
+ align-items: center;
81
+ width: 100%;
82
+ max-width: 100%;
83
+
84
+ /* Box model */
85
+ border-width: 1px;
86
+ border-style: solid;
87
+ border-radius: var(--stuic-notification-radius);
88
+
89
+ /* Shadow */
90
+ box-shadow: var(--stuic-notification-shadow);
91
+
92
+ /* Colors - use internal vars set by type */
93
+ background: var(--_bg);
94
+ color: var(--_text);
95
+ border-color: var(--_border);
96
+
97
+ /* Interaction */
98
+ pointer-events: auto;
99
+ }
100
+
101
+ @media (min-width: 40rem) {
102
+ .stuic-notification {
103
+ width: var(--stuic-notification-max-width);
104
+ }
105
+ }
106
+
107
+ /* ============================================================================
108
+ ICON
109
+ ============================================================================ */
110
+
111
+ .stuic-notification .icon {
112
+ display: flex;
113
+ align-items: center;
114
+ justify-content: center;
115
+ padding-top: var(--stuic-notification-padding-y);
116
+ padding-bottom: var(--stuic-notification-padding-y);
117
+ padding-left: var(--stuic-notification-padding-x);
118
+ padding-right: 0;
119
+ color: var(--_text);
120
+ opacity: 0.85;
121
+ }
122
+
123
+ .stuic-notification .icon svg {
124
+ width: var(--stuic-notification-icon-size);
125
+ height: var(--stuic-notification-icon-size);
126
+ }
127
+
128
+ /* ============================================================================
129
+ CONTENT
130
+ ============================================================================ */
131
+
132
+ .stuic-notification .content {
133
+ flex: 1;
134
+ display: flex;
135
+ flex-direction: column;
136
+ justify-content: center;
137
+ padding: var(--stuic-notification-padding-y) calc(var(--spacing) * 1)
138
+ var(--stuic-notification-padding-y) var(--stuic-notification-padding-x);
139
+ font-size: var(--stuic-notification-font-size);
140
+ letter-spacing: var(--tracking-tight);
141
+ }
142
+
143
+ .stuic-notification .content.no-close-button {
144
+ padding-right: var(--stuic-notification-padding-x);
145
+ }
146
+
147
+ /* ============================================================================
148
+ CLOSE BUTTON
149
+ ============================================================================ */
150
+
151
+ .stuic-notification .close-button {
152
+ align-self: stretch;
153
+ display: flex;
154
+ flex-direction: column;
155
+ align-items: center;
156
+ justify-content: center;
157
+ padding: 0 calc(var(--spacing) * 3);
158
+ border-top-right-radius: var(--stuic-notification-radius);
159
+ border-bottom-right-radius: var(--stuic-notification-radius);
160
+ color: var(--_text);
161
+ opacity: 0.75;
162
+ transition: opacity var(--stuic-notification-transition);
163
+ }
164
+
165
+ .stuic-notification .close-button:hover {
166
+ opacity: 1;
167
+ background: rgb(0 0 0 / 0.1);
168
+ }
169
+
170
+ .stuic-notification .close-button:focus-visible {
171
+ opacity: 1;
172
+ outline: none;
173
+ background: rgb(0 0 0 / 0.1);
174
+ }
175
+
176
+ /* ============================================================================
177
+ COUNTER BADGE
178
+ ============================================================================ */
179
+
180
+ .stuic-notification .count {
181
+ position: absolute;
182
+ top: calc(var(--spacing) * -2);
183
+ right: calc(var(--spacing) * -2);
184
+ display: flex;
185
+ align-items: center;
186
+ justify-content: center;
187
+ padding: var(--stuic-notification-badge-padding-y)
188
+ var(--stuic-notification-badge-padding-x);
189
+ border-radius: var(--stuic-notification-badge-radius);
190
+ font-size: var(--stuic-notification-badge-font-size);
191
+ line-height: 1;
192
+ background: var(--stuic-notification-badge-bg);
193
+ color: var(--stuic-notification-badge-text);
194
+ }
195
+
196
+ /* ============================================================================
197
+ PROGRESS BAR
198
+ ============================================================================ */
199
+
200
+ .stuic-notification .progress {
201
+ position: absolute;
202
+ inset: 0;
203
+ background: transparent;
204
+ border-bottom-left-radius: var(--stuic-notification-radius);
205
+ border-bottom-right-radius: var(--stuic-notification-radius);
206
+ overflow: hidden;
207
+ pointer-events: none;
208
+ }
209
+
210
+ .stuic-notification .progress-bar {
211
+ width: 100%;
212
+ height: 100%;
213
+ /* background: rgb(255 255 255 / 0.5); */
214
+ border-bottom-left-radius: var(--stuic-notification-radius);
215
+ border-bottom-right-radius: var(--stuic-notification-radius);
216
+ }
20
217
  }
@@ -132,6 +132,10 @@ export declare class NotificationsStack {
132
132
  success: (content: THC, n?: Partial<NotificationInput>) => this | undefined;
133
133
  /** Main api. */
134
134
  warn: (content: THC, n?: Partial<NotificationInput>) => this | undefined;
135
+ /** "warn" alias */
136
+ warning: (content: THC, n?: Partial<NotificationInput>) => this | undefined;
135
137
  /** Main api. */
136
138
  error: (content: THC, n?: Partial<NotificationInput>) => this | undefined;
139
+ /** "error" alias */
140
+ destructive: (content: THC, n?: Partial<NotificationInput>) => this | undefined;
137
141
  }
@@ -182,8 +182,16 @@ export class NotificationsStack {
182
182
  warn = (content, n) => {
183
183
  return this.#add({ ...(n || {}), type: "warn", content });
184
184
  };
185
+ /** "warn" alias */
186
+ warning = (content, n) => {
187
+ return this.#add({ ...(n || {}), type: "warn", content });
188
+ };
185
189
  /** Main api. */
186
190
  error = (content, n) => {
187
191
  return this.#add({ ...(n || {}), type: "error", content });
188
192
  };
193
+ /** "error" alias */
194
+ destructive = (content, n) => {
195
+ return this.#add({ ...(n || {}), type: "error", content });
196
+ };
189
197
  }
@@ -3,6 +3,7 @@
3
3
  type?: "bar" | "circle";
4
4
  progress?: number;
5
5
  class?: string;
6
+ style?: string;
6
7
  classBar?: string;
7
8
  styleBar?: string;
8
9
  }
@@ -16,13 +17,14 @@
16
17
  type = "bar",
17
18
  progress = 0,
18
19
  class: classProp,
20
+ style: styleProp,
19
21
  classBar,
20
22
  styleBar,
21
23
  }: Props = $props();
22
24
  </script>
23
25
 
24
26
  {#if type === "bar"}
25
- <Bar {progress} class={classProp} {classBar} {styleBar} />
27
+ <Bar {progress} class={classProp} style={styleProp} {classBar} {styleBar} />
26
28
  {:else if type === "circle"}
27
- <Circle {progress} class={classProp} />
29
+ <Circle {progress} class={classProp} style={styleProp} />
28
30
  {/if}
@@ -2,6 +2,7 @@ export interface Props {
2
2
  type?: "bar" | "circle";
3
3
  progress?: number;
4
4
  class?: string;
5
+ style?: string;
5
6
  classBar?: string;
6
7
  styleBar?: string;
7
8
  }