@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
@@ -0,0 +1,318 @@
1
+ /* =============================================================================
2
+ NAV COMPONENT TOKENS
3
+ Override globally: :root { --stuic-nav-radius: 0; }
4
+ Override locally: <Nav style="--stuic-nav-radius: 9999px;">
5
+ ============================================================================= */
6
+
7
+ :root {
8
+ /* Structure tokens */
9
+ --stuic-nav-radius: var(--radius-md);
10
+ --stuic-nav-transition: 150ms;
11
+ --stuic-nav-gap: 0.5rem;
12
+
13
+ /* Children indent */
14
+ --stuic-nav-children-indent: 1rem;
15
+ --stuic-nav-children-gap: 0.25rem;
16
+
17
+ /* Section title (static header above group) */
18
+ --stuic-nav-section-title-padding-x: 0.5rem;
19
+ --stuic-nav-section-title-padding-y: 0.25rem;
20
+ --stuic-nav-section-title-font-size: var(--text-xs);
21
+ --stuic-nav-section-title-font-weight: 600;
22
+ --stuic-nav-section-title-opacity: 0.5;
23
+ --stuic-nav-section-title-letter-spacing: 0.05em;
24
+
25
+ /* Title/header (collapsible group header) */
26
+ --stuic-nav-group-title-padding-x: 0.5rem;
27
+ --stuic-nav-group-title-padding-y: 0.5rem;
28
+ --stuic-nav-group-title-font-size: var(--text-sm);
29
+ --stuic-nav-group-title-font-weight: 700;
30
+ --stuic-nav-group-title-opacity: 0.75;
31
+ --stuic-nav-group-title-height: 2.125rem; /* 34px */
32
+
33
+ /* Item sizing */
34
+ --stuic-nav-item-padding-x: 0.5rem;
35
+ --stuic-nav-item-padding-y: 0.5rem;
36
+ --stuic-nav-item-height: 2.125rem; /* 34px */
37
+ --stuic-nav-item-font-size: var(--text-sm);
38
+
39
+ /* Touch-friendly modifier */
40
+ --stuic-nav-item-height-touch: 2.75rem; /* 44px */
41
+ --stuic-nav-item-padding-y-touch: 0.75rem;
42
+ --stuic-nav-group-title-height-touch: 2.75rem;
43
+
44
+ /* Collapsed mode */
45
+ --stuic-nav-item-size-collapsed: 2.125rem;
46
+ --stuic-nav-item-size-collapsed-touch: 2.75rem; /* 44px */
47
+
48
+ /* Icon */
49
+ --stuic-nav-icon-opacity: 0.75;
50
+
51
+ /* Chevron */
52
+ --stuic-nav-chevron-opacity: 0.5;
53
+
54
+ /* Color tokens: Base state */
55
+ --stuic-nav-item-bg: transparent;
56
+ --stuic-nav-item-text: inherit;
57
+
58
+ /* Color tokens: Hover state */
59
+ --stuic-nav-item-bg-hover: rgb(0 0 0 / 0.1);
60
+ --stuic-nav-item-text-hover: inherit;
61
+
62
+ /* Color tokens: Active state */
63
+ --stuic-nav-item-bg-active: var(--stuic-color-primary);
64
+ --stuic-nav-item-text-active: var(--stuic-color-primary-foreground);
65
+
66
+ /* Color tokens: Focused state (keyboard navigation) */
67
+ --stuic-nav-item-bg-focus: var(--stuic-color-primary);
68
+ --stuic-nav-item-text-focus: var(--stuic-color-primary-foreground);
69
+ }
70
+
71
+ @layer components {
72
+ /* =============================================================================
73
+ BASE CONTAINER
74
+ ============================================================================= */
75
+
76
+ .stuic-nav {
77
+ display: flex;
78
+ flex-direction: column;
79
+ gap: var(--stuic-nav-children-gap);
80
+ }
81
+
82
+ /* Center items horizontally when collapsed */
83
+ .stuic-nav[data-collapsed] {
84
+ align-items: center;
85
+ }
86
+
87
+ /* =============================================================================
88
+ SECTION TITLE (static header above group)
89
+ ============================================================================= */
90
+
91
+ .stuic-nav-section-title {
92
+ /* Layout */
93
+ display: block;
94
+ width: 100%;
95
+
96
+ /* Padding */
97
+ padding: var(--stuic-nav-section-title-padding-y)
98
+ var(--stuic-nav-section-title-padding-x);
99
+
100
+ /* Typography */
101
+ font-size: var(--stuic-nav-section-title-font-size);
102
+ font-weight: var(--stuic-nav-section-title-font-weight);
103
+ letter-spacing: var(--stuic-nav-section-title-letter-spacing);
104
+ line-height: 1;
105
+
106
+ /* Visual */
107
+ opacity: var(--stuic-nav-section-title-opacity);
108
+
109
+ /* Non-interactive */
110
+ user-select: none;
111
+ }
112
+
113
+ /* Collapsed mode: hide title but preserve space */
114
+ .stuic-nav-section-title[data-collapsed] {
115
+ visibility: hidden;
116
+ }
117
+
118
+ /* =============================================================================
119
+ GROUP TITLE/HEADER (collapsible)
120
+ ============================================================================= */
121
+
122
+ .stuic-nav-group-title {
123
+ /* Layout */
124
+ display: flex;
125
+ align-items: center;
126
+ gap: var(--stuic-nav-gap);
127
+ width: 100%;
128
+ height: var(--stuic-nav-group-title-height);
129
+
130
+ /* Padding */
131
+ padding: var(--stuic-nav-group-title-padding-y)
132
+ var(--stuic-nav-group-title-padding-x);
133
+
134
+ /* Typography */
135
+ font-size: var(--stuic-nav-group-title-font-size);
136
+ font-weight: var(--stuic-nav-group-title-font-weight);
137
+ text-align: left;
138
+ line-height: 1;
139
+
140
+ /* Visual */
141
+ opacity: var(--stuic-nav-group-title-opacity);
142
+ border-radius: var(--stuic-nav-radius);
143
+ background: transparent;
144
+ border: none;
145
+
146
+ /* Interaction */
147
+ cursor: pointer;
148
+ user-select: none;
149
+ -webkit-tap-highlight-color: transparent;
150
+ }
151
+
152
+ .stuic-nav-group-title:hover {
153
+ background: var(--stuic-nav-item-bg-hover);
154
+ }
155
+
156
+ .stuic-nav-group-title:focus {
157
+ outline: none;
158
+ }
159
+
160
+ .stuic-nav-group-title:focus-visible {
161
+ background: var(--stuic-nav-item-bg-hover);
162
+ }
163
+
164
+ /* Touch-friendly title */
165
+ .stuic-nav-group-title[data-touch-friendly] {
166
+ height: var(--stuic-nav-group-title-height-touch);
167
+ padding-top: var(--stuic-nav-item-padding-y-touch);
168
+ padding-bottom: var(--stuic-nav-item-padding-y-touch);
169
+ }
170
+
171
+ /* =============================================================================
172
+ CHILDREN CONTAINER
173
+ ============================================================================= */
174
+
175
+ .stuic-nav-children {
176
+ display: flex;
177
+ flex-direction: column;
178
+ gap: var(--stuic-nav-children-gap);
179
+ padding-left: var(--stuic-nav-children-indent);
180
+ list-style: none;
181
+ margin: 0;
182
+ }
183
+
184
+ /* No indent in collapsed mode */
185
+ .stuic-nav[data-collapsed] .stuic-nav-children {
186
+ padding-left: 0;
187
+ }
188
+
189
+ /* =============================================================================
190
+ ITEM STYLES
191
+ ============================================================================= */
192
+
193
+ .stuic-nav-item {
194
+ /* Layout */
195
+ display: flex;
196
+ align-items: center;
197
+ gap: var(--stuic-nav-gap);
198
+ width: 100%;
199
+ height: var(--stuic-nav-item-height);
200
+
201
+ /* Padding */
202
+ padding: var(--stuic-nav-item-padding-y)
203
+ var(--stuic-nav-item-padding-x);
204
+
205
+ /* Typography */
206
+ font-size: var(--stuic-nav-item-font-size);
207
+ text-align: left;
208
+ text-decoration: none;
209
+ line-height: 1;
210
+
211
+ /* Visual */
212
+ border-radius: var(--stuic-nav-radius);
213
+ background: var(--stuic-nav-item-bg);
214
+ color: var(--stuic-nav-item-text);
215
+ border: none;
216
+
217
+ /* Interaction */
218
+ cursor: pointer;
219
+ user-select: none;
220
+ -webkit-tap-highlight-color: transparent;
221
+ transition:
222
+ background var(--stuic-nav-transition),
223
+ color var(--stuic-nav-transition);
224
+ }
225
+
226
+ /* Icon opacity */
227
+ .stuic-nav-item > span:first-child {
228
+ opacity: var(--stuic-nav-icon-opacity);
229
+ }
230
+
231
+ /* =============================================================================
232
+ ITEM STATE STYLES
233
+ ============================================================================= */
234
+
235
+ /* Hover state */
236
+ .stuic-nav-item:hover:not(:disabled):not([data-active]) {
237
+ background: var(--stuic-nav-item-bg-hover);
238
+ color: var(--stuic-nav-item-text-hover);
239
+ }
240
+
241
+ /* Focus styles */
242
+ .stuic-nav-item:focus {
243
+ outline: none;
244
+ }
245
+
246
+ .stuic-nav-item:focus-visible:not([data-active]) {
247
+ background: var(--stuic-nav-item-bg-focus);
248
+ color: var(--stuic-nav-item-text-focus);
249
+ }
250
+
251
+ /* Active/Selected state */
252
+ .stuic-nav-item[data-active] {
253
+ background: var(--stuic-nav-item-bg-active);
254
+ color: var(--stuic-nav-item-text-active);
255
+ }
256
+
257
+ /* Active state: make icon full opacity */
258
+ .stuic-nav-item[data-active] > span:first-child {
259
+ opacity: 1;
260
+ }
261
+
262
+ /* Focused state (keyboard navigation) */
263
+ .stuic-nav-item[data-focused]:not([data-active]) {
264
+ background: var(--stuic-nav-item-bg-focus);
265
+ color: var(--stuic-nav-item-text-focus);
266
+ }
267
+
268
+ /* Disabled state */
269
+ .stuic-nav-item:disabled,
270
+ .stuic-nav-item[data-disabled] {
271
+ opacity: 0.5;
272
+ cursor: not-allowed;
273
+ pointer-events: none;
274
+ }
275
+
276
+ /* =============================================================================
277
+ TOUCH-FRIENDLY MODIFIER
278
+ ============================================================================= */
279
+
280
+ .stuic-nav-item[data-touch-friendly] {
281
+ height: var(--stuic-nav-item-height-touch);
282
+ padding-top: var(--stuic-nav-item-padding-y-touch);
283
+ padding-bottom: var(--stuic-nav-item-padding-y-touch);
284
+ }
285
+
286
+ /* =============================================================================
287
+ COLLAPSED MODE
288
+ ============================================================================= */
289
+
290
+ .stuic-nav-item[data-collapsed] {
291
+ /* Center content */
292
+ justify-content: center;
293
+ width: var(--stuic-nav-item-size-collapsed);
294
+ height: var(--stuic-nav-item-size-collapsed);
295
+ padding: 0.375rem;
296
+ }
297
+
298
+ /* Collapsed + touch-friendly: minimum 44x44 */
299
+ .stuic-nav-item[data-collapsed][data-touch-friendly] {
300
+ width: var(--stuic-nav-item-size-collapsed-touch);
301
+ height: var(--stuic-nav-item-size-collapsed-touch);
302
+ }
303
+
304
+ /* Expanding transition state - shift content left */
305
+ .stuic-nav-item[data-expanding] {
306
+ padding-left: var(--stuic-nav-item-padding-x);
307
+ justify-content: flex-start;
308
+ }
309
+
310
+ /* =============================================================================
311
+ CHEVRON STYLES
312
+ ============================================================================= */
313
+
314
+ .stuic-nav-group-title > span:first-child,
315
+ .stuic-nav-item[data-collapsed] > span:first-child {
316
+ opacity: var(--stuic-nav-chevron-opacity);
317
+ }
318
+ }
@@ -0,0 +1 @@
1
+ export { default as Nav, type Props as NavProps, type NavItem, type NavGroup, NAV_BASE_CLASSES, NAV_SECTION_TITLE_CLASSES, NAV_GROUP_TITLE_CLASSES, NAV_ITEM_CLASSES, NAV_CHILDREN_CLASSES, } from "./Nav.svelte";
@@ -0,0 +1 @@
1
+ export { default as Nav, NAV_BASE_CLASSES, NAV_SECTION_TITLE_CLASSES, NAV_GROUP_TITLE_CLASSES, NAV_ITEM_CLASSES, NAV_CHILDREN_CLASSES, } from "./Nav.svelte";
@@ -1,5 +1,4 @@
1
1
  <script lang="ts" module>
2
- import type { TW_COLORS } from "../../types.js";
3
2
  import type { NotificationsStack } from "./notifications-stack.svelte.js";
4
3
  import { notificationsDefaultIcons } from "./notifications-icons.js";
5
4
 
@@ -15,39 +14,33 @@
15
14
  posXMobile?: NOTIFICATIONS_POSX;
16
15
  posY?: NOTIFICATIONS_POSY;
17
16
  posYMobile?: NOTIFICATIONS_POSY;
18
- themeInfo?: TW_COLORS;
19
- themeError?: TW_COLORS;
20
- themeWarn?: TW_COLORS;
21
- themeSuccess?: TW_COLORS;
22
- noTheme?: boolean;
23
17
  noIcons?: boolean;
18
+ noProgress?: boolean;
19
+ noXButton?: boolean;
20
+ forceAsHtml?: boolean;
21
+ ariaCloseLabel?: string;
22
+ duration?: number;
23
+ iconFns?: Partial<Record<keyof typeof notificationsDefaultIcons, CallableFunction>>;
24
+ // Class overrides
25
+ class?: string;
24
26
  classWrapY?: string;
25
27
  classWrapX?: string;
26
- class?: string;
27
28
  classNotifCount?: string;
28
29
  classNotifIcon?: string;
29
30
  classNotifContent?: string;
30
- classNotifButton?: string;
31
- classNotifButtonX?: string;
32
- buttonXStrokeWidth?: 0.5 | 1 | 1.5 | 2 | 2.5 | 3 | 3.5 | 4;
33
31
  classProgress?: string;
34
32
  classProgressBar?: string;
35
- forceAsHtml?: boolean;
36
- ariaCloseLabel?: string;
37
- duration?: number;
38
- noProgress?: boolean;
39
- noXButton?: boolean;
40
- iconFns?: Partial<Record<keyof typeof notificationsDefaultIcons, CallableFunction>>;
33
+ el?: HTMLDivElement;
41
34
  }
42
35
  </script>
43
36
 
44
37
  <script lang="ts">
45
38
  import { fade } from "svelte/transition";
46
39
  import { twMerge } from "../../utils/tw-merge.js";
40
+ import Button from "../Button/Button.svelte";
47
41
  import Thc from "../Thc/Thc.svelte";
48
42
  import X from "../X/X.svelte";
49
- import "./index.css";
50
- import type { Notification, NotificationType } from "./notifications-stack.svelte.js";
43
+ import type { Notification } from "./notifications-stack.svelte.js";
51
44
  import Progress from "../Progress/Progress.svelte";
52
45
 
53
46
  const DEFAULT: {
@@ -81,33 +74,23 @@
81
74
  posY = DEFAULT.posY,
82
75
  posYMobile = DEFAULT.posYMobile,
83
76
  //
84
- themeInfo = "neutral",
85
- themeError = "red",
86
- themeWarn = "yellow",
87
- themeSuccess = "green",
88
- // use truthy `noTheme` if manual css-only var customization is needed
89
- noTheme,
90
77
  noIcons,
78
+ noProgress,
79
+ noXButton,
80
+ forceAsHtml,
81
+ ariaCloseLabel = "Close",
82
+ duration = 200,
83
+ iconFns = {},
91
84
  //
85
+ class: classNotifBox,
92
86
  classWrapY,
93
87
  classWrapX,
94
- class: classNotifBox,
95
88
  classNotifCount,
96
89
  classNotifIcon,
97
90
  classNotifContent,
98
- classNotifButton,
99
- classNotifButtonX,
100
- buttonXStrokeWidth = 3,
101
- //
102
91
  classProgress,
103
92
  classProgressBar,
104
- //
105
- forceAsHtml,
106
- ariaCloseLabel = "Close",
107
- duration = 200,
108
- noProgress,
109
- noXButton,
110
- iconFns = {},
93
+ el = $bindable(),
111
94
  }: Props = $props();
112
95
 
113
96
  let popoverEl: HTMLDivElement | null = $state(null);
@@ -128,79 +111,6 @@
128
111
  return (_iconFns?.[n.type] as any)?.();
129
112
  };
130
113
 
131
- const _classWrapX = `
132
- fixed z-50 flex flex-row inset-0
133
- pointer-events-none bg-transparent`;
134
-
135
- const _classWrapY = `
136
- p-4 space-y-4
137
- flex flex-col inset-0
138
- w-full sm:w-auto
139
- pointer-events-none bg-transparent`;
140
-
141
- const _classNotifBox = `
142
- relative flex
143
- pointer-events-auto
144
- w-full sm:w-sm max-w-full sm:max-w-sm
145
- rounded-lg
146
- shadow-lg
147
- border border-notif-border dark:border-notif-border-dark
148
- bg-notif-bg text-notif-text
149
- dark:bg-notif-bg-dark dark:text-notif-text-dark`;
150
-
151
- const _classNotifCount = `
152
- absolute -top-2 -right-2
153
- w-auto h-auto
154
- flex items-center justify-center
155
- px-2 py-1 rounded-full
156
- leading-none text-xs
157
- bg-neutral-950 text-neutral-50`;
158
-
159
- const _classNotifIcon = `
160
- flex items-center justify-center
161
- pt-4 pr-0 pb-4 pl-4
162
- text-neutral-200`;
163
-
164
- const _classNotifContent = `
165
- flex-1
166
- flex flex-col justify-center
167
- tracking-tight
168
- pl-4 pr-1 py-3`;
169
-
170
- const _classNotifButton = `
171
- flex flex-col items-center justify-center
172
- leading-none
173
- px-3
174
- hover:bg-neutral-950/10
175
- focus-visible:bg-neutral-950/10 focus-visible:outline-none focus-visible:ring-0
176
- group
177
- rounded-tr-md rounded-br-md`;
178
-
179
- const _classNotifButtonX = `opacity-75 group-hover:opacity-100`;
180
-
181
- const _classProgress = `absolute inset-0 size-full bg-transparent rounded-tl-md rounded-bl-md`;
182
- const _classProgressBar = `bg-white/10 dark:bg-white/10 size-full rounded-tl-md rounded-bl-md`;
183
-
184
- const _buildTheme = (type: NotificationType) => {
185
- if (noTheme) return "";
186
- let theme =
187
- {
188
- info: themeInfo,
189
- error: themeError,
190
- success: themeSuccess,
191
- warn: themeWarn,
192
- }[type] || "info";
193
- return [
194
- `--color-notif-bg: var(--color-bg-${type}, var(--color-${theme}-700));`,
195
- `--color-notif-text: var(--color-text-${type}, var(--color-${theme}-50));`,
196
- `--color-notif-border: var(--color-border-${type}, var(--color-${theme}-800));`,
197
- //
198
- `--color-notif-bg-dark: var(--color-bg-dark-${type}, var(--color-${theme}-800));`,
199
- `--color-notif-text-dark: var(--color-text-dark-${type}, var(--color-${theme}-200));`,
200
- `--color-notif-border-dark: var(--color-border-dark-${type}, var(--color-${theme}-700));`,
201
- ].join("");
202
- };
203
-
204
114
  // Manage popover visibility based on notifications
205
115
  $effect(() => {
206
116
  if (!popoverEl) return;
@@ -227,39 +137,48 @@
227
137
  >
228
138
  <div
229
139
  class={twMerge(
230
- "stuic-notifs wrap-x",
231
- _classWrapX,
140
+ "stuic-notifs fixed z-50 flex flex-row inset-0 pointer-events-none bg-transparent",
232
141
  XMAP[x],
233
142
  XMAP_M[xMobile],
234
143
  classWrapX
235
144
  )}
236
145
  >
237
- <div class={twMerge("wrap-y", _classWrapY, YMAP_M[yMobile], YMAP[y], classWrapY)}>
146
+ <div
147
+ class={twMerge(
148
+ "flex flex-col inset-0 w-full sm:w-auto pointer-events-none bg-transparent",
149
+ "p-4",
150
+ YMAP_M[yMobile],
151
+ YMAP[y],
152
+ classWrapY
153
+ )}
154
+ style="gap: var(--stuic-notification-gap);"
155
+ >
238
156
  {#each notifications.stack as n (n.id)}
239
157
  {@const iconHtml = maybeIcon(n)}
240
158
  {@const showXButton = !noXButton || n.ttl > 1000}
241
159
  <div
242
- class={twMerge("box", _classNotifBox, classNotifBox)}
160
+ bind:this={el}
161
+ class={twMerge("stuic-notification", classNotifBox)}
162
+ data-type={n.type}
243
163
  transition:fade|global={{ duration }}
244
164
  role="alert"
245
- style={_buildTheme(n.type)}
246
165
  >
247
166
  {#if n.ttl && !noProgress}
248
167
  <Progress
249
168
  progress={100 - n._ttlProgress * 100}
250
- class={twMerge(_classProgress, classProgress)}
251
- classBar={twMerge(_classProgressBar, classProgressBar)}
169
+ class={twMerge("progress h-full", classProgress)}
170
+ classBar={twMerge("progress-bar bg-black/5", classProgressBar)}
252
171
  styleBar="transition-duration: {notifications.options.disposeInterval}ms;"
253
172
  />
254
173
  {/if}
255
174
 
256
175
  {#if n.count > 1}
257
- <div class={twMerge("count", _classNotifCount, classNotifCount)}>
176
+ <div class={twMerge("count", classNotifCount)}>
258
177
  {n.count}
259
178
  </div>
260
179
  {/if}
261
180
  {#if !noIcons && iconHtml}
262
- <div class={twMerge("icon", _classNotifIcon, classNotifIcon)}>
181
+ <div class={twMerge("icon hidden! sm:block!", classNotifIcon)}>
263
182
  {@html iconHtml}
264
183
  </div>
265
184
  {/if}
@@ -267,9 +186,8 @@
267
186
  <div
268
187
  class={twMerge(
269
188
  "content",
270
- _classNotifContent,
271
- classNotifContent,
272
- !showXButton && "pr-4"
189
+ !showXButton && "no-close-button",
190
+ classNotifContent
273
191
  )}
274
192
  >
275
193
  <Thc
@@ -281,9 +199,9 @@
281
199
  </div>
282
200
 
283
201
  {#if showXButton}
284
- <button
285
- type="button"
286
- class={twMerge("button", _classNotifButton, classNotifButton)}
202
+ <Button
203
+ unstyled
204
+ class="close-button"
287
205
  aria-label={ariaCloseLabel}
288
206
  onclick={(e) => {
289
207
  e.preventDefault();
@@ -292,11 +210,8 @@
292
210
  notifications.removeById(n.id);
293
211
  }}
294
212
  >
295
- <X
296
- class={twMerge("x", _classNotifButtonX, classNotifButtonX)}
297
- strokeWidth={buttonXStrokeWidth}
298
- />
299
- </button>
213
+ <X />
214
+ </Button>
300
215
  {/if}
301
216
  </div>
302
217
  {/each}
@@ -1,4 +1,3 @@
1
- import type { TW_COLORS } from "../../types.js";
2
1
  import type { NotificationsStack } from "./notifications-stack.svelte.js";
3
2
  import { notificationsDefaultIcons } from "./notifications-icons.js";
4
3
  declare const X_POSITIONS: readonly ["left", "center", "right"];
@@ -11,31 +10,23 @@ export interface Props {
11
10
  posXMobile?: NOTIFICATIONS_POSX;
12
11
  posY?: NOTIFICATIONS_POSY;
13
12
  posYMobile?: NOTIFICATIONS_POSY;
14
- themeInfo?: TW_COLORS;
15
- themeError?: TW_COLORS;
16
- themeWarn?: TW_COLORS;
17
- themeSuccess?: TW_COLORS;
18
- noTheme?: boolean;
19
13
  noIcons?: boolean;
14
+ noProgress?: boolean;
15
+ noXButton?: boolean;
16
+ forceAsHtml?: boolean;
17
+ ariaCloseLabel?: string;
18
+ duration?: number;
19
+ iconFns?: Partial<Record<keyof typeof notificationsDefaultIcons, CallableFunction>>;
20
+ class?: string;
20
21
  classWrapY?: string;
21
22
  classWrapX?: string;
22
- class?: string;
23
23
  classNotifCount?: string;
24
24
  classNotifIcon?: string;
25
25
  classNotifContent?: string;
26
- classNotifButton?: string;
27
- classNotifButtonX?: string;
28
- buttonXStrokeWidth?: 0.5 | 1 | 1.5 | 2 | 2.5 | 3 | 3.5 | 4;
29
26
  classProgress?: string;
30
27
  classProgressBar?: string;
31
- forceAsHtml?: boolean;
32
- ariaCloseLabel?: string;
33
- duration?: number;
34
- noProgress?: boolean;
35
- noXButton?: boolean;
36
- iconFns?: Partial<Record<keyof typeof notificationsDefaultIcons, CallableFunction>>;
28
+ el?: HTMLDivElement;
37
29
  }
38
- import "./index.css";
39
- declare const Notifications: import("svelte").Component<Props, {}, "">;
30
+ declare const Notifications: import("svelte").Component<Props, {}, "el">;
40
31
  type Notifications = ReturnType<typeof Notifications>;
41
32
  export default Notifications;