@salmexio/ui 0.4.0 → 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 +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 +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 +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 +82 -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 +151 -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 +64 -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/navigation/CommandPalette/CommandPalette.svelte +407 -189
  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 +95 -181
  75. package/dist/navigation/Tabs/Tabs.svelte.d.ts +2 -2
  76. package/dist/primitives/Badge/Badge.svelte +83 -220
  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 +144 -195
  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 +197 -265
  92. package/package.json +5 -5
  93. package/dist/windowing/Window/Window.svelte +0 -637
  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 -425
  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
@@ -0,0 +1,239 @@
1
+ <!--
2
+ @component Toggle
3
+
4
+ Neo-Brutalist Dark — Accessible toggle switch with on/off states,
5
+ label positioning, size variants, and keyboard support.
6
+ Uses role="switch" with aria-checked for screen readers.
7
+
8
+ @example
9
+ <Toggle label="Dark mode" bind:checked={darkMode} />
10
+ <Toggle label="Notifications" checked size="lg" />
11
+ <Toggle label="Auto-save" labelPosition="left" disabled />
12
+ -->
13
+ <script lang="ts">
14
+ import { cn } from '../../utils/cn.js';
15
+
16
+ type ToggleSize = 'sm' | 'md' | 'lg';
17
+ type LabelPosition = 'left' | 'right';
18
+
19
+ interface Props {
20
+ /** Accessible label text. */
21
+ label: string;
22
+ /** Current checked state. */
23
+ checked?: boolean;
24
+ /** Disabled state. */
25
+ disabled?: boolean;
26
+ /** Size variant. */
27
+ size?: ToggleSize;
28
+ /** Label placement relative to the switch. */
29
+ labelPosition?: LabelPosition;
30
+ /** Hide the visible label (still announced to SR). */
31
+ hideLabel?: boolean;
32
+ /** Description text shown below the label. */
33
+ description?: string;
34
+ /** Additional CSS class. */
35
+ class?: string;
36
+ /** Change handler. */
37
+ onchange?: (checked: boolean) => void;
38
+ testId?: string;
39
+ }
40
+
41
+ let {
42
+ label,
43
+ checked = $bindable(false),
44
+ disabled = false,
45
+ size = 'md',
46
+ labelPosition = 'right',
47
+ hideLabel = false,
48
+ description,
49
+ class: className = '',
50
+ onchange,
51
+ testId
52
+ }: Props = $props();
53
+
54
+ const id = `toggle-${Math.random().toString(36).slice(2, 9)}`;
55
+ const descId = $derived(description ? `${id}-desc` : undefined);
56
+
57
+ function toggle() {
58
+ if (disabled) return;
59
+ checked = !checked;
60
+ onchange?.(checked);
61
+ }
62
+
63
+
64
+ </script>
65
+
66
+ <div
67
+ class={cn(
68
+ 'sx-toggle-wrapper',
69
+ `sx-toggle-${size}`,
70
+ labelPosition === 'left' && 'sx-toggle-label-left',
71
+ disabled && 'sx-toggle-disabled',
72
+ className
73
+ )}
74
+ data-testid={testId}
75
+ >
76
+ <button
77
+ type="button"
78
+ {id}
79
+ role="switch"
80
+ aria-checked={checked}
81
+ aria-label={hideLabel ? label : undefined}
82
+ aria-describedby={descId}
83
+ {disabled}
84
+ class={cn('sx-toggle-track', checked && 'sx-toggle-checked')}
85
+ onclick={toggle}
86
+ >
87
+ <span class="sx-toggle-thumb" aria-hidden="true"></span>
88
+ </button>
89
+
90
+ {#if !hideLabel}
91
+ <div class="sx-toggle-text">
92
+ <label for={id} class="sx-toggle-label">
93
+ {label}
94
+ </label>
95
+ {#if description}
96
+ <p id={descId} class="sx-toggle-description">{description}</p>
97
+ {/if}
98
+ </div>
99
+ {/if}
100
+ </div>
101
+
102
+ <style>
103
+ .sx-toggle-wrapper {
104
+ display: inline-flex;
105
+ align-items: flex-start;
106
+ gap: var(--sx-space-3);
107
+ }
108
+
109
+ .sx-toggle-label-left {
110
+ flex-direction: row-reverse;
111
+ }
112
+
113
+ .sx-toggle-disabled {
114
+ opacity: 0.5;
115
+ pointer-events: none;
116
+ }
117
+
118
+ /* Track */
119
+ .sx-toggle-track {
120
+ position: relative;
121
+ flex-shrink: 0;
122
+ display: inline-flex;
123
+ align-items: center;
124
+ width: var(--sx-toggle-w, 44px);
125
+ height: var(--sx-toggle-h, 24px);
126
+ padding: 2px;
127
+ border: 1px solid var(--sx-color-border-strong);
128
+ border-radius: var(--sx-radius-full);
129
+ background: var(--sx-color-surface-2);
130
+ cursor: pointer;
131
+ transition:
132
+ background var(--sx-transition-fast),
133
+ border-color var(--sx-transition-fast);
134
+ }
135
+
136
+ .sx-toggle-track:hover:not(:disabled) {
137
+ border-color: var(--sx-color-border-hover);
138
+ }
139
+
140
+ .sx-toggle-track:focus-visible {
141
+ outline: none;
142
+ box-shadow: 0 0 0 3px var(--sx-color-cyan-ring);
143
+ }
144
+
145
+ .sx-toggle-checked {
146
+ background: var(--sx-color-cyan);
147
+ border-color: var(--sx-color-cyan);
148
+ }
149
+
150
+ .sx-toggle-checked:hover:not(:disabled) {
151
+ border-color: var(--sx-color-cyan);
152
+ background: var(--sx-color-cyan-bright, var(--sx-color-cyan));
153
+ }
154
+
155
+ /* Thumb */
156
+ .sx-toggle-thumb {
157
+ display: block;
158
+ width: var(--sx-toggle-thumb, 18px);
159
+ height: var(--sx-toggle-thumb, 18px);
160
+ border-radius: var(--sx-radius-full);
161
+ background: var(--sx-color-text);
162
+ transition: transform var(--sx-transition-fast);
163
+ box-shadow: var(--sx-shadow-sm);
164
+ }
165
+
166
+ .sx-toggle-checked .sx-toggle-thumb {
167
+ transform: translateX(calc(var(--sx-toggle-w, 44px) - var(--sx-toggle-thumb, 18px) - 6px));
168
+ }
169
+
170
+ /* Size variants */
171
+ .sx-toggle-sm {
172
+ --sx-toggle-w: 36px;
173
+ --sx-toggle-h: 20px;
174
+ --sx-toggle-thumb: 14px;
175
+ }
176
+
177
+ .sx-toggle-md {
178
+ --sx-toggle-w: 44px;
179
+ --sx-toggle-h: 24px;
180
+ --sx-toggle-thumb: 18px;
181
+ }
182
+
183
+ .sx-toggle-lg {
184
+ --sx-toggle-w: 52px;
185
+ --sx-toggle-h: 28px;
186
+ --sx-toggle-thumb: 22px;
187
+ }
188
+
189
+ /* Text */
190
+ .sx-toggle-text {
191
+ display: flex;
192
+ flex-direction: column;
193
+ gap: var(--sx-space-0-5);
194
+ min-width: 0;
195
+ }
196
+
197
+ .sx-toggle-label {
198
+ font-family: var(--sx-font-body);
199
+ font-size: var(--sx-text-sm);
200
+ font-weight: 500;
201
+ color: var(--sx-color-text);
202
+ line-height: var(--sx-leading-normal);
203
+ cursor: pointer;
204
+ user-select: none;
205
+ }
206
+
207
+ .sx-toggle-description {
208
+ margin: 0;
209
+ font-size: var(--sx-text-xs);
210
+ color: var(--sx-color-text-secondary);
211
+ line-height: var(--sx-leading-relaxed);
212
+ }
213
+
214
+ @media (prefers-reduced-motion: reduce) {
215
+ .sx-toggle-track,
216
+ .sx-toggle-thumb {
217
+ transition: none;
218
+ }
219
+ }
220
+
221
+ @media (forced-colors: active) {
222
+ .sx-toggle-track {
223
+ border: 2px solid ButtonText;
224
+ }
225
+
226
+ .sx-toggle-checked {
227
+ background: Highlight;
228
+ border-color: Highlight;
229
+ }
230
+
231
+ .sx-toggle-thumb {
232
+ background: ButtonText;
233
+ }
234
+
235
+ .sx-toggle-checked .sx-toggle-thumb {
236
+ background: HighlightText;
237
+ }
238
+ }
239
+ </style>
@@ -0,0 +1,39 @@
1
+ type ToggleSize = 'sm' | 'md' | 'lg';
2
+ type LabelPosition = 'left' | 'right';
3
+ interface Props {
4
+ /** Accessible label text. */
5
+ label: string;
6
+ /** Current checked state. */
7
+ checked?: boolean;
8
+ /** Disabled state. */
9
+ disabled?: boolean;
10
+ /** Size variant. */
11
+ size?: ToggleSize;
12
+ /** Label placement relative to the switch. */
13
+ labelPosition?: LabelPosition;
14
+ /** Hide the visible label (still announced to SR). */
15
+ hideLabel?: boolean;
16
+ /** Description text shown below the label. */
17
+ description?: string;
18
+ /** Additional CSS class. */
19
+ class?: string;
20
+ /** Change handler. */
21
+ onchange?: (checked: boolean) => void;
22
+ testId?: string;
23
+ }
24
+ /**
25
+ * Toggle
26
+ *
27
+ * Neo-Brutalist Dark — Accessible toggle switch with on/off states,
28
+ * label positioning, size variants, and keyboard support.
29
+ * Uses role="switch" with aria-checked for screen readers.
30
+ *
31
+ * @example
32
+ * <Toggle label="Dark mode" bind:checked={darkMode} />
33
+ * <Toggle label="Notifications" checked size="lg" />
34
+ * <Toggle label="Auto-save" labelPosition="left" disabled />
35
+ */
36
+ declare const Toggle: import("svelte").Component<Props, {}, "checked">;
37
+ type Toggle = ReturnType<typeof Toggle>;
38
+ export default Toggle;
39
+ //# sourceMappingURL=Toggle.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toggle.svelte.d.ts","sourceRoot":"","sources":["../../../src/forms/Toggle/Toggle.svelte.ts"],"names":[],"mappings":"AAMA,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACrC,KAAK,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtC,UAAU,KAAK;IACd,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,sDAAsD;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AA4DD;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,MAAM,kDAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as Toggle } from './Toggle.svelte';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/forms/Toggle/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1 @@
1
+ export { default as Toggle } from './Toggle.svelte';
@@ -2,4 +2,7 @@ export { TextInput } from './TextInput/index.js';
2
2
  export { Checkbox } from './Checkbox/index.js';
3
3
  export { Select } from './Select/index.js';
4
4
  export type { SelectOption, SelectGroup } from './Select/index.js';
5
+ export { Textarea } from './Textarea/index.js';
6
+ export { Slider } from './Slider/index.js';
7
+ export { Toggle } from './Toggle/index.js';
5
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/forms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/forms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,3 +1,6 @@
1
1
  export { TextInput } from './TextInput/index.js';
2
2
  export { Checkbox } from './Checkbox/index.js';
3
3
  export { Select } from './Select/index.js';
4
+ export { Textarea } from './Textarea/index.js';
5
+ export { Slider } from './Slider/index.js';
6
+ export { Toggle } from './Toggle/index.js';
package/dist/index.d.ts CHANGED
@@ -4,6 +4,5 @@ export * from './layout/index.js';
4
4
  export * from './feedback/index.js';
5
5
  export * from './forms/index.js';
6
6
  export * from './dialogs/index.js';
7
- export * from './windowing/index.js';
8
7
  export * from './utils/index.js';
9
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -4,5 +4,4 @@ export * from './layout/index.js';
4
4
  export * from './feedback/index.js';
5
5
  export * from './forms/index.js';
6
6
  export * from './dialogs/index.js';
7
- export * from './windowing/index.js';
8
7
  export * from './utils/index.js';
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
  @component Card
3
3
 
4
- Win2K × Basquiat Panel with canvas background, bold 3px borders, flat shadow.
4
+ Neo-Brutalist DarkGlassmorphic panel with frosted background, subtle borders.
5
5
  Optional header/footer, semantic element support.
6
6
 
7
7
  @example
@@ -43,9 +43,9 @@ let {
43
43
  }: Props = $props();
44
44
 
45
45
  const paddingValues: Record<CardPadding, string> = {
46
- sm: 'var(--salmex-space-4)',
47
- md: 'var(--salmex-space-6)',
48
- lg: 'var(--salmex-space-8)'
46
+ sm: 'var(--sx-space-4)',
47
+ md: 'var(--sx-space-6)',
48
+ lg: 'var(--sx-space-8)'
49
49
  };
50
50
 
51
51
  const currentPadding = $derived(paddingValues[padding]);
@@ -54,21 +54,21 @@ const currentPadding = $derived(paddingValues[padding]);
54
54
  {#snippet cardContent()}
55
55
  {#if header}
56
56
  <div
57
- class="salmex-card-header"
58
- style="margin: calc(-1 * {currentPadding}) calc(-1 * {currentPadding}) {currentPadding}; padding: var(--salmex-space-4) {currentPadding};"
57
+ class="sx-card-header"
58
+ style="margin: calc(-1 * {currentPadding}) calc(-1 * {currentPadding}) {currentPadding}; padding: var(--sx-space-4) {currentPadding};"
59
59
  >
60
60
  {@render header()}
61
61
  </div>
62
62
  {/if}
63
63
  {#if children}
64
- <div class="salmex-card-content">
64
+ <div class="sx-card-content">
65
65
  {@render children()}
66
66
  </div>
67
67
  {/if}
68
68
  {#if footer}
69
69
  <div
70
- class="salmex-card-footer"
71
- style="margin: {currentPadding} calc(-1 * {currentPadding}) calc(-1 * {currentPadding}); padding: var(--salmex-space-4) {currentPadding};"
70
+ class="sx-card-footer"
71
+ style="margin: {currentPadding} calc(-1 * {currentPadding}) calc(-1 * {currentPadding}); padding: var(--sx-space-4) {currentPadding};"
72
72
  >
73
73
  {@render footer()}
74
74
  </div>
@@ -80,63 +80,88 @@ const currentPadding = $derived(paddingValues[padding]);
80
80
  this={as}
81
81
  {id}
82
82
  class={cn(
83
- 'salmex-card',
84
- `salmex-card-padding-${padding}`,
83
+ 'sx-card',
84
+ `sx-card-padding-${padding}`,
85
+ onclick && 'sx-card-clickable',
85
86
  className
86
87
  )}
88
+ role={onclick ? 'button' : undefined}
89
+ tabindex={onclick ? 0 : undefined}
87
90
  aria-labelledby={ariaLabelledby}
88
91
  data-testid={testId}
89
92
  {onclick}
90
- {onkeydown}
93
+ onkeydown={(e: KeyboardEvent) => {
94
+ if (onclick && (e.key === 'Enter' || e.key === ' ')) {
95
+ e.preventDefault();
96
+ onclick(e as unknown as MouseEvent);
97
+ }
98
+ onkeydown?.(e);
99
+ }}
91
100
  >
92
101
  {@render cardContent()}
93
102
  </svelte:element>
94
103
 
95
104
  <style>
96
- .salmex-card {
105
+ .sx-card {
97
106
  position: relative;
98
107
  overflow: hidden;
99
- border-radius: var(--salmex-radius-sm);
100
- background: rgb(var(--salmex-window-surface));
101
- /* Bold 2px border, flat shadow — Win2K × Basquiat */
102
- border: 2px solid rgb(var(--salmex-border-dark));
103
- box-shadow: var(--salmex-shadow-lg);
108
+ border-radius: var(--sx-radius-lg);
109
+ background: var(--sx-glass-bg);
110
+ border: var(--sx-glass-border);
111
+ backdrop-filter: var(--sx-glass-blur);
112
+ -webkit-backdrop-filter: var(--sx-glass-blur);
113
+ transition: var(--sx-transition-base);
114
+ transition-property: transform, border-color, box-shadow;
104
115
  }
105
116
 
106
- .salmex-card-padding-sm {
107
- padding: var(--salmex-space-4);
117
+ .sx-card-clickable {
118
+ cursor: pointer;
108
119
  }
109
120
 
110
- .salmex-card-padding-md {
111
- padding: var(--salmex-space-6);
121
+ .sx-card-clickable:hover {
122
+ transform: translateY(-2px);
123
+ border-color: var(--sx-color-cyan-active);
124
+ box-shadow: var(--sx-shadow-md);
112
125
  }
113
126
 
114
- .salmex-card-padding-lg {
115
- padding: var(--salmex-space-8);
127
+ .sx-card-clickable:focus-visible {
128
+ outline: 2px solid var(--sx-color-cyan);
129
+ outline-offset: 2px;
116
130
  }
117
131
 
118
- .salmex-card-header {
119
- border-bottom: 1px solid rgb(var(--salmex-border-default));
120
- font-weight: 700;
121
- letter-spacing: 0.3px;
132
+ @media (prefers-reduced-motion: reduce) {
133
+ .sx-card {
134
+ transition: none;
135
+ }
136
+
137
+ .sx-card-clickable:hover {
138
+ transform: none;
139
+ }
122
140
  }
123
141
 
124
- .salmex-card-footer {
125
- border-top: 1px solid rgb(var(--salmex-border-default));
142
+ .sx-card-padding-sm {
143
+ padding: var(--sx-space-4);
126
144
  }
127
145
 
128
- .salmex-card-content {
129
- display: block;
146
+ .sx-card-padding-md {
147
+ padding: var(--sx-space-6);
130
148
  }
131
149
 
132
- /* Dark mode — heavier shadow (flat shadow on near-black bg is invisible) */
133
- :global([data-theme='dark']) .salmex-card {
134
- box-shadow: 4px 4px 2px rgb(0 0 0 / 0.6);
150
+ .sx-card-padding-lg {
151
+ padding: var(--sx-space-8);
135
152
  }
136
153
 
137
- @media (prefers-color-scheme: dark) {
138
- :global(:root:not([data-theme='light'])) .salmex-card {
139
- box-shadow: 4px 4px 2px rgb(0 0 0 / 0.6);
140
- }
154
+ .sx-card-header {
155
+ border-bottom: 1px solid var(--sx-color-border);
156
+ font-weight: 700;
157
+ letter-spacing: 0.3px;
158
+ }
159
+
160
+ .sx-card-footer {
161
+ border-top: 1px solid var(--sx-color-border);
162
+ }
163
+
164
+ .sx-card-content {
165
+ display: block;
141
166
  }
142
167
  </style>
@@ -16,7 +16,7 @@ interface Props {
16
16
  /**
17
17
  * Card
18
18
  *
19
- * Win2K × Basquiat Panel with canvas background, bold 3px borders, flat shadow.
19
+ * Neo-Brutalist DarkGlassmorphic panel with frosted background, subtle borders.
20
20
  * Optional header/footer, semantic element support.
21
21
  *
22
22
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"Card.svelte.d.ts","sourceRoot":"","sources":["../../../src/layout/Card/Card.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAItC,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtC,UAAU,KAAK;IACd,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,EAAE,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AA8DD;;;;;;;;;GASG;AACH,QAAA,MAAM,IAAI,2CAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"Card.svelte.d.ts","sourceRoot":"","sources":["../../../src/layout/Card/Card.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAItC,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtC,UAAU,KAAK;IACd,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,EAAE,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAqED;;;;;;;;;GASG;AACH,QAAA,MAAM,IAAI,2CAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}