@skewedaspect/sleekspace-ui 0.8.1 → 0.9.1
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.
- package/dist/components/Dropdown/SkDropdown.vue.d.ts +9 -1
- package/dist/components/Dropdown/types.d.ts +2 -1
- package/dist/components/NavBar/SkNavBar.vue.d.ts +9 -1
- package/dist/components/NavBar/context.d.ts +2 -0
- package/dist/components/NavBar/types.d.ts +5 -1
- package/dist/components/NumberInput/SkNumberInput.vue.d.ts +8 -0
- package/dist/components/Page/SkPage.vue.d.ts +9 -0
- package/dist/components/ScrollArea/SkScrollArea.vue.d.ts +105 -4
- package/dist/composables/useCustomColors.d.ts +18 -56
- package/{src → dist}/global.d.ts +6 -2
- package/dist/sleekspace-ui.css +4257 -1253
- package/dist/sleekspace-ui.es.js +300 -170
- package/dist/sleekspace-ui.umd.js +299 -169
- package/dist/static/classes.d.ts +18 -0
- package/dist/static/components/alert.d.ts +12 -0
- package/dist/static/components/avatar.d.ts +9 -0
- package/dist/static/components/breadcrumbs.d.ts +6 -0
- package/dist/static/components/button.d.ts +13 -0
- package/dist/static/components/card.d.ts +5 -0
- package/dist/static/components/checkbox.d.ts +10 -0
- package/dist/static/components/colorPicker.d.ts +8 -0
- package/dist/static/components/divider.d.ts +8 -0
- package/dist/static/components/dropdown.d.ts +8 -0
- package/dist/static/components/field.d.ts +15 -0
- package/dist/static/components/group.d.ts +5 -0
- package/dist/static/components/input.d.ts +14 -0
- package/dist/static/components/navBar.d.ts +16 -0
- package/dist/static/components/numberInput.d.ts +15 -0
- package/dist/static/components/page.d.ts +9 -0
- package/dist/static/components/pagination.d.ts +5 -0
- package/dist/static/components/panel.d.ts +11 -0
- package/dist/static/components/progress.d.ts +9 -0
- package/dist/static/components/radio.d.ts +11 -0
- package/dist/static/components/select.d.ts +10 -0
- package/dist/static/components/sidebar.d.ts +9 -0
- package/dist/static/components/skeleton.d.ts +11 -0
- package/dist/static/components/slider.d.ts +12 -0
- package/dist/static/components/spinner.d.ts +12 -0
- package/dist/static/components/switchInput.d.ts +10 -0
- package/dist/static/components/table.d.ts +12 -0
- package/dist/static/components/tag.d.ts +8 -0
- package/dist/static/components/tagsInput.d.ts +7 -0
- package/dist/static/components/textarea.d.ts +12 -0
- package/dist/static/components/toolbar.d.ts +12 -0
- package/dist/static/components/tooltip.d.ts +7 -0
- package/dist/static/escape.d.ts +2 -0
- package/dist/static/index.cjs.js +1 -0
- package/dist/static/index.d.ts +68 -0
- package/dist/static/index.es.js +732 -0
- package/dist/static/render.d.ts +12 -0
- package/dist/static/specs.d.ts +2 -0
- package/dist/static/types.d.ts +43 -0
- package/dist/tokens.css +322 -0
- package/dist/types/index.d.ts +36 -0
- package/dist/utils/slots.d.ts +6 -0
- package/docs/guides/installation.md +8 -2
- package/docs/guides/pure-css/_meta.yaml +8 -0
- package/docs/guides/pure-css/class-api.md +1070 -0
- package/docs/guides/pure-css/custom-elements.md +574 -0
- package/docs/guides/pure-css/index.md +86 -0
- package/docs/guides/pure-css/limitations.md +152 -0
- package/docs/guides/pure-css/static-helpers.md +1203 -0
- package/llms-full.txt +3739 -261
- package/package.json +19 -5
- package/src/components/Alert/SkAlert.vue +4 -2
- package/src/components/Breadcrumbs/SkBreadcrumbs.vue +6 -12
- package/src/components/Button/SkButton.vue +8 -5
- package/src/components/Card/SkCard.vue +13 -5
- package/src/components/Checkbox/SkCheckbox.vue +9 -2
- package/src/components/ContextMenu/SkContextMenuRadioGroup.vue +4 -1
- package/src/components/Dropdown/SkDropdown.vue +20 -3
- package/src/components/Dropdown/SkDropdownRadioGroup.vue +4 -1
- package/src/components/Dropdown/types.ts +2 -1
- package/src/components/Modal/SkModal.vue +11 -4
- package/src/components/NavBar/SkNavBar.vue +19 -8
- package/src/components/NavBar/context.ts +4 -2
- package/src/components/NavBar/types.ts +6 -1
- package/src/components/NumberInput/SkNumberInput.vue +10 -1
- package/src/components/Page/SkPage.vue +29 -15
- package/src/components/Panel/SkPanel.vue +2 -1
- package/src/components/Popover/SkPopover.vue +11 -4
- package/src/components/Radio/SkRadio.vue +9 -2
- package/src/components/ScrollArea/SkScrollArea.vue +78 -5
- package/src/components/Switch/SkSwitch.vue +14 -13
- package/src/components/Tabs/SkTab.vue +7 -2
- package/src/components/TreeView/SkTreeItem.vue +10 -2
- package/src/components/TreeView/SkTreeView.vue +7 -2
- package/src/composables/useCustomColors.ts +86 -77
- package/src/composables/usePortalContext.test.ts +0 -2
- package/src/shims.d.ts +10 -0
- package/src/static/__tests__/parity.test.ts +717 -0
- package/src/static/__tests__/parityHarness.test.ts +98 -0
- package/src/static/__tests__/parityHarness.ts +260 -0
- package/src/static/classes.test.ts +82 -0
- package/src/static/classes.ts +111 -0
- package/src/static/components/__tests__/helpers.test.ts +837 -0
- package/src/static/components/alert.ts +117 -0
- package/src/static/components/avatar.ts +86 -0
- package/src/static/components/breadcrumbs.ts +28 -0
- package/src/static/components/button.ts +75 -0
- package/src/static/components/card.ts +27 -0
- package/src/static/components/checkbox.ts +48 -0
- package/src/static/components/colorPicker.ts +45 -0
- package/src/static/components/divider.ts +39 -0
- package/src/static/components/dropdown.ts +36 -0
- package/src/static/components/field.ts +86 -0
- package/src/static/components/group.ts +27 -0
- package/src/static/components/input.ts +55 -0
- package/src/static/components/navBar.ts +94 -0
- package/src/static/components/numberInput.ts +64 -0
- package/src/static/components/page.ts +31 -0
- package/src/static/components/pagination.ts +27 -0
- package/src/static/components/panel.ts +33 -0
- package/src/static/components/progress.ts +31 -0
- package/src/static/components/radio.ts +53 -0
- package/src/static/components/select.ts +51 -0
- package/src/static/components/sidebar.ts +85 -0
- package/src/static/components/skeleton.ts +66 -0
- package/src/static/components/slider.ts +50 -0
- package/src/static/components/spinner.ts +94 -0
- package/src/static/components/switchInput.ts +49 -0
- package/src/static/components/table.ts +88 -0
- package/src/static/components/tag.ts +76 -0
- package/src/static/components/tagsInput.ts +35 -0
- package/src/static/components/textarea.ts +53 -0
- package/src/static/components/toolbar.ts +74 -0
- package/src/static/components/tooltip.ts +29 -0
- package/src/static/escape.test.ts +53 -0
- package/src/static/escape.ts +28 -0
- package/src/static/generated/defaults.ts +379 -0
- package/src/static/generated/propTypes.ts +426 -0
- package/src/static/index.ts +116 -0
- package/src/static/render.test.ts +83 -0
- package/src/static/render.ts +76 -0
- package/src/static/specs.test.ts +58 -0
- package/src/static/specs.ts +230 -0
- package/src/static/types.ts +176 -0
- package/src/styles/__tests__/testHelpers.ts +97 -0
- package/src/styles/base/_custom-elements.scss +51 -0
- package/src/styles/base/_index.scss +4 -0
- package/src/styles/components/__tests__/componentSelectors.test.ts +2575 -0
- package/src/styles/components/_alert.scss +82 -39
- package/src/styles/components/_avatar.scss +102 -47
- package/src/styles/components/_breadcrumbs.scss +39 -37
- package/src/styles/components/_button.scss +58 -5
- package/src/styles/components/_card.scss +64 -2
- package/src/styles/components/_checkbox.scss +35 -5
- package/src/styles/components/_color-picker.scss +48 -13
- package/src/styles/components/_divider.scss +86 -52
- package/src/styles/components/_dropdown.scss +214 -0
- package/src/styles/components/_field.scss +76 -23
- package/src/styles/components/_group.scss +190 -79
- package/src/styles/components/_index.scss +1 -0
- package/src/styles/components/_input.scss +81 -5
- package/src/styles/components/_menu.scss +1 -1
- package/src/styles/components/_navbar.scss +76 -45
- package/src/styles/components/_number-input.scss +98 -85
- package/src/styles/components/_page.scss +82 -23
- package/src/styles/components/_pagination.scss +240 -212
- package/src/styles/components/_panel.scss +268 -122
- package/src/styles/components/_progress.scss +120 -70
- package/src/styles/components/_radio.scss +35 -5
- package/src/styles/components/_scroll-area.scss +50 -22
- package/src/styles/components/_select.scss +40 -9
- package/src/styles/components/_sidebar.scss +59 -34
- package/src/styles/components/_skeleton.scss +111 -65
- package/src/styles/components/_slider.scss +34 -10
- package/src/styles/components/_spinner.scss +107 -56
- package/src/styles/components/_switch.scss +36 -5
- package/src/styles/components/_table.scss +150 -166
- package/src/styles/components/_tag.scss +244 -154
- package/src/styles/components/_tags-input.scss +46 -12
- package/src/styles/components/_textarea.scss +36 -5
- package/src/styles/components/_toolbar.scss +85 -31
- package/src/styles/components/_tooltip.scss +172 -3
- package/src/styles/mixins/_cut-border.scss +18 -4
- package/src/styles/mixins/_dual-selector.scss +192 -0
- package/src/styles/mixins/_index.scss +1 -0
- package/src/styles/mixins/dualSelector.test.ts +151 -0
- package/src/styles/themes/_colorful.scss +25 -0
- package/src/styles/themes/_greyscale.scss +25 -0
- package/src/styles/themes/_shade-scale.scss +39 -0
- package/src/styles/tokens/_semantic-color-kinds.scss +66 -0
- package/src/{types.ts → types/index.ts} +19 -11
- package/src/utils/slots.ts +75 -0
- package/web-types.json +980 -137
- package/dist/composables/useCustomColors.test.d.ts +0 -1
- package/dist/composables/useFocusTrap.test.d.ts +0 -1
- package/dist/composables/usePortalContext.test.d.ts +0 -1
- package/dist/styles/mixins/fluidSize.test.d.ts +0 -1
- package/dist/types.d.ts +0 -29
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Spec Coverage Test
|
|
3
|
+
//
|
|
4
|
+
// Ensures every component directory under src/components/ has an entry in SPECS (or is
|
|
5
|
+
// explicitly noted as compound/hand-written). Catches drift when new Vue components are added.
|
|
6
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
import { describe, expect, it } from 'vitest';
|
|
9
|
+
import { readdirSync } from 'node:fs';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
|
|
13
|
+
import { SPECS } from './specs';
|
|
14
|
+
|
|
15
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
const componentsDir = join(here, '..', 'components');
|
|
19
|
+
|
|
20
|
+
// Components that are out-of-scope per the design spec (Vue-only, not pure-CSS-eligible)
|
|
21
|
+
const OUT_OF_SCOPE = new Set([
|
|
22
|
+
'Accordion',
|
|
23
|
+
'Collapsible',
|
|
24
|
+
'ContextMenu',
|
|
25
|
+
'Listbox',
|
|
26
|
+
'Modal',
|
|
27
|
+
'Popover',
|
|
28
|
+
'ScrollArea',
|
|
29
|
+
'Splitter',
|
|
30
|
+
'Tabs',
|
|
31
|
+
'Theme',
|
|
32
|
+
'Toast',
|
|
33
|
+
'TreeView',
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
// Components with hand-written helpers (compound structure beyond the generic renderer's reach)
|
|
37
|
+
const HAND_WRITTEN = new Set([ 'Button', 'Checkbox', 'Radio', 'Switch', 'NumberInput', 'TagsInput' ]);
|
|
38
|
+
|
|
39
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
describe('spec coverage', () =>
|
|
42
|
+
{
|
|
43
|
+
const componentDirs = readdirSync(componentsDir, { withFileTypes: true })
|
|
44
|
+
.filter((entry) => entry.isDirectory())
|
|
45
|
+
.map((entry) => entry.name)
|
|
46
|
+
.filter((dir) => !OUT_OF_SCOPE.has(dir) && !HAND_WRITTEN.has(dir));
|
|
47
|
+
|
|
48
|
+
for(const dir of componentDirs)
|
|
49
|
+
{
|
|
50
|
+
it(`${ dir } has a spec`, () =>
|
|
51
|
+
{
|
|
52
|
+
const key = dir.charAt(0).toLowerCase() + dir.slice(1);
|
|
53
|
+
expect(SPECS[key], `SPECS["${ key }"] should exist for ${ dir }`).toBeDefined();
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Per-Component Spec Registry
|
|
3
|
+
//
|
|
4
|
+
// Maps each component name to its RenderSpec. Used by helper functions to render the right
|
|
5
|
+
// HTML structure with the right modifier-class composition and custom-color handling.
|
|
6
|
+
//
|
|
7
|
+
// Hand-maintained. When adding a component, add its spec here. The codegen covers prop types
|
|
8
|
+
// and defaults but not the render shape — that's this file's job.
|
|
9
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
import type { RenderSpec } from './render';
|
|
12
|
+
|
|
13
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
export const SPECS : Record<string, RenderSpec> = {
|
|
16
|
+
panel: {
|
|
17
|
+
tag: 'div',
|
|
18
|
+
classSpec: {
|
|
19
|
+
base: 'sk-panel',
|
|
20
|
+
kind: true,
|
|
21
|
+
size: true,
|
|
22
|
+
booleanFlags: [ 'no-border', 'no-decoration' ],
|
|
23
|
+
listFlags: [ { prop: 'corners', family: 'cut' } ],
|
|
24
|
+
singleChoiceFlags: [ { prop: 'decorationCorner', family: 'decoration' } ],
|
|
25
|
+
},
|
|
26
|
+
customColorVars: { base: '--sk-panel-color-base', text: '--sk-panel-fg' },
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
card: {
|
|
30
|
+
tag: 'div',
|
|
31
|
+
classSpec: { base: 'sk-card', kind: true },
|
|
32
|
+
customColorVars: { base: '--sk-panel-color-base', text: '--sk-panel-fg' },
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
alert: {
|
|
36
|
+
tag: 'div',
|
|
37
|
+
classSpec: {
|
|
38
|
+
base: 'sk-alert',
|
|
39
|
+
kind: true,
|
|
40
|
+
booleanFlags: [ 'subtle' ],
|
|
41
|
+
},
|
|
42
|
+
extraAttrs: { role: 'alert' },
|
|
43
|
+
customColorVars: { base: '--sk-alert-color-base', text: '--sk-alert-fg' },
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
divider: {
|
|
47
|
+
tag: 'div',
|
|
48
|
+
classSpec: {
|
|
49
|
+
base: 'sk-divider',
|
|
50
|
+
kind: true,
|
|
51
|
+
booleanFlags: [ 'subtle' ],
|
|
52
|
+
singleChoiceFlags: [ { prop: 'orientation', family: 'orientation' } ],
|
|
53
|
+
},
|
|
54
|
+
extraAttrs: { role: 'separator' },
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
page: {
|
|
58
|
+
tag: 'div',
|
|
59
|
+
classSpec: {
|
|
60
|
+
base: 'sk-page',
|
|
61
|
+
booleanFlags: [ 'flush', 'fixed-header', 'fixed-footer' ],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
group: {
|
|
66
|
+
tag: 'div',
|
|
67
|
+
classSpec: {
|
|
68
|
+
base: 'sk-group',
|
|
69
|
+
singleChoiceFlags: [ { prop: 'orientation', family: 'orientation' } ],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
// `prop: 'variant'` matches Vue's prop name; CSS family `shape` (sk-shape-*) is unchanged.
|
|
74
|
+
skeleton: {
|
|
75
|
+
tag: 'div',
|
|
76
|
+
classSpec: {
|
|
77
|
+
base: 'sk-skeleton',
|
|
78
|
+
singleChoiceFlags: [ { prop: 'variant', family: 'shape' } ],
|
|
79
|
+
booleanFlags: [ 'shimmer', 'pulse' ],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
progress: {
|
|
84
|
+
tag: 'progress',
|
|
85
|
+
classSpec: {
|
|
86
|
+
base: 'sk-progress',
|
|
87
|
+
kind: true,
|
|
88
|
+
size: true,
|
|
89
|
+
booleanFlags: [ 'indeterminate' ],
|
|
90
|
+
},
|
|
91
|
+
void: true,
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
spinner: {
|
|
95
|
+
tag: 'div',
|
|
96
|
+
classSpec: { base: 'sk-spinner', kind: true, size: true },
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
// NavBar dir → camelCase key "navBar" (consistent with the test's key-derivation pattern)
|
|
100
|
+
navBar: {
|
|
101
|
+
tag: 'nav',
|
|
102
|
+
classSpec: { base: 'sk-navbar', kind: true, booleanFlags: [ 'sticky' ] },
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
toolbar: {
|
|
106
|
+
tag: 'div',
|
|
107
|
+
classSpec: {
|
|
108
|
+
base: 'sk-toolbar',
|
|
109
|
+
kind: true,
|
|
110
|
+
singleChoiceFlags: [ { prop: 'orientation', family: 'orientation' } ],
|
|
111
|
+
},
|
|
112
|
+
extraAttrs: { role: 'toolbar' },
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
sidebar: {
|
|
116
|
+
tag: 'aside',
|
|
117
|
+
classSpec: { base: 'sk-sidebar', kind: true, booleanFlags: [ 'dense' ] },
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
breadcrumbs: {
|
|
121
|
+
tag: 'nav',
|
|
122
|
+
classSpec: { base: 'sk-breadcrumbs', kind: true },
|
|
123
|
+
extraAttrs: { 'aria-label': 'Breadcrumbs' },
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
pagination: {
|
|
127
|
+
tag: 'nav',
|
|
128
|
+
classSpec: { base: 'sk-pagination', kind: true },
|
|
129
|
+
extraAttrs: { 'aria-label': 'Pagination' },
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
tag: {
|
|
133
|
+
tag: 'span',
|
|
134
|
+
classSpec: {
|
|
135
|
+
base: 'sk-tag',
|
|
136
|
+
kind: true,
|
|
137
|
+
size: true,
|
|
138
|
+
variant: true,
|
|
139
|
+
booleanFlags: [ 'removable' ],
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
avatar: {
|
|
144
|
+
tag: 'div',
|
|
145
|
+
classSpec: {
|
|
146
|
+
base: 'sk-avatar',
|
|
147
|
+
kind: true,
|
|
148
|
+
size: true,
|
|
149
|
+
singleChoiceFlags: [ { prop: 'shape', family: 'shape' } ],
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
field: {
|
|
154
|
+
tag: 'div',
|
|
155
|
+
classSpec: {
|
|
156
|
+
base: 'sk-field',
|
|
157
|
+
booleanFlags: [ 'has-error' ],
|
|
158
|
+
singleChoiceFlags: [ { prop: 'labelPosition', family: 'label-position' } ],
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
table: {
|
|
163
|
+
tag: 'table',
|
|
164
|
+
classSpec: {
|
|
165
|
+
base: 'sk-table',
|
|
166
|
+
kind: true,
|
|
167
|
+
variant: true,
|
|
168
|
+
booleanFlags: [ 'striped', 'bordered', 'compact', 'comfortable' ],
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
tooltip: {
|
|
173
|
+
tag: 'div',
|
|
174
|
+
classSpec: {
|
|
175
|
+
base: 'sk-tooltip',
|
|
176
|
+
kind: true,
|
|
177
|
+
variant: true,
|
|
178
|
+
singleChoiceFlags: [ { prop: 'placement', family: 'placement' } ],
|
|
179
|
+
},
|
|
180
|
+
extraAttrs: { role: 'tooltip' },
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
// Class-only form controls — class-API HTML on native elements
|
|
184
|
+
input: {
|
|
185
|
+
tag: 'input',
|
|
186
|
+
classSpec: { base: 'sk-input', kind: true, size: true },
|
|
187
|
+
void: true,
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
textarea: {
|
|
191
|
+
tag: 'textarea',
|
|
192
|
+
classSpec: { base: 'sk-textarea', kind: true, size: true },
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
select: {
|
|
196
|
+
tag: 'select',
|
|
197
|
+
classSpec: { base: 'sk-select', kind: true, size: true },
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
slider: {
|
|
201
|
+
tag: 'input',
|
|
202
|
+
classSpec: {
|
|
203
|
+
base: 'sk-slider',
|
|
204
|
+
kind: true,
|
|
205
|
+
size: true,
|
|
206
|
+
singleChoiceFlags: [ { prop: 'orientation', family: 'orientation' } ],
|
|
207
|
+
},
|
|
208
|
+
void: true,
|
|
209
|
+
extraAttrs: { type: 'range' },
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
colorPicker: {
|
|
213
|
+
tag: 'input',
|
|
214
|
+
classSpec: { base: 'sk-color-picker', size: true },
|
|
215
|
+
void: true,
|
|
216
|
+
extraAttrs: { type: 'color' },
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
// Compound components (checkbox/radio/switch/numberInput/tagsInput) are hand-written — see
|
|
220
|
+
// respective component files. They compose multiple inner elements the generic renderer
|
|
221
|
+
// can't express.
|
|
222
|
+
|
|
223
|
+
// Dropdown: disclosure via <details> + <summary>
|
|
224
|
+
dropdown: {
|
|
225
|
+
tag: 'details',
|
|
226
|
+
classSpec: { base: 'sk-dropdown', kind: true, size: true },
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Static Helpers — Shared Types
|
|
3
|
+
//
|
|
4
|
+
// All types are declared directly here — no imports from outside `src/static/`. This keeps
|
|
5
|
+
// TypeScript's computed common source root at `src/static/` so vite-plugin-dts emits
|
|
6
|
+
// declarations directly to `dist/static/` without any post-build file shuffling.
|
|
7
|
+
//
|
|
8
|
+
// The token types (SemanticKind, ColorKind, ComponentKind, ComponentSize, ComponentVariant) are
|
|
9
|
+
// copied from `src/types.ts`. They must be kept in sync manually if the canonical definitions
|
|
10
|
+
// change. Static module consumers can import these types from `@skewedaspect/sleekspace-ui/static`
|
|
11
|
+
// without pulling in the Vue package.
|
|
12
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
// Semantic kinds (themeable, colors with meaning)
|
|
15
|
+
export type SemanticKind = 'neutral' | 'primary' | 'accent' | 'danger' | 'info' | 'success' | 'warning';
|
|
16
|
+
|
|
17
|
+
// Color kinds (non-themeable, direct palette access)
|
|
18
|
+
export type ColorKind = 'boulder' | 'neon-blue' | 'light-blue' | 'neon-orange' | 'neon-purple' | 'neon-green'
|
|
19
|
+
| 'neon-mint' | 'neon-pink' | 'yellow' | 'red';
|
|
20
|
+
|
|
21
|
+
// All component kinds (semantic + color)
|
|
22
|
+
export type ComponentKind = SemanticKind | ColorKind;
|
|
23
|
+
|
|
24
|
+
// Common component sizes
|
|
25
|
+
export type ComponentSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
26
|
+
|
|
27
|
+
// Common button/interactive variants
|
|
28
|
+
export type ComponentVariant = 'solid' | 'outline' | 'subtle' | 'ghost' | 'link';
|
|
29
|
+
|
|
30
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
31
|
+
// Custom-color props (mirror of ComponentCustomColors from src/types.ts)
|
|
32
|
+
//
|
|
33
|
+
// Defined directly so the `./static` subpath doesn't pull in Vue-adjacent code.
|
|
34
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
export interface StaticCustomColors
|
|
37
|
+
{
|
|
38
|
+
baseColor ?: string;
|
|
39
|
+
textColor ?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
43
|
+
// Common helper signature
|
|
44
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
export type HtmlString = string;
|
|
47
|
+
|
|
48
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
49
|
+
// Alert
|
|
50
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
export type AlertKind = ComponentKind;
|
|
53
|
+
|
|
54
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
55
|
+
// Avatar
|
|
56
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
export type AvatarSize = ComponentSize;
|
|
59
|
+
|
|
60
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
61
|
+
// Breadcrumbs
|
|
62
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
export type BreadcrumbsKind = ComponentKind;
|
|
65
|
+
|
|
66
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
67
|
+
// Button
|
|
68
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
69
|
+
|
|
70
|
+
export type ButtonKind = ComponentKind;
|
|
71
|
+
export type ButtonSize = ComponentSize;
|
|
72
|
+
export type ButtonVariant = ComponentVariant;
|
|
73
|
+
export type ButtonType = 'button' | 'submit' | 'reset';
|
|
74
|
+
|
|
75
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
76
|
+
// Card
|
|
77
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
export type CardKind = ComponentKind;
|
|
80
|
+
|
|
81
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
82
|
+
// Divider
|
|
83
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
84
|
+
|
|
85
|
+
export type DividerOrientation = 'horizontal' | 'vertical';
|
|
86
|
+
export type DividerVariant = 'subtle';
|
|
87
|
+
|
|
88
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
89
|
+
// Field
|
|
90
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
export type FieldLabelPosition = 'top' | 'left';
|
|
93
|
+
|
|
94
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
95
|
+
// Group
|
|
96
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
export type GroupOrientation = 'horizontal' | 'vertical';
|
|
99
|
+
|
|
100
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
101
|
+
// NavBar
|
|
102
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
103
|
+
|
|
104
|
+
export type NavBarKind = ComponentKind;
|
|
105
|
+
|
|
106
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
107
|
+
// Page
|
|
108
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
109
|
+
|
|
110
|
+
export type PagePanelMode = 'auto' | 'persistent' | 'drawer';
|
|
111
|
+
|
|
112
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
113
|
+
// Pagination
|
|
114
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
115
|
+
|
|
116
|
+
export type PaginationKind = ComponentKind;
|
|
117
|
+
|
|
118
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
119
|
+
// Panel
|
|
120
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
export type PanelKind = ComponentKind;
|
|
123
|
+
export type PanelSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
124
|
+
export type PanelCorner = 'top-left' | 'top-right' | 'bottom-right' | 'bottom-left';
|
|
125
|
+
|
|
126
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
127
|
+
// Progress
|
|
128
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
export type ProgressSize = ComponentSize;
|
|
131
|
+
|
|
132
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
133
|
+
// Sidebar
|
|
134
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
export type SidebarKind = ComponentKind;
|
|
137
|
+
export type SidebarSide = 'left' | 'right';
|
|
138
|
+
|
|
139
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
140
|
+
// Spinner
|
|
141
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
142
|
+
|
|
143
|
+
export type SpinnerSize = ComponentSize;
|
|
144
|
+
export type SpinnerVariant = 'circular' | 'dots' | 'crosshair';
|
|
145
|
+
|
|
146
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
147
|
+
// Table
|
|
148
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
149
|
+
|
|
150
|
+
export type TableKind = ComponentKind;
|
|
151
|
+
export type TableVariant = 'default' | 'compact' | 'comfortable';
|
|
152
|
+
|
|
153
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
154
|
+
// Tag
|
|
155
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
156
|
+
|
|
157
|
+
export type TagVariant = 'solid' | 'outline' | 'subtle' | 'ghost';
|
|
158
|
+
export type TagSize = 'sm' | 'md' | 'lg' | 'xl';
|
|
159
|
+
|
|
160
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
161
|
+
// Toolbar
|
|
162
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
163
|
+
|
|
164
|
+
export type ToolbarKind = ComponentKind;
|
|
165
|
+
export type ToolbarOrientation = 'horizontal' | 'vertical';
|
|
166
|
+
export type ToolbarCorner = 'top-left' | 'top-right' | 'bottom-right' | 'bottom-left';
|
|
167
|
+
|
|
168
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
169
|
+
// Tooltip
|
|
170
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
171
|
+
|
|
172
|
+
export type TooltipKind = ComponentKind;
|
|
173
|
+
export type TooltipVariant = ComponentVariant;
|
|
174
|
+
export type TooltipSide = 'top' | 'right' | 'bottom' | 'left';
|
|
175
|
+
|
|
176
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Shared SCSS Test Helpers
|
|
3
|
+
//
|
|
4
|
+
// Parses the canonical kinds/sizes/variants lists from `src/styles/theme/_variables.scss` so
|
|
5
|
+
// test files can iterate over them without hardcoding. Also exports a small regex helper for
|
|
6
|
+
// matching Sass's unquoted attribute values (Sass strips quotes from attribute selectors when
|
|
7
|
+
// CSS allows it, so `[kind="primary"]` can be emitted as `[kind=primary]`).
|
|
8
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
import { readFileSync } from 'node:fs';
|
|
11
|
+
import { dirname, resolve } from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
|
|
14
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const variablesPath = resolve(here, '..', 'theme', '_variables.scss');
|
|
18
|
+
const variablesSource = readFileSync(variablesPath, 'utf8');
|
|
19
|
+
|
|
20
|
+
function extractList(name : string) : string[]
|
|
21
|
+
{
|
|
22
|
+
const pattern = new RegExp(`\\$${ name }\\s*:\\s*([^;]+);`, 'm');
|
|
23
|
+
const match = variablesSource.match(pattern);
|
|
24
|
+
if(!match)
|
|
25
|
+
{
|
|
26
|
+
throw new Error(`Could not find $${ name } in ${ variablesPath }`);
|
|
27
|
+
}
|
|
28
|
+
return match[1]
|
|
29
|
+
.split(',')
|
|
30
|
+
.map((entry) => entry.trim())
|
|
31
|
+
.filter(Boolean);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
export const SEMANTIC_KINDS : readonly string[] = extractList('semantic-kinds');
|
|
37
|
+
export const COLOR_KINDS : readonly string[] = extractList('color-kinds');
|
|
38
|
+
export const KINDS : readonly string[] = extractList('kinds');
|
|
39
|
+
export const VARIANTS : readonly string[] = extractList('variants');
|
|
40
|
+
export const SIZES : readonly string[] = extractList('sizes');
|
|
41
|
+
|
|
42
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
43
|
+
// Regex escape helpers
|
|
44
|
+
//
|
|
45
|
+
// `escapeRe` escapes hyphens in a value so it slots into a regex char class safely (only
|
|
46
|
+
// hyphens matter for the kinds/sizes/modifiers the selector tests assert on). `attrValueRe`
|
|
47
|
+
// wraps the escaped value in optional quotes so it matches both Sass's quoted and unquoted
|
|
48
|
+
// attribute-selector emissions. Use both inside `new RegExp(...)` template literals to keep
|
|
49
|
+
// dual-selector assertions short.
|
|
50
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
export function escapeRe(value : string) : string
|
|
53
|
+
{
|
|
54
|
+
return value.replace(/-/g, '\\-');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function attrValueRe(value : string) : string
|
|
58
|
+
{
|
|
59
|
+
return `"?${ escapeRe(value) }"?`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
63
|
+
// Dual-selector regex builder
|
|
64
|
+
//
|
|
65
|
+
// Builds the regex fragment matching a dual-selector pair of the form:
|
|
66
|
+
// .sk-<component>.sk-<classModifier><suffix>, sk-<component>[<attr><op><attrValue>]<suffix>
|
|
67
|
+
// Pass `attrValue` undefined for boolean attributes (just `[attr]`).
|
|
68
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
69
|
+
|
|
70
|
+
export interface DualSelectorOptions
|
|
71
|
+
{
|
|
72
|
+
attrOp ?: string;
|
|
73
|
+
suffix ?: string;
|
|
74
|
+
// Regex fragment appended after `\s+` to both the class and attribute forms (e.g. for
|
|
75
|
+
// a descendant combinator like `\.sk-page-header`).
|
|
76
|
+
descendant ?: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function dualSelectorRe(
|
|
80
|
+
component : string,
|
|
81
|
+
classModifier : string,
|
|
82
|
+
attr : string,
|
|
83
|
+
attrValue ?: string,
|
|
84
|
+
opts : DualSelectorOptions = {}
|
|
85
|
+
) : string
|
|
86
|
+
{
|
|
87
|
+
const op = opts.attrOp ?? '=';
|
|
88
|
+
const suffix = opts.suffix ?? '';
|
|
89
|
+
const tail = opts.descendant ? `${ suffix }\\s+${ opts.descendant }` : suffix;
|
|
90
|
+
const cls = `\\.sk-${ component }\\.sk-${ escapeRe(classModifier) }${ tail }`;
|
|
91
|
+
const attrFrag = attrValue === undefined
|
|
92
|
+
? `sk-${ component }\\[${ attr }\\]${ tail }`
|
|
93
|
+
: `sk-${ component }\\[${ attr }${ op }${ attrValueRe(attrValue) }\\]${ tail }`;
|
|
94
|
+
return `${ cls },\\s*${ attrFrag }`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Custom Element Base Styles
|
|
3
|
+
//
|
|
4
|
+
// Unknown elements default to `display: inline` in HTML. For the light-DOM custom-element forms
|
|
5
|
+
// of in-scope container components (`<sk-panel>`, `<sk-card>`, etc.), we want `display: block`
|
|
6
|
+
// (or an appropriate alternative) so they behave like their `<div>`-based class-API
|
|
7
|
+
// counterparts without authors having to add `display:block` themselves.
|
|
8
|
+
//
|
|
9
|
+
// This file ONLY applies to custom-element TAG names. The class API (`<div class="sk-panel">`)
|
|
10
|
+
// inherits display from the underlying element and is unaffected.
|
|
11
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
@layer base
|
|
14
|
+
{
|
|
15
|
+
// Block-level containers + separators
|
|
16
|
+
sk-panel,
|
|
17
|
+
sk-card,
|
|
18
|
+
sk-alert,
|
|
19
|
+
sk-page,
|
|
20
|
+
sk-navbar,
|
|
21
|
+
sk-toolbar,
|
|
22
|
+
sk-sidebar,
|
|
23
|
+
sk-breadcrumbs,
|
|
24
|
+
sk-pagination,
|
|
25
|
+
sk-field,
|
|
26
|
+
sk-table,
|
|
27
|
+
sk-progress,
|
|
28
|
+
sk-divider
|
|
29
|
+
{
|
|
30
|
+
display: block;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Inline-flex containers (layout helpers, badges)
|
|
34
|
+
sk-group,
|
|
35
|
+
sk-tag,
|
|
36
|
+
sk-avatar,
|
|
37
|
+
sk-spinner,
|
|
38
|
+
sk-skeleton
|
|
39
|
+
{
|
|
40
|
+
display: inline-flex;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Tooltip container — positioning handled by the component's CSS; the tag itself is a wrapper
|
|
44
|
+
sk-tooltip
|
|
45
|
+
{
|
|
46
|
+
display: inline-block;
|
|
47
|
+
position: relative;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
|
|
20
20
|
// 4. Typography
|
|
21
21
|
@include meta.load-css('typography');
|
|
22
|
+
|
|
23
|
+
// 5. Custom Element Display Defaults (must come after reset so the reset's
|
|
24
|
+
// element-level `display: inline` defaults don't override these rules)
|
|
25
|
+
@include meta.load-css('custom-elements');
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
//----------------------------------------------------------------------------------------------------------------------
|