@salmexio/ui 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/dialogs/ContextMenu/ContextMenu.svelte +11 -1
  2. package/dist/dialogs/Modal/Modal.svelte +34 -1
  3. package/dist/feedback/Alert/Alert.svelte +54 -11
  4. package/dist/feedback/ProgressBar/ProgressBar.svelte +11 -8
  5. package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts +2 -2
  6. package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts.map +1 -1
  7. package/dist/feedback/Skeleton/Skeleton.svelte +7 -3
  8. package/dist/feedback/Spinner/Spinner.svelte +2 -0
  9. package/dist/feedback/Toast/Toaster.svelte +35 -3
  10. package/dist/forms/Checkbox/Checkbox.svelte +30 -7
  11. package/dist/forms/Select/Select.svelte +19 -3
  12. package/dist/forms/Slider/Slider.svelte +41 -13
  13. package/dist/forms/Slider/Slider.svelte.d.ts +1 -1
  14. package/dist/forms/Slider/Slider.svelte.d.ts.map +1 -1
  15. package/dist/forms/TextInput/TextInput.svelte +19 -1
  16. package/dist/forms/Textarea/Textarea.svelte +18 -3
  17. package/dist/forms/Toggle/Toggle.svelte +70 -11
  18. package/dist/layout/Card/Card.svelte +125 -4
  19. package/dist/layout/Card/Card.svelte.d.ts +3 -0
  20. package/dist/layout/Card/Card.svelte.d.ts.map +1 -1
  21. package/dist/layout/ThermalBackground/ThermalBackground.svelte +2 -40
  22. package/dist/layout/ThermalBackground/ThermalBackground.svelte.d.ts +0 -2
  23. package/dist/layout/ThermalBackground/ThermalBackground.svelte.d.ts.map +1 -1
  24. package/dist/navigation/CommandPalette/CommandPalette.svelte +37 -3
  25. package/dist/navigation/NavMenu/NavMenu.svelte +800 -0
  26. package/dist/navigation/NavMenu/NavMenu.svelte.d.ts +81 -0
  27. package/dist/navigation/NavMenu/NavMenu.svelte.d.ts.map +1 -0
  28. package/dist/navigation/NavMenu/index.d.ts +3 -0
  29. package/dist/navigation/NavMenu/index.d.ts.map +1 -0
  30. package/dist/navigation/NavMenu/index.js +1 -0
  31. package/dist/navigation/Tabs/Tabs.svelte +37 -8
  32. package/dist/navigation/index.d.ts +2 -0
  33. package/dist/navigation/index.d.ts.map +1 -1
  34. package/dist/navigation/index.js +1 -0
  35. package/dist/primitives/Badge/Badge.svelte +55 -10
  36. package/dist/primitives/Button/Button.svelte +220 -71
  37. package/dist/primitives/Tooltip/Tooltip.svelte +9 -1
  38. package/dist/styles/tokens.css +1 -0
  39. package/package.json +1 -1
@@ -0,0 +1,81 @@
1
+ import type { Snippet } from 'svelte';
2
+ export interface NavMenuItem {
3
+ type: 'item';
4
+ /** Unique identifier for active state matching */
5
+ id: string;
6
+ /** Display label */
7
+ label: string;
8
+ /** Link target (renders <a>); omit for button behavior */
9
+ href?: string;
10
+ /** Icon snippet */
11
+ icon?: Snippet;
12
+ /** Badge text (e.g. "New", count) */
13
+ badge?: string | number;
14
+ /** Disabled state */
15
+ disabled?: boolean;
16
+ /** Nested sub-items */
17
+ children?: NavMenuItem[];
18
+ }
19
+ export interface NavMenuGroup {
20
+ type: 'group';
21
+ /** Group heading label */
22
+ label: string;
23
+ /** Whether the group starts collapsed */
24
+ defaultCollapsed?: boolean;
25
+ /** Items in this group */
26
+ items: NavMenuEntry[];
27
+ }
28
+ export interface NavMenuSeparator {
29
+ type: 'separator';
30
+ }
31
+ export type NavMenuEntry = NavMenuItem | NavMenuGroup | NavMenuSeparator;
32
+ interface Props {
33
+ /** Menu entries: items, groups, and separators */
34
+ items: NavMenuEntry[];
35
+ /** ID of the currently active item */
36
+ activeId?: string;
37
+ /** Fired when an item is activated (click or Enter) */
38
+ onselect?: (id: string, href?: string) => void;
39
+ /** Whether groups can be collapsed (default true) */
40
+ collapsible?: boolean;
41
+ /** Additional CSS class */
42
+ class?: string;
43
+ /** Accessible label for the nav element */
44
+ label?: string;
45
+ /** Test ID */
46
+ testId?: string;
47
+ }
48
+ /**
49
+ * NavMenu
50
+ *
51
+ * INFRARED — Persistent navigation menu with collapsible groups, sub-items,
52
+ * icons, badges, and keyboard navigation. Built for sidebars, settings panels,
53
+ * and any vertical nav structure.
54
+ *
55
+ * @example
56
+ * <NavMenu
57
+ * items={[
58
+ * {
59
+ * type: 'group',
60
+ * label: 'Getting Started',
61
+ * items: [
62
+ * { type: 'item', id: 'intro', label: 'Introduction', href: '/' },
63
+ * { type: 'item', id: 'install', label: 'Installation', href: '/install', badge: 'New' },
64
+ * ]
65
+ * },
66
+ * { type: 'separator' },
67
+ * {
68
+ * type: 'item',
69
+ * id: 'settings',
70
+ * label: 'Settings',
71
+ * href: '/settings',
72
+ * icon: settingsIcon,
73
+ * }
74
+ * ]}
75
+ * activeId="intro"
76
+ * />
77
+ */
78
+ declare const NavMenu: import("svelte").Component<Props, {}, "">;
79
+ type NavMenu = ReturnType<typeof NavMenu>;
80
+ export default NavMenu;
81
+ //# sourceMappingURL=NavMenu.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NavMenu.svelte.d.ts","sourceRoot":"","sources":["../../../src/navigation/NavMenu/NavMenu.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0BAA0B;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,WAAW,CAAC;CAClB;AAED,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,YAAY,GAAG,gBAAgB,CAAC;AAOzE,UAAU,KAAK;IACd,kDAAkD;IAClD,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,qDAAqD;IACrD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AA2TD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,QAAA,MAAM,OAAO,2CAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { default as NavMenu } from './NavMenu.svelte';
2
+ export type { NavMenuItem, NavMenuGroup, NavMenuSeparator, NavMenuEntry } from './NavMenu.svelte';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/navigation/NavMenu/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ export { default as NavMenu } from './NavMenu.svelte';
@@ -198,7 +198,7 @@ function handleKeydown(event: KeyboardEvent, currentIndex: number) {
198
198
  }
199
199
 
200
200
  /* ========================================
201
- TABLIST — Flat underline style
201
+ TABLIST — Recessed rail with depth
202
202
  ======================================== */
203
203
  .sx-tabs-list {
204
204
  display: flex;
@@ -211,6 +211,7 @@ function handleKeydown(event: KeyboardEvent, currentIndex: number) {
211
211
  position: relative;
212
212
  background: var(--sx-color-surface);
213
213
  border-bottom: 1px solid var(--sx-color-border);
214
+ box-shadow: inset 0 -2px 4px -2px rgba(0, 0, 0, 0.2);
214
215
  }
215
216
 
216
217
  .sx-tabs-list-sm {
@@ -273,40 +274,63 @@ function handleKeydown(event: KeyboardEvent, currentIndex: number) {
273
274
  background: var(--sx-color-primary-hover);
274
275
  }
275
276
 
276
- /* Selected tab — underline indicator via ::after for smooth transitions */
277
+ /* Selected tab — elevated with subtle depth */
277
278
  .sx-tab-selected {
278
279
  color: var(--sx-color-text);
279
280
  font-weight: 600;
280
281
  border-bottom-color: transparent;
281
282
  }
282
283
 
283
- /* Animated underlinescales in horizontally on select */
284
+ /* Forge-gradient indicator rail multi-color strip with glow bleed */
284
285
  .sx-tab::after {
285
286
  content: '';
286
287
  position: absolute;
287
- bottom: 0;
288
+ bottom: -1px;
288
289
  left: var(--sx-space-4);
289
290
  right: var(--sx-space-4);
290
- height: 2px;
291
- background: var(--sx-color-primary);
292
- border-radius: 1px;
291
+ height: 3px;
292
+ background:
293
+ linear-gradient(
294
+ 90deg,
295
+ #FF6B35,
296
+ #C8A84E 50%,
297
+ #3D8B8B
298
+ );
299
+ background-size: 200% 100%;
300
+ border-radius: 3px 3px 0 0;
293
301
  transform: scaleX(0);
294
302
  transform-origin: center;
295
- transition: transform var(--sx-duration-base) var(--sx-ease-out);
303
+ transition:
304
+ transform var(--sx-duration-base) var(--sx-ease-out),
305
+ box-shadow var(--sx-duration-base) var(--sx-ease-out);
306
+ box-shadow: none;
296
307
  }
297
308
 
298
309
  .sx-tab-sm::after {
299
310
  left: var(--sx-space-3);
300
311
  right: var(--sx-space-3);
312
+ height: 2px;
301
313
  }
302
314
 
303
315
  .sx-tab-lg::after {
304
316
  left: var(--sx-space-5);
305
317
  right: var(--sx-space-5);
318
+ height: 3px;
306
319
  }
307
320
 
308
321
  .sx-tab-selected::after {
309
322
  transform: scaleX(1);
323
+ animation: sx-tab-forge 6s ease-in-out infinite;
324
+
325
+ /* Glow bleed underneath the indicator */
326
+ box-shadow:
327
+ 0 0 8px -1px rgba(255, 107, 53, 0.4),
328
+ 0 0 16px -4px rgba(200, 168, 78, 0.2);
329
+ }
330
+
331
+ @keyframes sx-tab-forge {
332
+ 0%, 100% { background-position: 0% 50%; }
333
+ 50% { background-position: 100% 50%; }
310
334
  }
311
335
 
312
336
  /* Focus — primary ring */
@@ -404,5 +428,10 @@ function handleKeydown(event: KeyboardEvent, currentIndex: number) {
404
428
  .sx-tab::after {
405
429
  transition: none;
406
430
  }
431
+
432
+ .sx-tab-selected::after {
433
+ animation: none;
434
+ background: linear-gradient(90deg, #FF6B35, #C8A84E);
435
+ }
407
436
  }
408
437
  </style>
@@ -2,4 +2,6 @@ export { Tabs } from './Tabs/index.js';
2
2
  export type { TabOption } from './Tabs/index.js';
3
3
  export { CommandPalette } from './CommandPalette/index.js';
4
4
  export type { CommandItem, CommandGroup } from './CommandPalette/index.js';
5
+ export { NavMenu } from './NavMenu/index.js';
6
+ export type { NavMenuItem, NavMenuGroup, NavMenuSeparator, NavMenuEntry } from './NavMenu/index.js';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/navigation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/navigation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export { Tabs } from './Tabs/index.js';
2
2
  export { CommandPalette } from './CommandPalette/index.js';
3
+ export { NavMenu } from './NavMenu/index.js';
@@ -79,17 +79,20 @@ let {
79
79
  {/if}
80
80
 
81
81
  <style>
82
- /* Base */
82
+ /* Base — stamped metal tag with thin extrusion */
83
83
  .sx-badge {
84
84
  display: inline-flex;
85
85
  align-items: center;
86
86
  gap: var(--sx-space-1);
87
87
  font-family: var(--sx-font-body);
88
- font-weight: 500;
88
+ font-weight: 600;
89
+ letter-spacing: 0.02em;
89
90
  white-space: nowrap;
90
91
  transition: box-shadow var(--sx-transition-fast);
91
92
  border: 1px solid transparent;
92
- box-shadow: none;
93
+ box-shadow:
94
+ 0 1px 0 0 rgba(0, 0, 0, 0.2),
95
+ 0 2px 4px -1px rgba(0, 0, 0, 0.2);
93
96
  animation: sx-badge-pop 200ms var(--sx-ease-spring) both;
94
97
  }
95
98
 
@@ -157,82 +160,124 @@ let {
157
160
  STATUS VARIANTS - INFRARED
158
161
  ======================================== */
159
162
 
160
- /* Neutral */
163
+ /* Neutral — metal surface */
161
164
  .sx-badge-neutral {
162
165
  background: var(--sx-color-surface-2);
163
166
  color: var(--sx-color-text-secondary);
167
+ border-color: rgba(255, 255, 255, 0.04);
168
+ border-bottom-color: rgba(0, 0, 0, 0.15);
164
169
  }
165
170
 
166
171
  .sx-badge-dot.sx-badge-neutral {
167
172
  background: var(--sx-color-text-secondary);
168
173
  border: none;
174
+ box-shadow: 0 0 4px -1px rgba(160, 160, 180, 0.3);
169
175
  }
170
176
 
171
- /* Primary — vermilion */
177
+ /* Primary — vermilion stamped tag */
172
178
  .sx-badge-primary {
173
179
  background: var(--sx-color-primary-active);
174
180
  color: var(--sx-color-primary);
181
+ border-color: rgba(255, 107, 53, 0.1);
182
+ border-bottom-color: rgba(160, 50, 10, 0.2);
183
+ box-shadow:
184
+ 0 1px 0 0 rgba(160, 50, 10, 0.25),
185
+ 0 2px 4px -1px rgba(0, 0, 0, 0.2),
186
+ 0 0 6px -2px rgba(255, 107, 53, 0.15);
175
187
  }
176
188
 
177
189
  .sx-badge-dot.sx-badge-primary {
178
190
  background: var(--sx-color-primary);
179
191
  border: none;
192
+ box-shadow: 0 0 6px -1px rgba(255, 107, 53, 0.4);
180
193
  }
181
194
 
182
- /* Success — green */
195
+ /* Success — green stamped tag */
183
196
  .sx-badge-success {
184
197
  background: var(--sx-color-green-subtle);
185
198
  color: var(--sx-color-green);
199
+ border-color: rgba(34, 197, 94, 0.08);
200
+ border-bottom-color: rgba(20, 100, 50, 0.2);
201
+ box-shadow:
202
+ 0 1px 0 0 rgba(20, 100, 50, 0.25),
203
+ 0 2px 4px -1px rgba(0, 0, 0, 0.2),
204
+ 0 0 6px -2px rgba(34, 197, 94, 0.12);
186
205
  }
187
206
 
188
207
  .sx-badge-dot.sx-badge-success {
189
208
  background: var(--sx-color-green);
190
209
  border: none;
210
+ box-shadow: 0 0 6px -1px rgba(34, 197, 94, 0.4);
191
211
  }
192
212
 
193
- /* Warning — brass */
213
+ /* Warning — brass stamped tag */
194
214
  .sx-badge-warning {
195
215
  background: var(--sx-color-brass-subtle);
196
216
  color: var(--sx-color-secondary);
217
+ border-color: rgba(200, 168, 78, 0.08);
218
+ border-bottom-color: rgba(130, 108, 50, 0.2);
219
+ box-shadow:
220
+ 0 1px 0 0 rgba(130, 108, 50, 0.25),
221
+ 0 2px 4px -1px rgba(0, 0, 0, 0.2),
222
+ 0 0 6px -2px rgba(200, 168, 78, 0.12);
197
223
  }
198
224
 
199
225
  .sx-badge-dot.sx-badge-warning {
200
226
  background: var(--sx-color-secondary);
201
227
  border: none;
228
+ box-shadow: 0 0 6px -1px rgba(200, 168, 78, 0.4);
202
229
  }
203
230
 
204
- /* Error — red */
231
+ /* Error — crimson stamped tag */
205
232
  .sx-badge-error {
206
233
  background: var(--sx-color-red-hover);
207
234
  color: var(--sx-color-red);
235
+ border-color: rgba(220, 38, 38, 0.08);
236
+ border-bottom-color: rgba(140, 20, 20, 0.2);
237
+ box-shadow:
238
+ 0 1px 0 0 rgba(140, 20, 20, 0.25),
239
+ 0 2px 4px -1px rgba(0, 0, 0, 0.2),
240
+ 0 0 6px -2px rgba(220, 38, 38, 0.12);
208
241
  }
209
242
 
210
243
  .sx-badge-dot.sx-badge-error {
211
244
  background: var(--sx-color-red);
212
245
  border: none;
246
+ box-shadow: 0 0 6px -1px rgba(220, 38, 38, 0.4);
213
247
  }
214
248
 
215
- /* Info — teal */
249
+ /* Info — teal stamped tag */
216
250
  .sx-badge-info {
217
251
  background: var(--sx-color-teal-subtle);
218
252
  color: var(--sx-color-teal);
253
+ border-color: rgba(61, 139, 139, 0.08);
254
+ border-bottom-color: rgba(30, 80, 80, 0.2);
255
+ box-shadow:
256
+ 0 1px 0 0 rgba(30, 80, 80, 0.25),
257
+ 0 2px 4px -1px rgba(0, 0, 0, 0.2),
258
+ 0 0 6px -2px rgba(61, 139, 139, 0.12);
219
259
  }
220
260
 
221
261
  .sx-badge-dot.sx-badge-info {
222
262
  background: var(--sx-color-teal);
223
263
  border: none;
264
+ box-shadow: 0 0 6px -1px rgba(61, 139, 139, 0.4);
224
265
  }
225
266
 
226
- /* Outline — transparent with border */
267
+ /* Outline — recessed stamp, no fill */
227
268
  .sx-badge-outline {
228
269
  background: transparent;
229
270
  color: var(--sx-color-text-secondary);
230
271
  border: 1px solid var(--sx-color-border-strong);
272
+ box-shadow:
273
+ inset 0 1px 2px rgba(0, 0, 0, 0.15),
274
+ 0 1px 0 0 rgba(255, 255, 255, 0.03);
231
275
  }
232
276
 
233
277
  .sx-badge-dot.sx-badge-outline {
234
278
  background: var(--sx-color-border-strong);
235
279
  border: none;
280
+ box-shadow: none;
236
281
  }
237
282
 
238
283
  @media (prefers-reduced-motion: reduce) {