@salmexio/ui 0.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 (82) hide show
  1. package/README.md +7 -0
  2. package/dist/app.html +11 -0
  3. package/dist/feedback/Alert/Alert.svelte +538 -0
  4. package/dist/feedback/Alert/Alert.svelte.d.ts +30 -0
  5. package/dist/feedback/Alert/Alert.svelte.d.ts.map +1 -0
  6. package/dist/feedback/Alert/index.d.ts +2 -0
  7. package/dist/feedback/Alert/index.d.ts.map +1 -0
  8. package/dist/feedback/Alert/index.js +1 -0
  9. package/dist/feedback/Spinner/Spinner.svelte +421 -0
  10. package/dist/feedback/Spinner/Spinner.svelte.d.ts +25 -0
  11. package/dist/feedback/Spinner/Spinner.svelte.d.ts.map +1 -0
  12. package/dist/feedback/Spinner/index.d.ts +2 -0
  13. package/dist/feedback/Spinner/index.d.ts.map +1 -0
  14. package/dist/feedback/Spinner/index.js +1 -0
  15. package/dist/feedback/index.d.ts +3 -0
  16. package/dist/feedback/index.d.ts.map +1 -0
  17. package/dist/feedback/index.js +2 -0
  18. package/dist/forms/TextInput/TextInput.svelte +576 -0
  19. package/dist/forms/TextInput/TextInput.svelte.d.ts +50 -0
  20. package/dist/forms/TextInput/TextInput.svelte.d.ts.map +1 -0
  21. package/dist/forms/TextInput/index.d.ts +2 -0
  22. package/dist/forms/TextInput/index.d.ts.map +1 -0
  23. package/dist/forms/TextInput/index.js +1 -0
  24. package/dist/forms/index.d.ts +2 -0
  25. package/dist/forms/index.d.ts.map +1 -0
  26. package/dist/forms/index.js +1 -0
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +6 -0
  30. package/dist/layout/Card/Card.svelte +283 -0
  31. package/dist/layout/Card/Card.svelte.d.ts +35 -0
  32. package/dist/layout/Card/Card.svelte.d.ts.map +1 -0
  33. package/dist/layout/Card/index.d.ts +2 -0
  34. package/dist/layout/Card/index.d.ts.map +1 -0
  35. package/dist/layout/Card/index.js +1 -0
  36. package/dist/layout/Container/Container.svelte +202 -0
  37. package/dist/layout/Container/Container.svelte.d.ts +25 -0
  38. package/dist/layout/Container/Container.svelte.d.ts.map +1 -0
  39. package/dist/layout/Container/index.d.ts +2 -0
  40. package/dist/layout/Container/index.d.ts.map +1 -0
  41. package/dist/layout/Container/index.js +1 -0
  42. package/dist/layout/index.d.ts +3 -0
  43. package/dist/layout/index.d.ts.map +1 -0
  44. package/dist/layout/index.js +2 -0
  45. package/dist/navigation/Tabs/Tabs.svelte +448 -0
  46. package/dist/navigation/Tabs/Tabs.svelte.d.ts +59 -0
  47. package/dist/navigation/Tabs/Tabs.svelte.d.ts.map +1 -0
  48. package/dist/navigation/Tabs/index.d.ts +3 -0
  49. package/dist/navigation/Tabs/index.d.ts.map +1 -0
  50. package/dist/navigation/Tabs/index.js +1 -0
  51. package/dist/navigation/index.d.ts +3 -0
  52. package/dist/navigation/index.d.ts.map +1 -0
  53. package/dist/navigation/index.js +1 -0
  54. package/dist/primitives/Badge/Badge.svelte +351 -0
  55. package/dist/primitives/Badge/Badge.svelte.d.ts +35 -0
  56. package/dist/primitives/Badge/Badge.svelte.d.ts.map +1 -0
  57. package/dist/primitives/Badge/index.d.ts +2 -0
  58. package/dist/primitives/Badge/index.d.ts.map +1 -0
  59. package/dist/primitives/Badge/index.js +1 -0
  60. package/dist/primitives/Button/Button.svelte +383 -0
  61. package/dist/primitives/Button/Button.svelte.d.ts +47 -0
  62. package/dist/primitives/Button/Button.svelte.d.ts.map +1 -0
  63. package/dist/primitives/Button/index.d.ts +2 -0
  64. package/dist/primitives/Button/index.d.ts.map +1 -0
  65. package/dist/primitives/Button/index.js +1 -0
  66. package/dist/primitives/index.d.ts +3 -0
  67. package/dist/primitives/index.d.ts.map +1 -0
  68. package/dist/primitives/index.js +2 -0
  69. package/dist/routes/+layout.svelte +5 -0
  70. package/dist/routes/+layout.svelte.d.ts +6 -0
  71. package/dist/routes/+layout.svelte.d.ts.map +1 -0
  72. package/dist/routes/+page.svelte +6 -0
  73. package/dist/routes/+page.svelte.d.ts +27 -0
  74. package/dist/routes/+page.svelte.d.ts.map +1 -0
  75. package/dist/styles/tokens.css +340 -0
  76. package/dist/utils/cn.d.ts +9 -0
  77. package/dist/utils/cn.d.ts.map +1 -0
  78. package/dist/utils/cn.js +29 -0
  79. package/dist/utils/index.d.ts +2 -0
  80. package/dist/utils/index.d.ts.map +1 -0
  81. package/dist/utils/index.js +1 -0
  82. package/package.json +84 -0
@@ -0,0 +1,421 @@
1
+ <!--
2
+ @component Spinner
3
+
4
+ Win2K × Basquiat — Bold loading indicator.
5
+ Flat shadows, crown yellow / electric blue, geometric shapes. No soft gradients.
6
+ role="status", aria-label, delay, overlay. prefers-reduced-motion respected.
7
+ -->
8
+ <script lang="ts">
9
+ import { cn } from '../../utils/cn.js';
10
+
11
+ type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
12
+ type SpinnerVariant = 'primary' | 'secondary' | 'white';
13
+ type SpinnerStyle = 'ring' | 'bars' | 'segment' | 'dots' | 'pulse';
14
+
15
+ interface Props {
16
+ size?: SpinnerSize;
17
+ variant?: SpinnerVariant;
18
+ style?: SpinnerStyle;
19
+ label?: string;
20
+ showLabel?: boolean;
21
+ delay?: number;
22
+ overlay?: boolean;
23
+ class?: string;
24
+ id?: string;
25
+ }
26
+
27
+ let {
28
+ size = 'md',
29
+ variant = 'primary',
30
+ style = 'ring',
31
+ label = 'Loading...',
32
+ showLabel = false,
33
+ delay = 0,
34
+ overlay = false,
35
+ class: className = '',
36
+ id
37
+ }: Props = $props();
38
+
39
+ let isVisible = $state(false);
40
+
41
+ $effect(() => {
42
+ if (delay === 0) {
43
+ isVisible = true;
44
+ return;
45
+ }
46
+ isVisible = false;
47
+ const t = setTimeout(() => {
48
+ isVisible = true;
49
+ }, delay);
50
+ return () => clearTimeout(t);
51
+ });
52
+
53
+ const sizeConfig: Record<
54
+ SpinnerSize,
55
+ { dimension: number; stroke: number; fontSize: string; dotSize: number }
56
+ > = {
57
+ xs: { dimension: 16, stroke: 2.5, fontSize: 'var(--salmex-font-size-xs)', dotSize: 4 },
58
+ sm: { dimension: 20, stroke: 3, fontSize: 'var(--salmex-font-size-sm)', dotSize: 5 },
59
+ md: { dimension: 28, stroke: 4, fontSize: 'var(--salmex-font-size-sm)', dotSize: 6 },
60
+ lg: { dimension: 40, stroke: 5, fontSize: 'var(--salmex-font-size-base)', dotSize: 8 },
61
+ xl: { dimension: 56, stroke: 6, fontSize: 'var(--salmex-font-size-md)', dotSize: 10 }
62
+ };
63
+
64
+ const config = $derived(sizeConfig[size]);
65
+ </script>
66
+
67
+ {#if isVisible}
68
+ <div
69
+ {id}
70
+ class={cn(
71
+ 'salmex-spinner',
72
+ `salmex-spinner-${size}`,
73
+ `salmex-spinner-${variant}`,
74
+ `salmex-spinner-style-${style}`,
75
+ overlay && 'salmex-spinner-overlay',
76
+ className
77
+ )}
78
+ role="status"
79
+ aria-live="polite"
80
+ aria-busy="true"
81
+ aria-label={label}
82
+ >
83
+ <div class="salmex-spinner-content">
84
+ {#if style === 'ring'}
85
+ <svg
86
+ class="salmex-spinner-ring"
87
+ width={config.dimension}
88
+ height={config.dimension}
89
+ viewBox="0 0 32 32"
90
+ fill="none"
91
+ aria-hidden="true"
92
+ >
93
+ <!-- Track: full circle, bold stroke -->
94
+ <circle
95
+ class="salmex-spinner-track"
96
+ cx="16"
97
+ cy="16"
98
+ r="14"
99
+ stroke="currentColor"
100
+ stroke-width={config.stroke}
101
+ />
102
+ <!-- Arc: one bold segment, round caps -->
103
+ <circle
104
+ class="salmex-spinner-arc"
105
+ cx="16"
106
+ cy="16"
107
+ r="14"
108
+ stroke="currentColor"
109
+ stroke-width={config.stroke}
110
+ stroke-linecap="round"
111
+ stroke-dasharray="22 66"
112
+ />
113
+ </svg>
114
+ {/if}
115
+
116
+ {#if style === 'bars'}
117
+ <div
118
+ class="salmex-spinner-bars"
119
+ style="width: {config.dimension}px; height: {config.dimension}px;"
120
+ aria-hidden="true"
121
+ ></div>
122
+ {/if}
123
+
124
+ {#if style === 'segment'}
125
+ <div
126
+ class="salmex-spinner-segment"
127
+ style="width: {config.dimension}px; height: {config.dimension}px;"
128
+ aria-hidden="true"
129
+ ></div>
130
+ {/if}
131
+
132
+ {#if style === 'dots'}
133
+ <div
134
+ class="salmex-spinner-dots"
135
+ style="--dot-size: {config.dotSize}px; --spinner-dim: {config.dimension}px;"
136
+ aria-hidden="true"
137
+ >
138
+ <span class="salmex-spinner-dot salmex-spinner-dot-1"></span>
139
+ <span class="salmex-spinner-dot salmex-spinner-dot-2"></span>
140
+ <span class="salmex-spinner-dot salmex-spinner-dot-3"></span>
141
+ </div>
142
+ {/if}
143
+
144
+ {#if style === 'pulse'}
145
+ <div
146
+ class="salmex-spinner-pulse"
147
+ style="width: {config.dimension}px; height: {config.dimension}px;"
148
+ aria-hidden="true"
149
+ >
150
+ <span class="salmex-pulse-ring salmex-pulse-ring-1"></span>
151
+ <span class="salmex-pulse-ring salmex-pulse-ring-2"></span>
152
+ <span class="salmex-pulse-dot"></span>
153
+ </div>
154
+ {/if}
155
+
156
+ {#if showLabel}
157
+ <span class="salmex-spinner-label" style="font-size: {config.fontSize};">
158
+ {label}
159
+ </span>
160
+ {:else}
161
+ <span class="salmex-sr-only">{label}</span>
162
+ {/if}
163
+ </div>
164
+ </div>
165
+ {/if}
166
+
167
+ <style>
168
+ .salmex-spinner {
169
+ display: inline-flex;
170
+ align-items: center;
171
+ justify-content: center;
172
+ }
173
+
174
+ .salmex-spinner-content {
175
+ display: inline-flex;
176
+ align-items: center;
177
+ gap: var(--salmex-space-2);
178
+ }
179
+
180
+ .salmex-spinner-label {
181
+ font-family: var(--salmex-font-system);
182
+ font-weight: 700;
183
+ text-transform: uppercase;
184
+ letter-spacing: 0.3px;
185
+ color: rgb(var(--salmex-text-secondary));
186
+ }
187
+
188
+ .salmex-sr-only {
189
+ position: absolute;
190
+ width: 1px;
191
+ height: 1px;
192
+ padding: 0;
193
+ margin: -1px;
194
+ overflow: hidden;
195
+ clip: rect(0, 0, 0, 0);
196
+ white-space: nowrap;
197
+ border: 0;
198
+ }
199
+
200
+ .salmex-spinner-overlay {
201
+ position: absolute;
202
+ inset: 0;
203
+ display: flex;
204
+ align-items: center;
205
+ justify-content: center;
206
+ background: rgb(var(--salmex-chalk-white) / 0.9);
207
+ z-index: var(--salmex-z-modal-backdrop);
208
+ border-radius: inherit;
209
+ /* Flat, bold overlay edge - no blur */
210
+ box-shadow: inset 0 0 0 3px rgb(var(--salmex-border-default));
211
+ }
212
+
213
+ :global([data-theme='dark']) .salmex-spinner-overlay {
214
+ background: rgb(var(--salmex-midnight-black) / 0.9);
215
+ box-shadow: inset 0 0 0 3px rgb(var(--salmex-border-light));
216
+ }
217
+
218
+ /* Variants - crown yellow / electric blue, bold */
219
+ .salmex-spinner-primary {
220
+ color: rgb(var(--salmex-electric-blue));
221
+ }
222
+
223
+ :global([data-theme='dark']) .salmex-spinner-primary {
224
+ color: rgb(var(--salmex-crown-yellow));
225
+ }
226
+
227
+ .salmex-spinner-secondary {
228
+ color: rgb(var(--salmex-text-secondary));
229
+ }
230
+
231
+ .salmex-spinner-white {
232
+ color: rgb(var(--salmex-chalk-white));
233
+ }
234
+
235
+ /* ========== RING: bold stroke, one segment, round caps ========== */
236
+ .salmex-spinner-ring {
237
+ animation: salmex-spin 0.85s linear infinite;
238
+ filter: drop-shadow(var(--salmex-shadow-sm));
239
+ }
240
+
241
+ .salmex-spinner-track {
242
+ opacity: 0.25;
243
+ }
244
+
245
+ .salmex-spinner-arc {
246
+ transform-origin: center;
247
+ }
248
+
249
+ @keyframes salmex-spin {
250
+ to {
251
+ transform: rotate(360deg);
252
+ }
253
+ }
254
+
255
+ /* ========== BARS: conic gradient, 12 segments, geometric ========== */
256
+ .salmex-spinner-bars {
257
+ border-radius: 50%;
258
+ background: repeating-conic-gradient(
259
+ currentColor 0deg 12deg,
260
+ transparent 12deg 30deg
261
+ );
262
+ animation: salmex-spin 0.9s linear infinite;
263
+ box-shadow: var(--salmex-shadow-sm);
264
+ }
265
+
266
+ /* ========== SEGMENT: one bold pie slice, high contrast ========== */
267
+ .salmex-spinner-segment {
268
+ border-radius: 50%;
269
+ background: conic-gradient(
270
+ from 0deg,
271
+ currentColor 0deg 100deg,
272
+ transparent 100deg 360deg
273
+ );
274
+ animation: salmex-spin 0.75s linear infinite;
275
+ box-shadow: var(--salmex-shadow-sm);
276
+ }
277
+
278
+ /* ========== DOTS: bold, flat shadow ========== */
279
+ .salmex-spinner-dots {
280
+ display: flex;
281
+ align-items: center;
282
+ justify-content: center;
283
+ gap: calc(var(--dot-size) * 0.7);
284
+ height: var(--spinner-dim);
285
+ }
286
+
287
+ .salmex-spinner-dot {
288
+ width: var(--dot-size);
289
+ height: var(--dot-size);
290
+ border-radius: var(--salmex-radius-sm);
291
+ background: currentColor;
292
+ box-shadow: var(--salmex-shadow-sm);
293
+ animation: salmex-dot-bounce 1s ease-out infinite both;
294
+ }
295
+
296
+ .salmex-spinner-dot-1 {
297
+ animation-delay: -0.2s;
298
+ }
299
+
300
+ .salmex-spinner-dot-2 {
301
+ animation-delay: -0.1s;
302
+ }
303
+
304
+ @keyframes salmex-dot-bounce {
305
+ 0%, 60%, 100% {
306
+ transform: scale(0.75);
307
+ opacity: 0.7;
308
+ }
309
+ 30% {
310
+ transform: scale(1);
311
+ opacity: 1;
312
+ }
313
+ }
314
+
315
+ /* ========== PULSE: bold ring + dot ========== */
316
+ .salmex-spinner-pulse {
317
+ position: relative;
318
+ display: flex;
319
+ align-items: center;
320
+ justify-content: center;
321
+ }
322
+
323
+ .salmex-pulse-ring {
324
+ position: absolute;
325
+ inset: 0;
326
+ border-radius: 50%;
327
+ border: 3px solid currentColor;
328
+ opacity: 0;
329
+ animation: salmex-pulse-ring 1.5s ease-out infinite;
330
+ }
331
+
332
+ .salmex-pulse-ring-2 {
333
+ animation-delay: 0.75s;
334
+ }
335
+
336
+ .salmex-pulse-dot {
337
+ width: 28%;
338
+ height: 28%;
339
+ border-radius: var(--salmex-radius-sm);
340
+ background: currentColor;
341
+ box-shadow: var(--salmex-shadow-sm);
342
+ animation: salmex-pulse-dot 1.5s ease-out infinite;
343
+ }
344
+
345
+ @keyframes salmex-pulse-ring {
346
+ 0% {
347
+ transform: scale(0.4);
348
+ opacity: 0.9;
349
+ }
350
+ 100% {
351
+ transform: scale(1.15);
352
+ opacity: 0;
353
+ }
354
+ }
355
+
356
+ @keyframes salmex-pulse-dot {
357
+ 0%, 100% {
358
+ transform: scale(0.85);
359
+ opacity: 0.8;
360
+ }
361
+ 50% {
362
+ transform: scale(1);
363
+ opacity: 1;
364
+ }
365
+ }
366
+
367
+ /* ========== REDUCED MOTION ========== */
368
+ @media (prefers-reduced-motion: reduce) {
369
+ .salmex-spinner-ring,
370
+ .salmex-spinner-bars,
371
+ .salmex-spinner-segment {
372
+ animation: none;
373
+ }
374
+
375
+ .salmex-spinner-ring {
376
+ filter: none;
377
+ }
378
+
379
+ .salmex-spinner-arc {
380
+ stroke-dasharray: 22 66;
381
+ opacity: 0.9;
382
+ transform: rotate(-90deg);
383
+ }
384
+
385
+ .salmex-spinner-bars,
386
+ .salmex-spinner-segment {
387
+ opacity: 0.85;
388
+ }
389
+
390
+ .salmex-spinner-dot {
391
+ animation: none;
392
+ opacity: 0.8;
393
+ }
394
+
395
+ .salmex-spinner-dot-1 {
396
+ opacity: 0.5;
397
+ }
398
+
399
+ .salmex-spinner-dot-2 {
400
+ opacity: 0.75;
401
+ }
402
+
403
+ .salmex-pulse-ring,
404
+ .salmex-pulse-dot {
405
+ animation: none;
406
+ }
407
+
408
+ .salmex-pulse-ring {
409
+ opacity: 0.25;
410
+ transform: scale(1);
411
+ }
412
+
413
+ .salmex-pulse-ring-2 {
414
+ display: none;
415
+ }
416
+
417
+ .salmex-pulse-dot {
418
+ opacity: 1;
419
+ }
420
+ }
421
+ </style>
@@ -0,0 +1,25 @@
1
+ type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
2
+ type SpinnerVariant = 'primary' | 'secondary' | 'white';
3
+ type SpinnerStyle = 'ring' | 'bars' | 'segment' | 'dots' | 'pulse';
4
+ interface Props {
5
+ size?: SpinnerSize;
6
+ variant?: SpinnerVariant;
7
+ style?: SpinnerStyle;
8
+ label?: string;
9
+ showLabel?: boolean;
10
+ delay?: number;
11
+ overlay?: boolean;
12
+ class?: string;
13
+ id?: string;
14
+ }
15
+ /**
16
+ * Spinner
17
+ *
18
+ * Win2K × Basquiat — Bold loading indicator.
19
+ * Flat shadows, crown yellow / electric blue, geometric shapes. No soft gradients.
20
+ * role="status", aria-label, delay, overlay. prefers-reduced-motion respected.
21
+ */
22
+ declare const Spinner: import("svelte").Component<Props, {}, "">;
23
+ type Spinner = ReturnType<typeof Spinner>;
24
+ export default Spinner;
25
+ //# sourceMappingURL=Spinner.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Spinner.svelte.d.ts","sourceRoot":"","sources":["../../../src/feedback/Spinner/Spinner.svelte.ts"],"names":[],"mappings":"AAMC,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACpD,KAAK,cAAc,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;AACxD,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEnE,UAAU,KAAK;IACd,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;CACZ;AA2GF;;;;;;GAMG;AACH,QAAA,MAAM,OAAO,2CAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as Spinner } from './Spinner.svelte';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/feedback/Spinner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ export { default as Spinner } from './Spinner.svelte';
@@ -0,0 +1,3 @@
1
+ export { Alert } from './Alert/index.js';
2
+ export { Spinner } from './Spinner/index.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/feedback/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { Alert } from './Alert/index.js';
2
+ export { Spinner } from './Spinner/index.js';