@salmexio/ui 0.3.1 → 1.0.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 (110) hide show
  1. package/README.md +52 -3
  2. package/dist/dialogs/ContextMenu/ContextMenu.svelte +96 -93
  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 -102
  6. package/dist/dialogs/Modal/Modal.svelte.d.ts +1 -1
  7. package/dist/feedback/Alert/Alert.svelte +115 -221
  8. package/dist/feedback/Alert/Alert.svelte.d.ts +1 -1
  9. package/dist/feedback/ProgressBar/ProgressBar.svelte +246 -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 +153 -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 +88 -154
  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 +82 -103
  37. package/dist/forms/Checkbox/Checkbox.svelte.d.ts +1 -1
  38. package/dist/forms/Select/Select.svelte +136 -177
  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 +148 -164
  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 +64 -40
  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/navigation/CommandPalette/CommandPalette.svelte +410 -181
  72. package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts +8 -3
  73. package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts.map +1 -1
  74. package/dist/navigation/Tabs/Tabs.svelte +94 -178
  75. package/dist/navigation/Tabs/Tabs.svelte.d.ts +2 -2
  76. package/dist/primitives/Badge/Badge.svelte +85 -223
  77. package/dist/primitives/Badge/Badge.svelte.d.ts +2 -2
  78. package/dist/primitives/Badge/Badge.svelte.d.ts.map +1 -1
  79. package/dist/primitives/Button/Button.svelte +138 -208
  80. package/dist/primitives/Button/Button.svelte.d.ts +3 -3
  81. package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
  82. package/dist/primitives/Tooltip/Tooltip.svelte +260 -0
  83. package/dist/primitives/Tooltip/Tooltip.svelte.d.ts +36 -0
  84. package/dist/primitives/Tooltip/Tooltip.svelte.d.ts.map +1 -0
  85. package/dist/primitives/Tooltip/index.d.ts +2 -0
  86. package/dist/primitives/Tooltip/index.d.ts.map +1 -0
  87. package/dist/primitives/Tooltip/index.js +1 -0
  88. package/dist/primitives/index.d.ts +1 -0
  89. package/dist/primitives/index.d.ts.map +1 -1
  90. package/dist/primitives/index.js +1 -0
  91. package/dist/styles/tokens.css +200 -259
  92. package/package.json +5 -5
  93. package/dist/windowing/Window/Window.svelte +0 -602
  94. package/dist/windowing/Window/Window.svelte.d.ts +0 -65
  95. package/dist/windowing/Window/Window.svelte.d.ts.map +0 -1
  96. package/dist/windowing/Window/index.d.ts +0 -2
  97. package/dist/windowing/Window/index.d.ts.map +0 -1
  98. package/dist/windowing/Window/index.js +0 -1
  99. package/dist/windowing/WindowManager/WindowManager.svelte +0 -410
  100. package/dist/windowing/WindowManager/WindowManager.svelte.d.ts +0 -38
  101. package/dist/windowing/WindowManager/WindowManager.svelte.d.ts.map +0 -1
  102. package/dist/windowing/WindowManager/index.d.ts +0 -2
  103. package/dist/windowing/WindowManager/index.d.ts.map +0 -1
  104. package/dist/windowing/WindowManager/index.js +0 -1
  105. package/dist/windowing/index.d.ts +0 -5
  106. package/dist/windowing/index.d.ts.map +0 -1
  107. package/dist/windowing/index.js +0 -3
  108. package/dist/windowing/windowStore.svelte.d.ts +0 -49
  109. package/dist/windowing/windowStore.svelte.d.ts.map +0 -1
  110. 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
+ Neo-Brutalist Dark 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
+ Neo-Brutalist Dark — 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,81 +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: 3px solid rgb(var(--salmex-border-dark));
387
- box-shadow:
388
- inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
389
- inset -1px -1px 0 rgb(var(--salmex-button-shadow)),
390
- 5px 5px 0 rgb(0 0 0 / 0.35);
391
- 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;
392
393
  outline: none;
393
- font-family: var(--salmex-font-system);
394
- }
395
-
396
- :global([data-theme='dark']) .salmex-ctx {
397
- box-shadow:
398
- inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
399
- inset -1px -1px 0 rgb(var(--salmex-button-shadow)),
400
- 5px 5px 0 rgb(0 0 0 / 0.7);
401
394
  }
402
395
 
403
396
  /* ========================================
404
397
  SUBMENU — Positioned relative to parent
405
398
  ======================================== */
406
- .salmex-ctx-submenu {
399
+ .sx-context-submenu {
407
400
  position: absolute;
408
401
  }
409
402
 
410
403
  /* ========================================
411
404
  MENU ITEM
412
405
  ======================================== */
413
- .salmex-ctx-item {
406
+ .sx-context-item {
414
407
  display: flex;
415
408
  align-items: center;
416
- gap: var(--salmex-space-2);
417
- padding: var(--salmex-space-2) var(--salmex-space-4);
418
- font-size: var(--salmex-font-size-sm);
419
- font-weight: 600;
420
- 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);
421
414
  cursor: pointer;
422
415
  user-select: none;
423
416
  white-space: nowrap;
424
- 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);
425
421
  }
426
422
 
427
- .salmex-ctx-item-active {
428
- background: rgb(var(--salmex-electric-blue));
429
- color: rgb(var(--salmex-chalk-white));
423
+ .sx-context-item-active {
424
+ background: var(--sx-color-cyan-hover);
425
+ color: var(--sx-color-cyan);
430
426
  }
431
427
 
432
- :global([data-theme='dark']) .salmex-ctx-item-active {
433
- background: rgb(var(--salmex-primary-light));
434
- color: rgb(var(--salmex-midnight-black));
428
+ .sx-context-item-disabled {
429
+ color: var(--sx-color-text-disabled);
430
+ cursor: not-allowed;
435
431
  }
436
432
 
437
- .salmex-ctx-item-disabled {
438
- opacity: 0.4;
439
- 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);
440
437
  }
441
438
 
442
439
  /* ========================================
443
440
  ICON
444
441
  ======================================== */
445
- .salmex-ctx-icon {
442
+ .sx-context-icon {
446
443
  flex-shrink: 0;
447
444
  width: 16px;
448
- text-align: center;
449
- 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-cyan);
450
454
  }
451
455
 
452
- .salmex-ctx-icon-spacer {
456
+ .sx-context-icon-spacer {
453
457
  flex-shrink: 0;
454
458
  width: 16px;
455
459
  }
@@ -457,56 +461,55 @@ onMount(() => {
457
461
  /* ========================================
458
462
  LABEL & SHORTCUT
459
463
  ======================================== */
460
- .salmex-ctx-label {
464
+ .sx-context-label {
461
465
  flex: 1;
462
466
  }
463
467
 
464
- .salmex-ctx-shortcut {
465
- margin-left: var(--salmex-space-6);
466
- font-size: var(--salmex-font-size-xs);
467
- font-family: var(--salmex-font-mono);
468
- font-weight: 600;
469
- 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);
470
473
  text-align: right;
471
474
  }
472
475
 
473
- .salmex-ctx-item-active .salmex-ctx-shortcut {
474
- opacity: 0.85;
476
+ .sx-context-item-active .sx-context-shortcut {
477
+ color: var(--sx-color-cyan);
478
+ opacity: 0.7;
475
479
  }
476
480
 
477
481
  /* ========================================
478
482
  SUBMENU ARROW
479
483
  ======================================== */
480
- .salmex-ctx-submenu-arrow {
481
- margin-left: var(--salmex-space-4);
484
+ .sx-context-submenu-arrow {
485
+ margin-left: var(--sx-space-4);
482
486
  font-size: 8px;
483
- opacity: 0.7;
487
+ color: var(--sx-color-text-disabled);
484
488
  }
485
489
 
486
- .salmex-ctx-item-active .salmex-ctx-submenu-arrow {
487
- opacity: 1;
490
+ .sx-context-item-active .sx-context-submenu-arrow {
491
+ color: var(--sx-color-cyan);
488
492
  }
489
493
 
490
494
  /* ========================================
491
495
  SEPARATOR
492
496
  ======================================== */
493
- .salmex-ctx-separator {
497
+ .sx-context-separator {
494
498
  height: 0;
495
- margin: var(--salmex-space-1) var(--salmex-space-2);
496
- border-top: 1px solid rgb(var(--salmex-button-shadow));
497
- 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);
498
501
  }
499
502
 
500
503
  /* ========================================
501
504
  GROUP LABEL
502
505
  ======================================== */
503
- .salmex-ctx-group-label {
504
- padding: var(--salmex-space-2) var(--salmex-space-4) var(--salmex-space-1);
505
- font-size: var(--salmex-font-size-xs);
506
- font-weight: 700;
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;
507
511
  text-transform: uppercase;
508
- letter-spacing: 0.4px;
509
- color: rgb(var(--salmex-text-secondary));
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
+ * Neo-Brutalist Dark — 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"}