@skewedaspect/sleekspace-ui 0.5.0 → 0.6.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 (41) hide show
  1. package/dist/components/Card/SkCard.vue.d.ts +13 -1
  2. package/dist/components/Panel/SkPanel.vue.d.ts +15 -1
  3. package/dist/components/Panel/types.d.ts +1 -0
  4. package/dist/components/Select/SkSelect.vue.d.ts +61 -0
  5. package/dist/components/Select/SkSelectItem.vue.d.ts +134 -0
  6. package/dist/components/Select/SkSelectSeparator.vue.d.ts +2 -0
  7. package/dist/components/Select/index.d.ts +4 -0
  8. package/dist/components/Select/types.d.ts +3 -0
  9. package/dist/components/Sidebar/SkSidebar.vue.d.ts +8 -1
  10. package/dist/components/Sidebar/types.d.ts +1 -0
  11. package/dist/components/Skeleton/SkSkeleton.vue.d.ts +1 -1
  12. package/dist/components/Theme/types.d.ts +18 -3
  13. package/dist/index.d.ts +7 -0
  14. package/dist/sleekspace-ui.css +494 -74
  15. package/dist/sleekspace-ui.es.js +2014 -283
  16. package/dist/sleekspace-ui.umd.js +2013 -282
  17. package/docs/guides/design-tokens/advanced.md +6 -1
  18. package/docs/guides/theming.md +11 -1
  19. package/package.json +1 -1
  20. package/src/components/Card/SkCard.vue +17 -1
  21. package/src/components/Panel/SkPanel.vue +29 -4
  22. package/src/components/Panel/types.ts +3 -0
  23. package/src/components/Select/SkSelect.vue +210 -0
  24. package/src/components/Select/SkSelectItem.vue +112 -0
  25. package/src/components/Select/SkSelectSeparator.vue +40 -0
  26. package/src/components/Select/index.ts +10 -0
  27. package/src/components/Select/types.ts +10 -0
  28. package/src/components/Sidebar/SkSidebar.vue +39 -2
  29. package/src/components/Sidebar/types.ts +2 -0
  30. package/src/components/Theme/types.ts +20 -3
  31. package/src/global.d.ts +2 -0
  32. package/src/index.ts +10 -0
  33. package/src/styles/components/_button.scss +45 -9
  34. package/src/styles/components/_card.scss +45 -9
  35. package/src/styles/components/_index.scss +1 -0
  36. package/src/styles/components/_listbox.scss +1 -0
  37. package/src/styles/components/_panel.scss +119 -13
  38. package/src/styles/components/_select.scss +439 -0
  39. package/src/styles/components/_sidebar.scss +83 -4
  40. package/src/styles/themes/README.md +6 -2
  41. package/web-types.json +148 -1
@@ -0,0 +1,439 @@
1
+ @use '@/styles/mixins/cut-border' as *;
2
+
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+ // Select Component Styles
5
+ //----------------------------------------------------------------------------------------------------------------------
6
+
7
+ .sk-select
8
+ {
9
+ // Color tokens (can be overridden by custom colors)
10
+ --sk-select-color-base: var(--sk-neutral-base);
11
+ --sk-select-fg: var(--sk-neutral-text);
12
+
13
+ position: relative;
14
+ display: inline-flex;
15
+ width: 100%;
16
+
17
+ // Size variants
18
+ &.sk-sm
19
+ {
20
+ --sk-select-cut: 0.4rem;
21
+ }
22
+
23
+ &.sk-md
24
+ {
25
+ --sk-select-cut: 0.5rem;
26
+ }
27
+
28
+ &.sk-lg
29
+ {
30
+ --sk-select-cut: 0.6rem;
31
+ }
32
+
33
+ &.sk-xl
34
+ {
35
+ --sk-select-cut: 0.7rem;
36
+ }
37
+
38
+ // Kind variants
39
+ &.sk-neutral
40
+ {
41
+ --sk-select-color-base: var(--sk-neutral-base);
42
+ --sk-select-fg: var(--sk-neutral-text);
43
+ }
44
+
45
+ &.sk-primary
46
+ {
47
+ --sk-select-color-base: var(--sk-primary-base);
48
+ --sk-select-fg: var(--sk-primary-text);
49
+ }
50
+
51
+ &.sk-accent
52
+ {
53
+ --sk-select-color-base: var(--sk-accent-base);
54
+ --sk-select-fg: var(--sk-accent-text);
55
+ }
56
+
57
+ &.sk-info
58
+ {
59
+ --sk-select-color-base: var(--sk-info-base);
60
+ --sk-select-fg: var(--sk-info-text);
61
+ }
62
+
63
+ &.sk-success
64
+ {
65
+ --sk-select-color-base: var(--sk-success-base);
66
+ --sk-select-fg: var(--sk-success-text);
67
+ }
68
+
69
+ &.sk-warning
70
+ {
71
+ --sk-select-color-base: var(--sk-warning-base);
72
+ --sk-select-fg: var(--sk-warning-text);
73
+ }
74
+
75
+ &.sk-danger
76
+ {
77
+ --sk-select-color-base: var(--sk-danger-base);
78
+ --sk-select-fg: var(--sk-danger-text);
79
+ }
80
+
81
+ // Color kinds (direct palette access)
82
+ &.sk-neon-blue
83
+ {
84
+ --sk-select-color-base: var(--sk-neon-blue-base);
85
+ --sk-select-fg: var(--sk-neon-blue-text);
86
+ }
87
+
88
+ &.sk-neon-purple
89
+ {
90
+ --sk-select-color-base: var(--sk-neon-purple-base);
91
+ --sk-select-fg: var(--sk-neon-purple-text);
92
+ }
93
+
94
+ &.sk-neon-orange
95
+ {
96
+ --sk-select-color-base: var(--sk-neon-orange-base);
97
+ --sk-select-fg: var(--sk-neon-orange-text);
98
+ }
99
+
100
+ &.sk-neon-green
101
+ {
102
+ --sk-select-color-base: var(--sk-neon-green-base);
103
+ --sk-select-fg: var(--sk-neon-green-text);
104
+ }
105
+
106
+ &.sk-neon-mint
107
+ {
108
+ --sk-select-color-base: var(--sk-neon-mint-base);
109
+ --sk-select-fg: var(--sk-neon-mint-text);
110
+ }
111
+
112
+ &.sk-neon-pink
113
+ {
114
+ --sk-select-color-base: var(--sk-neon-pink-base);
115
+ --sk-select-fg: var(--sk-neon-pink-text);
116
+ }
117
+
118
+ &.sk-yellow
119
+ {
120
+ --sk-select-color-base: var(--sk-yellow-base);
121
+ --sk-select-fg: var(--sk-yellow-text);
122
+ }
123
+
124
+ &.sk-red
125
+ {
126
+ --sk-select-color-base: var(--sk-red-base);
127
+ --sk-select-fg: var(--sk-red-text);
128
+ }
129
+ }
130
+
131
+ //----------------------------------------------------------------------------------------------------------------------
132
+
133
+ .sk-select-trigger
134
+ {
135
+ display: flex;
136
+ align-items: center;
137
+ gap: var(--sk-space-sm);
138
+ width: 100%;
139
+
140
+ // Button reset (SelectTrigger renders as <button>)
141
+ font-family: var(--sk-font-family-base);
142
+ font-size: inherit;
143
+ text-align: left;
144
+
145
+ @include cut-border(
146
+ $cut: var(--sk-select-cut),
147
+ $border-width: var(--sk-border-width-thin),
148
+ $border-color: var(--sk-select-color-base),
149
+ $corners: (top-right)
150
+ );
151
+
152
+ // Base styling
153
+ background: color-mix(
154
+ in oklch,
155
+ color-mix(in oklch, var(--sk-select-color-base) 75%, transparent 25%),
156
+ #000 65%
157
+ );
158
+ color: var(--sk-select-fg);
159
+ cursor: pointer;
160
+ outline: none;
161
+
162
+ // Transitions
163
+ transition-property: background, border-color;
164
+ transition-duration: var(--sk-transition-duration-base);
165
+
166
+ // Size variants
167
+ .sk-select.sk-sm &
168
+ {
169
+ height: 2rem;
170
+ padding: 0 var(--sk-space-sm);
171
+ font-size: 0.875rem;
172
+ }
173
+
174
+ .sk-select.sk-md &
175
+ {
176
+ height: 2.5rem;
177
+ padding: 0 var(--sk-space-md);
178
+ font-size: 1rem;
179
+ }
180
+
181
+ .sk-select.sk-lg &
182
+ {
183
+ height: 3rem;
184
+ padding: 0 var(--sk-space-md);
185
+ font-size: 1.125rem;
186
+ }
187
+
188
+ .sk-select.sk-xl &
189
+ {
190
+ height: 3.5rem;
191
+ padding: 0 var(--sk-space-md);
192
+ font-size: 1.25rem;
193
+ }
194
+
195
+ // Focus state
196
+ &:focus-visible
197
+ {
198
+ border-color: color-mix(in oklch, var(--sk-select-color-base), white 35%);
199
+ background: color-mix(
200
+ in oklch,
201
+ color-mix(in oklch, var(--sk-select-color-base) 75%, transparent 25%),
202
+ #000 25%
203
+ );
204
+ }
205
+
206
+ // Hover state
207
+ &:hover:not(:disabled)
208
+ {
209
+ border-color: color-mix(in oklch, var(--sk-select-color-base), white 20%);
210
+ }
211
+
212
+ // Disabled state
213
+ &:disabled
214
+ {
215
+ opacity: 0.5;
216
+ cursor: not-allowed;
217
+ }
218
+
219
+ // SelectValue text -- fill remaining space
220
+ > span
221
+ {
222
+ flex: 1;
223
+ color: white;
224
+ overflow: hidden;
225
+ text-overflow: ellipsis;
226
+ white-space: nowrap;
227
+
228
+ // Placeholder (Reka UI adds data-placeholder when no value is selected)
229
+ &[data-placeholder]
230
+ {
231
+ color: color-mix(in oklch, var(--sk-select-fg), transparent 50%);
232
+ }
233
+ }
234
+
235
+ // Chevron icon -- fixed right
236
+ > svg
237
+ {
238
+ flex-shrink: 0;
239
+ opacity: 0.8;
240
+ }
241
+ }
242
+
243
+ //----------------------------------------------------------------------------------------------------------------------
244
+
245
+ .sk-select-content
246
+ {
247
+ // Color tokens - define defaults (can be overridden by kind variants)
248
+ --sk-menu-color-base: var(--sk-neutral-base);
249
+ --sk-menu-fg: var(--sk-neutral-text);
250
+
251
+ position: relative;
252
+ min-width: var(--reka-select-trigger-width);
253
+ max-height: 20rem;
254
+ overflow: auto;
255
+ padding: var(--sk-space-xs);
256
+ z-index: 1000;
257
+
258
+ @include cut-border(
259
+ $cut: 0.625rem,
260
+ $border-width: var(--sk-border-width-thin),
261
+ $border-color: var(--sk-menu-color-base),
262
+ $corners: (top-left)
263
+ );
264
+
265
+ // Base styling
266
+ background: color-mix(
267
+ in oklch,
268
+ color-mix(in oklch, var(--sk-menu-color-base) 95%, transparent 5%),
269
+ #000 46.25%
270
+ );
271
+ color: var(--sk-menu-fg);
272
+ box-shadow: var(--sk-shadow-lg);
273
+
274
+ // Kind variants (defined directly on content for portal support)
275
+ &.sk-neutral
276
+ {
277
+ --sk-menu-color-base: var(--sk-neutral-base);
278
+ --sk-menu-fg: var(--sk-neutral-text);
279
+ }
280
+
281
+ &.sk-primary
282
+ {
283
+ --sk-menu-color-base: var(--sk-primary-base);
284
+ --sk-menu-fg: var(--sk-primary-text);
285
+ }
286
+
287
+ &.sk-accent
288
+ {
289
+ --sk-menu-color-base: var(--sk-accent-base);
290
+ --sk-menu-fg: var(--sk-accent-text);
291
+ }
292
+
293
+ &.sk-info
294
+ {
295
+ --sk-menu-color-base: var(--sk-info-base);
296
+ --sk-menu-fg: var(--sk-info-text);
297
+ }
298
+
299
+ &.sk-success
300
+ {
301
+ --sk-menu-color-base: var(--sk-success-base);
302
+ --sk-menu-fg: var(--sk-success-text);
303
+ }
304
+
305
+ &.sk-warning
306
+ {
307
+ --sk-menu-color-base: var(--sk-warning-base);
308
+ --sk-menu-fg: var(--sk-warning-text);
309
+ }
310
+
311
+ &.sk-danger
312
+ {
313
+ --sk-menu-color-base: var(--sk-danger-base);
314
+ --sk-menu-fg: var(--sk-danger-text);
315
+ }
316
+
317
+ // Color kinds (direct palette access)
318
+ &.sk-neon-blue
319
+ {
320
+ --sk-menu-color-base: var(--sk-neon-blue-base);
321
+ --sk-menu-fg: var(--sk-neon-blue-text);
322
+ }
323
+
324
+ &.sk-neon-purple
325
+ {
326
+ --sk-menu-color-base: var(--sk-neon-purple-base);
327
+ --sk-menu-fg: var(--sk-neon-purple-text);
328
+ }
329
+
330
+ &.sk-neon-orange
331
+ {
332
+ --sk-menu-color-base: var(--sk-neon-orange-base);
333
+ --sk-menu-fg: var(--sk-neon-orange-text);
334
+ }
335
+
336
+ &.sk-neon-green
337
+ {
338
+ --sk-menu-color-base: var(--sk-neon-green-base);
339
+ --sk-menu-fg: var(--sk-neon-green-text);
340
+ }
341
+
342
+ &.sk-neon-mint
343
+ {
344
+ --sk-menu-color-base: var(--sk-neon-mint-base);
345
+ --sk-menu-fg: var(--sk-neon-mint-text);
346
+ }
347
+
348
+ &.sk-neon-pink
349
+ {
350
+ --sk-menu-color-base: var(--sk-neon-pink-base);
351
+ --sk-menu-fg: var(--sk-neon-pink-text);
352
+ }
353
+
354
+ &.sk-yellow
355
+ {
356
+ --sk-menu-color-base: var(--sk-yellow-base);
357
+ --sk-menu-fg: var(--sk-yellow-text);
358
+ }
359
+
360
+ &.sk-red
361
+ {
362
+ --sk-menu-color-base: var(--sk-red-base);
363
+ --sk-menu-fg: var(--sk-red-text);
364
+ }
365
+ }
366
+
367
+ //----------------------------------------------------------------------------------------------------------------------
368
+
369
+ .sk-select-item
370
+ {
371
+ display: flex;
372
+ align-items: center;
373
+ justify-content: space-between;
374
+ gap: var(--sk-space-md);
375
+ padding: var(--sk-space-xs) var(--sk-space-md);
376
+ cursor: pointer;
377
+ color: color-mix(in oklch, var(--sk-menu-fg), black 15%);
378
+ font-size: 0.875rem;
379
+ outline: none;
380
+ user-select: none;
381
+
382
+ @include cut-border(
383
+ $cut: 0.5rem,
384
+ $border-width: var(--sk-border-width-thin),
385
+ $border-color: transparent,
386
+ $corners: (top-left bottom-right)
387
+ );
388
+
389
+ // Hover state
390
+ &:hover:not([data-disabled])
391
+ {
392
+ background: color-mix(
393
+ in oklch,
394
+ color-mix(in oklch, var(--sk-menu-color-base), black 30%),
395
+ transparent 10%
396
+ );
397
+ color: var(--sk-menu-fg);
398
+ }
399
+
400
+ // Highlighted state (keyboard navigation)
401
+ &[data-highlighted]
402
+ {
403
+ background: color-mix(
404
+ in oklch,
405
+ color-mix(in oklch, var(--sk-menu-color-base), black 30%),
406
+ transparent 10%
407
+ );
408
+ color: var(--sk-menu-fg);
409
+ outline: none;
410
+ }
411
+
412
+ // Disabled state
413
+ &[data-disabled]
414
+ {
415
+ opacity: 0.5;
416
+ cursor: not-allowed;
417
+ }
418
+ }
419
+
420
+ //----------------------------------------------------------------------------------------------------------------------
421
+
422
+ .sk-select-item-indicator
423
+ {
424
+ display: flex;
425
+ align-items: center;
426
+ justify-content: center;
427
+ flex-shrink: 0;
428
+ }
429
+
430
+ //----------------------------------------------------------------------------------------------------------------------
431
+
432
+ .sk-select-separator
433
+ {
434
+ height: 1px;
435
+ margin: var(--sk-space-xs) 0;
436
+ background: color-mix(in oklch, var(--sk-menu-color-base), transparent 70%);
437
+ }
438
+
439
+ //----------------------------------------------------------------------------------------------------------------------
@@ -15,6 +15,26 @@
15
15
  width: var(--sk-sidebar-width, 180px);
16
16
  flex-shrink: 0;
17
17
 
18
+ // Item theming -- uses same darkened color derivation as button system.
19
+ // --sk-sidebar-color-base is overridden per kind below; bg/hover/active derive automatically.
20
+ --sk-sidebar-color-base: var(--sk-neutral-base);
21
+ --sk-sidebar-item-bg: color-mix(
22
+ in oklch,
23
+ color-mix(in oklch, var(--sk-sidebar-color-base) 75%, transparent 25%),
24
+ #000 46.25%
25
+ );
26
+ --sk-sidebar-item-hover-bg: color-mix(in oklch, var(--sk-sidebar-item-bg) 85%, white 15%);
27
+ --sk-sidebar-item-hover-text: color-mix(in oklch, var(--sk-sidebar-color-base), white 30%);
28
+ --sk-sidebar-item-active-text: color-mix(in oklch, var(--sk-sidebar-color-base), white 50%);
29
+ --sk-sidebar-item-active-bg: var(--sk-sidebar-item-bg);
30
+
31
+ &.sk-primary { --sk-sidebar-color-base: var(--sk-primary-base); }
32
+ &.sk-accent { --sk-sidebar-color-base: var(--sk-accent-base); }
33
+ &.sk-info { --sk-sidebar-color-base: var(--sk-info-base); }
34
+ &.sk-success { --sk-sidebar-color-base: var(--sk-success-base); }
35
+ &.sk-warning { --sk-sidebar-color-base: var(--sk-warning-base); }
36
+ &.sk-danger { --sk-sidebar-color-base: var(--sk-danger-base); }
37
+
18
38
  .sk-sidebar-nav
19
39
  {
20
40
  display: flex;
@@ -50,6 +70,7 @@
50
70
 
51
71
  .sk-sidebar-item
52
72
  {
73
+ position: relative;
53
74
  color: var(--sk-neutral-text);
54
75
  text-decoration: none;
55
76
  padding: 0.5rem 0.75rem;
@@ -60,8 +81,8 @@
60
81
 
61
82
  &:hover
62
83
  {
63
- background: color-mix(in oklch, var(--sk-neutral-base), black 40%);
64
- color: var(--sk-accent-base);
84
+ background: var(--sk-sidebar-item-hover-bg);
85
+ color: var(--sk-sidebar-item-hover-text);
65
86
  clip-path: polygon(
66
87
  10px 0%,
67
88
  100% 0%,
@@ -75,8 +96,8 @@
75
96
  &.sk-active,
76
97
  &.router-link-active
77
98
  {
78
- background: color-mix(in oklch, var(--sk-neutral-base), black 40%);
79
- color: var(--sk-primary-base);
99
+ background: var(--sk-sidebar-item-active-bg);
100
+ color: var(--sk-sidebar-item-active-text);
80
101
  font-weight: 600;
81
102
  clip-path: polygon(
82
103
  10px 0%,
@@ -86,6 +107,64 @@
86
107
  0% 100%,
87
108
  0% 10px
88
109
  );
110
+
111
+ // Active indicator: 2px L-shape tracing the left edge + top-left bevel
112
+ &::before
113
+ {
114
+ content: '';
115
+ position: absolute;
116
+ inset: 0;
117
+ background: var(--sk-sidebar-color-base);
118
+ clip-path: polygon(
119
+ 0% 100%,
120
+ 0px 10px,
121
+ 10px 0px,
122
+ 11.41px 1.41px,
123
+ 2px 10.83px,
124
+ 2px 100%
125
+ );
126
+ }
127
+ }
128
+
129
+ // Mirrored for right-side placement
130
+ .sk-sidebar-right &
131
+ {
132
+ &:hover
133
+ {
134
+ clip-path: polygon(
135
+ 0% 0%,
136
+ calc(100% - 10px) 0%,
137
+ 100% 10px,
138
+ 100% 100%,
139
+ 10px 100%,
140
+ 0% calc(100% - 10px)
141
+ );
142
+ }
143
+
144
+ &.sk-active,
145
+ &.router-link-active
146
+ {
147
+ clip-path: polygon(
148
+ 0% 0%,
149
+ calc(100% - 10px) 0%,
150
+ 100% 10px,
151
+ 100% 100%,
152
+ 10px 100%,
153
+ 0% calc(100% - 10px)
154
+ );
155
+
156
+ &::before
157
+ {
158
+ clip-path: polygon(
159
+ 100% 100%,
160
+ 100% 10px,
161
+ calc(100% - 10px) 0px,
162
+ calc(100% - 11.41px) 1.41px,
163
+ calc(100% - 2px) 10.83px,
164
+ calc(100% - 2px) 100%
165
+ );
166
+ }
167
+ }
89
168
  }
90
169
  }
91
170
 
@@ -83,10 +83,14 @@ To create a new theme:
83
83
  @forward 'mytheme'; // Add your theme
84
84
  ```
85
85
 
86
- 4. **Add the TypeScript type** in `src/components/Theme/types.ts`:
86
+ 4. **Register the TypeScript type** via module augmentation (e.g. in a `themes.d.ts` or your app's entry file):
87
87
 
88
88
  ```typescript
89
- export type SkThemeName = 'greyscale' | 'colorful' | 'mytheme';
89
+ declare module '@skewedaspect/sleekspace-ui' {
90
+ interface SkThemeNameMap {
91
+ mytheme : true;
92
+ }
93
+ }
90
94
  ```
91
95
 
92
96
  5. **Use your theme**: