@repobit/dex-system-design 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/README.md +43 -12
  3. package/package.json +6 -4
  4. package/schemas/component-manifest.json +207 -49
  5. package/schemas/manifest-omissions.json +2 -0
  6. package/src/components/accordion/accordion.css.js +12 -1
  7. package/src/components/agent-endpoints/agent-endpoints.js +1 -1
  8. package/src/components/alert/alert.css.js +22 -1
  9. package/src/components/anchor/anchor-nav.css.js +6 -1
  10. package/src/components/annotation/annotation.css.js +6 -1
  11. package/src/components/architecture.stories.js +6 -4
  12. package/src/components/avatar/avatar.js +37 -11
  13. package/src/components/avatar/avatar.stories.js +10 -6
  14. package/src/components/awards/awards-flex.css.js +31 -129
  15. package/src/components/awards/awards-flex.js +66 -116
  16. package/src/components/awards/awards-flex.stories.js +8 -6
  17. package/src/components/back/back.css.js +6 -1
  18. package/src/components/back/back.js +24 -12
  19. package/src/components/back/back.stories.js +3 -3
  20. package/src/components/badge/badge.js +6 -3
  21. package/src/components/badge/badge.stories.js +13 -9
  22. package/src/components/bento-grid/bento-grid.js +1 -1
  23. package/src/components/blockquote/blockquote.css.js +12 -3
  24. package/src/components/blockquote/blockquote.js +12 -5
  25. package/src/components/blockquote/blockquote.stories.js +6 -4
  26. package/src/components/button/button.css.js +46 -25
  27. package/src/components/button/button.js +44 -43
  28. package/src/components/button/button.stories.js +2 -2
  29. package/src/components/caption/caption.css.js +10 -0
  30. package/src/components/caption/caption.stories.js +4 -4
  31. package/src/components/carousel/carousel.css.js +19 -116
  32. package/src/components/carousel/carousel.js +70 -74
  33. package/src/components/carousel/carousel.stories.js +9 -8
  34. package/src/components/checkbox/checkbox.css.js +6 -1
  35. package/src/components/code/code.css.js +6 -1
  36. package/src/components/code/code.js +48 -7
  37. package/src/components/code/code.stories.js +7 -4
  38. package/src/components/divider/divider-horizontal.js +11 -3
  39. package/src/components/divider/divider-vertical.js +12 -5
  40. package/src/components/divider/divider.css.js +4 -1
  41. package/src/components/divider/divider.stories.js +6 -6
  42. package/src/components/dropdown/dropdown.js +67 -13
  43. package/src/components/dropdown/dropdown.stories.js +15 -14
  44. package/src/components/fieldset/fieldset.stories.js +41 -16
  45. package/src/components/footer/footer-nav-menu.css.js +6 -1
  46. package/src/components/footer/footer.css.js +6 -1
  47. package/src/components/header/header-code.js +1 -1
  48. package/src/components/header/header.css.js +9 -4
  49. package/src/components/heading/heading.stories.js +64 -31
  50. package/src/components/highlight/highlight.js +74 -34
  51. package/src/components/highlight/highlight.stories.js +5 -4
  52. package/src/components/icons/icon-element.js +49 -6
  53. package/src/components/icons/icons.stories.js +7 -0
  54. package/src/components/image/image.css.js +9 -98
  55. package/src/components/image/image.js +7 -2
  56. package/src/components/input/custom-form.stories.js +14 -19
  57. package/src/components/input/input-clipboard.css.js +6 -1
  58. package/src/components/input/input-clipboard.js +56 -8
  59. package/src/components/input/input.js +19 -2
  60. package/src/components/label/label.js +87 -1
  61. package/src/components/label/label.stories.js +21 -12
  62. package/src/components/link/link.css.js +52 -3
  63. package/src/components/link/link.js +52 -17
  64. package/src/components/link/link.stories.js +114 -3
  65. package/src/components/list/list-item/list-item.css.js +4 -6
  66. package/src/components/list/list-item/list-item.js +53 -5
  67. package/src/components/list/list-item/list-item.stories.js +22 -0
  68. package/src/components/list/list.js +27 -0
  69. package/src/components/modal/modal.css.js +6 -1
  70. package/src/components/pagination-dots/pagination-dots.css.js +161 -0
  71. package/src/components/pagination-dots/pagination-dots.js +202 -0
  72. package/src/components/pagination-dots/pagination-dots.stories.js +171 -0
  73. package/src/components/paragraph/paragraph.css.js +37 -1
  74. package/src/components/paragraph/paragraph.js +19 -2
  75. package/src/components/paragraph/paragraph.stories.js +40 -6
  76. package/src/components/picture/picture.css.js +8 -67
  77. package/src/components/picture/picture.js +15 -8
  78. package/src/components/pricing-cards/pricing-card.css.js +12 -2
  79. package/src/components/pricing-cards/pricing-card.js +4 -4
  80. package/src/components/progress/progress.js +24 -4
  81. package/src/components/progress/progress.stories.js +8 -6
  82. package/src/components/radio/radio.css.js +6 -1
  83. package/src/components/radio/radio.js +48 -3
  84. package/src/components/radio/radio.stories.js +1 -1
  85. package/src/components/shared/form-field.css.js +30 -4
  86. package/src/components/shared/token-scales.js +16 -0
  87. package/src/components/spinner/spinner.css.js +31 -4
  88. package/src/components/spinner/spinner.js +26 -4
  89. package/src/components/spinner/spinner.stories.js +10 -7
  90. package/src/components/switch/switch.css.js +21 -3
  91. package/src/components/switch/switch.js +8 -1
  92. package/src/components/switch/switch.stories.js +2 -1
  93. package/src/components/tab-list/tab-list.css.js +6 -1
  94. package/src/components/terminal/terminal-cursor.js +11 -0
  95. package/src/components/terminal/terminal-message.js +1 -1
  96. package/src/components/termsOfUse/terms.css.js +6 -1
  97. package/src/components/textarea/textarea.stories.js +23 -0
  98. package/src/components/tooltip/tooltip.css.js +24 -1
  99. package/src/components/tooltip/tooltip.js +135 -5
  100. package/src/components/tooltip/tooltip.stories.js +20 -14
  101. package/src/components/trust-panel/trust-panel.js +2 -2
  102. package/src/components/video/video.js +38 -3
  103. package/src/components/video/video.stories.js +10 -5
  104. package/src/components/video-player/video-player.css.js +6 -1
  105. package/src/tokens/elevation.stories.js +2 -3
  106. package/src/tokens/focus.stories.js +81 -15
  107. package/src/tokens/motion.stories.js +0 -6
  108. package/src/tokens/tokens.css +174 -97
  109. package/src/tokens/tokens.js +174 -97
  110. package/src/tokens/vertical-rhythm.stories.js +1 -1
  111. package/src/stories/Button.js +0 -20
  112. package/src/stories/Button.stories.js +0 -46
  113. package/src/stories/Configure.mdx +0 -364
  114. package/src/stories/Header.js +0 -45
  115. package/src/stories/Header.stories.js +0 -24
  116. package/src/stories/Page.js +0 -62
  117. package/src/stories/Page.stories.js +0 -20
  118. package/src/stories/assets/accessibility.png +0 -0
  119. package/src/stories/assets/accessibility.svg +0 -1
  120. package/src/stories/assets/addon-library.png +0 -0
  121. package/src/stories/assets/assets.png +0 -0
  122. package/src/stories/assets/avif-test-image.avif +0 -0
  123. package/src/stories/assets/context.png +0 -0
  124. package/src/stories/assets/discord.svg +0 -1
  125. package/src/stories/assets/docs.png +0 -0
  126. package/src/stories/assets/figma-plugin.png +0 -0
  127. package/src/stories/assets/github.svg +0 -1
  128. package/src/stories/assets/share.png +0 -0
  129. package/src/stories/assets/styling.png +0 -0
  130. package/src/stories/assets/testing.png +0 -0
  131. package/src/stories/assets/theming.png +0 -0
  132. package/src/stories/assets/tutorials.svg +0 -1
  133. package/src/stories/assets/youtube.svg +0 -1
  134. package/src/stories/button.css +0 -30
  135. package/src/stories/header.css +0 -32
  136. package/src/stories/page.css +0 -68
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifestVersion": 1,
3
3
  "package": "@repobit/dex-system-design",
4
- "packageVersion": "1.0.0",
4
+ "packageVersion": "2.0.0",
5
5
  "generatedFrom": [
6
6
  "package.json exports",
7
7
  "Lit static properties",
@@ -188,7 +188,7 @@
188
188
  },
189
189
  {
190
190
  "tag": "bd-custom-input-clipboard",
191
- "packageExport": "./input",
191
+ "packageExport": "./input-clipboard",
192
192
  "module": "./src/components/input/input-clipboard.js",
193
193
  "role": "form",
194
194
  "contentModel": "none",
@@ -231,7 +231,8 @@
231
231
  },
232
232
  {
233
233
  "name": "focused",
234
- "type": "boolean"
234
+ "type": "boolean",
235
+ "description": "Has keyboard focus. Setting it moves focus into the field and clearing it blurs the field; it reflects whether the field is focused. Set it on at most one field, since only one can hold focus."
235
236
  },
236
237
  {
237
238
  "name": "tooltip",
@@ -253,7 +254,16 @@
253
254
  "name": "value",
254
255
  "type": "string",
255
256
  "description": "The field contents. A paste button sits over the right-hand end and fills it from the clipboard."
257
+ },
258
+ {
259
+ "name": "name",
260
+ "type": "string",
261
+ "description": "Carried on the bd-input and bd-change event detail. NOT submitted with a form — the input lives in a shadow root."
256
262
  }
263
+ ],
264
+ "events": [
265
+ "bd-input",
266
+ "bd-change"
257
267
  ]
258
268
  },
259
269
  {
@@ -479,10 +489,11 @@
479
489
  "name": "size",
480
490
  "type": "string",
481
491
  "enum": [
482
- "small",
483
- "default",
484
- "large"
485
- ]
492
+ "sm",
493
+ "md",
494
+ "lg"
495
+ ],
496
+ "description": "A size step. small, default and large still resolve, and are rewritten to these."
486
497
  }
487
498
  ]
488
499
  },
@@ -622,6 +633,11 @@
622
633
  "custom-click"
623
634
  ],
624
635
  "props": [
636
+ {
637
+ "name": "description",
638
+ "type": "string",
639
+ "description": "Extra text a screen reader reads after the name, wired with aria-describedby inside the shadow root, where the control is. bd-tooltip sets it on a trigger."
640
+ },
625
641
  {
626
642
  "name": "variant",
627
643
  "type": "string",
@@ -767,6 +783,11 @@
767
783
  "custom-click"
768
784
  ],
769
785
  "props": [
786
+ {
787
+ "name": "description",
788
+ "type": "string",
789
+ "description": "Extra text a screen reader reads after the name, wired with aria-describedby inside the shadow root, where the control is. bd-tooltip sets it on a trigger."
790
+ },
770
791
  {
771
792
  "name": "variant",
772
793
  "type": "string",
@@ -933,9 +954,10 @@
933
954
  "name": "size",
934
955
  "type": "string",
935
956
  "enum": [
936
- "default",
937
- "small"
938
- ]
957
+ "sm",
958
+ "md"
959
+ ],
960
+ "description": "A size step; only sm has a rule of its own. default and small still resolve, and are rewritten to these."
939
961
  }
940
962
  ]
941
963
  },
@@ -1154,28 +1176,15 @@
1154
1176
  "role": "action",
1155
1177
  "contentModel": "none",
1156
1178
  "props": [
1157
- {
1158
- "name": "variant",
1159
- "type": "string",
1160
- "enum": [
1161
- "primary",
1162
- "secondary",
1163
- "tertiary",
1164
- "ghost",
1165
- "accent",
1166
- "white",
1167
- "outline-white"
1168
- ],
1169
- "description": "Visual variant. Replaces kind, which meant appearance here and size or marker elsewhere; kind still resolves. tertiary is a blue outline, ghost a dark outline, accent the red conversion fill — red is not a danger signal in this system. white and outline-white are fixed presets for a solid-colour banner and ignore surface on purpose."
1170
- },
1171
1179
  {
1172
1180
  "name": "label",
1173
1181
  "type": "string",
1174
- "description": "Both the visible text and the accessible name for this preset."
1182
+ "description": "Both the visible text and the accessible name. Defaults to \"Contact us\"."
1175
1183
  },
1176
1184
  {
1177
1185
  "name": "href",
1178
- "type": "string"
1186
+ "type": "string",
1187
+ "description": "Where the CTA goes. It renders an <a>, so without one it is not a link."
1179
1188
  },
1180
1189
  {
1181
1190
  "name": "align",
@@ -1184,7 +1193,8 @@
1184
1193
  "left",
1185
1194
  "center",
1186
1195
  "right"
1187
- ]
1196
+ ],
1197
+ "description": "Horizontal placement, as on bd-button. Set it as an attribute."
1188
1198
  },
1189
1199
  {
1190
1200
  "name": "shape",
@@ -1195,6 +1205,9 @@
1195
1205
  ],
1196
1206
  "description": "Corner shape. rounded takes --radius-3xl whatever the size; default keeps the size band's radius."
1197
1207
  }
1208
+ ],
1209
+ "events": [
1210
+ "custom-click"
1198
1211
  ]
1199
1212
  },
1200
1213
  {
@@ -1245,7 +1258,21 @@
1245
1258
  {
1246
1259
  "name": "disabled",
1247
1260
  "type": "boolean"
1261
+ },
1262
+ {
1263
+ "name": "value",
1264
+ "type": "string",
1265
+ "description": "The chosen option. Read it, or set it to choose one; unset, or set to an option that is not there, it is the first. Carried on the bd-input / bd-change detail."
1266
+ },
1267
+ {
1268
+ "name": "name",
1269
+ "type": "string",
1270
+ "description": "Carried on the bd-input and bd-change event detail. NOT submitted with a form — the select lives in a shadow root."
1248
1271
  }
1272
+ ],
1273
+ "events": [
1274
+ "bd-input",
1275
+ "bd-change"
1249
1276
  ]
1250
1277
  },
1251
1278
  {
@@ -1287,7 +1314,8 @@
1287
1314
  },
1288
1315
  {
1289
1316
  "name": "focused",
1290
- "type": "boolean"
1317
+ "type": "boolean",
1318
+ "description": "Has keyboard focus. Setting it moves focus into the field and clearing it blurs the field; it reflects whether the field is focused. Set it on at most one field, since only one can hold focus."
1291
1319
  },
1292
1320
  {
1293
1321
  "name": "tooltip",
@@ -1488,7 +1516,16 @@
1488
1516
  },
1489
1517
  {
1490
1518
  "name": "thickness",
1491
- "type": "string"
1519
+ "type": "string",
1520
+ "enum": [
1521
+ "0",
1522
+ "1",
1523
+ "2",
1524
+ "3",
1525
+ "4",
1526
+ "8"
1527
+ ],
1528
+ "description": "A border-width step, resolved to var(--border-width-N). \"1px\" and the other px spellings are read as their step; anything else is the 1px step."
1492
1529
  },
1493
1530
  {
1494
1531
  "name": "color",
@@ -2061,7 +2098,15 @@
2061
2098
  },
2062
2099
  {
2063
2100
  "name": "fit",
2064
- "type": "string"
2101
+ "type": "string",
2102
+ "enum": [
2103
+ "cover",
2104
+ "contain",
2105
+ "fill",
2106
+ "none",
2107
+ "scale-down"
2108
+ ],
2109
+ "description": "object-fit for the image. Applied as a class; any other value falls back to \"cover\"."
2065
2110
  },
2066
2111
  {
2067
2112
  "name": "radius",
@@ -2080,7 +2125,15 @@
2080
2125
  },
2081
2126
  {
2082
2127
  "name": "shadow",
2083
- "type": "string"
2128
+ "type": "string",
2129
+ "enum": [
2130
+ "none",
2131
+ "sm",
2132
+ "md",
2133
+ "lg",
2134
+ "xl"
2135
+ ],
2136
+ "description": "A shadow step. Applied as a class; any other value falls back to \"none\"."
2084
2137
  }
2085
2138
  ]
2086
2139
  },
@@ -2133,10 +2186,11 @@
2133
2186
  "name": "size",
2134
2187
  "type": "string",
2135
2188
  "enum": [
2136
- "small",
2137
- "default",
2138
- "large"
2139
- ]
2189
+ "sm",
2190
+ "md",
2191
+ "lg"
2192
+ ],
2193
+ "description": "A size step. small, default and large still resolve, and are rewritten to these."
2140
2194
  },
2141
2195
  {
2142
2196
  "name": "for",
@@ -2320,6 +2374,11 @@
2320
2374
  "role": "content",
2321
2375
  "contentModel": "text-or-children",
2322
2376
  "props": [
2377
+ {
2378
+ "name": "description",
2379
+ "type": "string",
2380
+ "description": "Extra text a screen reader reads after the link's name, wired with aria-describedby inside the shadow root, where the <a> is. bd-tooltip sets it on a trigger."
2381
+ },
2323
2382
  {
2324
2383
  "name": "variant",
2325
2384
  "type": "string",
@@ -2401,6 +2460,11 @@
2401
2460
  "error"
2402
2461
  ],
2403
2462
  "description": "A semantic colour role, not a CSS colour. Resolves to a palette token."
2463
+ },
2464
+ {
2465
+ "name": "arrow",
2466
+ "type": "boolean",
2467
+ "description": "A trailing arrow after the label, for a standalone call-to-action link such as Read more. Every variant, state and surface applies; the arrow takes the link's ink. Slot a bd-*-icon into slot=\"icon\" to swap the glyph. It is decorative: the label must say where the link goes."
2404
2468
  }
2405
2469
  ]
2406
2470
  },
@@ -2413,15 +2477,32 @@
2413
2477
  "props": [
2414
2478
  {
2415
2479
  "name": "type",
2416
- "type": "string"
2480
+ "type": "string",
2481
+ "enum": [
2482
+ "unordered",
2483
+ "ordered"
2484
+ ],
2485
+ "description": "The tag: <ul> or <ol>. Any other value falls back to \"unordered\"."
2417
2486
  },
2418
2487
  {
2419
2488
  "name": "spacing",
2420
- "type": "string"
2489
+ "type": "string",
2490
+ "enum": [
2491
+ "sm",
2492
+ "md",
2493
+ "lg"
2494
+ ],
2495
+ "description": "The gap between items when horizontal. Any other value falls back to \"md\"."
2421
2496
  },
2422
2497
  {
2423
2498
  "name": "variant",
2424
- "type": "string"
2499
+ "type": "string",
2500
+ "enum": [
2501
+ "default",
2502
+ "compact",
2503
+ "spacious"
2504
+ ],
2505
+ "description": "The gap between items. Any other value falls back to \"default\"."
2425
2506
  },
2426
2507
  {
2427
2508
  "name": "start",
@@ -2429,7 +2510,12 @@
2429
2510
  },
2430
2511
  {
2431
2512
  "name": "orientation",
2432
- "type": "string"
2513
+ "type": "string",
2514
+ "enum": [
2515
+ "vertical",
2516
+ "horizontal"
2517
+ ],
2518
+ "description": "Flow of the items. Any other value falls back to \"vertical\"."
2433
2519
  }
2434
2520
  ]
2435
2521
  },
@@ -2549,9 +2635,10 @@
2549
2635
  "small",
2550
2636
  "regular",
2551
2637
  "large",
2552
- "lead"
2638
+ "lead",
2639
+ "eyebrow"
2553
2640
  ],
2554
- "description": "Body type role. Replaces kind, which still resolves."
2641
+ "description": "Body type role. Replaces kind, which still resolves. eyebrow is the short brand-ink label above a section title, in text-brand: the label-large role (16px, Medium 500) from lg up, label-default (14px) below lg."
2555
2642
  },
2556
2643
  {
2557
2644
  "name": "kind",
@@ -2652,7 +2739,7 @@
2652
2739
  "warning",
2653
2740
  "error"
2654
2741
  ],
2655
- "description": "A text colour role, the same vocabulary as bd-h. Anything else is dropped."
2742
+ "description": "A semantic colour role, not a CSS colour, the same set bd-h and bd-display take. primary is brand blue; inverse is white on a dark or brand band."
2656
2743
  }
2657
2744
  ]
2658
2745
  },
@@ -2732,6 +2819,66 @@
2732
2819
  }
2733
2820
  ]
2734
2821
  },
2822
+ {
2823
+ "tag": "bd-pagination-dots",
2824
+ "packageExport": "./pagination-dots",
2825
+ "module": "./src/components/pagination-dots/pagination-dots.js",
2826
+ "role": "navigation",
2827
+ "contentModel": "none",
2828
+ "events": [
2829
+ "bd-change",
2830
+ "bd-toggle"
2831
+ ],
2832
+ "props": [
2833
+ {
2834
+ "name": "count",
2835
+ "type": "number",
2836
+ "description": "How many dots, one per slide or page. Below 2 nothing renders."
2837
+ },
2838
+ {
2839
+ "name": "current",
2840
+ "type": "number",
2841
+ "description": "Which dot is current, 1-based, held between 1 and count. The owner of the slides sets it; a visitor's pick fires bd-change with detail.current."
2842
+ },
2843
+ {
2844
+ "name": "label",
2845
+ "type": "string",
2846
+ "default": "Slides",
2847
+ "description": "Accessible name of the group: what the dots move through. Set it in the page's language."
2848
+ },
2849
+ {
2850
+ "name": "itemLabel",
2851
+ "type": "string",
2852
+ "attributeName": "item-label",
2853
+ "default": "Go to slide",
2854
+ "description": "Starts each dot's accessible name; the dot's number follows it. Set it in the page's language."
2855
+ },
2856
+ {
2857
+ "name": "autoplay",
2858
+ "type": "boolean",
2859
+ "default": false,
2860
+ "description": "The atom advances itself every delay ms, wrapping after the last slide, and the current pill fills as the time runs. Each advance fires bd-change like a click. Picking a dot stops it for good (WCAG 2.2.2); it never starts under prefers-reduced-motion."
2861
+ },
2862
+ {
2863
+ "name": "delay",
2864
+ "type": "number",
2865
+ "default": 4000,
2866
+ "description": "Milliseconds each slide shows under autoplay. Held at 1000 or more."
2867
+ },
2868
+ {
2869
+ "name": "paused",
2870
+ "type": "boolean",
2871
+ "default": false,
2872
+ "description": "Autoplay stopped for good: set when the visitor picks a dot, or under prefers-reduced-motion, and otherwise only by the owner. bd-toggle reports it."
2873
+ },
2874
+ {
2875
+ "name": "held",
2876
+ "type": "boolean",
2877
+ "default": false,
2878
+ "description": "A transient hold the owner sets while the pointer or focus is on its slides. The atom holds itself the same way while the pointer or focus is on the dots."
2879
+ }
2880
+ ]
2881
+ },
2735
2882
  {
2736
2883
  "tag": "bd-picture",
2737
2884
  "packageExport": "./picture",
@@ -2767,7 +2914,15 @@
2767
2914
  },
2768
2915
  {
2769
2916
  "name": "fit",
2770
- "type": "string"
2917
+ "type": "string",
2918
+ "enum": [
2919
+ "cover",
2920
+ "contain",
2921
+ "fill",
2922
+ "none",
2923
+ "scale-down"
2924
+ ],
2925
+ "description": "object-fit for the fallback image. Applied as a class; any other value falls back to \"cover\"."
2771
2926
  },
2772
2927
  {
2773
2928
  "name": "radius",
@@ -2886,7 +3041,8 @@
2886
3041
  "info",
2887
3042
  "success",
2888
3043
  "error"
2889
- ]
3044
+ ],
3045
+ "description": "Colour of the fill. Unset is the default fill; any other value is cleared."
2890
3046
  }
2891
3047
  ]
2892
3048
  },
@@ -2960,10 +3116,11 @@
2960
3116
  "name": "size",
2961
3117
  "type": "string",
2962
3118
  "enum": [
2963
- "small",
2964
- "default",
2965
- "large"
2966
- ]
3119
+ "sm",
3120
+ "md",
3121
+ "lg"
3122
+ ],
3123
+ "description": "A size step. small, default and large still resolve, and are rewritten to these."
2967
3124
  },
2968
3125
  {
2969
3126
  "name": "surface",
@@ -3251,7 +3408,8 @@
3251
3408
  },
3252
3409
  {
3253
3410
  "name": "controls",
3254
- "type": "boolean"
3411
+ "type": "boolean",
3412
+ "description": "Native playback controls, on by default. In HTML, controls=\"false\" turns them off; leaving the attribute out does not. Off only for decoration that is muted and loops."
3255
3413
  },
3256
3414
  {
3257
3415
  "name": "muted",
@@ -51,6 +51,7 @@
51
51
  "bd-compare-section: component declares \"scoreLabel\" but the manifest omits it",
52
52
  "bd-compare-section: component declares \"variant\" but the manifest omits it",
53
53
  "bd-contact-button: component declares \"buyLink\" but the manifest omits it",
54
+ "bd-contact-button: component declares \"description\" but the manifest omits it",
54
55
  "bd-contact-button: component declares \"disabled\" but the manifest omits it",
55
56
  "bd-contact-button: component declares \"fontSize\" but the manifest omits it",
56
57
  "bd-contact-button: component declares \"fontWeight\" but the manifest omits it",
@@ -64,6 +65,7 @@
64
65
  "bd-contact-button: component declares \"strong\" but the manifest omits it",
65
66
  "bd-contact-button: component declares \"surface\" but the manifest omits it",
66
67
  "bd-contact-button: component declares \"target\" but the manifest omits it",
68
+ "bd-contact-button: component declares \"variant\" but the manifest omits it",
67
69
  "bd-feature-col is registered by ./features but absent from the manifest",
68
70
  "bd-features is registered by ./features but absent from the manifest",
69
71
  "bd-features-tab is registered by ./features-tab but absent from the manifest",
@@ -58,6 +58,12 @@ export const accordionItem = css`
58
58
  position: relative;
59
59
  z-index: var(--z-base);
60
60
  box-shadow: var(--focus-outline-primary);
61
+ /* forced-colors mode does not paint box-shadow, so the ring
62
+ vanishes there; it does paint an outline, in a system colour. This one
63
+ is transparent everywhere else, and the offset lands it on the ring's
64
+ outer band. */
65
+ outline: var(--border-width-2) solid transparent;
66
+ outline-offset: var(--focus-outline-offset);
61
67
  }
62
68
 
63
69
  :host(:last-child) {
@@ -367,7 +373,12 @@ export const accordionSection = css`
367
373
  }
368
374
 
369
375
  .user-guide-link a:focus-visible {
370
- outline: none;
376
+ /* forced-colors mode does not paint box-shadow, so the ring
377
+ vanishes there; it does paint an outline, in a system colour. This one
378
+ is transparent everywhere else, and the offset lands it on the ring's
379
+ outer band. */
380
+ outline: var(--border-width-2) solid transparent;
381
+ outline-offset: var(--focus-outline-offset);
371
382
  box-shadow: var(--focus-outline-primary);
372
383
  border-radius: var(--focus-outline-radius);
373
384
  }
@@ -31,7 +31,7 @@ class AgentEndpoints extends LitElement {
31
31
  return html`
32
32
  <div class="bd-ensemble bd-agentendpoints-wrapper">
33
33
  ${this.eyebrow
34
- ? html`<bd-p variant="regular" font-weight="semibold" class="bd-agentendpoints-eyebrow"><slot name="eyebrow">${this.eyebrow}</slot></bd-p>`
34
+ ? html`<bd-p variant="eyebrow" class="bd-agentendpoints-eyebrow"><slot name="eyebrow">${this.eyebrow}</slot></bd-p>`
35
35
  : nothing}
36
36
 
37
37
  ${this.title
@@ -177,7 +177,17 @@ export const alertCSS = css`
177
177
  display: none;
178
178
  }
179
179
 
180
+ /* A 24px target around the 16px icon. The button was the icon and
181
+ nothing else, 16x16, under the 24px WCAG 2.5.8 asks of a pointer target
182
+ -- and an alert's close button is the one control on it a reader is
183
+ trying to hit. The ::before below is that target: it reaches
184
+ --spacing-4 past the button on each side, and a click on it is a click
185
+ on the button -- 24x24 at the default text size, and larger, never
186
+ smaller, for a reader who enlarges their text, since the reach is rem.
187
+ The button's own box is unchanged, so the icon sits exactly where it did
188
+ and the alert is no taller. */
180
189
  .dismiss {
190
+ position: relative;
181
191
  flex: none;
182
192
  display: flex;
183
193
  padding: var(--spacing-0);
@@ -188,9 +198,20 @@ export const alertCSS = css`
188
198
  cursor: pointer;
189
199
  }
190
200
 
201
+ .dismiss::before {
202
+ content: "";
203
+ position: absolute;
204
+ inset: calc(-1 * var(--spacing-4));
205
+ }
206
+
191
207
  /* One token, one painter -- the same invariant accordion.css.js records. */
192
208
  .dismiss:focus-visible {
193
- outline: none;
209
+ /* forced-colors mode does not paint box-shadow, so the ring
210
+ vanishes there; it does paint an outline, in a system colour. This one
211
+ is transparent everywhere else, and the offset lands it on the ring's
212
+ outer band. */
213
+ outline: var(--border-width-2) solid transparent;
214
+ outline-offset: var(--focus-outline-offset);
194
215
  box-shadow: var(--focus-outline-primary);
195
216
  }
196
217
  `;
@@ -54,7 +54,12 @@ export const anchorNavStyles = css`
54
54
  .bd-anchor-nav__dropdown-toggle:focus-visible,
55
55
  .bd-anchor-nav__dropdown-option:focus-visible {
56
56
  /* the one focus ring — see Foundations/Focus */
57
- outline: none;
57
+ /* forced-colors mode does not paint box-shadow, so the ring
58
+ vanishes there; it does paint an outline, in a system colour. This one
59
+ is transparent everywhere else, and the offset lands it on the ring's
60
+ outer band. */
61
+ outline: var(--border-width-2) solid transparent;
62
+ outline-offset: var(--focus-outline-offset);
58
63
  box-shadow: var(--focus-outline-primary);
59
64
  /* No border-radius here, for the reason back.css.js records: the ring is a
60
65
  box-shadow and already follows the shape of what it sits on, and both of
@@ -33,7 +33,12 @@ export const annotationCSS = css`
33
33
  /* the one focus ring — see Foundations/Focus. A two-colour ring whose
34
34
  white inner band keeps it visible on a coloured or dark surface, which
35
35
  a single-colour outline cannot do. */
36
- outline: none;
36
+ /* forced-colors mode does not paint box-shadow, so the ring
37
+ vanishes there; it does paint an outline, in a system colour. This one
38
+ is transparent everywhere else, and the offset lands it on the ring's
39
+ outer band. */
40
+ outline: var(--border-width-2) solid transparent;
41
+ outline-offset: var(--focus-outline-offset);
37
42
  box-shadow: var(--focus-outline-primary);
38
43
  border-radius: var(--focus-outline-radius);
39
44
  }
@@ -146,10 +146,12 @@ export const LayerModel = () =>
146
146
  lede : 'Foundations, Atoms, Components, Modules, Layout, and internal primitives — what each one owns in ' +
147
147
  'this repository, with the rules for adding to them. Derived from the library as it stands, not from a ' +
148
148
  'textbook hierarchy.',
149
- note: html`This page is documentation. It is filed under its own group because
150
- <code>lint:tokens</code> reads the atom tier from a story&rsquo;s <code>title</code>, and
151
- <code>verify:typography</code> builds its population from the <code>Atoms/</code> and
152
- <code>Components/</code> prefixes — so where a page is filed changes what the gates believe.`,
149
+ note: html`This page is documentation, and where it is filed changes nothing the gates
150
+ believe. <code>lint:tokens</code> and <code>verify:typography</code> read each unit&rsquo;s layer
151
+ from <code>scripts/architecture.json</code>, keyed on its source path — not from a story&rsquo;s
152
+ <code>title</code>, which is what they used to read — so a page can be moved between groups
153
+ without changing what is enforced. This one is recorded there as <code>FOUNDATION</code>; see
154
+ <em>Where classification lives</em> below.`,
153
155
  children: html`
154
156
  ${refSection({ name: 'The six layers', meta: 'what belongs where', children: layerTable() })}
155
157
 
@@ -1,4 +1,4 @@
1
- import { LitElement, html } from 'lit';
1
+ import { LitElement, html, nothing } from 'lit';
2
2
  // Installs the design tokens into document scope; see src/tokens/tokens.js
3
3
  import '../../tokens/tokens.js';
4
4
  import { avatarCSS } from './avatar.css.js';
@@ -8,9 +8,10 @@ export class BdAvatar extends LitElement {
8
8
  static styles = [avatarCSS];
9
9
 
10
10
  static properties = {
11
- src : { type: String },
12
- name: { type: String },
13
- size: { type: String, reflect: true }
11
+ src : { type: String },
12
+ name : { type: String },
13
+ size : { type: String, reflect: true },
14
+ _failed: { state: true }
14
15
  };
15
16
 
16
17
  constructor() {
@@ -23,17 +24,42 @@ export class BdAvatar extends LitElement {
23
24
  willUpdate(changed) {
24
25
  // small / default / large still resolve; see shared/prop-vocabulary.js
25
26
  if (changed.has('size')) this.size = resolveSize(this.size, 'md');
27
+ // a new image gets its own chance to load
28
+ if (changed.has('src')) this._failed = false;
26
29
  }
27
30
 
31
+ /* The first letter of each word, at most two, upper-cased. name can be
32
+ null -- a removed attribute sets it so -- and used to throw on split. */
33
+ get _initials() {
34
+ return (this.name ?? '').trim()
35
+ .split(/\s+/)
36
+ .map(w => w[0] || '')
37
+ .join('')
38
+ .slice(0, 2)
39
+ .toUpperCase();
40
+ }
41
+
42
+ /* THE FALLBACKS.
43
+ An image that fails to load used to stay on screen as an empty circle;
44
+ it now falls back to the initials, as having no src does.
45
+
46
+ With no name there is nothing to say, so the avatar is hidden from
47
+ assistive technology instead of being announced: it used to be an img
48
+ named "Avatar", which tells a screen reader user only that a picture is
49
+ there, on every avatar in a list. */
28
50
  render() {
51
+ const name = (this.name ?? '').trim();
52
+ const showImage = this.src && !this._failed;
29
53
  return html`
30
- <span class="avatar" role="img" aria-label=${this.name || 'Avatar'}>
31
- ${this.src
32
- ? html`<img src=${this.src} alt="" />`
33
- : html`${this.name.split(' ').map(w => w[0] || '')
34
- .join('')
35
- .slice(0, 2)
36
- .toUpperCase()}`}
54
+ <span
55
+ class="avatar"
56
+ role=${name ? 'img' : nothing}
57
+ aria-label=${name || nothing}
58
+ aria-hidden=${name ? nothing : 'true'}
59
+ >
60
+ ${showImage
61
+ ? html`<img src=${this.src} alt="" @error=${() => { this._failed = true; }} />`
62
+ : this._initials}
37
63
  </span>
38
64
  `;
39
65
  }