@keenmate/web-components-devkit 1.0.0-rc01 → 1.0.0-rc03

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/README.md +70 -12
  3. package/components.json +206 -189
  4. package/package.json +4 -1
  5. package/src/cli/commands/doctor.js +1 -0
  6. package/src/cli/commands/new.js +29 -8
  7. package/src/cli/kmwc.js +1 -0
  8. package/src/config.d.ts +5 -0
  9. package/src/config.js +26 -3
  10. package/src/examples/chapter-links.js +35 -0
  11. package/src/examples/chapter-search.js +84 -0
  12. package/src/examples/constants.js +51 -0
  13. package/src/examples/css/content.css +4 -34
  14. package/src/examples/css/controls.css +30 -25
  15. package/src/examples/css/copy-link.css +1 -0
  16. package/src/examples/css/demo.css +2 -0
  17. package/src/examples/css/form-controls.css +285 -0
  18. package/src/examples/css/index-page.css +1 -1
  19. package/src/examples/css/spotlight.css +417 -0
  20. package/src/examples/css/style.css +3 -0
  21. package/src/examples/css/tables.css +141 -0
  22. package/src/examples/css/tokens.css +69 -27
  23. package/src/examples/index.d.ts +38 -0
  24. package/src/examples/index.js +6 -3
  25. package/src/examples/kit.js +11 -4
  26. package/src/examples/page-config.js +1 -0
  27. package/src/examples/sections.js +38 -1
  28. package/src/examples/spotlight.js +473 -0
  29. package/src/vite/chapter-index.js +107 -0
  30. package/src/vite/index.js +19 -1
  31. package/src/vite/page-composer.js +17 -10
  32. package/templates/claude-block.md +9 -2
  33. package/templates/new/component-variables.manifest.json +3 -3
  34. package/templates/new/docs/examples.md +1 -1
  35. package/templates/new/docs/theming.md +1 -1
  36. package/templates/new/e2e/dark-mode.spec.ts +3 -3
  37. package/templates/new/examples-theming.html +3 -3
  38. package/templates/new/src/css/base.css +5 -3
  39. package/templates/new/src/css/variables.css +10 -8
  40. package/templates/new-minimal/src/css/base.css +5 -3
  41. package/templates/new-minimal/src/css/variables.css +7 -5
@@ -0,0 +1,417 @@
1
+ /* ==============================================================================
2
+ EXAMPLES KIT — SPOTLIGHT
3
+ ==============================================================================
4
+ Ctrl/⌘+K chapter search (spotlight.js). MIRRORS web-commandpalette's CSS
5
+ (src/css/dialog.css, search.css, results.css, footer.css, animations.css):
6
+ same elements under the kit prefix, same layout, the same --base-* hooks
7
+ for backdrop, focused row and highlight — so both look alike under a theme.
8
+ A rule marked `mirrors …` keeps the wcp rule; keep them in step
9
+ (scripts/spotlight-mirror.json, `npm run check:spotlight-mirror`).
10
+ Spotlight-only: the header trigger button and the section-code chip. */
11
+ @layer kmwc {
12
+ /* ==========================================================================
13
+ TRIGGER (spotlight only) — left of the theme switch
14
+ ========================================================================== */
15
+ .kmwc-spotlight__trigger {
16
+ position: fixed;
17
+ top: 0.75rem;
18
+ right: calc(0.75rem + 36px + 0.5rem);
19
+ z-index: 9000;
20
+ display: inline-flex;
21
+ align-items: center;
22
+ gap: 0.4rem;
23
+ height: 36px;
24
+ padding: 0 0.6rem 0 0.7rem;
25
+ border-radius: 18px;
26
+ border: 1px solid var(--kmwc-border-color);
27
+ background: var(--kmwc-main-bg);
28
+ color: var(--kmwc-text-color-2);
29
+ box-shadow: 0 2px 6px var(--kmwc-shadow-color);
30
+ font: inherit;
31
+ cursor: pointer;
32
+ }
33
+
34
+ .kmwc-spotlight__trigger:hover {
35
+ background: var(--kmwc-hover-bg);
36
+ color: var(--kmwc-text-color-1);
37
+ }
38
+
39
+ .kmwc-spotlight__trigger:focus-visible {
40
+ outline: 2px solid var(--kmwc-accent-color);
41
+ outline-offset: 2px;
42
+ }
43
+
44
+ .kmwc-spotlight__trigger svg,
45
+ .kmwc-spotlight__close svg {
46
+ width: 18px;
47
+ height: 18px;
48
+ flex: none;
49
+ fill: none;
50
+ stroke: currentColor;
51
+ stroke-width: 2;
52
+ stroke-linecap: round;
53
+ }
54
+
55
+ /* ==========================================================================
56
+ DIALOG — mirrors wcp dialog.css
57
+ ========================================================================== */
58
+ .kmwc-spotlight {
59
+ position: fixed;
60
+ inset: 0;
61
+ z-index: 9100; /* above the kit chrome (9000); wcp: --base-z-popover + 1 */
62
+ display: none;
63
+ align-items: flex-start;
64
+ justify-content: center;
65
+ padding-top: 128px;
66
+ font-family: var(--kmwc-font-family);
67
+ }
68
+
69
+ .kmwc-spotlight--active {
70
+ display: flex;
71
+ }
72
+
73
+ .kmwc-spotlight__backdrop {
74
+ position: absolute;
75
+ inset: 0;
76
+ background-color: var(--kmwc-overlay-bg);
77
+ backdrop-filter: blur(4px);
78
+ animation: kmwc-spotlight-fade-in 0.2s ease;
79
+ }
80
+
81
+ .kmwc-spotlight__container {
82
+ position: relative;
83
+ width: 100%;
84
+ max-width: 608px;
85
+ background-color: var(--kmwc-main-bg);
86
+ color: var(--kmwc-text-color-1);
87
+ border-radius: var(--kmwc-radius-md);
88
+ box-shadow: 0 16px 48px var(--kmwc-shadow-color);
89
+ animation: kmwc-spotlight-slide-down 0.2s ease;
90
+ overflow: hidden;
91
+ }
92
+
93
+ @media (max-width: 768px) {
94
+ .kmwc-spotlight {
95
+ padding-top: 1rem;
96
+ }
97
+
98
+ .kmwc-spotlight__container {
99
+ max-width: calc(100% - 2rem);
100
+ }
101
+ }
102
+
103
+ /* Phone fullscreen sheet — mirrors wcp dialog.css `--fullscreen` */
104
+ .kmwc-spotlight__fullscreen-bar {
105
+ display: none;
106
+ flex: 0 0 auto;
107
+ align-items: center;
108
+ justify-content: space-between;
109
+ gap: 0.5rem;
110
+ padding: calc(0.5rem + env(safe-area-inset-top)) 0.5rem 0.5rem;
111
+ border-bottom: 1px solid var(--kmwc-border-color);
112
+ }
113
+
114
+ .kmwc-spotlight__fullscreen-title {
115
+ font-size: 1.5rem;
116
+ font-weight: 600;
117
+ color: var(--kmwc-text-color-1);
118
+ }
119
+
120
+ .kmwc-spotlight__close {
121
+ display: inline-flex;
122
+ align-items: center;
123
+ justify-content: center;
124
+ width: 38px;
125
+ height: 38px;
126
+ padding: 0;
127
+ border: var(--kmwc-input-border);
128
+ border-radius: var(--kmwc-radius-md);
129
+ background-color: var(--kmwc-input-bg);
130
+ color: var(--kmwc-text-color-1);
131
+ cursor: pointer;
132
+ }
133
+
134
+ .kmwc-spotlight--fullscreen {
135
+ padding: 0;
136
+ align-items: stretch;
137
+ justify-content: stretch;
138
+ }
139
+
140
+ .kmwc-spotlight--fullscreen .kmwc-spotlight__backdrop {
141
+ display: none;
142
+ }
143
+
144
+ .kmwc-spotlight--fullscreen .kmwc-spotlight__container {
145
+ position: fixed;
146
+ top: 0;
147
+ inset-inline-start: 0;
148
+ width: 100vw;
149
+ max-width: 100vw;
150
+ height: 100dvh;
151
+ max-height: 100dvh;
152
+ border-radius: 0;
153
+ box-shadow: none;
154
+ animation: none;
155
+ display: flex;
156
+ flex-direction: column;
157
+ }
158
+
159
+ .kmwc-spotlight--fullscreen .kmwc-spotlight__fullscreen-bar {
160
+ display: flex;
161
+ }
162
+
163
+ .kmwc-spotlight--fullscreen .kmwc-spotlight__search {
164
+ flex: 0 0 auto;
165
+ }
166
+
167
+ .kmwc-spotlight--fullscreen .kmwc-spotlight__results {
168
+ flex: 1 1 0;
169
+ min-height: 0;
170
+ max-height: none;
171
+ }
172
+
173
+ .kmwc-spotlight--fullscreen .kmwc-spotlight__footer {
174
+ flex: 0 0 auto;
175
+ padding-bottom: calc(0.5rem + env(safe-area-inset-bottom));
176
+ }
177
+
178
+ /* ==========================================================================
179
+ SEARCH — mirrors wcp search.css
180
+ ========================================================================== */
181
+ .kmwc-spotlight__search {
182
+ position: relative;
183
+ border-bottom: 1px solid var(--kmwc-border-color);
184
+ padding: 0.5rem;
185
+ }
186
+
187
+ .kmwc-spotlight__input-wrapper {
188
+ position: relative;
189
+ }
190
+
191
+ .kmwc-spotlight__input {
192
+ box-sizing: border-box; /* wcp gets it from its shadow-root reset */
193
+ width: 100%;
194
+ height: 38px;
195
+ padding: 0 0.5rem;
196
+ font: inherit;
197
+ font-size: 1rem;
198
+ border: var(--kmwc-input-border);
199
+ border-radius: var(--kmwc-radius-md);
200
+ background-color: var(--kmwc-input-bg);
201
+ color: var(--kmwc-input-color);
202
+ outline: none;
203
+ transition: border-color 0.15s ease-out, box-shadow 0.15s ease-out;
204
+ }
205
+
206
+ .kmwc-spotlight__input:focus {
207
+ border-color: var(--kmwc-accent-color);
208
+ box-shadow: 0 0 0 3px var(--kmwc-accent-light-bg);
209
+ }
210
+
211
+ .kmwc-spotlight__input::placeholder {
212
+ color: var(--kmwc-text-color-3);
213
+ opacity: 1;
214
+ }
215
+
216
+ /* ==========================================================================
217
+ RESULTS — mirrors wcp results.css
218
+ ========================================================================== */
219
+ .kmwc-spotlight__results {
220
+ max-height: min(384px, max(160px, 100dvh - 128px - 120px));
221
+ overflow-y: auto;
222
+ overscroll-behavior: contain;
223
+ padding: 0.5rem 0;
224
+ position: relative;
225
+ scrollbar-width: thin;
226
+ }
227
+
228
+ @media (max-width: 768px) {
229
+ .kmwc-spotlight__results {
230
+ max-height: 60vh;
231
+ }
232
+ }
233
+
234
+ .kmwc-spotlight__home-section:not(:first-child) {
235
+ border-top: 1px solid var(--kmwc-border-color);
236
+ margin-top: 0.25rem;
237
+ padding-top: 0.25rem;
238
+ }
239
+
240
+ .kmwc-spotlight__home-heading {
241
+ padding: 0.25rem 0.5rem;
242
+ font-size: 0.7rem;
243
+ font-weight: 600;
244
+ color: var(--kmwc-text-color-2);
245
+ text-transform: uppercase;
246
+ letter-spacing: 0.05em;
247
+ }
248
+
249
+ .kmwc-spotlight__empty {
250
+ padding: 2rem 0.5rem;
251
+ text-align: center;
252
+ color: var(--kmwc-text-color-2);
253
+ font-size: 0.875rem;
254
+ }
255
+
256
+ .kmwc-spotlight__item {
257
+ padding: 0.5rem;
258
+ cursor: pointer;
259
+ transition: background-color 0.15s ease;
260
+ display: flex;
261
+ align-items: center;
262
+ gap: 0.5rem;
263
+ color: inherit;
264
+ text-decoration: none;
265
+ }
266
+
267
+ .kmwc-spotlight__item:hover {
268
+ background-color: var(--kmwc-hover-bg);
269
+ text-decoration: none;
270
+ }
271
+
272
+ /* The keyboard cursor (where Enter goes): the focused item state — an inset
273
+ outline (offset = minus its width, so a thicker outline stays inside the row). */
274
+ .kmwc-spotlight__item--active {
275
+ background-color: var(--kmwc-focused-bg);
276
+ outline: var(--kmwc-focused-outline);
277
+ outline-offset: calc(-1 * var(--kmwc-outline-width));
278
+ }
279
+
280
+ .kmwc-spotlight__item--active:hover {
281
+ background-color: var(--kmwc-hover-bg);
282
+ }
283
+
284
+ .kmwc-spotlight__item--active .kmwc-spotlight__item-title {
285
+ color: var(--kmwc-focused-text-color);
286
+ }
287
+
288
+ /* The section code, in the slot wcp gives the item icon (spotlight only). */
289
+ .kmwc-spotlight__item-code {
290
+ flex-shrink: 0;
291
+ min-width: 3.4rem;
292
+ padding: 0.15rem 0.35rem;
293
+ border-radius: var(--kmwc-radius-sm);
294
+ background-color: var(--kmwc-accent-light-bg);
295
+ color: var(--kmwc-accent-color);
296
+ font-family: var(--kmwc-mono-font-family);
297
+ font-size: 0.78rem;
298
+ font-weight: 700;
299
+ text-align: center;
300
+ }
301
+
302
+ .kmwc-spotlight__item-content {
303
+ flex: 1;
304
+ min-width: 0;
305
+ }
306
+
307
+ .kmwc-spotlight__item-title {
308
+ display: block;
309
+ font-size: 0.875rem;
310
+ font-weight: 500;
311
+ color: var(--kmwc-text-color-1);
312
+ white-space: nowrap;
313
+ overflow: hidden;
314
+ text-overflow: ellipsis;
315
+ }
316
+
317
+ /* The matched part of the query. */
318
+ .kmwc-spotlight__item-title mark,
319
+ .kmwc-spotlight__item-code mark {
320
+ background-color: var(--kmwc-accent-light-bg-hover);
321
+ color: var(--kmwc-accent-color);
322
+ font-weight: 600;
323
+ padding: 0 2px;
324
+ border-radius: var(--kmwc-radius-sm);
325
+ }
326
+
327
+ .kmwc-spotlight__item-code mark {
328
+ padding: 0;
329
+ }
330
+
331
+ /* Screen-reader-only result count (wcp: .cp-sr-only). */
332
+ .kmwc-spotlight__live {
333
+ position: absolute;
334
+ width: 1px;
335
+ height: 1px;
336
+ margin: -1px;
337
+ overflow: hidden;
338
+ clip-path: inset(50%);
339
+ white-space: nowrap;
340
+ }
341
+
342
+ /* ==========================================================================
343
+ FOOTER — mirrors wcp footer.css
344
+ ========================================================================== */
345
+ .kmwc-spotlight__footer {
346
+ border-top: 1px solid var(--kmwc-border-color);
347
+ padding: 0.5rem;
348
+ display: flex;
349
+ flex-wrap: wrap;
350
+ gap: 1rem;
351
+ font-size: 0.75rem;
352
+ color: var(--kmwc-text-color-2);
353
+ }
354
+
355
+ .kmwc-spotlight__hint {
356
+ display: flex;
357
+ align-items: center;
358
+ gap: 0.25rem;
359
+ }
360
+
361
+ .kmwc-spotlight__key,
362
+ .kmwc-spotlight__trigger-key {
363
+ padding: 2px 0.25rem;
364
+ background-color: var(--kmwc-elevated-bg);
365
+ color: var(--kmwc-text-color-1);
366
+ border: 1px solid var(--kmwc-border-color);
367
+ border-radius: var(--kmwc-radius-sm);
368
+ font-family: var(--kmwc-font-family);
369
+ font-weight: 600;
370
+ font-size: 0.75rem;
371
+ line-height: 1;
372
+ }
373
+
374
+ .kmwc-spotlight__trigger-key {
375
+ color: var(--kmwc-text-color-3);
376
+ font-weight: 400;
377
+ }
378
+
379
+ /* ==========================================================================
380
+ ANIMATIONS — mirrors wcp animations.css
381
+ ========================================================================== */
382
+ @keyframes kmwc-spotlight-fade-in {
383
+ from { opacity: 0; }
384
+ to { opacity: 1; }
385
+ }
386
+
387
+ @keyframes kmwc-spotlight-slide-down {
388
+ from {
389
+ opacity: 0;
390
+ transform: translateY(-20px);
391
+ }
392
+ to {
393
+ opacity: 1;
394
+ transform: translateY(0);
395
+ }
396
+ }
397
+
398
+ @media (prefers-reduced-motion: reduce) {
399
+ .kmwc-spotlight__backdrop,
400
+ .kmwc-spotlight__container {
401
+ animation: none;
402
+ }
403
+ }
404
+
405
+ @media (max-width: 768px) {
406
+ .kmwc-spotlight__trigger-key,
407
+ .kmwc-spotlight__footer {
408
+ display: none;
409
+ }
410
+
411
+ .kmwc-spotlight__trigger {
412
+ width: 36px;
413
+ padding: 0;
414
+ justify-content: center;
415
+ }
416
+ }
417
+ }
@@ -20,11 +20,14 @@
20
20
 
21
21
  @import './tokens.css';
22
22
  @import './base.css';
23
+ @import './form-controls.css';
23
24
  @import './controls.css';
24
25
  @import './content.css';
26
+ @import './tables.css';
25
27
  @import './widgets.css';
26
28
  @import './demo.css';
27
29
  @import './copy-link.css';
28
30
  @import './chapter-nav.css';
31
+ @import './spotlight.css';
29
32
  @import './theme-switch.css';
30
33
  @import './index-page.css';
@@ -0,0 +1,141 @@
1
+ /* ==============================================================================
2
+ EXAMPLES KIT — TABLES
3
+ ==============================================================================
4
+ Any <table> on a page gets the base look (header fill, row lines, hover),
5
+ modelled on pure-admin's .pa-table. `.reference-table` is the full-width,
6
+ fully bordered API / option table most pages use. Modifiers combine:
7
+
8
+ .table-bordered every cell boxed (what .reference-table has)
9
+ .table-striped zebra rows
10
+ .table-compact tighter cells; controls inside shrink with them
11
+ .table-full full width
12
+ tr.is-highlight an accent-tinted row
13
+ .num a right-aligned, tabular-figure cell
14
+
15
+ The base is zero-specificity (:where()), so a page or component rule wins;
16
+ `kmwc-native` on the table (or an ancestor) leaves it unstyled. */
17
+ @layer kmwc {
18
+ /* ==========================================================================
19
+ BASE — every table
20
+ ========================================================================== */
21
+ :where(table):not(:where(.kmwc-native, .kmwc-native *)) {
22
+ border-collapse: collapse;
23
+ font-size: 0.875rem;
24
+ margin-bottom: 1rem;
25
+ }
26
+
27
+ :where(table):not(:where(.kmwc-native, .kmwc-native *)) :where(th, td) {
28
+ padding: 0.6rem 0.9rem;
29
+ text-align: start;
30
+ vertical-align: middle;
31
+ border-bottom: 1px solid var(--kmwc-border-color);
32
+ }
33
+
34
+ :where(table):not(:where(.kmwc-native, .kmwc-native *)) :where(th) {
35
+ background: var(--kmwc-elevated-bg);
36
+ color: var(--kmwc-text-color-1);
37
+ font-weight: 600;
38
+ }
39
+
40
+ :where(table):not(:where(.kmwc-native, .kmwc-native *)) :where(thead th) {
41
+ border-bottom: 2px solid var(--kmwc-border-color);
42
+ }
43
+
44
+ :where(table):not(:where(.kmwc-native, .kmwc-native *)) :where(tbody tr:hover) {
45
+ background: var(--kmwc-hover-bg);
46
+ }
47
+
48
+ :where(table):not(:where(.kmwc-native, .kmwc-native *)) :where(tfoot td, tfoot th) {
49
+ border-top: 2px solid var(--kmwc-border-color);
50
+ border-bottom: none;
51
+ font-weight: 600;
52
+ }
53
+
54
+ :where(table):not(:where(.kmwc-native, .kmwc-native *)) :where(caption) {
55
+ caption-side: top;
56
+ padding-bottom: 0.5rem;
57
+ text-align: start;
58
+ font-size: 0.8rem;
59
+ color: var(--kmwc-text-color-2);
60
+ }
61
+
62
+ :where(table):not(:where(.kmwc-native, .kmwc-native *)) :where(code) {
63
+ padding: 0.125rem 0.375rem;
64
+ font-size: 0.75rem;
65
+ }
66
+
67
+ /* ==========================================================================
68
+ MODIFIERS
69
+ ========================================================================== */
70
+ .table-full {
71
+ width: 100%;
72
+ }
73
+
74
+ .table-bordered :is(th, td) {
75
+ border: 1px solid var(--kmwc-border-color);
76
+ }
77
+
78
+ .table-striped tbody tr:nth-child(even) {
79
+ background: var(--kmwc-table-stripe-bg);
80
+ }
81
+
82
+ .table-striped tbody tr:nth-child(even):hover {
83
+ background: var(--kmwc-hover-bg);
84
+ }
85
+
86
+ /* Tighter cells, and the controls in them shrink too: buttons, inputs and
87
+ selects read --kmwc-control-height (form-controls.css). */
88
+ .table-compact {
89
+ --kmwc-control-height: 1.75rem;
90
+ font-size: 0.8125rem;
91
+ }
92
+
93
+ .table-compact :is(th, td) {
94
+ padding: 0.3rem 0.55rem;
95
+ }
96
+
97
+ .table-compact :is(button, input, select) {
98
+ font-size: 0.8125rem;
99
+ }
100
+
101
+ .table-compact button {
102
+ padding-inline: 0.6rem;
103
+ }
104
+
105
+ tr.is-highlight,
106
+ tr.is-highlight:hover {
107
+ background: var(--kmwc-accent-light-bg);
108
+ }
109
+
110
+ :is(th, td).num {
111
+ text-align: end;
112
+ font-variant-numeric: tabular-nums;
113
+ white-space: nowrap;
114
+ }
115
+
116
+ /* ==========================================================================
117
+ REFERENCE TABLE — the API / option table (full width, every cell boxed)
118
+ ========================================================================== */
119
+ .reference-table {
120
+ width: 100%;
121
+ margin-bottom: 2rem;
122
+ }
123
+
124
+ .reference-table th,
125
+ .reference-table td {
126
+ padding: 0.75rem 1rem;
127
+ border: 1px solid var(--kmwc-border-color);
128
+ }
129
+
130
+ /* A wide table scrolls inside its card instead of widening the page.
131
+ Widening matters beyond looks: mobile browsers grow the layout viewport
132
+ to fit, so a 390 px phone reports ~600 px and the page's own device /
133
+ breakpoint detection lies. */
134
+ @media (max-width: 768px) {
135
+ :where(table):not(:where(.kmwc-native, .kmwc-native *)) {
136
+ display: block;
137
+ max-width: 100%;
138
+ overflow-x: auto;
139
+ }
140
+ }
141
+ }