@salmexio/ui 0.4.0 → 1.1.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 (119) hide show
  1. package/README.md +52 -3
  2. package/dist/dialogs/ContextMenu/ContextMenu.svelte +97 -94
  3. package/dist/dialogs/ContextMenu/ContextMenu.svelte.d.ts +3 -2
  4. package/dist/dialogs/ContextMenu/ContextMenu.svelte.d.ts.map +1 -1
  5. package/dist/dialogs/Modal/Modal.svelte +112 -116
  6. package/dist/dialogs/Modal/Modal.svelte.d.ts +1 -1
  7. package/dist/feedback/Alert/Alert.svelte +119 -220
  8. package/dist/feedback/Alert/Alert.svelte.d.ts +1 -1
  9. package/dist/feedback/ProgressBar/ProgressBar.svelte +265 -0
  10. package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts +40 -0
  11. package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts.map +1 -0
  12. package/dist/feedback/ProgressBar/index.d.ts +2 -0
  13. package/dist/feedback/ProgressBar/index.d.ts.map +1 -0
  14. package/dist/feedback/ProgressBar/index.js +1 -0
  15. package/dist/feedback/Skeleton/Skeleton.svelte +157 -0
  16. package/dist/feedback/Skeleton/Skeleton.svelte.d.ts +37 -0
  17. package/dist/feedback/Skeleton/Skeleton.svelte.d.ts.map +1 -0
  18. package/dist/feedback/Skeleton/index.d.ts +2 -0
  19. package/dist/feedback/Skeleton/index.d.ts.map +1 -0
  20. package/dist/feedback/Skeleton/index.js +1 -0
  21. package/dist/feedback/Spinner/Spinner.svelte +86 -151
  22. package/dist/feedback/Spinner/Spinner.svelte.d.ts +5 -3
  23. package/dist/feedback/Spinner/Spinner.svelte.d.ts.map +1 -1
  24. package/dist/feedback/Toast/Toaster.svelte +431 -0
  25. package/dist/feedback/Toast/Toaster.svelte.d.ts +22 -0
  26. package/dist/feedback/Toast/Toaster.svelte.d.ts.map +1 -0
  27. package/dist/feedback/Toast/index.d.ts +4 -0
  28. package/dist/feedback/Toast/index.d.ts.map +1 -0
  29. package/dist/feedback/Toast/index.js +2 -0
  30. package/dist/feedback/Toast/toastStore.d.ts +34 -0
  31. package/dist/feedback/Toast/toastStore.d.ts.map +1 -0
  32. package/dist/feedback/Toast/toastStore.js +43 -0
  33. package/dist/feedback/index.d.ts +4 -0
  34. package/dist/feedback/index.d.ts.map +1 -1
  35. package/dist/feedback/index.js +3 -0
  36. package/dist/forms/Checkbox/Checkbox.svelte +87 -104
  37. package/dist/forms/Checkbox/Checkbox.svelte.d.ts +1 -1
  38. package/dist/forms/Select/Select.svelte +137 -179
  39. package/dist/forms/Select/Select.svelte.d.ts +1 -1
  40. package/dist/forms/Slider/Slider.svelte +356 -0
  41. package/dist/forms/Slider/Slider.svelte.d.ts +50 -0
  42. package/dist/forms/Slider/Slider.svelte.d.ts.map +1 -0
  43. package/dist/forms/Slider/index.d.ts +2 -0
  44. package/dist/forms/Slider/index.d.ts.map +1 -0
  45. package/dist/forms/Slider/index.js +1 -0
  46. package/dist/forms/TextInput/TextInput.svelte +161 -167
  47. package/dist/forms/TextInput/TextInput.svelte.d.ts +1 -1
  48. package/dist/forms/Textarea/Textarea.svelte +615 -0
  49. package/dist/forms/Textarea/Textarea.svelte.d.ts +47 -0
  50. package/dist/forms/Textarea/Textarea.svelte.d.ts.map +1 -0
  51. package/dist/forms/Textarea/index.d.ts +2 -0
  52. package/dist/forms/Textarea/index.d.ts.map +1 -0
  53. package/dist/forms/Textarea/index.js +1 -0
  54. package/dist/forms/Toggle/Toggle.svelte +239 -0
  55. package/dist/forms/Toggle/Toggle.svelte.d.ts +39 -0
  56. package/dist/forms/Toggle/Toggle.svelte.d.ts.map +1 -0
  57. package/dist/forms/Toggle/index.d.ts +2 -0
  58. package/dist/forms/Toggle/index.d.ts.map +1 -0
  59. package/dist/forms/Toggle/index.js +1 -0
  60. package/dist/forms/index.d.ts +3 -0
  61. package/dist/forms/index.d.ts.map +1 -1
  62. package/dist/forms/index.js +3 -0
  63. package/dist/index.d.ts +0 -1
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +0 -1
  66. package/dist/layout/Card/Card.svelte +66 -39
  67. package/dist/layout/Card/Card.svelte.d.ts +1 -1
  68. package/dist/layout/Card/Card.svelte.d.ts.map +1 -1
  69. package/dist/layout/Container/Container.svelte +71 -71
  70. package/dist/layout/Container/Container.svelte.d.ts +2 -2
  71. package/dist/layout/ThermalBackground/ThermalBackground.svelte +313 -0
  72. package/dist/layout/ThermalBackground/ThermalBackground.svelte.d.ts +16 -0
  73. package/dist/layout/ThermalBackground/ThermalBackground.svelte.d.ts.map +1 -0
  74. package/dist/layout/ThermalBackground/index.d.ts +2 -0
  75. package/dist/layout/ThermalBackground/index.d.ts.map +1 -0
  76. package/dist/layout/ThermalBackground/index.js +1 -0
  77. package/dist/layout/index.d.ts +1 -0
  78. package/dist/layout/index.d.ts.map +1 -1
  79. package/dist/layout/index.js +1 -0
  80. package/dist/navigation/CommandPalette/CommandPalette.svelte +407 -189
  81. package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts +8 -3
  82. package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts.map +1 -1
  83. package/dist/navigation/Tabs/Tabs.svelte +139 -192
  84. package/dist/navigation/Tabs/Tabs.svelte.d.ts +2 -2
  85. package/dist/primitives/Badge/Badge.svelte +85 -220
  86. package/dist/primitives/Badge/Badge.svelte.d.ts +2 -2
  87. package/dist/primitives/Badge/Badge.svelte.d.ts.map +1 -1
  88. package/dist/primitives/Button/Button.svelte +214 -194
  89. package/dist/primitives/Button/Button.svelte.d.ts +3 -3
  90. package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
  91. package/dist/primitives/Tooltip/Tooltip.svelte +260 -0
  92. package/dist/primitives/Tooltip/Tooltip.svelte.d.ts +36 -0
  93. package/dist/primitives/Tooltip/Tooltip.svelte.d.ts.map +1 -0
  94. package/dist/primitives/Tooltip/index.d.ts +2 -0
  95. package/dist/primitives/Tooltip/index.d.ts.map +1 -0
  96. package/dist/primitives/Tooltip/index.js +1 -0
  97. package/dist/primitives/index.d.ts +1 -0
  98. package/dist/primitives/index.d.ts.map +1 -1
  99. package/dist/primitives/index.js +1 -0
  100. package/dist/styles/tokens.css +329 -260
  101. package/package.json +5 -5
  102. package/dist/windowing/Window/Window.svelte +0 -637
  103. package/dist/windowing/Window/Window.svelte.d.ts +0 -65
  104. package/dist/windowing/Window/Window.svelte.d.ts.map +0 -1
  105. package/dist/windowing/Window/index.d.ts +0 -2
  106. package/dist/windowing/Window/index.d.ts.map +0 -1
  107. package/dist/windowing/Window/index.js +0 -1
  108. package/dist/windowing/WindowManager/WindowManager.svelte +0 -425
  109. package/dist/windowing/WindowManager/WindowManager.svelte.d.ts +0 -38
  110. package/dist/windowing/WindowManager/WindowManager.svelte.d.ts.map +0 -1
  111. package/dist/windowing/WindowManager/index.d.ts +0 -2
  112. package/dist/windowing/WindowManager/index.d.ts.map +0 -1
  113. package/dist/windowing/WindowManager/index.js +0 -1
  114. package/dist/windowing/index.d.ts +0 -5
  115. package/dist/windowing/index.d.ts.map +0 -1
  116. package/dist/windowing/index.js +0 -3
  117. package/dist/windowing/windowStore.svelte.d.ts +0 -49
  118. package/dist/windowing/windowStore.svelte.d.ts.map +0 -1
  119. package/dist/windowing/windowStore.svelte.js +0 -170
package/README.md CHANGED
@@ -1,7 +1,56 @@
1
1
  # @salmexio/ui
2
2
 
3
- Experimental Svelte 5 UI component library. Use at your own risk.
3
+ INFRARED component library for Salmex I/O products. Built with Svelte 5 and TypeScript.
4
4
 
5
- **Install:** `pnpm add @salmexio/ui` or `npm i @salmexio/ui`
5
+ ## Install
6
6
 
7
- UNLICENSED.
7
+ ```bash
8
+ pnpm add @salmexio/ui
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```svelte
14
+ <script>
15
+ import { Button, TextInput, Card } from '@salmexio/ui';
16
+ import '@salmexio/ui/styles';
17
+ </script>
18
+
19
+ <Card>
20
+ <TextInput label="Name" placeholder="Enter your name" />
21
+ <Button variant="primary">Submit</Button>
22
+ </Card>
23
+ ```
24
+
25
+ ## Components
26
+
27
+ | Category | Components |
28
+ |---|---|
29
+ | **Primitives** | Button, Badge, Tooltip |
30
+ | **Layout** | Card, Container |
31
+ | **Forms** | TextInput, Textarea, Checkbox, Select, Slider, Toggle |
32
+ | **Feedback** | Alert, Spinner, Toast, ProgressBar, Skeleton |
33
+ | **Navigation** | Tabs, CommandPalette |
34
+ | **Dialogs** | Modal, ContextMenu |
35
+
36
+ ## Exports
37
+
38
+ - `@salmexio/ui` — All components
39
+ - `@salmexio/ui/styles` — Design tokens CSS
40
+ - `@salmexio/ui/primitives` — Primitive components only
41
+ - `@salmexio/ui/navigation` — Navigation components only
42
+ - `@salmexio/ui/utils` — Utilities (cn)
43
+
44
+ ## Development
45
+
46
+ ```bash
47
+ pnpm dev # Watch mode
48
+ pnpm build # Build for production
49
+ pnpm test # Run tests
50
+ pnpm check # Type check
51
+ pnpm lint # Lint code
52
+ ```
53
+
54
+ ## License
55
+
56
+ UNLICENSED — (c) 2026 Salmen Hichri
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
  @component ContextMenu
3
3
 
4
- Win2K × Basquiat — Right-click context menu with raised panel, keyboard navigation,
4
+ INFRARED — Right-click context menu with glass panel, keyboard navigation,
5
5
  separators, section headers, submenus, and keyboard shortcut hints.
6
6
 
7
7
  @example
@@ -19,12 +19,14 @@
19
19
  </div>
20
20
  -->
21
21
  <script lang="ts" module>
22
+ import type { Snippet } from 'svelte';
23
+
22
24
  export interface MenuItem {
23
25
  type: 'item';
24
26
  label: string;
25
27
  shortcut?: string;
26
28
  disabled?: boolean;
27
- icon?: string;
29
+ icon?: Snippet;
28
30
  action?: () => void;
29
31
  children?: MenuItemOrSeparator[];
30
32
  }
@@ -259,7 +261,7 @@ onMount(() => {
259
261
  <!-- svelte-ignore a11y_no_noninteractive_element_interactions a11y_click_events_have_key_events -->
260
262
  <div
261
263
  bind:this={menuEl}
262
- class={cn('salmex-ctx', className)}
264
+ class={cn('sx-context', className)}
263
265
  style="left: {posX}px; top: {posY}px;"
264
266
  role="menu"
265
267
  tabindex="-1"
@@ -268,16 +270,16 @@ onMount(() => {
268
270
  >
269
271
  {#each items as item, i}
270
272
  {#if item.type === 'separator'}
271
- <div class="salmex-ctx-separator" role="separator"></div>
273
+ <div class="sx-context-separator" role="separator"></div>
272
274
  {:else if item.type === 'group'}
273
- <div class="salmex-ctx-group-label">{item.label}</div>
275
+ <div class="sx-context-group-label">{item.label}</div>
274
276
  {#each item.items as groupItem}
275
277
  {#if groupItem.type === 'item'}
276
278
  <!-- svelte-ignore a11y_no_noninteractive_element_interactions a11y_click_events_have_key_events -->
277
279
  <div
278
280
  class={cn(
279
- 'salmex-ctx-item',
280
- groupItem.disabled && 'salmex-ctx-item-disabled'
281
+ 'sx-context-item',
282
+ groupItem.disabled && 'sx-context-item-disabled'
281
283
  )}
282
284
  role="menuitem"
283
285
  tabindex="-1"
@@ -287,26 +289,26 @@ onMount(() => {
287
289
  onmouseenter={() => { if (!groupItem.disabled) { activeIndex = -1; openSubmenuIndex = -1; } }}
288
290
  >
289
291
  {#if groupItem.icon}
290
- <span class="salmex-ctx-icon" aria-hidden="true">{groupItem.icon}</span>
292
+ <span class="sx-context-icon" aria-hidden="true">{@render groupItem.icon()}</span>
291
293
  {:else}
292
- <span class="salmex-ctx-icon-spacer"></span>
294
+ <span class="sx-context-icon-spacer"></span>
293
295
  {/if}
294
- <span class="salmex-ctx-label">{groupItem.label}</span>
296
+ <span class="sx-context-label">{groupItem.label}</span>
295
297
  {#if groupItem.shortcut}
296
- <span class="salmex-ctx-shortcut">{groupItem.shortcut}</span>
298
+ <span class="sx-context-shortcut">{groupItem.shortcut}</span>
297
299
  {/if}
298
300
  </div>
299
301
  {:else if groupItem.type === 'separator'}
300
- <div class="salmex-ctx-separator" role="separator"></div>
302
+ <div class="sx-context-separator" role="separator"></div>
301
303
  {/if}
302
304
  {/each}
303
305
  {:else if item.type === 'item'}
304
306
  <!-- svelte-ignore a11y_no_noninteractive_element_interactions a11y_click_events_have_key_events -->
305
307
  <div
306
308
  class={cn(
307
- 'salmex-ctx-item',
308
- i === activeIndex && 'salmex-ctx-item-active',
309
- item.disabled && 'salmex-ctx-item-disabled'
309
+ 'sx-context-item',
310
+ i === activeIndex && 'sx-context-item-active',
311
+ item.disabled && 'sx-context-item-disabled'
310
312
  )}
311
313
  role="menuitem"
312
314
  tabindex="-1"
@@ -317,35 +319,35 @@ onMount(() => {
317
319
  onkeydown={handleKeydown}
318
320
  >
319
321
  {#if item.icon}
320
- <span class="salmex-ctx-icon" aria-hidden="true">{item.icon}</span>
322
+ <span class="sx-context-icon" aria-hidden="true">{@render item.icon()}</span>
321
323
  {:else}
322
- <span class="salmex-ctx-icon-spacer"></span>
324
+ <span class="sx-context-icon-spacer"></span>
323
325
  {/if}
324
- <span class="salmex-ctx-label">{item.label}</span>
326
+ <span class="sx-context-label">{item.label}</span>
325
327
  {#if item.children?.length}
326
- <span class="salmex-ctx-submenu-arrow" aria-hidden="true">&#9654;</span>
328
+ <span class="sx-context-submenu-arrow" aria-hidden="true">&#9654;</span>
327
329
  {:else if item.shortcut}
328
- <span class="salmex-ctx-shortcut">{item.shortcut}</span>
330
+ <span class="sx-context-shortcut">{item.shortcut}</span>
329
331
  {/if}
330
332
  </div>
331
333
 
332
334
  <!-- Submenu -->
333
335
  {#if openSubmenuIndex === i && item.children?.length}
334
336
  <div
335
- class="salmex-ctx salmex-ctx-submenu"
337
+ class="sx-context sx-context-submenu"
336
338
  style="left: {submenuPosX}px; top: {submenuPosY}px;"
337
339
  role="menu"
338
340
  >
339
341
  {#each item.children as subItem, si}
340
342
  {#if subItem.type === 'separator'}
341
- <div class="salmex-ctx-separator" role="separator"></div>
343
+ <div class="sx-context-separator" role="separator"></div>
342
344
  {:else if subItem.type === 'item'}
343
345
  <!-- svelte-ignore a11y_no_noninteractive_element_interactions a11y_click_events_have_key_events -->
344
346
  <div
345
347
  class={cn(
346
- 'salmex-ctx-item',
347
- si === submenuActiveIndex && 'salmex-ctx-item-active',
348
- subItem.disabled && 'salmex-ctx-item-disabled'
348
+ 'sx-context-item',
349
+ si === submenuActiveIndex && 'sx-context-item-active',
350
+ subItem.disabled && 'sx-context-item-disabled'
349
351
  )}
350
352
  role="menuitem"
351
353
  tabindex="-1"
@@ -355,13 +357,13 @@ onMount(() => {
355
357
  onkeydown={handleKeydown}
356
358
  >
357
359
  {#if subItem.icon}
358
- <span class="salmex-ctx-icon" aria-hidden="true">{subItem.icon}</span>
360
+ <span class="sx-context-icon" aria-hidden="true">{@render subItem.icon()}</span>
359
361
  {:else}
360
- <span class="salmex-ctx-icon-spacer"></span>
362
+ <span class="sx-context-icon-spacer"></span>
361
363
  {/if}
362
- <span class="salmex-ctx-label">{subItem.label}</span>
364
+ <span class="sx-context-label">{subItem.label}</span>
363
365
  {#if subItem.shortcut}
364
- <span class="salmex-ctx-shortcut">{subItem.shortcut}</span>
366
+ <span class="sx-context-shortcut">{subItem.shortcut}</span>
365
367
  {/if}
366
368
  </div>
367
369
  {/if}
@@ -375,82 +377,83 @@ onMount(() => {
375
377
 
376
378
  <style>
377
379
  /* ========================================
378
- MENU PANEL — Raised, bold shadow
380
+ MENU PANEL
379
381
  ======================================== */
380
- .salmex-ctx {
382
+ .sx-context {
381
383
  position: fixed;
382
- z-index: var(--salmex-z-popover);
384
+ z-index: var(--sx-z-popover, 1060);
383
385
  min-width: 180px;
384
386
  max-width: 320px;
385
- background: rgb(var(--salmex-bg-primary));
386
- border: 2px solid rgb(var(--salmex-border-dark));
387
- border-radius: var(--salmex-radius-md);
388
- box-shadow:
389
- inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
390
- inset -1px -1px 0 rgb(var(--salmex-button-shadow)),
391
- 4px 4px 2px rgb(0 0 0 / 0.3);
392
- padding: var(--salmex-space-1) 0;
387
+ background: var(--sx-color-surface-2);
388
+ border: 1px solid var(--sx-color-border-strong);
389
+ border-radius: var(--sx-radius-md);
390
+ box-shadow: var(--sx-shadow-lg);
391
+ backdrop-filter: var(--sx-glass-blur);
392
+ padding: var(--sx-space-1) 0;
393
393
  outline: none;
394
- font-family: var(--salmex-font-system);
395
- }
396
-
397
- :global([data-theme='dark']) .salmex-ctx {
398
- box-shadow:
399
- inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
400
- inset -1px -1px 0 rgb(var(--salmex-button-shadow)),
401
- 4px 4px 2px rgb(0 0 0 / 0.6);
402
394
  }
403
395
 
404
396
  /* ========================================
405
397
  SUBMENU — Positioned relative to parent
406
398
  ======================================== */
407
- .salmex-ctx-submenu {
399
+ .sx-context-submenu {
408
400
  position: absolute;
409
401
  }
410
402
 
411
403
  /* ========================================
412
404
  MENU ITEM
413
405
  ======================================== */
414
- .salmex-ctx-item {
406
+ .sx-context-item {
415
407
  display: flex;
416
408
  align-items: center;
417
- gap: var(--salmex-space-2);
418
- padding: var(--salmex-space-2) var(--salmex-space-4);
419
- font-size: var(--salmex-font-size-sm);
420
- font-weight: 600;
421
- color: rgb(var(--salmex-text-primary));
409
+ gap: var(--sx-space-2);
410
+ padding: var(--sx-space-2) var(--sx-space-3);
411
+ margin: 0 var(--sx-space-1);
412
+ font-size: var(--sx-text-sm);
413
+ color: var(--sx-color-text);
422
414
  cursor: pointer;
423
415
  user-select: none;
424
416
  white-space: nowrap;
425
- transition: background var(--salmex-transition-fast);
417
+ border-radius: var(--sx-radius-sm);
418
+ transition:
419
+ background var(--sx-transition-fast),
420
+ color var(--sx-transition-fast);
426
421
  }
427
422
 
428
- .salmex-ctx-item-active {
429
- background: rgb(var(--salmex-electric-blue));
430
- color: rgb(var(--salmex-chalk-white));
423
+ .sx-context-item-active {
424
+ background: var(--sx-color-primary-hover);
425
+ color: var(--sx-color-primary);
431
426
  }
432
427
 
433
- :global([data-theme='dark']) .salmex-ctx-item-active {
434
- background: rgb(var(--salmex-primary-light));
435
- color: rgb(var(--salmex-midnight-black));
428
+ .sx-context-item-disabled {
429
+ color: var(--sx-color-text-disabled);
430
+ cursor: not-allowed;
436
431
  }
437
432
 
438
- .salmex-ctx-item-disabled {
439
- opacity: 0.4;
440
- cursor: not-allowed;
433
+ .sx-context-item-disabled:hover,
434
+ .sx-context-item-disabled.sx-context-item-active {
435
+ background: transparent;
436
+ color: var(--sx-color-text-disabled);
441
437
  }
442
438
 
443
439
  /* ========================================
444
440
  ICON
445
441
  ======================================== */
446
- .salmex-ctx-icon {
442
+ .sx-context-icon {
447
443
  flex-shrink: 0;
448
444
  width: 16px;
449
- text-align: center;
450
- font-size: 14px;
445
+ height: 16px;
446
+ display: flex;
447
+ align-items: center;
448
+ justify-content: center;
449
+ color: var(--sx-color-text-secondary);
450
+ }
451
+
452
+ .sx-context-item-active .sx-context-icon {
453
+ color: var(--sx-color-primary);
451
454
  }
452
455
 
453
- .salmex-ctx-icon-spacer {
456
+ .sx-context-icon-spacer {
454
457
  flex-shrink: 0;
455
458
  width: 16px;
456
459
  }
@@ -458,55 +461,55 @@ onMount(() => {
458
461
  /* ========================================
459
462
  LABEL & SHORTCUT
460
463
  ======================================== */
461
- .salmex-ctx-label {
464
+ .sx-context-label {
462
465
  flex: 1;
463
466
  }
464
467
 
465
- .salmex-ctx-shortcut {
466
- margin-left: var(--salmex-space-6);
467
- font-size: var(--salmex-font-size-xs);
468
- font-family: var(--salmex-font-mono);
469
- font-weight: 600;
470
- opacity: 0.6;
468
+ .sx-context-shortcut {
469
+ margin-left: var(--sx-space-6);
470
+ font-size: var(--sx-text-xs);
471
+ font-family: var(--sx-font-mono);
472
+ color: var(--sx-color-text-disabled);
471
473
  text-align: right;
472
474
  }
473
475
 
474
- .salmex-ctx-item-active .salmex-ctx-shortcut {
475
- opacity: 0.85;
476
+ .sx-context-item-active .sx-context-shortcut {
477
+ color: var(--sx-color-primary);
478
+ opacity: 0.7;
476
479
  }
477
480
 
478
481
  /* ========================================
479
482
  SUBMENU ARROW
480
483
  ======================================== */
481
- .salmex-ctx-submenu-arrow {
482
- margin-left: var(--salmex-space-4);
484
+ .sx-context-submenu-arrow {
485
+ margin-left: var(--sx-space-4);
483
486
  font-size: 8px;
484
- opacity: 0.7;
487
+ color: var(--sx-color-text-disabled);
485
488
  }
486
489
 
487
- .salmex-ctx-item-active .salmex-ctx-submenu-arrow {
488
- opacity: 1;
490
+ .sx-context-item-active .sx-context-submenu-arrow {
491
+ color: var(--sx-color-primary);
489
492
  }
490
493
 
491
494
  /* ========================================
492
495
  SEPARATOR
493
496
  ======================================== */
494
- .salmex-ctx-separator {
497
+ .sx-context-separator {
495
498
  height: 0;
496
- margin: var(--salmex-space-1) var(--salmex-space-2);
497
- border-top: 1px solid rgb(var(--salmex-button-shadow));
498
- border-bottom: 1px solid rgb(var(--salmex-button-highlight));
499
+ margin: var(--sx-space-1) var(--sx-space-2);
500
+ border-top: 1px solid var(--sx-color-border);
499
501
  }
500
502
 
501
503
  /* ========================================
502
504
  GROUP LABEL
503
505
  ======================================== */
504
- .salmex-ctx-group-label {
505
- padding: var(--salmex-space-2) var(--salmex-space-4) var(--salmex-space-1);
506
- font-size: var(--salmex-font-size-xs);
507
- font-weight: 700;
508
- letter-spacing: 0.4px;
509
- color: rgb(var(--salmex-text-secondary));
506
+ .sx-context-group-label {
507
+ padding: var(--sx-space-2) var(--sx-space-3) var(--sx-space-1);
508
+ font-size: var(--sx-text-xs);
509
+ font-weight: 600;
510
+ letter-spacing: 0.05em;
511
+ text-transform: uppercase;
512
+ color: var(--sx-color-text-disabled);
510
513
  user-select: none;
511
514
  }
512
515
 
@@ -514,7 +517,7 @@ onMount(() => {
514
517
  REDUCED MOTION
515
518
  ======================================== */
516
519
  @media (prefers-reduced-motion: reduce) {
517
- .salmex-ctx-item {
520
+ .sx-context-item {
518
521
  transition: none;
519
522
  }
520
523
  }
@@ -1,9 +1,10 @@
1
+ import type { Snippet } from 'svelte';
1
2
  export interface MenuItem {
2
3
  type: 'item';
3
4
  label: string;
4
5
  shortcut?: string;
5
6
  disabled?: boolean;
6
- icon?: string;
7
+ icon?: Snippet;
7
8
  action?: () => void;
8
9
  children?: MenuItemOrSeparator[];
9
10
  }
@@ -27,7 +28,7 @@ interface Props {
27
28
  /**
28
29
  * ContextMenu
29
30
  *
30
- * Win2K × Basquiat — Right-click context menu with raised panel, keyboard navigation,
31
+ * INFRARED — Right-click context menu with glass panel, keyboard navigation,
31
32
  * separators, section headers, submenus, and keyboard shortcut hints.
32
33
  *
33
34
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"ContextMenu.svelte.d.ts","sourceRoot":"","sources":["../../../src/dialogs/ContextMenu/ContextMenu.svelte.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,WAAW,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC7B;AAED,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;AAQvE,UAAU,KAAK;IACd,iBAAiB;IACjB,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAC7B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAsSD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,QAAA,MAAM,WAAW;cA5RC,MAAM,KAAK,MAAM;;MA4RsB,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ContextMenu.svelte.d.ts","sourceRoot":"","sources":["../../../src/dialogs/ContextMenu/ContextMenu.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,WAAW,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC7B;AAED,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;AAQvE,UAAU,KAAK;IACd,iBAAiB;IACjB,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAC7B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAsSD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,QAAA,MAAM,WAAW;cA5RC,MAAM,KAAK,MAAM;;MA4RsB,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}