ui-style-kit-css 1.2.2 → 2.0.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/CHANGELOG.md +28 -1
- package/CONTRIBUTING.md +6 -5
- package/README.md +133 -17
- package/STYLE-MAP.md +24 -0
- package/demo/index.html +1076 -73
- package/dist/ui-style-kit.css +2932 -8339
- package/dist/ui-style-kit.min.css +1 -1
- package/dist/ui-style-kit.with-bridge.css +5861 -0
- package/dist/ui-style-kit.with-bridge.min.css +1 -0
- package/docs/PUBLISHING.md +3 -3
- package/docs/STYLE-GUIDE.md +3 -1
- package/docs/TOKENS.md +215 -10
- package/package.json +15 -3
- package/styles/bauhaus.css +142 -702
- package/styles/bento.css +142 -701
- package/styles/brutalism.css +137 -702
- package/styles/cyberpunk.css +128 -699
- package/styles/interactive-surface-bridge.css +147 -311
- package/styles/maximalist.css +143 -702
- package/styles/minimal-saas.css +138 -701
- package/styles/native-elements.css +374 -0
- package/styles/neumorphism.css +144 -702
- package/styles/retro-glass.css +131 -702
- package/styles/retrofuturism.css +144 -702
- package/styles/tactile.css +142 -701
- package/styles/theme-colors.css +787 -0
- package/styles/y2k.css +122 -696
package/demo/index.html
CHANGED
|
@@ -1,120 +1,1123 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
-
<meta charset="utf-8"
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1"
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title>UI Style Kit CSS Demo</title>
|
|
7
|
-
<link rel="stylesheet" href="../dist/ui-style-kit.css"
|
|
7
|
+
<link id="styleKitStylesheet" rel="stylesheet" href="../dist/ui-style-kit.css">
|
|
8
8
|
<style>
|
|
9
|
-
.demo-controls {
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
.demo-controls {
|
|
10
|
+
position: sticky;
|
|
11
|
+
top: 0;
|
|
12
|
+
z-index: 1000;
|
|
13
|
+
display: grid;
|
|
14
|
+
grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
|
|
15
|
+
gap: .75rem;
|
|
16
|
+
padding: 1rem;
|
|
17
|
+
background: Canvas;
|
|
18
|
+
color: CanvasText;
|
|
19
|
+
border: 0;
|
|
20
|
+
border-bottom: 1px solid color-mix(in srgb, CanvasText 20%, transparent);
|
|
21
|
+
border-radius: 0;
|
|
22
|
+
box-shadow: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.demo-controls label,
|
|
26
|
+
.demo-switch-control {
|
|
27
|
+
display: grid;
|
|
28
|
+
gap: .25rem;
|
|
29
|
+
font: 700 .85rem system-ui, sans-serif;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.demo-controls select {
|
|
33
|
+
min-height: 2.5rem;
|
|
34
|
+
padding: .5rem;
|
|
35
|
+
font: inherit;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.demo-switch-control {
|
|
39
|
+
position: relative;
|
|
40
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
41
|
+
align-items: center;
|
|
42
|
+
column-gap: .75rem;
|
|
43
|
+
padding: .65rem .75rem;
|
|
44
|
+
border: 1px solid color-mix(in srgb, CanvasText 18%, transparent);
|
|
45
|
+
border-radius: 1rem;
|
|
46
|
+
background: color-mix(in srgb, Canvas 88%, CanvasText 12%);
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.demo-switch-control input {
|
|
51
|
+
position: absolute;
|
|
52
|
+
inset: 0;
|
|
53
|
+
z-index: 2;
|
|
54
|
+
inline-size: 100%;
|
|
55
|
+
block-size: 100%;
|
|
56
|
+
opacity: 0;
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.demo-switch-track {
|
|
61
|
+
position: relative;
|
|
62
|
+
inline-size: 3.35rem;
|
|
63
|
+
block-size: 1.85rem;
|
|
64
|
+
border: 1px solid color-mix(in srgb, CanvasText 22%, transparent);
|
|
65
|
+
border-radius: 999px;
|
|
66
|
+
background: color-mix(in srgb, Canvas 76%, CanvasText 24%);
|
|
67
|
+
box-shadow: inset 0 1px 3px rgb(0 0 0 / .18);
|
|
68
|
+
transition: background 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.demo-switch-thumb {
|
|
72
|
+
position: absolute;
|
|
73
|
+
inset-block-start: .2rem;
|
|
74
|
+
inset-inline-start: .2rem;
|
|
75
|
+
inline-size: 1.35rem;
|
|
76
|
+
block-size: 1.35rem;
|
|
77
|
+
border-radius: 50%;
|
|
78
|
+
background: Canvas;
|
|
79
|
+
box-shadow: 0 2px 8px rgb(0 0 0 / .25);
|
|
80
|
+
transition: transform 180ms ease, background 180ms ease;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.demo-switch-control input:focus-visible + .demo-switch-track {
|
|
84
|
+
outline: 3px solid Highlight;
|
|
85
|
+
outline-offset: 3px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.demo-switch-control input:checked + .demo-switch-track {
|
|
89
|
+
background: Highlight;
|
|
90
|
+
border-color: Highlight;
|
|
91
|
+
box-shadow: inset 0 1px 3px rgb(0 0 0 / .2), 0 0 0 3px color-mix(in srgb, Highlight 22%, transparent);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.demo-switch-control input:checked + .demo-switch-track .demo-switch-thumb {
|
|
95
|
+
transform: translateX(1.5rem);
|
|
96
|
+
background: Canvas;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.demo-switch-copy {
|
|
100
|
+
display: grid;
|
|
101
|
+
gap: .15rem;
|
|
102
|
+
min-width: 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.demo-switch-copy strong {
|
|
106
|
+
color: CanvasText;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.demo-switch-copy span {
|
|
110
|
+
color: color-mix(in srgb, CanvasText 72%, transparent);
|
|
111
|
+
font-weight: 650;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.demo-showcase {
|
|
115
|
+
min-height: 100vh;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.demo-section-lede {
|
|
119
|
+
max-width: 72rem;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.demo-showcase-grid,
|
|
123
|
+
.demo-native-grid,
|
|
124
|
+
.demo-state-grid,
|
|
125
|
+
.demo-token-grid,
|
|
126
|
+
.demo-bridge-grid {
|
|
127
|
+
display: grid;
|
|
128
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
|
|
129
|
+
gap: 1rem;
|
|
130
|
+
align-items: start;
|
|
131
|
+
grid-auto-flow: dense;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.demo-showcase-grid > *,
|
|
135
|
+
.demo-native-grid > *,
|
|
136
|
+
.demo-state-grid > *,
|
|
137
|
+
.demo-token-grid > *,
|
|
138
|
+
.demo-bridge-grid > * {
|
|
139
|
+
min-width: 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* The component showcase needs a tighter tablet grid than the wider native-element samples. */
|
|
143
|
+
#components .demo-showcase-grid {
|
|
144
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 18.5rem), 1fr));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
#components .demo-showcase-grid > article {
|
|
148
|
+
display: grid;
|
|
149
|
+
align-content: start;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
#components .demo-showcase-grid h3 {
|
|
153
|
+
font-size: clamp(1.08rem, 1.4vw, 1.55rem);
|
|
154
|
+
line-height: 1.18;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
#components .demo-showcase-grid > [data-testid="component-table"] {
|
|
158
|
+
align-content: stretch;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.demo-control-card {
|
|
162
|
+
gap: 1.15rem;
|
|
163
|
+
overflow: visible;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.demo-control-showcase {
|
|
167
|
+
display: grid;
|
|
168
|
+
grid-template-areas:
|
|
169
|
+
"buttons progress"
|
|
170
|
+
"buttons loading"
|
|
171
|
+
"tooltips tooltips";
|
|
172
|
+
grid-template-columns: minmax(14rem, .9fr) minmax(16rem, 1fr);
|
|
173
|
+
gap: 1rem;
|
|
174
|
+
align-items: start;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.demo-control-panel {
|
|
178
|
+
display: grid;
|
|
179
|
+
gap: .75rem;
|
|
180
|
+
min-width: 0;
|
|
181
|
+
padding-block-start: .8rem;
|
|
182
|
+
border-block-start: 1px solid color-mix(in srgb, currentColor 16%, transparent);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.demo-control-panel h4 {
|
|
186
|
+
margin: 0;
|
|
187
|
+
font-size: .82rem;
|
|
188
|
+
line-height: 1.2;
|
|
189
|
+
letter-spacing: .08em;
|
|
190
|
+
text-transform: uppercase;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.demo-control-panel[data-testid="component-buttons"] {
|
|
194
|
+
grid-area: buttons;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.demo-control-panel[data-testid="component-progress"] {
|
|
198
|
+
grid-area: progress;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.demo-control-panel[data-testid="component-spinner"] {
|
|
202
|
+
grid-area: loading;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.demo-control-panel[data-testid="component-tooltips"] {
|
|
206
|
+
grid-area: tooltips;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.demo-progress-stack {
|
|
210
|
+
display: grid;
|
|
211
|
+
gap: .55rem;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.demo-tooltip-row {
|
|
215
|
+
display: flex;
|
|
216
|
+
flex-wrap: wrap;
|
|
217
|
+
gap: .8rem;
|
|
218
|
+
align-items: center;
|
|
219
|
+
padding-block-end: .45rem;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.demo-badge-showcase {
|
|
223
|
+
display: grid;
|
|
224
|
+
gap: .8rem;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.demo-badge-group {
|
|
228
|
+
display: grid;
|
|
229
|
+
gap: .45rem;
|
|
230
|
+
padding-block-start: .72rem;
|
|
231
|
+
border-block-start: 1px solid color-mix(in srgb, currentColor 14%, transparent);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.demo-badge-group:first-child {
|
|
235
|
+
padding-block-start: 0;
|
|
236
|
+
border-block-start: 0;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.demo-badge-label {
|
|
240
|
+
margin: 0;
|
|
241
|
+
color: color-mix(in srgb, currentColor 72%, transparent);
|
|
242
|
+
font-size: .76rem;
|
|
243
|
+
font-weight: 850;
|
|
244
|
+
line-height: 1.2;
|
|
245
|
+
text-transform: uppercase;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.demo-badge-row {
|
|
249
|
+
display: flex;
|
|
250
|
+
flex-wrap: wrap;
|
|
251
|
+
gap: .52rem;
|
|
252
|
+
align-items: center;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
@media (min-width: 720px) and (max-width: 979.98px) {
|
|
256
|
+
#components .demo-showcase-grid {
|
|
257
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
#components .demo-showcase-grid > [data-testid="component-controls"],
|
|
261
|
+
#components .demo-showcase-grid > [data-testid="component-buttons-states"],
|
|
262
|
+
#components .demo-showcase-grid > [data-testid="component-fields"],
|
|
263
|
+
#components .demo-showcase-grid > [data-testid="component-table"] {
|
|
264
|
+
grid-column: 1 / -1;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@media (min-width: 980px) {
|
|
269
|
+
#components .demo-showcase-grid {
|
|
270
|
+
grid-template-columns: repeat(12, minmax(0, 1fr));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
#components .demo-showcase-grid > [data-testid="component-controls"] {
|
|
274
|
+
grid-column: span 7;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
#components .demo-showcase-grid > [data-testid="component-buttons-states"] {
|
|
278
|
+
grid-column: span 5;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
#components .demo-showcase-grid > [data-testid="component-fields"] {
|
|
282
|
+
grid-column: span 5;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
#components .demo-showcase-grid > [data-testid="component-badges"] {
|
|
286
|
+
grid-column: span 3;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
#components .demo-showcase-grid > [data-testid="component-alerts"] {
|
|
290
|
+
grid-column: span 4;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
#components .demo-showcase-grid > [data-testid="component-table"] {
|
|
294
|
+
grid-column: 1 / -1;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.demo-table-card {
|
|
299
|
+
padding: clamp(1rem, 2vw, 1.4rem);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.demo-table-card table {
|
|
303
|
+
inline-size: 100%;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.demo-tight-grid {
|
|
307
|
+
display: grid;
|
|
308
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
|
|
309
|
+
gap: .75rem;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.demo-state-sample,
|
|
313
|
+
.demo-native-sample,
|
|
314
|
+
.demo-token-sample {
|
|
315
|
+
display: grid;
|
|
316
|
+
gap: .65rem;
|
|
317
|
+
min-width: 0;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.demo-state-sample > p,
|
|
321
|
+
.demo-native-sample > p,
|
|
322
|
+
.demo-token-sample > p {
|
|
323
|
+
margin: 0;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.demo-button-row,
|
|
327
|
+
.demo-inline-row {
|
|
328
|
+
display: flex;
|
|
329
|
+
flex-wrap: wrap;
|
|
330
|
+
gap: .65rem;
|
|
331
|
+
align-items: center;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.demo-color-chip-grid,
|
|
335
|
+
.demo-utility-surface-grid {
|
|
336
|
+
display: grid;
|
|
337
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
|
|
338
|
+
gap: .65rem;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.demo-color-chip,
|
|
342
|
+
.demo-utility-surface {
|
|
343
|
+
display: grid;
|
|
344
|
+
gap: .35rem;
|
|
345
|
+
min-width: 0;
|
|
346
|
+
padding: .75rem;
|
|
347
|
+
border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
|
|
348
|
+
border-radius: .75rem;
|
|
349
|
+
background: color-mix(in srgb, Canvas 88%, CanvasText 12%);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.demo-color-chip {
|
|
353
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
354
|
+
align-items: center;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.demo-color-swatch {
|
|
358
|
+
inline-size: 1.1rem;
|
|
359
|
+
block-size: 1.1rem;
|
|
360
|
+
border-radius: 50%;
|
|
361
|
+
background: var(--demo-token-color);
|
|
362
|
+
box-shadow: 0 0 0 1px color-mix(in srgb, CanvasText 18%, transparent);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.demo-color-chip small {
|
|
366
|
+
display: block;
|
|
367
|
+
color: color-mix(in srgb, currentColor 72%, transparent);
|
|
368
|
+
font-size: .78rem;
|
|
369
|
+
line-height: 1.35;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.demo-utility-layout-sample {
|
|
373
|
+
display: flex;
|
|
374
|
+
flex-wrap: wrap;
|
|
375
|
+
gap: .5rem;
|
|
376
|
+
align-items: center;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.demo-utility-label {
|
|
380
|
+
margin: 0;
|
|
381
|
+
font-size: .78rem;
|
|
382
|
+
font-weight: 850;
|
|
383
|
+
letter-spacing: .08em;
|
|
384
|
+
text-transform: uppercase;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
@media (max-width: 760px) {
|
|
388
|
+
.demo-control-showcase {
|
|
389
|
+
grid-template-areas:
|
|
390
|
+
"buttons"
|
|
391
|
+
"progress"
|
|
392
|
+
"loading"
|
|
393
|
+
"tooltips";
|
|
394
|
+
grid-template-columns: 1fr;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.demo-form-grid {
|
|
399
|
+
display: grid;
|
|
400
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
|
|
401
|
+
gap: .85rem;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.demo-media-box,
|
|
405
|
+
.demo-object,
|
|
406
|
+
.demo-embed,
|
|
407
|
+
.demo-iframe {
|
|
408
|
+
display: block;
|
|
409
|
+
inline-size: 100%;
|
|
410
|
+
min-block-size: 8rem;
|
|
411
|
+
border: 1px dashed color-mix(in srgb, currentColor 35%, transparent);
|
|
412
|
+
border-radius: .75rem;
|
|
413
|
+
background:
|
|
414
|
+
linear-gradient(135deg, color-mix(in srgb, currentColor 16%, transparent), transparent 55%),
|
|
415
|
+
color-mix(in srgb, Canvas 92%, CanvasText 8%);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.demo-canvas {
|
|
419
|
+
aspect-ratio: 16 / 7;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
.demo-inline-dialog {
|
|
423
|
+
position: static;
|
|
424
|
+
display: block;
|
|
425
|
+
inline-size: 100%;
|
|
426
|
+
margin: 0;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.demo-code {
|
|
430
|
+
white-space: pre-wrap;
|
|
431
|
+
word-break: break-word;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.demo-native-table-scroll {
|
|
435
|
+
overflow-x: auto;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.demo-bridge-preview .demo-switch-control {
|
|
439
|
+
max-inline-size: 36rem;
|
|
440
|
+
margin-block: 1rem 1.25rem;
|
|
441
|
+
background: color-mix(in srgb, currentColor 7%, transparent);
|
|
442
|
+
color: inherit;
|
|
443
|
+
border-color: color-mix(in srgb, currentColor 22%, transparent);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.demo-bridge-preview .demo-switch-copy strong {
|
|
447
|
+
color: inherit;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.demo-bridge-preview .demo-switch-copy span {
|
|
451
|
+
color: color-mix(in srgb, currentColor 72%, transparent);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.demo-bridge-preview .interactive-surface {
|
|
455
|
+
display: grid;
|
|
456
|
+
gap: .5rem;
|
|
457
|
+
min-block-size: 7rem;
|
|
458
|
+
align-content: start;
|
|
459
|
+
padding: 1rem;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.demo-bridge-preview small {
|
|
463
|
+
color: inherit;
|
|
464
|
+
opacity: .8;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
@media (max-width: 720px) {
|
|
468
|
+
.demo-controls {
|
|
469
|
+
position: static;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
12
472
|
</style>
|
|
13
473
|
</head>
|
|
14
|
-
<body data-ui="minimal-saas" data-theme="arctic-indigo" data-mode="light">
|
|
474
|
+
<body data-ui="minimal-saas" data-theme="arctic-indigo" data-mode="light" data-bridge="detached">
|
|
15
475
|
<a id="skip" class="saas-skip-link" href="#main">Skip to content</a>
|
|
16
476
|
<aside class="demo-controls" aria-label="Demo controls">
|
|
17
|
-
<label>
|
|
18
|
-
|
|
19
|
-
|
|
477
|
+
<label>
|
|
478
|
+
UI Style
|
|
479
|
+
<select id="uiSelect">
|
|
480
|
+
<option value="minimal-saas" data-prefix="saas">Minimal SaaS</option>
|
|
481
|
+
<option value="bento" data-prefix="bento">Bento UI</option>
|
|
482
|
+
<option value="maximalist" data-prefix="max">Maximalist / Playful</option>
|
|
483
|
+
<option value="bauhaus" data-prefix="bau">Bauhaus / Swiss Modern</option>
|
|
484
|
+
<option value="tactile" data-prefix="tactile">Skeuomorphic / Tactile</option>
|
|
485
|
+
<option value="neumorphism" data-prefix="neo">Neumorphism</option>
|
|
486
|
+
<option value="retrofuturism" data-prefix="retro">Retrofuturism</option>
|
|
487
|
+
<option value="brutalism" data-prefix="brutal">Brutalism</option>
|
|
488
|
+
<option value="cyberpunk" data-prefix="cyber">Cyberpunk</option>
|
|
489
|
+
<option value="y2k" data-prefix="y2k">Y2K</option>
|
|
490
|
+
<option value="retro-glass" data-prefix="rg">Retro Glass</option>
|
|
491
|
+
</select>
|
|
492
|
+
</label>
|
|
493
|
+
<label>
|
|
494
|
+
Color Theme
|
|
495
|
+
<select id="themeSelect">
|
|
496
|
+
<option value="midnight-gold">midnight-gold</option>
|
|
497
|
+
<option value="ocean-steel">ocean-steel</option>
|
|
498
|
+
<option value="forest-moss">forest-moss</option>
|
|
499
|
+
<option value="sunset-ember">sunset-ember</option>
|
|
500
|
+
<option value="royal-plum">royal-plum</option>
|
|
501
|
+
<option value="graphite-cyan">graphite-cyan</option>
|
|
502
|
+
<option value="desert-sage">desert-sage</option>
|
|
503
|
+
<option value="rose-quartz">rose-quartz</option>
|
|
504
|
+
<option value="cyber-lime">cyber-lime</option>
|
|
505
|
+
<option value="arctic-indigo" selected>arctic-indigo</option>
|
|
506
|
+
</select>
|
|
507
|
+
</label>
|
|
508
|
+
<label>
|
|
509
|
+
Mode
|
|
510
|
+
<select id="modeSelect">
|
|
511
|
+
<option value="light">light</option>
|
|
512
|
+
<option value="dark">dark</option>
|
|
513
|
+
<option value="contrast">contrast</option>
|
|
514
|
+
</select>
|
|
515
|
+
</label>
|
|
20
516
|
</aside>
|
|
517
|
+
|
|
21
518
|
<main id="main"></main>
|
|
519
|
+
|
|
22
520
|
<script>
|
|
23
|
-
const stylePrefixes = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
521
|
+
const stylePrefixes = {
|
|
522
|
+
"minimal-saas": "saas",
|
|
523
|
+
bento: "bento",
|
|
524
|
+
maximalist: "max",
|
|
525
|
+
bauhaus: "bau",
|
|
526
|
+
tactile: "tactile",
|
|
527
|
+
neumorphism: "neo",
|
|
528
|
+
retrofuturism: "retro",
|
|
529
|
+
brutalism: "brutal",
|
|
530
|
+
cyberpunk: "cyber",
|
|
531
|
+
y2k: "y2k",
|
|
532
|
+
"retro-glass": "rg"
|
|
533
|
+
};
|
|
534
|
+
const styleTitles = {
|
|
535
|
+
"minimal-saas": "Minimal SaaS",
|
|
536
|
+
bento: "Bento UI",
|
|
537
|
+
maximalist: "Maximalist / Playful",
|
|
538
|
+
bauhaus: "Bauhaus / Swiss Modern",
|
|
539
|
+
tactile: "Skeuomorphic / Tactile",
|
|
540
|
+
neumorphism: "Neumorphism",
|
|
541
|
+
retrofuturism: "Retrofuturism",
|
|
542
|
+
brutalism: "Brutalism",
|
|
543
|
+
cyberpunk: "Cyberpunk",
|
|
544
|
+
y2k: "Y2K",
|
|
545
|
+
"retro-glass": "Retro Glass"
|
|
546
|
+
};
|
|
547
|
+
const bridgeAwareBundle = "../dist/ui-style-kit.with-bridge.css";
|
|
548
|
+
const defaultBundle = "../dist/ui-style-kit.css";
|
|
549
|
+
const stylesWithCustomChoices = new Set([
|
|
550
|
+
"minimal-saas",
|
|
551
|
+
"bento",
|
|
552
|
+
"maximalist",
|
|
553
|
+
"bauhaus",
|
|
554
|
+
"tactile",
|
|
555
|
+
"neumorphism",
|
|
556
|
+
"retrofuturism"
|
|
557
|
+
]);
|
|
558
|
+
const uiSelect = document.getElementById("uiSelect");
|
|
559
|
+
const themeSelect = document.getElementById("themeSelect");
|
|
560
|
+
const modeSelect = document.getElementById("modeSelect");
|
|
561
|
+
const styleKitStylesheet = document.getElementById("styleKitStylesheet");
|
|
562
|
+
const main = document.getElementById("main");
|
|
563
|
+
const skip = document.getElementById("skip");
|
|
564
|
+
let bridgeAttached = false;
|
|
565
|
+
const interactiveSurfaceSelector = [
|
|
566
|
+
"a[href]",
|
|
567
|
+
"button:not(:disabled)",
|
|
568
|
+
"input:not([type='hidden']):not(:disabled)",
|
|
569
|
+
"select:not(:disabled)",
|
|
570
|
+
"textarea:not(:disabled)",
|
|
571
|
+
"summary",
|
|
572
|
+
"audio[controls]",
|
|
573
|
+
"video[controls]"
|
|
574
|
+
].join(",");
|
|
575
|
+
|
|
576
|
+
function renderChoiceControls(ui, p) {
|
|
577
|
+
if (!stylesWithCustomChoices.has(ui)) {
|
|
578
|
+
return `
|
|
579
|
+
<div class="demo-inline-row">
|
|
580
|
+
<label><input type="checkbox" checked> Native checkbox</label>
|
|
581
|
+
<label><input type="radio" name="native-choice-${ui}" checked> Native radio</label>
|
|
582
|
+
<label><input type="radio" name="native-choice-${ui}"> Native radio</label>
|
|
583
|
+
</div>`;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
return `
|
|
587
|
+
<div class="demo-inline-row">
|
|
588
|
+
<label class="${p}-check"><input type="checkbox" checked><span class="${p}-check-control"></span><span>Checked</span></label>
|
|
589
|
+
<label class="${p}-check"><input type="checkbox"><span class="${p}-check-control"></span><span>Unchecked</span></label>
|
|
590
|
+
<label class="${p}-radio"><input type="radio" name="component-radio-${ui}" checked><span class="${p}-radio-control"></span><span>Radio A</span></label>
|
|
591
|
+
<label class="${p}-radio"><input type="radio" name="component-radio-${ui}"><span class="${p}-radio-control"></span><span>Radio B</span></label>
|
|
592
|
+
<label class="${p}-switch"><input type="checkbox" checked><span class="${p}-switch-track"><span class="${p}-switch-thumb"></span></span><span>Switch</span></label>
|
|
593
|
+
</div>`;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
function renderStyleSpecificSurface(ui, p) {
|
|
597
|
+
const extras = {
|
|
598
|
+
"minimal-saas": `
|
|
599
|
+
<div class="${p}-metric"><span class="${p}-metric-value">98%</span><span class="${p}-metric-label">metric</span></div>
|
|
600
|
+
<div class="${p}-empty-state"><h3 class="${p}-heading">Empty state</h3><p class="${p}-copy">No records need attention.</p></div>`,
|
|
601
|
+
bento: `
|
|
602
|
+
<div class="${p}-grid-feature">
|
|
603
|
+
<div class="${p}-tile ${p}-tile-lg"><span class="${p}-stat-value">42</span><span class="${p}-stat-label">large tile</span></div>
|
|
604
|
+
<div class="${p}-tile ${p}-tile-sm"><span class="${p}-stat-value">8</span><span class="${p}-stat-label">small tile</span></div>
|
|
605
|
+
</div>`,
|
|
606
|
+
maximalist: `
|
|
607
|
+
<span class="${p}-sticker">Sticker</span>
|
|
608
|
+
<div class="${p}-callout ${p}-wiggle">Playful callout motion utility</div>`,
|
|
609
|
+
bauhaus: `
|
|
610
|
+
<div class="${p}-composition"><div class="${p}-block">Block</div><div class="${p}-rail">Rail</div></div>`,
|
|
611
|
+
tactile: `
|
|
612
|
+
<div class="${p}-bevel">Beveled surface</div>
|
|
613
|
+
<button class="${p}-button ${p}-pressed">Pressed surface</button>
|
|
614
|
+
<span class="${p}-knob" aria-hidden="true"></span>`,
|
|
615
|
+
brutalism: `
|
|
616
|
+
<button class="${p}-button ${p}-pressed">Pressed block</button>`,
|
|
617
|
+
cyberpunk: `
|
|
618
|
+
<div class="${p}-console"><code>console.surface.ready()</code></div>`,
|
|
619
|
+
y2k: `
|
|
620
|
+
<div class="${p}-bubble">Bubble surface</div>`,
|
|
621
|
+
"retro-glass": `
|
|
622
|
+
<div class="${p}-console"><code>glass.surface.ready()</code></div>`
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
return extras[ui] || `<div class="${p}-well">Core surfaces carry this style preset.</div>`;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
function getSurfaceVariant(element) {
|
|
629
|
+
const className = element.getAttribute("class") || "";
|
|
630
|
+
const inputType = element.getAttribute("type");
|
|
631
|
+
|
|
632
|
+
if (element.matches("[aria-current='page'], [aria-pressed='true'], .is-active")) return "primary";
|
|
633
|
+
if (className.includes("-button-danger") || inputType === "reset") return "danger";
|
|
634
|
+
if (className.includes("-button-secondary")) return "secondary";
|
|
635
|
+
if (className.includes("-button-primary") || inputType === "submit" || inputType === "button") return "primary";
|
|
636
|
+
|
|
637
|
+
return "subtle";
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
function getSurfaceLevel(element) {
|
|
641
|
+
const inputType = element.getAttribute("type");
|
|
642
|
+
|
|
643
|
+
if (element.matches("[aria-current='page'], [aria-pressed='true'], .is-active, [aria-busy='true']")) return "3";
|
|
644
|
+
if (element.matches("button, select, summary, audio[controls], video[controls]")) return "2";
|
|
645
|
+
if (["button", "submit", "reset"].includes(inputType)) return "2";
|
|
646
|
+
|
|
647
|
+
return "1";
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
function syncInteractiveSurfaceHooks(isAttached) {
|
|
651
|
+
const elements = document.querySelectorAll(interactiveSurfaceSelector);
|
|
652
|
+
|
|
653
|
+
elements.forEach((element) => {
|
|
654
|
+
if (!isAttached) {
|
|
655
|
+
element.classList.remove("interactive-surface");
|
|
656
|
+
delete element.dataset.surfaceVariant;
|
|
657
|
+
delete element.dataset.surfaceLevel;
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
element.classList.add("interactive-surface");
|
|
662
|
+
element.dataset.surfaceVariant = getSurfaceVariant(element);
|
|
663
|
+
element.dataset.surfaceLevel = getSurfaceLevel(element);
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
function updateBridge() {
|
|
668
|
+
const bridgeToggle = document.getElementById("bridgeToggle");
|
|
669
|
+
const bridgeStatus = document.querySelector("[data-testid='bridge-status']");
|
|
670
|
+
const isAttached = bridgeToggle ? bridgeToggle.checked : bridgeAttached;
|
|
671
|
+
|
|
672
|
+
bridgeAttached = isAttached;
|
|
673
|
+
|
|
674
|
+
document.body.dataset.bridge = isAttached ? "attached" : "detached";
|
|
675
|
+
styleKitStylesheet.setAttribute("href", isAttached ? bridgeAwareBundle : defaultBundle);
|
|
676
|
+
if (bridgeStatus) {
|
|
677
|
+
bridgeStatus.textContent = isAttached
|
|
678
|
+
? "Attached - using with-bridge bundle"
|
|
679
|
+
: "Detached - default bundle";
|
|
680
|
+
}
|
|
681
|
+
// The bridge stylesheet owns the surface visuals; the demo only attaches the expected hooks.
|
|
682
|
+
syncInteractiveSurfaceHooks(isAttached);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
function syncPrimaryNavCurrent(targetId = "overview") {
|
|
686
|
+
const nav = main.querySelector('nav[aria-label="Primary"]');
|
|
687
|
+
if (!nav) return;
|
|
688
|
+
|
|
689
|
+
nav.querySelectorAll('a[href^="#"]').forEach((link) => {
|
|
690
|
+
const isCurrent = link.getAttribute("href") === `#${targetId}`;
|
|
691
|
+
link.classList.toggle("is-active", isCurrent);
|
|
692
|
+
|
|
693
|
+
if (isCurrent) {
|
|
694
|
+
link.setAttribute("aria-current", "page");
|
|
695
|
+
} else {
|
|
696
|
+
link.removeAttribute("aria-current");
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
function bindPrimaryNav() {
|
|
702
|
+
const nav = main.querySelector('nav[aria-label="Primary"]');
|
|
703
|
+
if (!nav) return;
|
|
704
|
+
|
|
705
|
+
nav.querySelectorAll('a[href^="#"]').forEach((link) => {
|
|
706
|
+
link.addEventListener("click", () => {
|
|
707
|
+
syncPrimaryNavCurrent(link.getAttribute("href").slice(1));
|
|
708
|
+
});
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
function drawDemoCanvas() {
|
|
713
|
+
const canvas = document.querySelector("[data-demo-canvas]");
|
|
714
|
+
if (!canvas) return;
|
|
715
|
+
|
|
716
|
+
const ctx = canvas.getContext("2d");
|
|
717
|
+
const styles = getComputedStyle(document.body);
|
|
718
|
+
const primary = styles.getPropertyValue(`--${stylePrefixes[uiSelect.value]}-primary`).trim() || "#6f8cff";
|
|
719
|
+
const accent = styles.getPropertyValue(`--${stylePrefixes[uiSelect.value]}-accent`).trim() || "#ffcc66";
|
|
720
|
+
|
|
721
|
+
// Canvas is drawn after render so the native canvas element is visibly represented.
|
|
722
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
723
|
+
ctx.fillStyle = primary;
|
|
724
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
725
|
+
ctx.fillStyle = accent;
|
|
726
|
+
ctx.beginPath();
|
|
727
|
+
ctx.arc(canvas.width * .72, canvas.height * .46, canvas.height * .28, 0, Math.PI * 2);
|
|
728
|
+
ctx.fill();
|
|
729
|
+
ctx.fillStyle = "rgba(255, 255, 255, .72)";
|
|
730
|
+
ctx.fillRect(canvas.width * .08, canvas.height * .2, canvas.width * .42, canvas.height * .12);
|
|
731
|
+
ctx.fillRect(canvas.width * .08, canvas.height * .42, canvas.width * .3, canvas.height * .12);
|
|
732
|
+
}
|
|
30
733
|
|
|
31
734
|
function render() {
|
|
32
735
|
const ui = uiSelect.value;
|
|
33
736
|
const p = stylePrefixes[ui];
|
|
34
737
|
const title = styleTitles[ui];
|
|
738
|
+
|
|
35
739
|
document.body.dataset.ui = ui;
|
|
36
740
|
document.body.dataset.theme = themeSelect.value;
|
|
37
741
|
document.body.dataset.mode = modeSelect.value;
|
|
38
742
|
skip.className = `${p}-skip-link`;
|
|
743
|
+
|
|
39
744
|
main.innerHTML = `
|
|
40
|
-
<section class="${p}-page">
|
|
745
|
+
<section class="${p}-page demo-showcase">
|
|
41
746
|
<div class="${p}-container ${p}-stack">
|
|
42
747
|
<nav class="${p}-nav" aria-label="Primary">
|
|
43
|
-
<a class="${p}-nav-link is-active" href="#">Overview</a>
|
|
748
|
+
<a class="${p}-nav-link is-active" aria-current="page" href="#overview">Overview</a>
|
|
44
749
|
<a class="${p}-nav-link" href="#components">Components</a>
|
|
45
750
|
<a class="${p}-nav-link" href="#native">Native HTML</a>
|
|
46
|
-
<a class="${p}-nav-link" href="#
|
|
751
|
+
<a class="${p}-nav-link" href="#bridge">Bridge</a>
|
|
752
|
+
<a class="${p}-nav-link" href="#usage">Usage</a>
|
|
47
753
|
</nav>
|
|
48
754
|
|
|
49
|
-
<
|
|
755
|
+
<header id="overview" class="${p}-card ${p}-hover-lift">
|
|
50
756
|
<p class="${p}-kicker">${title}</p>
|
|
51
757
|
<h1 class="${p}-title">UI Style Kit CSS</h1>
|
|
52
|
-
<p class="${p}-subtitle">A CSS-only style kit with
|
|
758
|
+
<p class="${p}-subtitle demo-section-lede">A CSS-only style kit with 11 UI systems, 10 shared color themes, light/dark/contrast modes, component classes, native HTML coverage, and an optional Interactive Surface bridge.</p>
|
|
53
759
|
<div class="${p}-cluster">
|
|
54
760
|
<button class="${p}-button ${p}-button-primary">Primary</button>
|
|
55
761
|
<button class="${p}-button ${p}-button-secondary">Secondary</button>
|
|
56
762
|
<button class="${p}-button">Neutral</button>
|
|
57
|
-
<button class="${p}-
|
|
763
|
+
<button class="${p}-button ${p}-button-ghost">Ghost</button>
|
|
764
|
+
<button class="${p}-icon-button" aria-label="Favorite">★</button>
|
|
58
765
|
<span class="${p}-badge ${p}-badge-primary">Primary</span>
|
|
59
766
|
<span class="${p}-badge ${p}-badge-warning">Warning</span>
|
|
60
767
|
</div>
|
|
61
|
-
</
|
|
62
|
-
|
|
63
|
-
<section id="components" class="${p}-
|
|
64
|
-
<
|
|
65
|
-
<p class="${p}-kicker">
|
|
66
|
-
<h2 class="${p}-heading">
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
768
|
+
</header>
|
|
769
|
+
|
|
770
|
+
<section id="components" class="${p}-stack">
|
|
771
|
+
<div class="demo-section-lede">
|
|
772
|
+
<p class="${p}-kicker">Components</p>
|
|
773
|
+
<h2 class="${p}-heading">Prefixed component classes and visible states</h2>
|
|
774
|
+
<p class="${p}-copy">Each style preset uses the same component API with a style-specific prefix such as <code>${p}-button</code>, <code>${p}-card</code>, and <code>${p}-alert</code>.</p>
|
|
775
|
+
</div>
|
|
776
|
+
|
|
777
|
+
<div class="demo-showcase-grid">
|
|
778
|
+
<article class="${p}-card demo-control-card" data-testid="component-controls">
|
|
779
|
+
<p class="${p}-kicker">Controls</p>
|
|
780
|
+
<h3 class="${p}-heading">Buttons, progress, loading, and tooltips</h3>
|
|
781
|
+
<div class="demo-control-showcase">
|
|
782
|
+
<section class="demo-control-panel" data-testid="component-buttons">
|
|
783
|
+
<h4>Button variants</h4>
|
|
784
|
+
<div class="demo-button-row">
|
|
785
|
+
<button class="${p}-button ${p}-button-primary">Primary</button>
|
|
786
|
+
<button class="${p}-button ${p}-button-secondary">Secondary</button>
|
|
787
|
+
<button class="${p}-button">Neutral</button>
|
|
788
|
+
<button class="${p}-button ${p}-button-danger">Danger</button>
|
|
789
|
+
<button class="${p}-button ${p}-button-ghost">Ghost</button>
|
|
790
|
+
<button class="${p}-icon-button" aria-label="Icon action">?</button>
|
|
791
|
+
</div>
|
|
792
|
+
</section>
|
|
793
|
+
|
|
794
|
+
<section class="demo-control-panel" data-testid="component-progress">
|
|
795
|
+
<h4>Progress</h4>
|
|
796
|
+
<div class="demo-progress-stack">
|
|
797
|
+
<div class="${p}-progress" aria-label="Component progress"><div class="${p}-progress-bar" style="--${p}-progress-value: 68%"></div></div>
|
|
798
|
+
<div class="${p}-progress" aria-label="Secondary progress"><div class="${p}-progress-bar" style="--${p}-progress-value: 34%"></div></div>
|
|
799
|
+
</div>
|
|
800
|
+
</section>
|
|
801
|
+
|
|
802
|
+
<section class="demo-control-panel" data-testid="component-spinner">
|
|
803
|
+
<h4>Loading</h4>
|
|
804
|
+
<div class="demo-button-row">
|
|
805
|
+
<span class="${p}-spinner ${p}-spinner-sm" aria-label="Small loading spinner"></span>
|
|
806
|
+
<span class="${p}-spinner" aria-label="Loading spinner"></span>
|
|
807
|
+
<span class="${p}-spinner ${p}-spinner-lg" aria-label="Large loading spinner"></span>
|
|
808
|
+
<span class="ui-spinner" data-loading-spinner aria-label="Native loading spinner"></span>
|
|
809
|
+
</div>
|
|
810
|
+
</section>
|
|
811
|
+
|
|
812
|
+
<section class="demo-control-panel" data-testid="component-tooltips">
|
|
813
|
+
<h4>Visible tooltips</h4>
|
|
814
|
+
<div class="demo-tooltip-row">
|
|
815
|
+
<span class="${p}-tooltip ${p}-tooltip-top" role="tooltip" data-testid="tooltip-primary">Primary tip<span class="${p}-tooltip-arrow" aria-hidden="true"></span></span>
|
|
816
|
+
<span class="${p}-tooltip ${p}-tooltip-right" role="tooltip" data-testid="tooltip-secondary">Context cue<span class="${p}-tooltip-arrow" aria-hidden="true"></span></span>
|
|
817
|
+
<span class="${p}-tooltip ${p}-tooltip-bottom" role="tooltip" data-testid="tooltip-accent">Action hint<span class="${p}-tooltip-arrow" aria-hidden="true"></span></span>
|
|
818
|
+
</div>
|
|
819
|
+
</section>
|
|
820
|
+
</div>
|
|
821
|
+
</article>
|
|
822
|
+
|
|
823
|
+
<article class="${p}-card" data-testid="component-buttons-states">
|
|
824
|
+
<p class="${p}-kicker">States</p>
|
|
825
|
+
<h3 class="${p}-heading">Interactive states</h3>
|
|
826
|
+
<div class="demo-state-grid">
|
|
827
|
+
<button class="${p}-button" data-testid="component-button-hover">Hover target</button>
|
|
828
|
+
<button class="${p}-button" data-testid="component-button-focus">Focus target</button>
|
|
829
|
+
<button class="${p}-button is-active" data-testid="component-button-active" aria-pressed="true">Active pressed</button>
|
|
830
|
+
<button class="${p}-button" data-testid="component-button-disabled" disabled>Disabled</button>
|
|
831
|
+
<button class="${p}-button ${p}-button-primary" data-testid="component-button-busy" aria-busy="true">Busy</button>
|
|
832
|
+
</div>
|
|
833
|
+
</article>
|
|
834
|
+
|
|
835
|
+
<article class="${p}-card" data-testid="component-fields">
|
|
836
|
+
<p class="${p}-kicker">Fields</p>
|
|
837
|
+
<h3 class="${p}-heading">Inputs and choices</h3>
|
|
838
|
+
<div class="demo-form-grid">
|
|
839
|
+
<label class="${p}-field"><span class="${p}-label">Text input</span><input class="${p}-input" value="Styled input"><span class="${p}-help-text">Help text</span></label>
|
|
840
|
+
<label class="${p}-field"><span class="${p}-label">Select</span><select class="${p}-select"><option>Default</option><option>Alternate</option></select></label>
|
|
841
|
+
<label class="${p}-field"><span class="${p}-label">Textarea</span><textarea class="${p}-textarea">Styled textarea content.</textarea></label>
|
|
842
|
+
</div>
|
|
843
|
+
${renderChoiceControls(ui, p)}
|
|
844
|
+
</article>
|
|
845
|
+
|
|
846
|
+
<article class="${p}-card" data-testid="component-badges">
|
|
847
|
+
<p class="${p}-kicker">Badges</p>
|
|
848
|
+
<h3 class="${p}-heading">Status badges</h3>
|
|
849
|
+
<div class="demo-badge-showcase">
|
|
850
|
+
<div class="demo-badge-group">
|
|
851
|
+
<p class="demo-badge-label">Color roles</p>
|
|
852
|
+
<div class="demo-badge-row">
|
|
853
|
+
<span class="${p}-badge">Neutral</span>
|
|
854
|
+
<span class="${p}-badge ${p}-badge-primary">Primary</span>
|
|
855
|
+
<span class="${p}-badge ${p}-badge-secondary">Secondary</span>
|
|
856
|
+
<span class="${p}-badge ${p}-badge-success">Success</span>
|
|
857
|
+
<span class="${p}-badge ${p}-badge-warning">Warning</span>
|
|
858
|
+
<span class="${p}-badge ${p}-badge-danger">Danger</span>
|
|
859
|
+
</div>
|
|
860
|
+
</div>
|
|
861
|
+
<div class="demo-badge-group">
|
|
862
|
+
<p class="demo-badge-label">Workflow</p>
|
|
863
|
+
<div class="demo-badge-row">
|
|
864
|
+
<span class="${p}-badge ${p}-badge-primary">Draft</span>
|
|
865
|
+
<span class="${p}-badge ${p}-badge-secondary">Review</span>
|
|
866
|
+
<span class="${p}-badge ${p}-badge-success">Ready</span>
|
|
867
|
+
<span class="${p}-badge ${p}-badge-warning">Blocked</span>
|
|
868
|
+
</div>
|
|
869
|
+
</div>
|
|
870
|
+
<div class="demo-badge-group">
|
|
871
|
+
<p class="demo-badge-label">Counts</p>
|
|
872
|
+
<div class="demo-badge-row">
|
|
873
|
+
<span class="${p}-badge">12 open</span>
|
|
874
|
+
<span class="${p}-badge ${p}-badge-primary">4 new</span>
|
|
875
|
+
<span class="${p}-badge ${p}-badge-danger">2 failed</span>
|
|
876
|
+
</div>
|
|
877
|
+
</div>
|
|
878
|
+
</div>
|
|
879
|
+
</article>
|
|
880
|
+
|
|
881
|
+
<article class="${p}-card" data-testid="component-alerts">
|
|
882
|
+
<p class="${p}-kicker">Alerts</p>
|
|
883
|
+
<h3 class="${p}-heading">Messages</h3>
|
|
884
|
+
<div class="${p}-alert ${p}-alert-success"><p class="${p}-alert-title">Success</p><p class="${p}-alert-body">The stylesheet is active.</p></div>
|
|
885
|
+
<div class="${p}-alert ${p}-alert-warning"><p class="${p}-alert-title">Warning</p><p class="${p}-alert-body">Check contrast mode before release.</p></div>
|
|
886
|
+
<div class="${p}-alert ${p}-alert-danger"><p class="${p}-alert-title">Danger</p><p class="${p}-alert-body">Invalid state styling is visible.</p></div>
|
|
887
|
+
</article>
|
|
888
|
+
|
|
889
|
+
<article class="${p}-table-wrap demo-table-card" data-testid="component-table">
|
|
890
|
+
<table class="${p}-table">
|
|
891
|
+
<caption>Classed table component</caption>
|
|
892
|
+
<thead><tr><th>Element</th><th>State</th><th>Coverage</th></tr></thead>
|
|
893
|
+
<tbody>
|
|
894
|
+
<tr><td>Button</td><td>hover / active / disabled / busy</td><td>Classed</td></tr>
|
|
895
|
+
<tr><td>Input</td><td>hover / focus / invalid / disabled</td><td>Classed</td></tr>
|
|
896
|
+
<tr><td>Table</td><td>header / caption / row hover</td><td>Classed</td></tr>
|
|
897
|
+
</tbody>
|
|
898
|
+
</table>
|
|
899
|
+
</article>
|
|
900
|
+
</div>
|
|
86
901
|
</section>
|
|
87
902
|
|
|
88
|
-
<section
|
|
89
|
-
<
|
|
90
|
-
<
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
903
|
+
<section class="${p}-card" data-testid="utility-classes">
|
|
904
|
+
<p class="${p}-kicker">Utilities</p>
|
|
905
|
+
<h2 class="${p}-heading">Text, surfaces, layout, and style-specific utilities</h2>
|
|
906
|
+
<div class="demo-token-grid">
|
|
907
|
+
<div class="demo-token-sample" data-testid="utility-color-grid">
|
|
908
|
+
<p class="demo-utility-label">Color utilities</p>
|
|
909
|
+
<div class="demo-color-chip-grid">
|
|
910
|
+
<div class="demo-color-chip" data-testid="utility-color-chip" style="--demo-token-color: var(--${p}-primary)"><span class="demo-color-swatch"></span><span><strong class="${p}-text-primary">Primary</strong><small>Action emphasis</small></span></div>
|
|
911
|
+
<div class="demo-color-chip" data-testid="utility-color-chip" style="--demo-token-color: var(--${p}-secondary)"><span class="demo-color-swatch"></span><span><strong class="${p}-text-secondary">Secondary</strong><small>Supporting action</small></span></div>
|
|
912
|
+
<div class="demo-color-chip" data-testid="utility-color-chip" style="--demo-token-color: var(--${p}-accent)"><span class="demo-color-swatch"></span><span><strong class="${p}-text-accent">Accent</strong><small>Highlight note</small></span></div>
|
|
913
|
+
<div class="demo-color-chip" data-testid="utility-color-chip" style="--demo-token-color: var(--${p}-success)"><span class="demo-color-swatch"></span><span><strong class="${p}-text-success">Success</strong><small>Positive state</small></span></div>
|
|
914
|
+
<div class="demo-color-chip" data-testid="utility-color-chip" style="--demo-token-color: var(--${p}-warning)"><span class="demo-color-swatch"></span><span><strong class="${p}-text-warning">Warning</strong><small>Needs review</small></span></div>
|
|
915
|
+
<div class="demo-color-chip" data-testid="utility-color-chip" style="--demo-token-color: var(--${p}-danger)"><span class="demo-color-swatch"></span><span><strong class="${p}-text-danger">Danger</strong><small>Blocking state</small></span></div>
|
|
916
|
+
</div>
|
|
917
|
+
</div>
|
|
918
|
+
<div class="demo-token-sample" data-testid="utility-surface-grid">
|
|
919
|
+
<p class="demo-utility-label">Surface utilities</p>
|
|
920
|
+
<div class="demo-utility-surface-grid">
|
|
921
|
+
<div class="${p}-well demo-utility-surface"><strong>Inset content</strong><span class="${p}-text-muted">Well utility</span></div>
|
|
922
|
+
<div class="${p}-well ${p}-surface-sm demo-utility-surface"><strong>Compact inset</strong><span class="${p}-text-muted">Small surface</span></div>
|
|
923
|
+
<div class="${p}-bg-primary ${p}-rounded-lg demo-utility-surface"><strong>Primary fill</strong><span>Background utility</span></div>
|
|
924
|
+
</div>
|
|
925
|
+
</div>
|
|
926
|
+
<div class="demo-token-sample" data-testid="utility-layout-sample">
|
|
927
|
+
<p class="demo-utility-label">Shape and layout utilities</p>
|
|
928
|
+
<div class="demo-utility-layout-sample">
|
|
929
|
+
<span class="${p}-badge ${p}-pill">Pill shape</span>
|
|
930
|
+
<span class="${p}-badge ${p}-rounded">Rounded</span>
|
|
931
|
+
<span class="${p}-badge ${p}-border">Border utility</span>
|
|
932
|
+
<span class="${p}-text-muted">Muted annotation</span>
|
|
933
|
+
</div>
|
|
934
|
+
<hr class="${p}-divider">
|
|
935
|
+
${renderStyleSpecificSurface(ui, p)}
|
|
936
|
+
</div>
|
|
937
|
+
</div>
|
|
99
938
|
</section>
|
|
100
939
|
|
|
101
|
-
<section id="
|
|
102
|
-
<
|
|
103
|
-
<
|
|
104
|
-
<
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
940
|
+
<section id="native" class="${p}-stack">
|
|
941
|
+
<div class="demo-section-lede">
|
|
942
|
+
<p class="${p}-kicker">Native HTML</p>
|
|
943
|
+
<h2 class="${p}-heading">Unclassed elements styled by <code>data-ui</code></h2>
|
|
944
|
+
<p class="${p}-copy">These samples use semantic HTML without UI Style Kit component classes, so the native fallback selectors are visible.</p>
|
|
945
|
+
</div>
|
|
946
|
+
|
|
947
|
+
<div class="demo-native-grid">
|
|
948
|
+
<section class="${p}-panel demo-native-sample" data-testid="native-text">
|
|
949
|
+
<h1>Native heading h1</h1>
|
|
950
|
+
<h2>Native heading h2</h2>
|
|
951
|
+
<h3>Native heading h3</h3>
|
|
952
|
+
<p>Paragraph text with a <a href="#native">link</a>, <mark>mark</mark>, <code>code</code>, <kbd>Ctrl</kbd>, <samp>sample</samp>, <abbr title="Accessible Rich Internet Applications">ARIA</abbr>, <small>small text</small>, <strong>strong</strong>, <em>emphasis</em>, <q>quote</q>, <ins>inserted</ins>, <del>deleted</del>, H<sub>2</sub>O, x<sup>2</sup>, <time datetime="2026-06-22">June 22, 2026</time>, <data value="20">20 tokens</data>, and <dfn>definition</dfn>.</p>
|
|
953
|
+
<p><ruby>UI<rt>style</rt></ruby> <output>Output value</output></p>
|
|
954
|
+
<blockquote>Native blockquote styling is part of the fallback surface.</blockquote>
|
|
955
|
+
<pre><code>button:not([class]) {
|
|
956
|
+
color: var(--${p}-on-primary);
|
|
957
|
+
}</code></pre>
|
|
958
|
+
<hr>
|
|
959
|
+
</section>
|
|
960
|
+
|
|
961
|
+
<section class="${p}-panel demo-native-sample" data-testid="native-lists">
|
|
962
|
+
<h3>Lists and descriptions</h3>
|
|
963
|
+
<ul><li>Unordered item</li><li>Second unordered item</li></ul>
|
|
964
|
+
<ol><li>Ordered item</li><li>Second ordered item</li></ol>
|
|
965
|
+
<menu><li>Menu item</li><li>Second menu item</li></menu>
|
|
966
|
+
<dl><dt>Definition term</dt><dd>Definition description</dd><dt>Token</dt><dd>Shared color variable</dd></dl>
|
|
967
|
+
</section>
|
|
968
|
+
|
|
969
|
+
<section class="${p}-panel demo-native-sample" data-testid="native-media">
|
|
970
|
+
<h3>Media elements</h3>
|
|
971
|
+
<figure>
|
|
972
|
+
<picture>
|
|
973
|
+
<img alt="Abstract style swatch" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 160'%3E%3Crect width='320' height='160' fill='%236f8cff'/%3E%3Ccircle cx='235' cy='78' r='46' fill='%23ffcc66'/%3E%3Cpath d='M38 116 L126 32 L188 116 Z' fill='%23ffffff' fill-opacity='.72'/%3E%3C/svg%3E">
|
|
974
|
+
</picture>
|
|
975
|
+
<figcaption>Figure, picture, image, and figcaption.</figcaption>
|
|
976
|
+
</figure>
|
|
977
|
+
<canvas class="demo-media-box demo-canvas" width="320" height="140" data-demo-canvas>Canvas preview</canvas>
|
|
978
|
+
<svg class="demo-media-box" role="img" aria-label="Inline SVG sample" viewBox="0 0 320 140"><rect width="320" height="140" fill="currentColor" opacity=".12"></rect><circle cx="90" cy="70" r="42" fill="currentColor" opacity=".45"></circle><rect x="150" y="45" width="110" height="50" fill="currentColor" opacity=".28"></rect></svg>
|
|
979
|
+
<video class="demo-media-box" controls></video>
|
|
980
|
+
<audio controls></audio>
|
|
981
|
+
<iframe class="demo-iframe" title="Inline iframe sample" srcdoc="<p>iframe preview</p>"></iframe>
|
|
982
|
+
<object class="demo-object" aria-label="Object sample">Object sample</object>
|
|
983
|
+
<embed class="demo-embed" title="Embed sample">
|
|
984
|
+
<math><mi>x</mi><mo>=</mo><mn>2</mn></math>
|
|
985
|
+
</section>
|
|
986
|
+
|
|
987
|
+
<section class="${p}-panel demo-native-sample" data-testid="native-forms">
|
|
988
|
+
<h3>Forms</h3>
|
|
989
|
+
<fieldset>
|
|
990
|
+
<legend>Native fieldset</legend>
|
|
991
|
+
<div class="demo-form-grid">
|
|
992
|
+
<label>Text <input type="text" value="Text value"></label>
|
|
993
|
+
<label>Email <input type="email" value="name@example.com"></label>
|
|
994
|
+
<label>Search <search><input type="search" value="Query"></search></label>
|
|
995
|
+
<label>Textarea <textarea>Native textarea</textarea></label>
|
|
996
|
+
<label>Select <select><optgroup label="Group"><option>Option A</option><option>Option B</option></optgroup></select></label>
|
|
997
|
+
<label>Invalid <input required aria-invalid="true" placeholder="Required"></label>
|
|
998
|
+
<label>Disabled <input disabled value="Disabled"></label>
|
|
999
|
+
<label>Color <input type="color" value="#6f8cff"></label>
|
|
1000
|
+
<label>File <input type="file"></label>
|
|
1001
|
+
</div>
|
|
1002
|
+
<div class="demo-inline-row">
|
|
1003
|
+
<label><input type="checkbox" checked> Checked</label>
|
|
1004
|
+
<label><input type="checkbox"> Unchecked</label>
|
|
1005
|
+
<label><input type="radio" name="native-radio-${ui}" checked> Radio A</label>
|
|
1006
|
+
<label><input type="radio" name="native-radio-${ui}"> Radio B</label>
|
|
1007
|
+
</div>
|
|
1008
|
+
<label>Range <input type="range" value="62"></label>
|
|
1009
|
+
</fieldset>
|
|
1010
|
+
</section>
|
|
1011
|
+
|
|
1012
|
+
<section class="${p}-panel demo-native-sample" data-testid="native-buttons">
|
|
1013
|
+
<h3>Native buttons</h3>
|
|
1014
|
+
<div class="demo-button-row">
|
|
1015
|
+
<button>Native button</button>
|
|
1016
|
+
<button type="button">Hover target</button>
|
|
1017
|
+
<button type="button" aria-busy="true">Busy native</button>
|
|
1018
|
+
<button type="button" disabled>Disabled native</button>
|
|
1019
|
+
<input type="button" value="Input button">
|
|
1020
|
+
<input type="submit" value="Submit input">
|
|
1021
|
+
<input type="reset" value="Reset input">
|
|
1022
|
+
</div>
|
|
1023
|
+
</section>
|
|
1024
|
+
|
|
1025
|
+
<section class="${p}-panel demo-native-sample" data-testid="native-table">
|
|
1026
|
+
<h3>Native table</h3>
|
|
1027
|
+
<div class="demo-native-table-scroll">
|
|
1028
|
+
<table>
|
|
1029
|
+
<caption>Native table caption</caption>
|
|
1030
|
+
<thead><tr><th>Element</th><th>Selector</th></tr></thead>
|
|
1031
|
+
<tbody><tr><td>Table cell</td><td>td</td></tr><tr><td>Header cell</td><td>th</td></tr></tbody>
|
|
1032
|
+
</table>
|
|
1033
|
+
</div>
|
|
1034
|
+
</section>
|
|
1035
|
+
|
|
1036
|
+
<section class="${p}-panel demo-native-sample" data-testid="native-disclosure-dialog">
|
|
1037
|
+
<h3>Disclosure and dialog</h3>
|
|
1038
|
+
<details open><summary>Open details summary</summary><p>Details content is styled as a native disclosure.</p></details>
|
|
1039
|
+
<dialog class="demo-inline-dialog" open>
|
|
1040
|
+
<form method="dialog">
|
|
1041
|
+
<h3>Inline dialog</h3>
|
|
1042
|
+
<p>This open dialog shows the native dialog surface without a modal backdrop.</p>
|
|
1043
|
+
<button>Close sample</button>
|
|
1044
|
+
</form>
|
|
1045
|
+
</dialog>
|
|
1046
|
+
</section>
|
|
1047
|
+
|
|
1048
|
+
<section class="${p}-panel demo-native-sample" data-testid="native-meter-progress">
|
|
1049
|
+
<h3>Meter and progress</h3>
|
|
1050
|
+
<label>Progress <progress value="72" max="100">72%</progress></label>
|
|
1051
|
+
<label>Meter <meter value=".68">68%</meter></label>
|
|
1052
|
+
</section>
|
|
1053
|
+
|
|
1054
|
+
<section class="${p}-panel demo-native-sample" data-testid="native-semantics">
|
|
1055
|
+
<header><h3>Semantic regions</h3></header>
|
|
1056
|
+
<nav aria-label="Native region navigation"><a href="#overview" aria-current="page">Current link</a> <a href="#usage">Usage link</a></nav>
|
|
1057
|
+
<article><p>Native article surface</p></article>
|
|
1058
|
+
<aside><p>Native aside surface</p></aside>
|
|
1059
|
+
<address>Address block, 100 Demo Avenue</address>
|
|
1060
|
+
<footer><small>Footer and small text</small></footer>
|
|
1061
|
+
<p hidden>Hidden content remains hidden.</p>
|
|
1062
|
+
</section>
|
|
1063
|
+
</div>
|
|
1064
|
+
</section>
|
|
1065
|
+
|
|
1066
|
+
<section id="bridge" class="${p}-card demo-bridge-preview" data-testid="bridge-preview">
|
|
1067
|
+
<p class="${p}-kicker">Interactive Surface Bridge</p>
|
|
1068
|
+
<h2 class="${p}-heading">Detached by default, attached on demand</h2>
|
|
1069
|
+
<p class="${p}-copy">The bridge swaps the demo stylesheet between <code>${defaultBundle}</code> and <code>${bridgeAwareBundle}</code>. When attached, interactable elements receive <code>.interactive-surface</code>, <code>data-surface-variant</code>, and <code>data-surface-level</code> hooks.</p>
|
|
1070
|
+
<label class="demo-switch-control" data-testid="bridge-switch">
|
|
1071
|
+
<input id="bridgeToggle" type="checkbox" role="switch" />
|
|
1072
|
+
<span class="demo-switch-track" data-testid="bridge-switch-track" aria-hidden="true">
|
|
1073
|
+
<span class="demo-switch-thumb" data-testid="bridge-switch-thumb"></span>
|
|
1074
|
+
</span>
|
|
1075
|
+
<span class="demo-switch-copy">
|
|
1076
|
+
<strong>Attach interactive surface bridge</strong>
|
|
1077
|
+
<span data-testid="bridge-status">Detached - default bundle</span>
|
|
1078
|
+
</span>
|
|
1079
|
+
</label>
|
|
1080
|
+
<div class="demo-bridge-grid">
|
|
1081
|
+
<div class="interactive-surface" data-surface-variant="subtle" data-surface-level="1" data-testid="bridge-level-1"><strong>Level 1 surface</strong><small>Subtle rest layer for quiet inline interactions.</small></div>
|
|
1082
|
+
<div class="interactive-surface" data-surface-variant="secondary" data-surface-level="2" data-testid="bridge-level-2"><strong>Level 2 surface</strong><small>Raised state for controls, selects, and grouped actions.</small></div>
|
|
1083
|
+
<div class="interactive-surface" data-surface-variant="primary" data-surface-level="3" data-testid="bridge-level-3"><strong>Level 3 surface</strong><small>Prominent active state with the strongest state layer.</small></div>
|
|
1084
|
+
</div>
|
|
1085
|
+
</section>
|
|
1086
|
+
|
|
1087
|
+
<section id="usage" class="${p}-card" data-testid="usage-imports">
|
|
1088
|
+
<p class="${p}-kicker">Usage</p>
|
|
1089
|
+
<h2 class="${p}-heading">Import paths and data attributes</h2>
|
|
1090
|
+
<div class="demo-showcase-grid">
|
|
1091
|
+
<pre class="demo-code"><code>import "ui-style-kit-css";
|
|
1092
|
+
|
|
1093
|
+
document.body.dataset.ui = "${ui}";
|
|
1094
|
+
document.body.dataset.theme = "${themeSelect.value}";
|
|
1095
|
+
document.body.dataset.mode = "${modeSelect.value}";</code></pre>
|
|
1096
|
+
<pre class="demo-code"><code>import "ui-style-kit-css/theme-colors.css";
|
|
1097
|
+
import "ui-style-kit-css/native-elements.css";
|
|
1098
|
+
import "ui-style-kit-css/${ui}.css";</code></pre>
|
|
1099
|
+
<pre class="demo-code"><code>import "ui-style-kit-css/with-bridge.css";
|
|
1100
|
+
import "ui-style-kit-css/interactive-surface-bridge.css";</code></pre>
|
|
1101
|
+
</div>
|
|
111
1102
|
</section>
|
|
112
1103
|
</div>
|
|
113
1104
|
</section>`;
|
|
1105
|
+
|
|
1106
|
+
const bridgeToggle = document.getElementById("bridgeToggle");
|
|
1107
|
+
bindPrimaryNav();
|
|
1108
|
+
syncPrimaryNavCurrent(window.location.hash.slice(1) || "overview");
|
|
1109
|
+
if (bridgeToggle) {
|
|
1110
|
+
bridgeToggle.checked = bridgeAttached;
|
|
1111
|
+
bridgeToggle.addEventListener("change", updateBridge);
|
|
1112
|
+
}
|
|
1113
|
+
drawDemoCanvas();
|
|
1114
|
+
updateBridge();
|
|
114
1115
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
1116
|
+
|
|
1117
|
+
uiSelect.addEventListener("change", render);
|
|
1118
|
+
themeSelect.addEventListener("change", render);
|
|
1119
|
+
modeSelect.addEventListener("change", render);
|
|
1120
|
+
window.addEventListener("hashchange", () => syncPrimaryNavCurrent(window.location.hash.slice(1) || "overview"));
|
|
118
1121
|
render();
|
|
119
1122
|
</script>
|
|
120
1123
|
</body>
|