@uxelle/skills 0.2.0-beta.2 → 0.2.2
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/README.md +3 -5
- package/dist/index.js +98 -88
- package/index.json +98 -88
- package/package.json +1 -1
- package/skills/uxelle-components/ChoiceChip.md +1 -1
- package/skills/uxelle-components/ChoiceChipGroup.md +3 -3
- package/skills/uxelle-components/FilterChip.md +2 -2
- package/skills/uxelle-components/FilterChipGroup.md +1 -1
- package/skills/uxelle-components/Hero.md +2 -2
- package/skills/uxelle-components/Image.md +10 -3
- package/skills/uxelle-components/Logo.md +1 -1
- package/skills/uxelle-components/MultiSelect.md +3 -2
- package/skills/uxelle-components/SKILL.md +3 -1
- package/skills/uxelle-components/Select.md +2 -1
- package/skills/uxelle-components/Table.md +7 -4
- package/skills/uxelle-components/getting-started.md +54 -0
- package/skills/uxelle-design-harness/SKILL.md +44 -20
- package/skills/uxelle-design-harness/a2ui.md +22 -2
- package/skills/uxelle-design-harness/density.md +138 -0
- package/skills/uxelle-design-harness/how-to-accessibility.md +2 -0
- package/skills/uxelle-design-harness/how-to-color.md +6 -3
- package/skills/uxelle-design-harness/how-to-host.md +5 -22
- package/skills/uxelle-design-harness/how-to-page-layout.md +51 -6
- package/skills/uxelle-design-harness/principles.md +10 -6
- package/skills/uxelle-design-harness/recipe-app-chrome.md +20 -16
- package/skills/uxelle-design-harness/recipe-card-grid.md +14 -5
- package/skills/uxelle-design-harness/recipe-cta-band.md +16 -6
- package/skills/uxelle-design-harness/recipe-dashboard-overview.md +17 -5
- package/skills/uxelle-design-harness/recipe-data-table-page.md +30 -137
- package/skills/uxelle-design-harness/recipe-feature-section.md +9 -7
- package/skills/uxelle-design-harness/recipe-footer.md +7 -4
- package/skills/uxelle-design-harness/recipe-form-section.md +2 -2
- package/skills/uxelle-design-harness/recipe-hero.md +35 -15
- package/skills/uxelle-design-harness/recipe-landing-page.md +27 -4
- package/skills/uxelle-design-harness/recipe-logo-wall.md +11 -9
- package/skills/uxelle-design-harness/recipe-multi-step-flow.md +5 -3
- package/skills/uxelle-design-harness/recipe-page-header.md +14 -4
- package/skills/uxelle-design-harness/recipe-page-shell.md +2 -2
- package/skills/uxelle-design-harness/recipe-pricing.md +5 -2
- package/skills/uxelle-design-harness/recipe-query-bar.md +21 -5
- package/skills/uxelle-design-harness/recipe-record-detail.md +5 -2
- package/skills/uxelle-design-harness/recipe-settings-page.md +3 -3
- package/skills/uxelle-design-harness/recipe-stat-callouts.md +8 -3
- package/skills/uxelle-design-harness/recipe-states.md +9 -4
- package/skills/uxelle-design-harness/recipe-summary-list.md +5 -3
- package/skills/uxelle-design-harness/recipe-template.md +6 -0
- package/skills/uxelle-design-harness/recipe-testimonial.md +5 -3
- package/skills/uxelle-design-harness/spacing-steps.md +17 -8
- package/skills/uxelle-design-harness/tokens.md +45 -4
package/index.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"skills": [
|
|
5
5
|
{
|
|
6
6
|
"name": "uxelle-components",
|
|
7
|
-
"description": "Reference for uxElle Generative Product Foundation (GPF) components. Use when generating UI with uxElle, implementing designs, building layouts, or when the user mentions uxElle components
|
|
7
|
+
"description": "Reference for uxElle Generative Product Foundation (GPF) components. Use when generating UI with uxElle, implementing designs, building layouts, installing or setting up a React or Next.js app with @uxelle/components, loading theme CSS, or when the user mentions uxElle components or enterprise UI.",
|
|
8
8
|
"files": [
|
|
9
9
|
{
|
|
10
10
|
"path": "Accordion.md",
|
|
@@ -68,13 +68,13 @@
|
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"path": "ChoiceChip.md",
|
|
71
|
-
"size":
|
|
72
|
-
"hash": "sha256:
|
|
71
|
+
"size": 4061,
|
|
72
|
+
"hash": "sha256:6d3233c0895eb04bad20f0adb1818e0f591afa94c2cd3dba36d3d7af1baa4ee8"
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"path": "ChoiceChipGroup.md",
|
|
76
|
-
"size":
|
|
77
|
-
"hash": "sha256:
|
|
76
|
+
"size": 4999,
|
|
77
|
+
"hash": "sha256:97f3f8c26837e0adb78b7bea234e04160c58819dc8ff4664f8852a9080da54cc"
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
80
|
"path": "DatePicker.md",
|
|
@@ -138,23 +138,28 @@
|
|
|
138
138
|
},
|
|
139
139
|
{
|
|
140
140
|
"path": "FilterChip.md",
|
|
141
|
-
"size":
|
|
142
|
-
"hash": "sha256:
|
|
141
|
+
"size": 3290,
|
|
142
|
+
"hash": "sha256:feaa21e3cf7b095ea8f9d37bc84693206bf479209ee8a7b4a77ccb66c5028e4d"
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
145
|
"path": "FilterChipGroup.md",
|
|
146
|
-
"size":
|
|
147
|
-
"hash": "sha256:
|
|
146
|
+
"size": 4422,
|
|
147
|
+
"hash": "sha256:811a57ccac9b6777f8264651e52ca0ccb13da9bad3c428fe5ad8ffe324ed0772"
|
|
148
148
|
},
|
|
149
149
|
{
|
|
150
150
|
"path": "Footer.md",
|
|
151
151
|
"size": 1276,
|
|
152
152
|
"hash": "sha256:e2ca30ae7eba1e8c206d70791f4636a66e4f654059dbddda1b508bfd08e7b5c2"
|
|
153
153
|
},
|
|
154
|
+
{
|
|
155
|
+
"path": "getting-started.md",
|
|
156
|
+
"size": 2276,
|
|
157
|
+
"hash": "sha256:c40148458f76df3bdd9a0cf85732cd09bbe621c5625d20c4251aa7f4bd808a90"
|
|
158
|
+
},
|
|
154
159
|
{
|
|
155
160
|
"path": "Hero.md",
|
|
156
|
-
"size":
|
|
157
|
-
"hash": "sha256:
|
|
161
|
+
"size": 3578,
|
|
162
|
+
"hash": "sha256:e79223c6415b55c68cbe9d86e00d19a66ff369f43d6158231356cc409055a419"
|
|
158
163
|
},
|
|
159
164
|
{
|
|
160
165
|
"path": "Icon.md",
|
|
@@ -168,8 +173,8 @@
|
|
|
168
173
|
},
|
|
169
174
|
{
|
|
170
175
|
"path": "Image.md",
|
|
171
|
-
"size":
|
|
172
|
-
"hash": "sha256:
|
|
176
|
+
"size": 3893,
|
|
177
|
+
"hash": "sha256:37e001e0dde7ec499fe1d2ac3a805402972d12e64fc773991579310ff6738a7a"
|
|
173
178
|
},
|
|
174
179
|
{
|
|
175
180
|
"path": "Label.md",
|
|
@@ -228,8 +233,8 @@
|
|
|
228
233
|
},
|
|
229
234
|
{
|
|
230
235
|
"path": "Logo.md",
|
|
231
|
-
"size":
|
|
232
|
-
"hash": "sha256:
|
|
236
|
+
"size": 3306,
|
|
237
|
+
"hash": "sha256:3767cebd00da0e312142d2151d56a819cbaa89310efddca96824fd8c3b995021"
|
|
233
238
|
},
|
|
234
239
|
{
|
|
235
240
|
"path": "Menu.md",
|
|
@@ -238,8 +243,8 @@
|
|
|
238
243
|
},
|
|
239
244
|
{
|
|
240
245
|
"path": "MultiSelect.md",
|
|
241
|
-
"size":
|
|
242
|
-
"hash": "sha256:
|
|
246
|
+
"size": 6171,
|
|
247
|
+
"hash": "sha256:1b106b8d5368b4236e1671e0000545fb41dea75ff6ffc67595ec33a360a04f17"
|
|
243
248
|
},
|
|
244
249
|
{
|
|
245
250
|
"path": "Navigation.md",
|
|
@@ -323,8 +328,8 @@
|
|
|
323
328
|
},
|
|
324
329
|
{
|
|
325
330
|
"path": "Select.md",
|
|
326
|
-
"size":
|
|
327
|
-
"hash": "sha256:
|
|
331
|
+
"size": 6321,
|
|
332
|
+
"hash": "sha256:629e02b1014c0134b8c2a0f8716e2e161ac268a502b64568429d5060f68ccd06"
|
|
328
333
|
},
|
|
329
334
|
{
|
|
330
335
|
"path": "Sheet.md",
|
|
@@ -338,8 +343,8 @@
|
|
|
338
343
|
},
|
|
339
344
|
{
|
|
340
345
|
"path": "SKILL.md",
|
|
341
|
-
"size":
|
|
342
|
-
"hash": "sha256:
|
|
346
|
+
"size": 14408,
|
|
347
|
+
"hash": "sha256:de312111538d710c822a0212af2188584591d594d4f99ba7f3efb7a4435e9021"
|
|
343
348
|
},
|
|
344
349
|
{
|
|
345
350
|
"path": "Spinner.md",
|
|
@@ -368,8 +373,8 @@
|
|
|
368
373
|
},
|
|
369
374
|
{
|
|
370
375
|
"path": "Table.md",
|
|
371
|
-
"size":
|
|
372
|
-
"hash": "sha256:
|
|
376
|
+
"size": 3695,
|
|
377
|
+
"hash": "sha256:5455212f7c8f0370d369702dc6198c95e37fbde14695823413b7930b8421eefd"
|
|
373
378
|
},
|
|
374
379
|
{
|
|
375
380
|
"path": "TabsCompact.md",
|
|
@@ -409,163 +414,168 @@
|
|
|
409
414
|
"files": [
|
|
410
415
|
{
|
|
411
416
|
"path": "a2ui.md",
|
|
412
|
-
"size":
|
|
413
|
-
"hash": "sha256:
|
|
417
|
+
"size": 4779,
|
|
418
|
+
"hash": "sha256:e557e7caba1471f250a651f6449aa4b8e73b40e05c331dcbda25892b958ecd99"
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
"path": "density.md",
|
|
422
|
+
"size": 7471,
|
|
423
|
+
"hash": "sha256:1f819b3670222a54105b50c5c6f76059dd0e739b4b642c245be586e5c03f6e4a"
|
|
414
424
|
},
|
|
415
425
|
{
|
|
416
426
|
"path": "how-to-accessibility.md",
|
|
417
|
-
"size":
|
|
418
|
-
"hash": "sha256:
|
|
427
|
+
"size": 3554,
|
|
428
|
+
"hash": "sha256:c19043086e302c1681ae462efa9f7282a9e227aeb78dfe93bf66f6c4f4710bf7"
|
|
419
429
|
},
|
|
420
430
|
{
|
|
421
431
|
"path": "how-to-color.md",
|
|
422
|
-
"size":
|
|
423
|
-
"hash": "sha256:
|
|
432
|
+
"size": 3923,
|
|
433
|
+
"hash": "sha256:a72c5a4d88d007d68e6b640bccba0434fdd2c23ae8f291a77bdaec8689163425"
|
|
424
434
|
},
|
|
425
435
|
{
|
|
426
436
|
"path": "how-to-host.md",
|
|
427
|
-
"size":
|
|
428
|
-
"hash": "sha256:
|
|
437
|
+
"size": 2647,
|
|
438
|
+
"hash": "sha256:bdab3b08e77adaabcd582dff4b64838e0723ade66d5c9416be9111f9dc9b49cd"
|
|
429
439
|
},
|
|
430
440
|
{
|
|
431
441
|
"path": "how-to-page-layout.md",
|
|
432
|
-
"size":
|
|
433
|
-
"hash": "sha256:
|
|
442
|
+
"size": 10962,
|
|
443
|
+
"hash": "sha256:b01626a0661950a5bbb9a7def38e82b6b3ce9ded32a328edd72aa5c256588a84"
|
|
434
444
|
},
|
|
435
445
|
{
|
|
436
446
|
"path": "principles.md",
|
|
437
|
-
"size":
|
|
438
|
-
"hash": "sha256:
|
|
447
|
+
"size": 4551,
|
|
448
|
+
"hash": "sha256:7e93db6f61f469237feb5405b61f2d49e5aeef4d15425efdaa947bfafb6aabc8"
|
|
439
449
|
},
|
|
440
450
|
{
|
|
441
451
|
"path": "recipe-app-chrome.md",
|
|
442
|
-
"size":
|
|
443
|
-
"hash": "sha256:
|
|
452
|
+
"size": 10042,
|
|
453
|
+
"hash": "sha256:225ebbfabfa65538c9275744c4cc6e5cc7798a36ab496643b41283efae3ea1a3"
|
|
444
454
|
},
|
|
445
455
|
{
|
|
446
456
|
"path": "recipe-card-grid.md",
|
|
447
|
-
"size":
|
|
448
|
-
"hash": "sha256:
|
|
457
|
+
"size": 4099,
|
|
458
|
+
"hash": "sha256:3e594d337994417cf391f31222464c99fc84b9f4f251560c82d8f3501bdee5f4"
|
|
449
459
|
},
|
|
450
460
|
{
|
|
451
461
|
"path": "recipe-cta-band.md",
|
|
452
|
-
"size":
|
|
453
|
-
"hash": "sha256:
|
|
462
|
+
"size": 3645,
|
|
463
|
+
"hash": "sha256:4259be1f810e29abe43400010bde395ebf3e3e7ed7dc465b1c58d6ed87f3154c"
|
|
454
464
|
},
|
|
455
465
|
{
|
|
456
466
|
"path": "recipe-dashboard-overview.md",
|
|
457
|
-
"size":
|
|
458
|
-
"hash": "sha256:
|
|
467
|
+
"size": 4708,
|
|
468
|
+
"hash": "sha256:a6a581ca179595535d9d3df0469d362d8e7175e5595bea3222a32733c66c4615"
|
|
459
469
|
},
|
|
460
470
|
{
|
|
461
471
|
"path": "recipe-data-table-page.md",
|
|
462
|
-
"size":
|
|
463
|
-
"hash": "sha256:
|
|
472
|
+
"size": 14334,
|
|
473
|
+
"hash": "sha256:3133781fb670d44f0d0e6c25c75520272800127d4a11dab00b0bebcccf75f53c"
|
|
464
474
|
},
|
|
465
475
|
{
|
|
466
476
|
"path": "recipe-feature-section.md",
|
|
467
|
-
"size":
|
|
468
|
-
"hash": "sha256:
|
|
477
|
+
"size": 3422,
|
|
478
|
+
"hash": "sha256:4e6927fe2efdc1eafc94511037a4cdeb528896e377eebaef16728f7a29cffe20"
|
|
469
479
|
},
|
|
470
480
|
{
|
|
471
481
|
"path": "recipe-footer.md",
|
|
472
|
-
"size":
|
|
473
|
-
"hash": "sha256:
|
|
482
|
+
"size": 7241,
|
|
483
|
+
"hash": "sha256:8c2bd3e9b3c88c7444b2d9a92308f883541cb61cd8f039d757ca885ba9d122af"
|
|
474
484
|
},
|
|
475
485
|
{
|
|
476
486
|
"path": "recipe-form-section.md",
|
|
477
|
-
"size":
|
|
478
|
-
"hash": "sha256:
|
|
487
|
+
"size": 9125,
|
|
488
|
+
"hash": "sha256:dfdac68a0788e17fe48a5b8084717bbac7f59a80b0fbfcb1622ce2421211706c"
|
|
479
489
|
},
|
|
480
490
|
{
|
|
481
491
|
"path": "recipe-hero.md",
|
|
482
|
-
"size":
|
|
483
|
-
"hash": "sha256:
|
|
492
|
+
"size": 4106,
|
|
493
|
+
"hash": "sha256:14a1e862832226591244646ff442cf46b25ca8e088c2f15b0376a8ac8bde0cc2"
|
|
484
494
|
},
|
|
485
495
|
{
|
|
486
496
|
"path": "recipe-landing-page.md",
|
|
487
|
-
"size":
|
|
488
|
-
"hash": "sha256:
|
|
497
|
+
"size": 4900,
|
|
498
|
+
"hash": "sha256:7cf05d3d24e98b680e28f52b9691c59f881b420993f7af2ed1adc6ef1279ccc1"
|
|
489
499
|
},
|
|
490
500
|
{
|
|
491
501
|
"path": "recipe-logo-wall.md",
|
|
492
|
-
"size":
|
|
493
|
-
"hash": "sha256:
|
|
502
|
+
"size": 2920,
|
|
503
|
+
"hash": "sha256:6b9c2199a0a18d20cf8350013ebbba4f9a8c94f4d5b50642d93ac1551c054eff"
|
|
494
504
|
},
|
|
495
505
|
{
|
|
496
506
|
"path": "recipe-multi-step-flow.md",
|
|
497
|
-
"size":
|
|
498
|
-
"hash": "sha256:
|
|
507
|
+
"size": 3876,
|
|
508
|
+
"hash": "sha256:351069ddf1e5d085d9f1a89caa47c368874b5d15d4cb9a53e9e1691c3df44a14"
|
|
499
509
|
},
|
|
500
510
|
{
|
|
501
511
|
"path": "recipe-page-header.md",
|
|
502
|
-
"size":
|
|
503
|
-
"hash": "sha256:
|
|
512
|
+
"size": 4161,
|
|
513
|
+
"hash": "sha256:7487c48c7ea6ba57a613d9e91b4b4a1c6271ea27120f4a3c857dc1501dfce518"
|
|
504
514
|
},
|
|
505
515
|
{
|
|
506
516
|
"path": "recipe-page-shell.md",
|
|
507
|
-
"size":
|
|
508
|
-
"hash": "sha256:
|
|
517
|
+
"size": 3826,
|
|
518
|
+
"hash": "sha256:0e87856ed26f73a19cc057f63c505bfce7a6973b2f389f257ffdde9bac64faca"
|
|
509
519
|
},
|
|
510
520
|
{
|
|
511
521
|
"path": "recipe-pricing.md",
|
|
512
|
-
"size":
|
|
513
|
-
"hash": "sha256:
|
|
522
|
+
"size": 3374,
|
|
523
|
+
"hash": "sha256:072d554945710df4b2a2be3c78836a3aa1d0b910bace362c2838272130e152e1"
|
|
514
524
|
},
|
|
515
525
|
{
|
|
516
526
|
"path": "recipe-query-bar.md",
|
|
517
|
-
"size":
|
|
518
|
-
"hash": "sha256:
|
|
527
|
+
"size": 4990,
|
|
528
|
+
"hash": "sha256:d63bc538947160d1cf14209c9777233bc78e9cc1b2b52278b21b7959ff4e06c2"
|
|
519
529
|
},
|
|
520
530
|
{
|
|
521
531
|
"path": "recipe-record-detail.md",
|
|
522
|
-
"size":
|
|
523
|
-
"hash": "sha256:
|
|
532
|
+
"size": 3480,
|
|
533
|
+
"hash": "sha256:1d21484544c0307fc409570aeacf5f10bd03cde564e91e32ad271d46b29c7da6"
|
|
524
534
|
},
|
|
525
535
|
{
|
|
526
536
|
"path": "recipe-settings-page.md",
|
|
527
|
-
"size":
|
|
528
|
-
"hash": "sha256:
|
|
537
|
+
"size": 8287,
|
|
538
|
+
"hash": "sha256:eda9f10d2367b9bab26ef66ae471d65f6189c410829ea2176c07d6b1a82f89f8"
|
|
529
539
|
},
|
|
530
540
|
{
|
|
531
541
|
"path": "recipe-stat-callouts.md",
|
|
532
|
-
"size":
|
|
533
|
-
"hash": "sha256:
|
|
542
|
+
"size": 4017,
|
|
543
|
+
"hash": "sha256:fb3857880f691fd016cb1414ee788e3a9fdfc49f7e61376442965aa018896f6e"
|
|
534
544
|
},
|
|
535
545
|
{
|
|
536
546
|
"path": "recipe-states.md",
|
|
537
|
-
"size":
|
|
538
|
-
"hash": "sha256:
|
|
547
|
+
"size": 4150,
|
|
548
|
+
"hash": "sha256:cda9dedd98d44e1eddcb25b1cca721f686e15a7642d53ebcfe926c8241cca38d"
|
|
539
549
|
},
|
|
540
550
|
{
|
|
541
551
|
"path": "recipe-summary-list.md",
|
|
542
|
-
"size":
|
|
543
|
-
"hash": "sha256:
|
|
552
|
+
"size": 2951,
|
|
553
|
+
"hash": "sha256:a7fad25286bc6b6e357acfcc2b1afb5c562078b3bf633a190ad68648b2748cc4"
|
|
544
554
|
},
|
|
545
555
|
{
|
|
546
556
|
"path": "recipe-template.md",
|
|
547
|
-
"size":
|
|
548
|
-
"hash": "sha256:
|
|
557
|
+
"size": 3703,
|
|
558
|
+
"hash": "sha256:d3fe331af035c4af72d143b0d65ebba7a719a6b104af34ef7939afb1f05ef14a"
|
|
549
559
|
},
|
|
550
560
|
{
|
|
551
561
|
"path": "recipe-testimonial.md",
|
|
552
|
-
"size":
|
|
553
|
-
"hash": "sha256:
|
|
562
|
+
"size": 2453,
|
|
563
|
+
"hash": "sha256:7a755896fb14b0d3f4771ead61996f494033bb856e6ac847dfb78eb216bfce6c"
|
|
554
564
|
},
|
|
555
565
|
{
|
|
556
566
|
"path": "SKILL.md",
|
|
557
|
-
"size":
|
|
558
|
-
"hash": "sha256:
|
|
567
|
+
"size": 10810,
|
|
568
|
+
"hash": "sha256:096a85cb85d2fe413bc5f2abb241c45ea6e59dfc3b9547a00b639c7739fc014e"
|
|
559
569
|
},
|
|
560
570
|
{
|
|
561
571
|
"path": "spacing-steps.md",
|
|
562
|
-
"size":
|
|
563
|
-
"hash": "sha256:
|
|
572
|
+
"size": 2959,
|
|
573
|
+
"hash": "sha256:dcfcadc6371c478bd80f796231502fdaf65548914cda7786457a26e59b37e8ab"
|
|
564
574
|
},
|
|
565
575
|
{
|
|
566
576
|
"path": "tokens.md",
|
|
567
|
-
"size":
|
|
568
|
-
"hash": "sha256:
|
|
577
|
+
"size": 6758,
|
|
578
|
+
"hash": "sha256:69af34fc3fbfbf63a7796c2c49dc123c4cefc7b8553c3678b86bce6cd33dcdaf"
|
|
569
579
|
}
|
|
570
580
|
]
|
|
571
581
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uxelle/skills",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "uxElle generate-UI agent skills: component API reference and design harness, as versioned markdown with a machine-readable manifest",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -41,4 +41,4 @@ Toggle pill for choice sets (facets, sort, view options).
|
|
|
41
41
|
|
|
42
42
|
## Notes
|
|
43
43
|
|
|
44
|
-
- Uses `checked` / `defaultChecked` with `aria-pressed`. Checked chips show a leading check. Selection policy (single vs multi) is owned by the app — this control only toggles itself. Compose in **ChoiceChipGroup**. For exclusive single-select, keep one checked value in app state and
|
|
44
|
+
- Uses `checked` / `defaultChecked` with `aria-pressed`. Checked chips show a leading check. Unchecked labels use **Text** type `Condensed`; checked labels use `Condensed Alt`. Pass `label` as a string — do not wrap a `Text` node. Selection policy (single vs multi) is owned by the app — this control only toggles itself. Compose in **ChoiceChipGroup**. For exclusive single-select, keep one checked value in app state and leave `role="group"`. ChoiceChip stays a toggle button (`aria-pressed`), not a radio — use **RadioGroup** or **SegmentedControl** when you need radio semantics. Use **FilterChip** for dismissible applied filters. There is no InputChip — compose entry (e.g. Textfield) with FilterChips for removable values. Controlled: set `checked` from `onChange` (next pressed value). Uncontrolled: `defaultChecked` is mount-only.
|
|
@@ -17,7 +17,7 @@ Groups choice toggles under an optional legend, wrapping to new rows as needed.
|
|
|
17
17
|
| fieldMessageType | `"Info" \| "Danger" \| "Warning" \| "Success"` | `CHOICE_CHIP_GROUP_DEFAULTS.fieldMessageType` | Tone of the wrapped **FieldMessage** — `Info`, `Danger`, `Warning`, or `Success`. Forced to `Danger` while `invalid` is true. `Danger` wires the message as `aria-errormessage` and announces it politely; other tones link through `aria-describedby`. |
|
|
18
18
|
| required | `boolean` | `false` | Sets `aria-required` on the fieldset and shows the **Label** asterisk while a legend is visible. No native validation is enforced — the app owns that. |
|
|
19
19
|
| invalid | `boolean` | `false` | Sets `aria-invalid="true"` and shows a Danger field message (uses `fieldMessage` when set, otherwise a default error string). Also wires `aria-errormessage` and announces the message politely. `aria-invalid={true}` does the same; `false` is treated as omitted so this prop can still apply. |
|
|
20
|
-
| role | `string` | `"group"` | ARIA role on the fieldset.
|
|
20
|
+
| role | `string` | `"group"` | ARIA role on the fieldset. Default `group`. Chip children are not radio buttons — do not set `radiogroup`. For exclusive choice, keep one checked value in app state. Use **RadioGroup** or **SegmentedControl** for radio semantics. |
|
|
21
21
|
| "aria-label" | `string` | `""` | Accessible name for the fieldset, used only when no legend is showing. Prefer a visible legend via `label` and `labelText`; this value is dropped while one renders. |
|
|
22
22
|
| "aria-labelledby" | `string` | `""` | IDs of elements that name the fieldset when no legend renders, space-separated. Dropped while a legend is showing, since the legend already names the group. |
|
|
23
23
|
| "aria-describedby" | `string` | `""` | IDs of elements describing the group, space-separated. Merged with the field-message region id for non-`Danger` messages rather than replacing it. |
|
|
@@ -38,7 +38,7 @@ Groups choice toggles under an optional legend, wrapping to new rows as needed.
|
|
|
38
38
|
|
|
39
39
|
```tsx
|
|
40
40
|
// Exclusive single-select (app-owned)
|
|
41
|
-
<ChoiceChipGroup label labelText="Sort by"
|
|
41
|
+
<ChoiceChipGroup label labelText="Sort by">
|
|
42
42
|
<ChoiceChip label="Relevance" checked onChange={() => {}} />
|
|
43
43
|
<ChoiceChip label="Newest" onChange={() => {}} />
|
|
44
44
|
</ChoiceChipGroup>
|
|
@@ -47,4 +47,4 @@ Groups choice toggles under an optional legend, wrapping to new rows as needed.
|
|
|
47
47
|
|
|
48
48
|
## Notes
|
|
49
49
|
|
|
50
|
-
- Pass **ChoiceChip** children. Root is a **`fieldset`** with default **`role="group"`**; name it with the legend (`label` + `labelText`) or `aria-label` / `aria-labelledby`. Selection policy (single vs multi) is app-owned — this group does not enforce exclusivity. Keep **`role="group"
|
|
50
|
+
- Pass **ChoiceChip** children. Root is a **`fieldset`** with default **`role="group"`**; name it with the legend (`label` + `labelText`) or `aria-label` / `aria-labelledby`. Each chip owns its label type: `Condensed` when unchecked, `Condensed Alt` when checked. Selection policy (single vs multi) is app-owned — this group does not enforce exclusivity. Keep **`role="group"`**. For exclusive single-select, keep one checked value in app state — the chips remain `aria-pressed` toggles. Do not set **`role="radiogroup"`** (that role requires radio children). Use **RadioGroup** or **SegmentedControl** for radio semantics. Form parity: **`fieldMessage`**, **`required`**, **`invalid`**, and merged **`aria-describedby`** / **`aria-errormessage`**. For dismissible applied filters, use **FilterChipGroup**. There is no InputChip — compose entry (e.g. Textfield) with FilterChips for removable values.
|
|
@@ -10,7 +10,7 @@ Removable pill for an applied filter value.
|
|
|
10
10
|
|
|
11
11
|
| Prop | Type | Default | Description |
|
|
12
12
|
|------|------|---------|-------------|
|
|
13
|
-
| label (required) | `string` | `"Filter Chip"` | Filter value shown on the chip; also seeds the remove control's default name (`Remove {label}`). Whitespace is trimmed, an empty result renders no chip,
|
|
13
|
+
| label (required) | `string` | `"Filter Chip"` | Filter value shown on the chip; also seeds the remove control's default name (`Remove {label}`). Whitespace is trimmed, an empty result renders no chip. The label hugs content so chips wrap as units; it ellipsizes only when the chip itself is narrower than the label, so the dismiss control stays visible. |
|
|
14
14
|
| disabled | `boolean` | `false` | Applies disabled styling and blocks dismissal — the remove control ignores clicks and keys, and arrow-key navigation inside **FilterChipGroup** skips it. |
|
|
15
15
|
| leadingIcon | `boolean` | `false` | Adds a decorative icon before the label, useful for showing which facet the value belongs to. |
|
|
16
16
|
| leadingIconName | `string` | `"add"` | Material Symbol drawn before the label. Ignored unless `leadingIcon` is `true`. |
|
|
@@ -32,4 +32,4 @@ Removable pill for an applied filter value.
|
|
|
32
32
|
|
|
33
33
|
## Notes
|
|
34
34
|
|
|
35
|
-
- Always requires `onRemove` — the chip’s job is to represent a filter that can be dismissed. Root is a non-interactive `span` so the dismiss Icon Button nests correctly; the surface does not use hover/pressed fills. Prefer **ChoiceChip** for selectable option sets. There is no InputChip — compose entry (e.g. Textfield) with FilterChips for removable values. Keyboard: focus the remove control, then **Enter** / **Space** or **Delete** / **Backspace** to dismiss. Inside **FilterChipGroup**, arrow keys move between chips (one Tab stop for the set). Removal is announced via a polite live region.
|
|
35
|
+
- Always requires `onRemove` — the chip’s job is to represent a filter that can be dismissed. The label uses **Text** type `Condensed`. Pass `label` as a string — do not wrap a `Text` node. The label hugs content so chips wrap as whole units in **FilterChipGroup**. When a single chip is wider than its container, the label ellipsizes so the dismiss control stays visible. Root is a non-interactive `span` so the dismiss Icon Button nests correctly; the surface does not use hover/pressed fills. Prefer **ChoiceChip** for selectable option sets. There is no InputChip — compose entry (e.g. Textfield) with FilterChips for removable values. Keyboard: focus the remove control, then **Enter** / **Space** or **Delete** / **Backspace** to dismiss. Inside **FilterChipGroup**, arrow keys move between chips (one Tab stop for the set). Removal is announced via a polite live region.
|
|
@@ -39,4 +39,4 @@ Groups dismissible applied-filter chips under an optional legend, wrapping to ne
|
|
|
39
39
|
|
|
40
40
|
## Notes
|
|
41
41
|
|
|
42
|
-
- Pass **FilterChip** children. Root is a **`fieldset`** with default **`role="group"`**; name it with the legend (`label` + `labelText`) or `aria-label` / `aria-labelledby`. Keyboard: one Tab stop into the set; **Arrow** keys move between remove controls; **Delete** / **Backspace** dismisses the focused chip. Removals are announced politely. Form parity: **`fieldMessage`**, **`required`**, **`invalid`**, and merged **`aria-describedby`** / **`aria-errormessage`**. For choice option toggles, use **ChoiceChipGroup**. There is no InputChip — compose entry (e.g. Textfield) with FilterChips for removable values.
|
|
42
|
+
- Pass **FilterChip** children. Root is a **`fieldset`** with default **`role="group"`**; name it with the legend (`label` + `labelText`) or `aria-label` / `aria-labelledby`. Each child’s label uses **Text** type `Condensed`. Keyboard: one Tab stop into the set; **Arrow** keys move between remove controls; **Delete** / **Backspace** dismisses the focused chip. Removals are announced politely. Form parity: **`fieldMessage`**, **`required`**, **`invalid`**, and merged **`aria-describedby`** / **`aria-errormessage`**. For choice option toggles, use **ChoiceChipGroup**. There is no InputChip — compose entry (e.g. Textfield) with FilterChips for removable values.
|
|
@@ -11,7 +11,7 @@ Full-bleed marketing band with overlaid copy and actions.
|
|
|
11
11
|
| Prop | Type | Default | Description |
|
|
12
12
|
|------|------|---------|-------------|
|
|
13
13
|
| contentDirection | `"Left" \| "Right" \| "Bottom"` | `"Left"` | Where the content panel sits over the media. From the tablet breakpoint (678px) up, `Left` and `Right` pin a half-width, vertically centered panel to that edge, while `Bottom` keeps a full-width panel along the bottom. Below 678px all three collapse to the same full-width bottom panel. |
|
|
14
|
-
| image (required) | `ReactNode` | `—` | Full-bleed media behind the hero. Pass a **direct** child `Image`, `img`, `picture`, or `video` — extra wrappers are unsupported and will not fill the media layer. Prefer `Image` for source, alt text, and optional overlay. Do not
|
|
14
|
+
| image (required) | `ReactNode` | `—` | Full-bleed media behind the hero. Pass a **direct** child `Image`, `img`, `picture`, or `video` — extra wrappers are unsupported and will not fill the media layer. Prefer `Image` for source, alt text, and optional overlay. Do not set `Image` `aspectRatio` or box size (`width`, `height`, `minWidth`, `maxWidth`, `minHeight`, `maxHeight`) — Hero owns the responsive crop. Keep this region non-interactive; put actions in `contentSlot`. |
|
|
15
15
|
| contentSlot (required) | `ReactNode` | `—` | Overlay panel content, stacked in a column with theme gap — typically a `Lockup` plus a `ButtonGroup`. Required: the hero always renders the panel, and it is where any interactive content belongs. |
|
|
16
16
|
| "data-color-switcher" | `string` | `—` | Color-switcher palette applied to the hero root, which drives the content panel surface and text colors. Falls back to `brand-1`; pass another palette name such as `brand-2` or `neutral` to override it. |
|
|
17
17
|
|
|
@@ -58,4 +58,4 @@ Full-bleed marketing band with overlaid copy and actions.
|
|
|
58
58
|
|
|
59
59
|
## Notes
|
|
60
60
|
|
|
61
|
-
- Pass media in `image` as a direct child `Image`, `img`, `picture`, or `video` (wrappers are unsupported) and composed intro content in `contentSlot` (usually `Lockup` and `ButtonGroup`). `contentDirection` controls panel placement: `Left` / `Right` for side panels on tablet and up, `Bottom` for a full-width bottom panel at every size. Below the tablet breakpoint, `Left` and `Right` use the bottom panel layout. Content-area spacing remaps through theme breakpoint aliases that currently start at 375px — widths below that need a theme update before spacing sign-off. The root defaults to `data-color-switcher="brand-1"`; pass a different attribute to override. Do not add a landmark role by default — pass `role="region"` with `aria-label` or `aria-labelledby` when a named region is needed. Remaining HTML attributes are forwarded to the root element.
|
|
61
|
+
- Pass media in `image` as a direct child `Image`, `img`, `picture`, or `video` (wrappers are unsupported) and composed intro content in `contentSlot` (usually `Lockup` and `ButtonGroup`). `contentDirection` controls panel placement: `Left` / `Right` for side panels on tablet and up, `Bottom` for a full-width bottom panel at every size. Below the tablet breakpoint, `Left` and `Right` use the bottom panel layout. Content-area spacing remaps through theme breakpoint aliases that currently start at 375px — widths below that need a theme update before spacing sign-off. The root defaults to `data-color-switcher="brand-1"`; pass a different attribute to override. Do not add a landmark role by default — pass `role="region"` with `aria-label` or `aria-labelledby` when a named region is needed. Remaining HTML attributes are forwarded to the root element. Nested `Image` `aspectRatio` and box size (`width`, `height`, `minWidth`, `maxWidth`, `minHeight`, `maxHeight`) have no effect — this component sizes the media layer.
|
|
@@ -12,7 +12,13 @@ Responsive image that optionally crops its source to a selected aspect ratio.
|
|
|
12
12
|
|------|------|---------|-------------|
|
|
13
13
|
| src (required) | `string` | `""` | Source URL forwarded to the inner `img` element. Nothing renders in its place when the request fails, so guard missing values upstream. |
|
|
14
14
|
| alt (required) | `string` | `""` | Text alternative announced by assistive technology. Describe what the image conveys, or pass an empty string to mark it decorative and drop it from the accessibility tree. |
|
|
15
|
-
| aspectRatio | `"1:1" \| "4:3" \| "3:2" \| "16:9" \| "21:9" \| "3:4" \| "2:3"` | `undefined` | Crops the image to a fixed ratio — `1:1`, `4:3`, `3:2`, `16:9`, `21:9`, `3:4`, or `2:3
|
|
15
|
+
| aspectRatio | `"1:1" \| "4:3" \| "3:2" \| "16:9" \| "21:9" \| "3:4" \| "2:3"` | `undefined` | Crops the image to a fixed ratio — `1:1`, `4:3`, `3:2`, `16:9`, `21:9`, `3:4`, or `2:3` — and covers the box so overflow is trimmed. With `width` or `height` it sizes the missing axis; with both, the explicit box wins and this only crops. Omit to keep the source's intrinsic proportions. |
|
|
16
|
+
| width | `string` | `""` | Layout width of the image box. Numbers are pixels; strings pass through as CSS (`400px`, `var(--uxl-…)`). Omit to fill the parent width. |
|
|
17
|
+
| minWidth | `string` | `""` | Floor for the box width. Numbers are pixels; strings pass through as CSS. With `aspectRatio`, this clamps the computed width rather than replacing the ratio. |
|
|
18
|
+
| maxWidth | `string` | `""` | Ceiling for the box width. Numbers are pixels; strings pass through as CSS. With `aspectRatio`, this clamps the computed width rather than replacing the ratio. |
|
|
19
|
+
| height | `string` | `""` | Layout height of the image box. Numbers are pixels; strings pass through as CSS. With `aspectRatio` and no `width`, this sizes the box and the ratio computes width. Omit to size height from the source or from `aspectRatio`. |
|
|
20
|
+
| minHeight | `string` | `""` | Floor for the box height. Numbers are pixels; strings pass through as CSS. With `aspectRatio`, this clamps the computed height rather than replacing the ratio. |
|
|
21
|
+
| maxHeight | `string` | `""` | Ceiling for the box height. Numbers are pixels; strings pass through as CSS. With `aspectRatio`, this clamps the computed height rather than replacing the ratio. |
|
|
16
22
|
| overlay | `"100" \| "200"` | `undefined` | Layers a decorative gradient wash over the image so text placed on top keeps contrast: `100` is a light wash, `200` a dark wash weighted to the bottom edge. Omit for no overlay. |
|
|
17
23
|
|
|
18
24
|
<!-- prettier-ignore-end -->
|
|
@@ -27,6 +33,7 @@ Responsive image that optionally crops its source to a selected aspect ratio.
|
|
|
27
33
|
<Image
|
|
28
34
|
src="/images/hero.jpg"
|
|
29
35
|
alt="Crop field at sunrise"
|
|
36
|
+
width={640}
|
|
30
37
|
aspectRatio="21:9"
|
|
31
38
|
overlay="200"
|
|
32
39
|
/>
|
|
@@ -35,6 +42,6 @@ Responsive image that optionally crops its source to a selected aspect ratio.
|
|
|
35
42
|
|
|
36
43
|
## Notes
|
|
37
44
|
|
|
38
|
-
-
|
|
45
|
+
- `width` and `height` size the layout box (numbers are pixels; strings pass through as CSS). `aspectRatio` is a preferred ratio used when at least one axis is still automatic: with only `width` it computes height, with only `height` it computes width, and with both the explicit box wins while the image still covers that box. `minWidth` / `maxWidth` and `minHeight` / `maxHeight` clamp the computed axis rather than replacing the ratio. Omit `aspectRatio` to keep the source's intrinsic proportions, except when `height` is set — then the image covers the box. Supply meaningful `alt` text when the image conveys information, or `alt=""` when it is decorative.
|
|
39
46
|
- Set `overlay` to `"100"` or `"200"` to layer a decorative gradient wash for contrast (for example under text). The wash is non-interactive and hidden from assistive technologies.
|
|
40
|
-
- This component is non-interactive. Wrap it in a link or button only when the surrounding experience requires an action, and name that control separately.
|
|
47
|
+
- This component is non-interactive. Wrap it in a link or button only when the surrounding experience requires an action, and name that control separately. Inside Hero, omit `aspectRatio` and box-size props (`width`, `height`, `minWidth`, `maxWidth`, `minHeight`, `maxHeight`) — Hero owns the media box.
|
|
@@ -10,7 +10,7 @@ Brand logo slot for navigation, footer, and marketing surfaces.
|
|
|
10
10
|
|
|
11
11
|
| Prop | Type | Default | Description |
|
|
12
12
|
|------|------|---------|-------------|
|
|
13
|
-
| name | `"generic"` | `"generic"` | Which mark to render from the
|
|
13
|
+
| name | `"generic"` | `"generic"` | Which mark to render from the bundled **LogoName** set. It picks the asset file together with `color` and `background`, and fixes the aspect ratio that `width` scales. |
|
|
14
14
|
| background | `"default" \| "onDark"` | `"default"` | Surface the mark sits on. `onDark` swaps in the on-dark full-color asset for the brands that ship one, and only applies while `color` is `fullColor`. |
|
|
15
15
|
| color | `"fullColor" \| "black" \| "white" \| "colorSwitcherIcon"` | `"fullColor"` | Color treatment: `fullColor` for the brand palette, `black` or `white` for the monochrome mark, `colorSwitcherIcon` to tint the black mark with `--uxl-color-switcher-icon` from the nearest color-switcher context. Anything but `fullColor` overrides `background`. |
|
|
16
16
|
| interactive | `boolean` | `false` | Fades the mark to 80% opacity on hover. `Logo` is not a control on its own, so set this only when it sits inside a link or button. |
|
|
@@ -34,6 +34,7 @@ Multi-select dropdown with removable chips, label, optional `FieldMessage`, and
|
|
|
34
34
|
| readOnly | `boolean` | `false` | Shows the selection as comma-separated text instead of chips, blocks opening the listbox, and hides the trailing chevron; the trigger stays focusable. |
|
|
35
35
|
| required | `boolean` | `—` | Adds the asterisk to `Label` and `aria-required` on the trigger. Advisory only — no native constraint validation runs on the hidden inputs. |
|
|
36
36
|
| name | `string` | `—` | Form field name for the hidden inputs that post the selection — one input per selected value, and none at all while nothing is selected. |
|
|
37
|
+
| onClick | `MouseEventHandler<HTMLDivElement>` | `—` | Fired on the field chrome. `currentTarget` is the trigger wrapper, not the combobox input. |
|
|
37
38
|
| disabled | `boolean` | `false` | Blocks interaction, collapses chips to comma-separated text, and removes the trigger from the tab order; a `name` hidden input still submits each selected value. |
|
|
38
39
|
|
|
39
40
|
<!-- prettier-ignore-end -->
|
|
@@ -49,6 +50,6 @@ Multi-select dropdown with removable chips, label, optional `FieldMessage`, and
|
|
|
49
50
|
## Notes
|
|
50
51
|
|
|
51
52
|
- Chips stay on one row when interactive; overflowed chips collapse to “and N more”. Read-only and disabled states show comma-separated text with truncation.
|
|
52
|
-
- **Accessibility**: Visible label uses `<Label htmlFor>`; selected values render as Filter Chip–styled tags
|
|
53
|
-
- **Focus**: Tab
|
|
53
|
+
- **Accessibility**: Visible label uses `<Label htmlFor>`; selected values render as Filter Chip–styled tags beside a readonly combobox `<input>` (standard tag-in-input pattern). Remove controls use `tabIndex={-1}` and are omitted from the accessibility tree; toggle selections via the listbox. The combobox `value` is the comma-separated selection summary, including overflowed labels. Composable list rows should use `listboxOptionProps()`. `FieldMessage` uses `aria-describedby` (info) or `aria-errormessage` (error). Pass `id` for stable ids; use `aria-label` when `label={false}`.
|
|
54
|
+
- **Focus**: The combobox is a readonly `<input>` (not a `<button>`) so Safari's default Tab cycle can land on it. **Arrow** keys move the active option while open. **Enter** / **Space** toggle the active option; **Escape** closes the list.
|
|
54
55
|
- **Forms**: With `name`, one hidden input is rendered per selected value.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: uxelle-components
|
|
3
|
-
description: Reference for uxElle Generative Product Foundation (GPF) components. Use when generating UI with uxElle, implementing designs, building layouts, or when the user mentions uxElle components
|
|
3
|
+
description: Reference for uxElle Generative Product Foundation (GPF) components. Use when generating UI with uxElle, implementing designs, building layouts, installing or setting up a React or Next.js app with @uxelle/components, loading theme CSS, or when the user mentions uxElle components or enterprise UI.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# uxElle Components — Generative Workflow Reference
|
|
@@ -10,6 +10,7 @@ Reference for accurately using uxElle Generative Product Foundation (GPF) compon
|
|
|
10
10
|
## Context discipline
|
|
11
11
|
|
|
12
12
|
- Load this SKILL.md when working with uxElle components.
|
|
13
|
+
- New app or host without packages and CSS? Read [getting-started.md](getting-started.md) first, then [how-to-host.md](../uxelle-design-harness/how-to-host.md). Skip getting-started when the host already loads theme CSS, component CSS, and `data-*`.
|
|
13
14
|
- Load individual component files (e.g. Button.md, ListItem.md) only when you need that component's props or examples.
|
|
14
15
|
- Do not preload all component files.
|
|
15
16
|
|
|
@@ -236,6 +237,7 @@ For secondary nav or brand hero bands: `data-color-switcher="brand-2"` on second
|
|
|
236
237
|
|
|
237
238
|
## Additional Resources
|
|
238
239
|
|
|
240
|
+
- [Getting started](getting-started.md) — install `@uxelle/components` and `@uxelle/themes`, load CSS, theme provider, Next.js/SSR
|
|
239
241
|
- [Design harness](../uxelle-design-harness/SKILL.md) — principles, variables, page chrome, responsiveness, WCAG AA, recipes
|
|
240
242
|
- [Form field contract](../../docs/guides/form-field-contract.md) — HTML `value` / `checked` (not Figma `Selected` / `Activated`)
|
|
241
243
|
- [Design variables (`--uxl-*`)](../uxelle-design-harness/tokens.md) — spacing, radius, elevation, color switcher, type
|
|
@@ -34,6 +34,7 @@ Single-select dropdown with label, design tokens, optional `FieldMessage`, and l
|
|
|
34
34
|
| readOnly | `boolean` | `false` | Shows the current selection but blocks opening the listbox and hides the trailing chevron; the trigger stays focusable and reports `aria-readonly`. |
|
|
35
35
|
| required | `boolean` | `—` | Adds the asterisk to `Label` and `aria-required` on the trigger. Advisory only — no native constraint validation runs on the hidden input. |
|
|
36
36
|
| name | `string` | `—` | Form field name for the hidden input that posts the selected value. No input is rendered while nothing is selected, so an empty selection is never submitted. |
|
|
37
|
+
| onClick | `MouseEventHandler<HTMLDivElement>` | `—` | Fired on the field chrome. `currentTarget` is the trigger wrapper, not the combobox input. |
|
|
37
38
|
| disabled | `boolean` | `false` | Blocks interaction, removes the trigger from the tab order, and applies disabled styling; a `name` hidden input still submits the current value. |
|
|
38
39
|
|
|
39
40
|
<!-- prettier-ignore-end -->
|
|
@@ -51,5 +52,5 @@ Single-select dropdown with label, design tokens, optional `FieldMessage`, and l
|
|
|
51
52
|
- **Simple API** — pass `options` with `value` / `onChange` for controlled usage; optional `leadingIcon` / `leadingIconName`.
|
|
52
53
|
- **Composable API** — pass `children` to render custom `ListItem` rows in the listbox; pass `leading` for a custom leading slot. Each row should spread `listboxOptionProps()` plus selection handlers (see dev console when the list opens).
|
|
53
54
|
- **Accessibility**: Visible label uses `<Label htmlFor>`; the combobox name uses `aria-labelledby` on the label text only (not `fieldDescription`, which is linked via `aria-describedby`). `FieldMessage` uses `aria-describedby` (info) or `aria-errormessage` (error). Pass `id` for stable ids; use `aria-label` when `label={false}`.
|
|
54
|
-
- **Focus**: Tab focuses the
|
|
55
|
+
- **Focus**: The combobox is a readonly `<input>` (not a `<button>`) so Safari's default Tab cycle — text fields, not buttons — can land on it, and a click actually focuses the control. **Arrow** keys move the active option (`aria-activedescendant`) while open. **Enter** commits the active option; **Escape** closes the list. Options use `tabIndex={-1}` and are not separate tab stops.
|
|
55
56
|
- **Forms**: With `name`, a hidden input posts the selected value; when nothing is selected, no hidden input is rendered.
|
|
@@ -11,7 +11,7 @@ Composable table shell and semantic grid for tabular data. Columns support resiz
|
|
|
11
11
|
| Prop | Type | Default | Description |
|
|
12
12
|
|------|------|---------|-------------|
|
|
13
13
|
| topSlot | `ReactNode` | `—` | Band rendered above the table and outside its horizontal scrollport — typically a title, toolbar, filters, or search. Omitted entirely when unset. |
|
|
14
|
-
| bottomSlot | `ReactNode` | `—` | Band rendered below the table and outside its horizontal scrollport — typically
|
|
14
|
+
| bottomSlot | `ReactNode` | `—` | Band rendered below the table and outside its horizontal scrollport — typically **Pagination** or bulk actions. Omitted entirely when unset. |
|
|
15
15
|
| tableSlot | `ReactNode` | `—` | The table itself: one **TableGrid** with its head, body, rows, and cells, placed in the scroll region that drives the horizontal scroll hint. Same slot as `children`, and it wins when both are passed. |
|
|
16
16
|
| children | `ReactNode` | `—` | Alias for `tableSlot`, ignored when `tableSlot` is also passed. Compose one `TableGrid` (give it `aria-label` and `gridTemplateColumns`) holding a `TableHead` with a `TableRow` of `TableHeaderCell` children, then a `TableBody` with one `TableRow` of `TableCell` children per record — all exported from `@uxelle/components`. |
|
|
17
17
|
|
|
@@ -23,7 +23,7 @@ Extends `HTMLAttributes` — supports standard HTML attributes.
|
|
|
23
23
|
|
|
24
24
|
```tsx
|
|
25
25
|
const columns = [
|
|
26
|
-
{ flex: 0
|
|
26
|
+
{ flex: 0, minWidth: 48, maxWidth: 72 },
|
|
27
27
|
{ flex: 1, minWidth: 120 },
|
|
28
28
|
] as const;
|
|
29
29
|
|
|
@@ -44,12 +44,15 @@ function OrdersGrid() {
|
|
|
44
44
|
<OrdersGrid />
|
|
45
45
|
</TableColumnSizingProvider>
|
|
46
46
|
}
|
|
47
|
+
bottomSlot={
|
|
48
|
+
<Pagination totalItems={100} defaultItemsPerPage={10} aria-label="Orders pagination" />
|
|
49
|
+
}
|
|
47
50
|
/>
|
|
48
51
|
```
|
|
49
52
|
|
|
50
53
|
|
|
51
54
|
## Notes
|
|
52
55
|
|
|
53
|
-
- Optional top and bottom slots frame the table region;
|
|
54
|
-
- Horizontal scroll and the trailing-edge hint appear automatically when content overflows the container. Define column proportions with **TableColumnSizingProvider** and **useColumnGridTemplate**.
|
|
56
|
+
- Optional top and bottom slots frame the table region; pass **Pagination** in `bottomSlot` when the dataset is paged. A horizontal scroll hint appears when the grid is wider than its container. Fixed columns are implemented as sticky cells inside one `TableGrid`—not as a separate grid—so each row stays a single unit for assistive technology. Use **TableColumnPinProvider** or `pinned="start"` on **TableHeaderCell** and **TableCell** with **usePinnedStartOffsets** to keep leading columns visible during horizontal scroll.
|
|
57
|
+
- Horizontal scroll and the trailing-edge hint appear automatically when content overflows the container. Define column proportions with **TableColumnSizingProvider** and **useColumnGridTemplate**. Set `flex: 0` and `maxWidth` on compact columns (selection, icons) so leftover `fr` space does not stretch them on a wide viewport. `flex: 0` without a pixel `minWidth` or `maxWidth` sizes the track to content (`max-content`) instead of collapsing. `maxWidth` on a growing column (`flex > 0`) is a resize ceiling only. Cell copy wraps and the row height follows the tallest cell. Header titles stay on one line and ellipsize when the column is narrower than the name. Pass `truncation` on **Text** in a body cell only when that column must stay single-line. Resizing a column persists every column as a pixel track at the widths on screen, so siblings are not stretched or shrunk to fit the container. Call **useResetTableColumnWidths** to restore every column to its template.
|
|
55
58
|
- Layout is left-to-right only; right-to-left document direction is not supported yet.
|