@repobit/dex-system-design 0.25.12 → 1.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 (336) hide show
  1. package/CHANGELOG.md +204 -0
  2. package/README.md +131 -8
  3. package/package.json +96 -13
  4. package/schemas/component-manifest.json +3294 -405
  5. package/schemas/manifest-omissions.json +173 -0
  6. package/src/blog/src/breakpoints.js +6 -6
  7. package/src/blog/src/content/blog-atoms-showcase.js +1 -1
  8. package/src/blog/src/content/blog-page-layout.js +2 -2
  9. package/src/blog/src/lib/article-toc.js +7 -7
  10. package/src/blog/src/shell/blog-shell.js +1 -1
  11. package/src/blog/src/tokens/blog.js +2 -2
  12. package/src/blog/src/tokens/core.js +34 -35
  13. package/src/blog/src/tokens/legacy.js +0 -9
  14. package/src/blog/tokens/blog.js +2 -2
  15. package/src/blog/tokens/core.js +34 -35
  16. package/src/blog/tokens/legacy.js +0 -9
  17. package/src/blog/tokens.css +36 -46
  18. package/src/components/accordion/accordion-bg.css.js +83 -59
  19. package/src/components/accordion/accordion-bg.js +29 -10
  20. package/src/components/accordion/accordion-bg.stories.js +67 -67
  21. package/src/components/accordion/accordion-keyboard.js +80 -0
  22. package/src/components/accordion/accordion.css.js +142 -80
  23. package/src/components/accordion/accordion.js +37 -10
  24. package/src/components/accordion/accordion.stories.js +7 -7
  25. package/src/components/agent-endpoints/agent-endpoints.css.js +36 -39
  26. package/src/components/agent-endpoints/agent-endpoints.js +30 -20
  27. package/src/components/agent-endpoints/agent-endpoints.stories.js +1 -1
  28. package/src/components/ai-guardian-demo.stories.js +91 -91
  29. package/src/components/alert/alert.css.js +198 -0
  30. package/src/components/alert/alert.js +103 -0
  31. package/src/components/alert/alert.stories.js +206 -0
  32. package/src/components/anchor/anchor-nav.css.js +213 -101
  33. package/src/components/anchor/anchor-nav.js +26 -40
  34. package/src/components/anchor/anchor.stories.js +22 -12
  35. package/src/components/annotation/annotation.css.js +58 -0
  36. package/src/components/annotation/annotation.js +67 -0
  37. package/src/components/annotation/annotation.stories.js +63 -0
  38. package/src/components/architecture.stories.js +285 -0
  39. package/src/components/atoms.stories.js +342 -0
  40. package/src/components/avatar/avatar.css.js +67 -0
  41. package/src/components/avatar/avatar.js +42 -0
  42. package/src/components/avatar/avatar.stories.js +95 -0
  43. package/src/components/awards/awards-flex.css.js +209 -23
  44. package/src/components/awards/awards-flex.js +66 -7
  45. package/src/components/awards/awards-flex.stories.js +1 -1
  46. package/src/components/awards/{awards-light.stories.js → awards-summary.stories.js} +54 -64
  47. package/src/components/awards/awards.css.js +116 -58
  48. package/src/components/awards/awards.js +102 -28
  49. package/src/components/awards/awards.stories.js +1 -1
  50. package/src/components/back/back.css.js +51 -22
  51. package/src/components/back/back.js +28 -7
  52. package/src/components/back/back.stories.js +9 -3
  53. package/src/components/badge/badge.css.js +158 -46
  54. package/src/components/badge/badge.js +62 -74
  55. package/src/components/badge/badge.stories.js +176 -248
  56. package/src/components/bento-grid/bento-grid.css.js +21 -16
  57. package/src/components/bento-grid/bento-grid.js +16 -4
  58. package/src/components/bento-grid/bento-grid.stories.js +19 -18
  59. package/src/components/bento-grid/bento-item.css.js +52 -28
  60. package/src/components/bento-grid/bento-item.js +2 -2
  61. package/src/components/blockquote/blockquote.css.js +47 -0
  62. package/src/components/blockquote/blockquote.js +29 -0
  63. package/src/components/blockquote/blockquote.stories.js +62 -0
  64. package/src/components/breadcrumb/breadcrumb.css.js +92 -22
  65. package/src/components/breadcrumb/breadcrumb.js +56 -11
  66. package/src/components/button/button.css.js +531 -161
  67. package/src/components/button/button.js +206 -214
  68. package/src/components/button/button.stories.js +322 -174
  69. package/src/components/caption/caption.css.js +21 -0
  70. package/src/components/caption/caption.js +31 -0
  71. package/src/components/caption/caption.stories.js +62 -0
  72. package/src/components/card-features/card-features.css.js +14 -22
  73. package/src/components/card-features/card-features.js +68 -9
  74. package/src/components/card-features/card-features.stories.js +11 -11
  75. package/src/components/cards/card.css.js +60 -81
  76. package/src/components/cards/card.js +56 -25
  77. package/src/components/cards/card.stories.js +39 -39
  78. package/src/components/carousel/carousel.css.js +93 -99
  79. package/src/components/carousel/carousel.js +32 -4
  80. package/src/components/checkbox/checkbox.css.js +111 -93
  81. package/src/components/checkbox/checkbox.js +64 -90
  82. package/src/components/checkbox/checkbox.stories.js +96 -29
  83. package/src/components/code/code.css.js +70 -0
  84. package/src/components/code/code.js +40 -0
  85. package/src/components/code/code.stories.js +73 -0
  86. package/src/components/compare/compare.css.js +179 -43
  87. package/src/components/compare/compare.js +52 -25
  88. package/src/components/compare/compare.stories.js +61 -4
  89. package/src/components/comparison-panel/comparison-panel.css.js +38 -51
  90. package/src/components/comparison-panel/comparison-panel.js +5 -4
  91. package/src/components/comparison-panel/comparison-panel.stories.js +1 -1
  92. package/src/components/compatibility-table/compatibility-table.css.js +180 -80
  93. package/src/components/compatibility-table/compatibility-table.js +37 -9
  94. package/src/components/control-alignment.stories.js +393 -0
  95. package/src/components/cta-banner/cta-banner.css.js +41 -13
  96. package/src/components/cta-banner/cta-banner.js +6 -5
  97. package/src/components/cta-banner/cta-banner.stories.js +43 -98
  98. package/src/components/display/display.css.js +25 -1
  99. package/src/components/display/display.js +46 -13
  100. package/src/components/display/display.stories.js +270 -40
  101. package/src/components/divider/divider-horizontal.js +21 -5
  102. package/src/components/divider/divider-vertical.js +15 -7
  103. package/src/components/divider/divider.css.js +2 -2
  104. package/src/components/divider/divider.stories.js +38 -34
  105. package/src/components/dropdown/dropdown.css.js +93 -126
  106. package/src/components/dropdown/dropdown.js +114 -34
  107. package/src/components/dropdown/dropdown.stories.js +56 -24
  108. package/src/components/features/features.css.js +24 -11
  109. package/src/components/features/features.js +7 -3
  110. package/src/components/features/features.stories.js +37 -37
  111. package/src/components/features-tab/features-tab.css.js +19 -8
  112. package/src/components/features-tab/features-tab.js +6 -5
  113. package/src/components/features-tab/features-tab.stories.js +23 -23
  114. package/src/components/fieldset/fieldset.css.js +30 -0
  115. package/src/components/fieldset/fieldset.js +28 -0
  116. package/src/components/fieldset/fieldset.stories.js +84 -0
  117. package/src/components/footer/footer-links-group.css.js +10 -14
  118. package/src/components/footer/footer-links-group.js +4 -3
  119. package/src/components/footer/footer-lp.css.js +59 -30
  120. package/src/components/footer/footer-lp.js +17 -12
  121. package/src/components/footer/footer-lp.stories.js +63 -75
  122. package/src/components/footer/footer-nav-menu.css.js +26 -4
  123. package/src/components/footer/footer-nav-menu.js +3 -2
  124. package/src/components/footer/footer.css.js +146 -264
  125. package/src/components/footer/footer.js +176 -106
  126. package/src/components/footer/footer.stories.js +9 -9
  127. package/src/components/footer/localeMap.js +1 -1
  128. package/src/components/grid/grid.css.js +1 -1
  129. package/src/components/grid/grid.js +49 -7
  130. package/src/components/grid/grid.stories.js +111 -0
  131. package/src/components/header/header-code.css.js +61 -51
  132. package/src/components/header/header-code.js +28 -14
  133. package/src/components/header/header-code.stories.js +5 -5
  134. package/src/components/header/header.css.js +655 -176
  135. package/src/components/header/header.js +269 -36
  136. package/src/components/header/header.stories.js +841 -18
  137. package/src/components/heading/heading.css.js +14 -17
  138. package/src/components/heading/heading.js +48 -33
  139. package/src/components/heading/heading.stories.js +27 -25
  140. package/src/components/help-text/help-text.css.js +21 -0
  141. package/src/components/help-text/help-text.js +25 -0
  142. package/src/components/help-text/help-text.stories.js +66 -0
  143. package/src/components/highlight/highlight.css.js +86 -64
  144. package/src/components/highlight/highlight.js +18 -27
  145. package/src/components/highlight/highlight.stories.js +14 -3
  146. package/src/components/icons/analysis-icon.js +6 -16
  147. package/src/components/icons/arrow-down-icon.js +6 -19
  148. package/src/components/icons/arrow-icon.js +44 -0
  149. package/src/components/icons/arrow-right-icon.js +30 -23
  150. package/src/components/icons/arrow-up-icon.js +19 -18
  151. package/src/components/icons/bd-ai-icon.js +1 -1
  152. package/src/components/icons/brand-marks.stories.js +279 -0
  153. package/src/components/icons/brand-signature-icon.js +42 -0
  154. package/src/components/icons/check-icon.js +27 -0
  155. package/src/components/icons/circle-info-icon.js +33 -0
  156. package/src/components/icons/close-icon.js +6 -18
  157. package/src/components/icons/family-icon.js +8 -20
  158. package/src/components/icons/globe-icon.js +6 -18
  159. package/src/components/icons/guide-icon.js +6 -18
  160. package/src/components/icons/icon-element.js +99 -0
  161. package/src/components/icons/icons.js +36 -0
  162. package/src/components/icons/icons.stories.js +184 -52
  163. package/src/components/icons/individual-icon.js +6 -18
  164. package/src/components/icons/laurel-icon.js +9 -19
  165. package/src/components/icons/machine-learning-icon.js +6 -17
  166. package/src/components/icons/marks.js +41 -0
  167. package/src/components/icons/minus-icon.js +7 -21
  168. package/src/components/icons/missing-icon.js +52 -0
  169. package/src/components/icons/plus-icon.js +7 -21
  170. package/src/components/icons/quote-icon.js +19 -19
  171. package/src/components/image/image.css.js +72 -25
  172. package/src/components/image/image.js +11 -6
  173. package/src/components/image/image.stories.js +2 -2
  174. package/src/components/input/custom-form.stories.js +214 -62
  175. package/src/components/input/input-clipboard.css.js +51 -144
  176. package/src/components/input/input-clipboard.js +31 -15
  177. package/src/components/input/input.css.js +8 -146
  178. package/src/components/input/input.js +93 -38
  179. package/src/components/install-options/install-options.css.js +84 -77
  180. package/src/components/install-options/install-options.js +33 -30
  181. package/src/components/install-options/install-options.stories.js +3 -3
  182. package/src/components/label/label.css.js +35 -0
  183. package/src/components/label/label.js +38 -0
  184. package/src/components/label/label.stories.js +82 -0
  185. package/src/components/light-carousel/light-carousel.css.js +111 -63
  186. package/src/components/light-carousel/light-carousel.js +85 -11
  187. package/src/components/light-carousel/light-carousel.stories.js +126 -82
  188. package/src/components/link/link.css.js +150 -99
  189. package/src/components/link/link.js +86 -11
  190. package/src/components/link/link.stories.js +124 -30
  191. package/src/components/list/list-item/list-item.css.js +74 -22
  192. package/src/components/list/list-item/list-item.js +32 -10
  193. package/src/components/list/list-item/list-item.stories.js +23 -23
  194. package/src/components/list/list.css.js +8 -2
  195. package/src/components/list/list.js +3 -2
  196. package/src/components/list/list.stories.js +222 -0
  197. package/src/components/modal/modal.css.js +114 -24
  198. package/src/components/modal/modal.js +83 -7
  199. package/src/components/modal/modal.stories.js +9 -9
  200. package/src/components/overview/overview.css.js +19 -14
  201. package/src/components/overview/overview.js +6 -5
  202. package/src/components/overview/overview.stories.js +10 -10
  203. package/src/components/page-switcher/page-switcher.css.js +97 -40
  204. package/src/components/page-switcher/page-switcher.js +28 -5
  205. package/src/components/page-switcher/page-switcher.stories.js +95 -0
  206. package/src/components/paragraph/paragraph.css.js +15 -10
  207. package/src/components/paragraph/paragraph.js +41 -44
  208. package/src/components/paragraph/paragraph.stories.js +56 -21
  209. package/src/components/picture/picture.css.js +103 -44
  210. package/src/components/picture/picture.js +100 -30
  211. package/src/components/picture/picture.stories.js +1 -1
  212. package/src/components/pricing-cards/new-pricing-card.js +3 -3
  213. package/src/components/pricing-cards/new-pricing.css.js +24 -15
  214. package/src/components/pricing-cards/pricing-card-actions.css.js +1 -1
  215. package/src/components/pricing-cards/pricing-card-actions.js +3 -4
  216. package/src/components/pricing-cards/pricing-card-container.css.js +3 -3
  217. package/src/components/pricing-cards/pricing-card-container.js +3 -2
  218. package/src/components/pricing-cards/pricing-card-header.css.js +10 -8
  219. package/src/components/pricing-cards/pricing-card-header.js +6 -7
  220. package/src/components/pricing-cards/pricing-card-pricing.css.js +16 -9
  221. package/src/components/pricing-cards/pricing-card-pricing.js +8 -6
  222. package/src/components/pricing-cards/pricing-card-show-more.css.js +11 -3
  223. package/src/components/pricing-cards/pricing-card-show-more.js +8 -3
  224. package/src/components/pricing-cards/pricing-card.css.js +244 -190
  225. package/src/components/pricing-cards/pricing-card.js +54 -70
  226. package/src/components/pricing-cards/pricing-feature-item.css.js +25 -8
  227. package/src/components/pricing-cards/pricing-feature-item.js +8 -3
  228. package/src/components/process-steps/process-steps.css.js +26 -14
  229. package/src/components/process-steps/process-steps.js +23 -6
  230. package/src/components/process-steps/process-steps.stories.js +1 -1
  231. package/src/components/progress/progress.css.js +80 -0
  232. package/src/components/progress/progress.js +42 -0
  233. package/src/components/progress/progress.stories.js +79 -0
  234. package/src/components/quick-answer/quick-answer.css.js +75 -13
  235. package/src/components/quick-answer/quick-answer.js +8 -3
  236. package/src/components/radio/radio.css.js +92 -128
  237. package/src/components/radio/radio.js +106 -127
  238. package/src/components/radio/radio.stories.js +54 -19
  239. package/src/components/review/review-grid.css.js +5 -6
  240. package/src/components/review/review-grid.js +14 -11
  241. package/src/components/review/review.css.js +11 -6
  242. package/src/components/review/review.js +3 -8
  243. package/src/components/shared/ensemble.css.js +93 -0
  244. package/src/components/shared/form-field.css.js +206 -0
  245. package/src/components/shared/prop-vocabulary.js +48 -0
  246. package/src/components/shared/token-scales.js +306 -0
  247. package/src/components/skeleton/skeleton.css.js +34 -0
  248. package/src/components/skeleton/skeleton.js +32 -0
  249. package/src/components/skeleton/skeleton.stories.js +70 -0
  250. package/src/components/spinner/spinner.css.js +62 -0
  251. package/src/components/spinner/spinner.js +38 -0
  252. package/src/components/spinner/spinner.stories.js +92 -0
  253. package/src/components/spotlight-section/spotlight-section.css.js +14 -13
  254. package/src/components/spotlight-section/spotlight-section.js +42 -39
  255. package/src/components/switch/switch.css.js +103 -0
  256. package/src/components/switch/switch.js +44 -0
  257. package/src/components/switch/switch.stories.js +86 -0
  258. package/src/components/tab-list/content-switcher.stories.js +189 -0
  259. package/src/components/tab-list/tab-list.css.js +250 -0
  260. package/src/components/tab-list/tab-list.js +184 -0
  261. package/src/components/tab-list/tab-list.stories.js +221 -0
  262. package/src/components/tabs/tabs.css.js +14 -123
  263. package/src/components/tabs/tabs.js +16 -19
  264. package/src/components/tabs/tabs.stories.js +95 -95
  265. package/src/components/tag/tag.css.js +54 -0
  266. package/src/components/tag/tag.js +32 -0
  267. package/src/components/tag/tag.stories.js +126 -0
  268. package/src/components/terminal/terminal-message.css.js +164 -60
  269. package/src/components/terminal/terminal-message.js +5 -5
  270. package/src/components/terminal/terminal-message.stories.js +70 -1
  271. package/src/components/termsOfUse/terms.css.js +25 -20
  272. package/src/components/termsOfUse/terms.js +13 -9
  273. package/src/components/termsOfUse/terms.stories.js +1 -1
  274. package/src/components/textarea/textarea.css.js +51 -0
  275. package/src/components/textarea/textarea.js +136 -0
  276. package/src/components/textarea/textarea.stories.js +191 -0
  277. package/src/components/tooltip/tooltip.css.js +75 -0
  278. package/src/components/tooltip/tooltip.js +156 -0
  279. package/src/components/tooltip/tooltip.stories.js +161 -0
  280. package/src/components/trust-panel/trust-panel.css.js +85 -33
  281. package/src/components/trust-panel/trust-panel.js +18 -10
  282. package/src/components/trust-panel/trust-panel.stories.js +1 -1
  283. package/src/components/ultimate-security-demo.stories.js +431 -0
  284. package/src/components/video/video.css.js +17 -0
  285. package/src/components/video/video.js +40 -0
  286. package/src/components/video/video.stories.js +106 -0
  287. package/src/components/video-player/video-player.css.js +67 -11
  288. package/src/components/video-player/video-player.js +35 -4
  289. package/src/components/video-player/video-player.stories.js +1 -1
  290. package/src/components/visual-alignment.stories.js +411 -0
  291. package/src/components/visually-hidden/visually-hidden.css.js +24 -0
  292. package/src/components/visually-hidden/visually-hidden.js +16 -0
  293. package/src/components/visually-hidden/visually-hidden.stories.js +56 -0
  294. package/src/stories/Button.stories.js +17 -17
  295. package/src/stories/Header.stories.js +10 -10
  296. package/src/stories/Page.js +1 -1
  297. package/src/stories/Page.stories.js +6 -6
  298. package/src/tokens/borders.stories.js +339 -0
  299. package/src/tokens/color-responsibilities.stories.js +227 -0
  300. package/src/tokens/dark-derivation.js +309 -0
  301. package/src/tokens/dark-findings.js +197 -0
  302. package/src/tokens/dark-mode.stories.js +207 -0
  303. package/src/tokens/dimension.stories.js +251 -0
  304. package/src/tokens/elevation.stories.js +143 -0
  305. package/src/tokens/focus.stories.js +276 -0
  306. package/src/tokens/fonts.css +20 -20
  307. package/src/tokens/fonts.stories.js +354 -374
  308. package/src/tokens/layout.css +25 -11
  309. package/src/tokens/motion.stories.js +231 -0
  310. package/src/tokens/shape.stories.js +272 -0
  311. package/src/tokens/spacing-rhythm.stories.js +359 -0
  312. package/src/tokens/spacing.stories.js +208 -703
  313. package/src/tokens/story-chrome.js +503 -0
  314. package/src/tokens/surfaces.stories.js +224 -0
  315. package/src/tokens/text-on-surface.stories.js +164 -0
  316. package/src/tokens/token-map.js +220 -0
  317. package/src/tokens/token-map.stories.js +257 -0
  318. package/src/tokens/token-purposes.js +266 -0
  319. package/src/tokens/tokens-grid.stories.js +388 -900
  320. package/src/tokens/tokens.css +1633 -1045
  321. package/src/tokens/tokens.js +1130 -492
  322. package/src/tokens/tokens.stories.js +137 -47
  323. package/src/tokens/type-ceiling-words.js +299 -0
  324. package/src/tokens/typography.stories.js +1003 -965
  325. package/src/tokens/vertical-rhythm.stories.js +224 -0
  326. package/src/components/awards/awards-icon.js +0 -56
  327. package/src/components/awards/awards-light.js +0 -240
  328. package/src/components/banner/banner.js +0 -60
  329. package/src/components/banner/banner.stories.js +0 -51
  330. package/src/components/button/icons.js +0 -24
  331. package/src/components/input/index.js +0 -0
  332. package/src/components/light-carousel/light-carousel-simple.css.js +0 -183
  333. package/src/components/light-carousel/light-carousel-simple.js +0 -74
  334. package/src/tokens/colors.js +0 -121
  335. package/src/tokens/typography.css.js +0 -207
  336. package/src/tokens/typography.js +0 -0
@@ -0,0 +1,70 @@
1
+ import { html } from 'lit';
2
+ import './skeleton.js';
3
+
4
+ export default {
5
+ title : 'Atoms/Skeleton',
6
+ tags : ['autodocs'],
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component: `
11
+ **BdSkeleton** is a placeholder for content that has not arrived yet, shaped
12
+ roughly like the thing it stands in for.
13
+
14
+ ### Usage
15
+ \`\`\`html
16
+ <bd-skeleton></bd-skeleton>
17
+ <bd-skeleton lines="3"></bd-skeleton>
18
+ <bd-skeleton shape="title"></bd-skeleton>
19
+ <bd-skeleton shape="circle"></bd-skeleton>
20
+ \`\`\`
21
+
22
+ ### Props
23
+ | Prop | Values | Default |
24
+ |---|---|---|
25
+ | \`lines\` | number of bars | \`1\` |
26
+ | \`shape\` | \`line\`, \`title\`, \`circle\` | \`line\` |
27
+
28
+ ### Notes
29
+ With more than one line the last bar is drawn at 60% width, because real
30
+ paragraphs do not end flush with the column.
31
+
32
+ \`shape="circle"\` stands in for an avatar, \`title\` for a heading.
33
+
34
+ ### It is invisible to assistive tech, on purpose
35
+ The whole thing carries \`aria-hidden="true"\`, so a screen reader is not read a
36
+ list of meaningless bars.
37
+
38
+ That means **the skeleton alone tells a screen reader user nothing is
39
+ happening.** Pair it with a live region — an \`aria-busy\` on the container, or a
40
+ \`<bd-spinner>\` with its own label — or the wait is silent for them.
41
+
42
+ It respects \`prefers-reduced-motion\`: the shimmer stops and the bars settle to
43
+ a static tint.
44
+ `
45
+ }
46
+ }
47
+ },
48
+ argTypes: {
49
+ lines: {
50
+ control : 'number',
51
+ description: 'How many bars to draw. Above one, the last is shortened to 60%.',
52
+ table : { type: { summary: 'number' }, defaultValue: { summary: "1" }, category: 'Structure' }
53
+ },
54
+ shape: {
55
+ control : { type: 'select' },
56
+ options : ['line', 'title', 'circle'],
57
+ description: 'What the placeholder stands in for.',
58
+ table : { type: { summary: 'string' }, defaultValue: { summary: "line" }, category: 'Appearance' }
59
+ }
60
+ }
61
+ };
62
+
63
+ export const Lines = () => html`
64
+ <bd-skeleton lines="3"></bd-skeleton>
65
+ `;
66
+
67
+ export const Shapes = () => html`
68
+ <bd-skeleton shape="title"></bd-skeleton>
69
+ <bd-skeleton shape="circle"></bd-skeleton>
70
+ `;
@@ -0,0 +1,62 @@
1
+ import { css } from 'lit';
2
+
3
+ /** Styled entirely from design tokens — see npm run lint:tokens. */
4
+ export const spinnerCSS = css`
5
+ /* The arc and the track are component-local properties rather than values
6
+ written into the rule, because a spinner is often the one thing on a
7
+ coloured panel and was previously pinned to blue-500 on neutral-200 —
8
+ 3.5:1 against a white page, and invisible on a blue one. Set them on the
9
+ element to place it anywhere, or use surface="dark" for the common case.
10
+
11
+ bd-button does not use this element. Its loading mark is drawn inline
12
+ because it needs to be em-sized to track the button's own type scale,
13
+ currentColor to follow the variant's label, and decorative rather than
14
+ announced — the button already carries aria-busy. Three different
15
+ requirements from this component's one, so they stay separate. */
16
+ :host {
17
+ display: inline-flex;
18
+ --bd-spinner-arc: var(--color-action-primary);
19
+ --bd-spinner-track: var(--color-border-subtle);
20
+ /* no role: the two roles at blue-100 are the heavier tints of the brand
21
+ and info families -- a badge shade. This is a decorative pulse behind a
22
+ spinning arc, which is not that job. Note the name says "fill" and .pulse
23
+ reads it as a background, so the gate's kind inference is off by a
24
+ category here; the classification does not depend on it. */
25
+ --bd-spinner-pulse-fill: var(--color-blue-100);
26
+ }
27
+
28
+ :host([surface='dark']) {
29
+ --bd-spinner-arc: var(--color-neutral-0);
30
+ --bd-spinner-track: color-mix(in srgb, var(--color-neutral-0) 30%, transparent);
31
+ /* no role: an alpha value, which an opaque palette cannot express at all --
32
+ the same class as the scrim in modal.css.js. */
33
+ --bd-spinner-pulse-fill: color-mix(in srgb, var(--color-neutral-0) 30%, transparent);
34
+ }
35
+
36
+ .spinner {
37
+ width: var(--dimension-24);
38
+ height: var(--dimension-24);
39
+ border: var(--border-width-2) solid var(--bd-spinner-track);
40
+ border-top-color: var(--bd-spinner-arc);
41
+ border-radius: var(--radius-full);
42
+ animation: bd-spin var(--transition-duration-slower) var(--transition-easing-linear) infinite;
43
+ }
44
+
45
+ :host([size='sm']) .spinner { width: var(--dimension-16); height: var(--dimension-16); }
46
+ :host([size='lg']) .spinner { width: var(--dimension-40); height: var(--dimension-40); }
47
+
48
+ @keyframes bd-spin { to { transform: rotate(360deg); } }
49
+
50
+ /* a spinner that cannot spin should still say something, so fall back to a
51
+ pulse rather than freezing solid */
52
+ @media (prefers-reduced-motion: reduce) {
53
+ .spinner {
54
+ animation: bd-pulse var(--transition-duration-slower) var(--transition-easing-smooth) infinite alternate;
55
+ border-top-color: var(--bd-spinner-track);
56
+ background: var(--bd-spinner-pulse-fill);
57
+ }
58
+ @keyframes bd-pulse { to { opacity: var(--opacity-pulse); } }
59
+ }
60
+ `;
61
+
62
+ export default spinnerCSS;
@@ -0,0 +1,38 @@
1
+ import { LitElement, html } from 'lit';
2
+ // Installs the design tokens into document scope; see src/tokens/tokens.js
3
+ import '../../tokens/tokens.js';
4
+ import { spinnerCSS } from './spinner.css.js';
5
+ import { resolveSize } from '../shared/prop-vocabulary.js';
6
+
7
+ export class BdSpinner extends LitElement {
8
+ static styles = [spinnerCSS];
9
+
10
+ static properties = {
11
+ size : { type: String, reflect: true },
12
+ label : { type: String },
13
+ /* The surface the spinner sits on. Its default arc and track were both
14
+ chosen against a white page, so on a filled panel it all but disappears.
15
+ Same attribute, same meaning, as on bd-button. */
16
+ surface: { type: String, reflect: true }
17
+ };
18
+
19
+ constructor() {
20
+ super();
21
+ this.size = 'md';
22
+ this.label = 'Loading';
23
+ this.surface = 'light';
24
+ }
25
+
26
+ willUpdate(changed) {
27
+ // small / default / large still resolve; see shared/prop-vocabulary.js
28
+ if (changed.has('size')) this.size = resolveSize(this.size, 'md');
29
+ }
30
+
31
+ render() {
32
+ return html`
33
+ <span class="spinner" role="status" aria-label=${this.label}></span>
34
+ `;
35
+ }
36
+ }
37
+
38
+ customElements.define('bd-spinner', BdSpinner);
@@ -0,0 +1,92 @@
1
+ import { html } from 'lit';
2
+ import './spinner.js';
3
+ import '../button/button.js';
4
+
5
+ export default {
6
+ title : 'Atoms/Spinner',
7
+ tags : ['autodocs'],
8
+ parameters: {
9
+ docs: {
10
+ description: {
11
+ component: `
12
+ **BdSpinner** is an indeterminate loading indicator — for work whose length is
13
+ unknown. When you know the proportion done, use \`<bd-progress>\` instead.
14
+
15
+ ### Usage
16
+ \`\`\`html
17
+ <bd-spinner></bd-spinner>
18
+ <bd-spinner size="sm"></bd-spinner>
19
+ <bd-spinner size="lg" label="Checking your licence"></bd-spinner>
20
+ \`\`\`
21
+
22
+ ### Props
23
+ | Prop | Values | Default |
24
+ |---|---|---|
25
+ | \`size\` | \`small\`, \`default\`, \`large\` | \`default\` |
26
+ | \`label\` | the accessible name | \`Loading\` |
27
+
28
+ ### Accessibility
29
+ It carries \`role="status"\` with \`aria-label\` from \`label\`, so the wait is
30
+ announced politely rather than interrupting. Give it a specific \`label\` where
31
+ you can — "Checking your licence" is more use than the default "Loading".
32
+
33
+ Under \`prefers-reduced-motion\` it stops spinning and pulses instead, so it
34
+ still reads as active without rotating.
35
+
36
+ ### Note on colour
37
+ The spinner's track and head are fixed at \`--color-neutral-200\` and
38
+ \`--color-blue-500\`, and its sizes are fixed pixel steps. That makes it wrong
39
+ for use on a coloured surface or inside a filled button, where the mark needs
40
+ to follow the surrounding text colour — \`bd-button\`'s loading state draws its
41
+ own \`currentColor\` spinner for that reason. A \`currentColor\` mode here would
42
+ let the two converge.
43
+ `
44
+ }
45
+ }
46
+ },
47
+ argTypes: {
48
+ size: {
49
+ control : { type: 'select' },
50
+ options : ['small', 'default', 'large'],
51
+ description: 'Diameter of the spinner.',
52
+ table : { type: { summary: 'string' }, defaultValue: { summary: "default" }, category: 'Appearance' }
53
+ },
54
+ label: {
55
+ control : 'text',
56
+ description: 'The accessible name, announced politely. Prefer something specific to the task.',
57
+ table : { type: { summary: 'string' }, defaultValue: { summary: "Loading" }, category: 'Accessibility' }
58
+ }
59
+ }
60
+ };
61
+
62
+ export const Sizes = () => html`
63
+ <bd-spinner size="sm"></bd-spinner>
64
+ <bd-spinner></bd-spinner>
65
+ <bd-spinner size="lg"></bd-spinner>
66
+ `;
67
+
68
+ /**
69
+ * On a filled panel the default arc — `--color-action-primary` on a
70
+ * `--color-border-subtle` track — is nearly invisible, because both were
71
+ * chosen against a white page. `surface="dark"` switches them to white and a
72
+ * translucent white, the same attribute `bd-button` uses to say the same
73
+ * thing.
74
+ *
75
+ * The first spinner below is the default and shows what opting out looks like;
76
+ * the second and third opt in. The button draws its own `currentColor` mark
77
+ * rather than composing this element — it needs to be em-sized to the button's
78
+ * type scale and decorative rather than announced — so it is here as the thing
79
+ * the opted-in spinner should match.
80
+ */
81
+ export const OnDarkSurface = () => html`
82
+ <div
83
+ style="display: flex; align-items: center; gap: var(--spacing-24);
84
+ padding: var(--spacing-24); border-radius: var(--radius-md);
85
+ background: var(--color-blue-600)"
86
+ >
87
+ <bd-spinner label="Default, on a panel it was not designed for"></bd-spinner>
88
+ <bd-spinner surface="dark" size="sm"></bd-spinner>
89
+ <bd-spinner surface="dark"></bd-spinner>
90
+ <bd-button variant="primary" surface="dark" loading>Loading</bd-button>
91
+ </div>
92
+ `;
@@ -1,15 +1,15 @@
1
- import { css } from "lit";
1
+ import { css, unsafeCSS } from "lit";
2
+ import { below } from "../shared/token-scales.js";
2
3
 
3
4
  export default css`
4
5
  :host {
5
6
  display: block;
6
- font-family: "Roboto", "roboto-normal-400-fallback", helvetica, ubuntu, roboto, noto, sans-serif;
7
- max-width: 1290px;
8
- margin: 0 auto;
7
+ font-family: var(--typography-fontFamily-sans);
9
8
  }
10
9
 
11
10
  .bd-spotlightsection-container {
12
- background: linear-gradient(87.6deg, var(--color-blue-500) 0%, var(--color-blue-950) 100%);
11
+ /* no role: blue-950 is the gradient's far stop, as on bd-cta-banner. */
12
+ background: linear-gradient(87.6deg, var(--color-surface-brand) 0%, var(--color-blue-950) 100%);
13
13
  border-radius: var(--radius-2xl);
14
14
  padding: var(--spacing-48);
15
15
  box-sizing: border-box;
@@ -27,20 +27,19 @@ export default css`
27
27
  align-items: flex-start;
28
28
  gap: var(--spacing-16);
29
29
  flex: 1 1 320px;
30
- max-width: 560px;
30
+ max-width: var(--content-width-readable);
31
31
  }
32
32
 
33
33
  .bd-spotlightsection-title {
34
34
  display: block;
35
35
  margin: 0;
36
- color: var(--color-neutral-0, #fff);
37
- line-height: var(--typography-lineHeight-tight, 1.15);
36
+ color: var(--color-text-inverse);
38
37
  }
39
38
 
40
39
  .bd-spotlightsection-icon {
41
40
  display: flex;
42
41
  align-items: center;
43
- color: var(--color-neutral-0, #fff);
42
+ color: var(--color-text-inverse);
44
43
  margin-bottom: var(--spacing-4);
45
44
  }
46
45
 
@@ -55,6 +54,7 @@ export default css`
55
54
  left column is a mirror of the right one, not a different layout. */
56
55
  .bd-spotlightsection-icon ::slotted(*) {
57
56
  display: block;
57
+ /* no token: a logo's width cap, set by the artwork rather than a scale. */
58
58
  max-width: 160px;
59
59
  width: 100%;
60
60
  height: auto;
@@ -62,7 +62,9 @@ export default css`
62
62
 
63
63
  .bd-spotlightsection-description {
64
64
  margin: 0;
65
- color: rgba(255, 255, 255, 0.65);
65
+ /* Full inverse ink. White at 65% measured 2.6:1 on the brand end of the
66
+ gradient, and bd-p's color="inverse" already painted over it. */
67
+ color: var(--color-text-inverse);
66
68
  }
67
69
 
68
70
  .bd-spotlightsection-buttons {
@@ -73,7 +75,7 @@ export default css`
73
75
  margin-top: var(--spacing-4);
74
76
  }
75
77
 
76
- @media (max-width: 699px) {
78
+ @media ${unsafeCSS(below('md'))} {
77
79
  .bd-spotlightsection-container {
78
80
  padding: var(--spacing-28) var(--spacing-24);
79
81
  flex-direction: column;
@@ -99,7 +101,6 @@ export default css`
99
101
  .bd-spotlightsection-description--large {
100
102
  display: block;
101
103
  margin: 0;
102
- color: var(--color-neutral-0, #fff);
103
- line-height: var(--typography-lineHeight-tight, 1.15);
104
+ color: var(--color-text-inverse);
104
105
  }
105
106
  `;
@@ -3,6 +3,7 @@ import { tokens } from "../../tokens/tokens.js";
3
3
  import "../heading/heading.js";
4
4
  import "../paragraph/paragraph.js";
5
5
  import spotlightSectionCSS from "./spotlight-section.css.js";
6
+ import { ensembleCSS } from "../shared/ensemble.css.js";
6
7
 
7
8
 
8
9
  class BdSpotlightSection extends LitElement {
@@ -15,7 +16,7 @@ class BdSpotlightSection extends LitElement {
15
16
  _hasRightButtons: { state: true }
16
17
  };
17
18
 
18
- static styles = [tokens, spotlightSectionCSS];
19
+ static styles = [tokens, ensembleCSS, spotlightSectionCSS];
19
20
 
20
21
  constructor() {
21
22
  super();
@@ -38,50 +39,52 @@ class BdSpotlightSection extends LitElement {
38
39
  const flipped = this._hasLeftIcon;
39
40
 
40
41
  return html`
41
- <div class="bd-spotlightsection-container">
42
- <div class="bd-spotlightsection-left">
43
- <div class="bd-spotlightsection-icon" ?hidden=${!this._hasLeftIcon}>
44
- <slot name="left-icon" @slotchange=${(e) => this._onSlotChange("_hasLeftIcon", e)}></slot>
45
- </div>
42
+ <div class="bd-ensemble">
43
+ <div class="bd-spotlightsection-container">
44
+ <div class="bd-spotlightsection-left">
45
+ <div class="bd-spotlightsection-icon" ?hidden=${!this._hasLeftIcon}>
46
+ <slot name="left-icon" @slotchange=${(e) => this._onSlotChange("_hasLeftIcon", e)}></slot>
47
+ </div>
46
48
 
47
- ${flipped
48
- ? html`
49
- <bd-p kind="large" color="var(--color-neutral-0)" class="bd-spotlightsection-title bd-spotlightsection-title--small">
50
- <slot name="title">${this.title}</slot>
51
- </bd-p>
52
- `
53
- : html`
54
- <bd-h as="h2" fontWeight="400" class="bd-spotlightsection-title">
55
- <slot name="title">${this.title}</slot>
56
- </bd-h>
57
- `}
49
+ ${flipped
50
+ ? html`
51
+ <bd-p kind="large" color="inverse" class="bd-spotlightsection-title bd-spotlightsection-title--small">
52
+ <slot name="title">${this.title}</slot>
53
+ </bd-p>
54
+ `
55
+ : html`
56
+ <bd-h as="h2" fontWeight="normal" class="bd-spotlightsection-title">
57
+ <slot name="title">${this.title}</slot>
58
+ </bd-h>
59
+ `}
58
60
 
59
- <div class="bd-spotlightsection-buttons" ?hidden=${!this._hasLeftButtons}>
60
- <slot name="left-buttons" @slotchange=${(e) => this._onSlotChange("_hasLeftButtons", e)}></slot>
61
+ <div class="bd-spotlightsection-buttons" ?hidden=${!this._hasLeftButtons}>
62
+ <slot name="left-buttons" @slotchange=${(e) => this._onSlotChange("_hasLeftButtons", e)}></slot>
63
+ </div>
61
64
  </div>
62
- </div>
63
65
 
64
- <div class="bd-spotlightsection-side">
65
- <div class="bd-spotlightsection-icon" ?hidden=${!this._hasRightIcon}>
66
- <slot name="icon" @slotchange=${(e) => this._onSlotChange("_hasRightIcon", e)}></slot>
67
- </div>
66
+ <div class="bd-spotlightsection-side">
67
+ <div class="bd-spotlightsection-icon" ?hidden=${!this._hasRightIcon}>
68
+ <slot name="icon" @slotchange=${(e) => this._onSlotChange("_hasRightIcon", e)}></slot>
69
+ </div>
68
70
 
69
- ${this.description
70
- ? flipped
71
- ? html`
72
- <bd-h as="h2" fontWeight="400" color="var(--color-neutral-0)" class="bd-spotlightsection-description bd-spotlightsection-description--large">
73
- <slot name="description">${this.description}</slot>
74
- </bd-h>
75
- `
76
- : html`
77
- <bd-p kind="large" color="var(--color-neutral-0)" class="bd-spotlightsection-description">
78
- <slot name="description">${this.description}</slot>
79
- </bd-p>
80
- `
81
- : nothing}
71
+ ${this.description
72
+ ? flipped
73
+ ? html`
74
+ <bd-h as="h2" fontWeight="normal" color="inverse" class="bd-spotlightsection-description bd-spotlightsection-description--large">
75
+ <slot name="description">${this.description}</slot>
76
+ </bd-h>
77
+ `
78
+ : html`
79
+ <bd-p kind="large" color="inverse" class="bd-spotlightsection-description">
80
+ <slot name="description">${this.description}</slot>
81
+ </bd-p>
82
+ `
83
+ : nothing}
82
84
 
83
- <div class="bd-spotlightsection-buttons" ?hidden=${!this._hasRightButtons}>
84
- <slot name="right-buttons" @slotchange=${(e) => this._onSlotChange("_hasRightButtons", e)}></slot>
85
+ <div class="bd-spotlightsection-buttons" ?hidden=${!this._hasRightButtons}>
86
+ <slot name="right-buttons" @slotchange=${(e) => this._onSlotChange("_hasRightButtons", e)}></slot>
87
+ </div>
85
88
  </div>
86
89
  </div>
87
90
  </div>
@@ -0,0 +1,103 @@
1
+ import { css } from 'lit';
2
+
3
+ /** Styled entirely from design tokens — see npm run lint:tokens. */
4
+ export const switchCSS = css`
5
+ :host { display: inline-flex; }
6
+
7
+ /* The row is the control, matching bd-checkbox and bd-radio: same gap, same
8
+ padding, same type, same inherited weight. This was the label-default
9
+ weight (medium) where those two inherit normal, so a switch label sat
10
+ bolder than a checkbox label on the same line of the same form.
11
+
12
+ Padding rather than a min-height, so the focus ring below insets evenly on
13
+ all four sides. */
14
+ label {
15
+ display: inline-flex;
16
+ align-items: center;
17
+ gap: var(--spacing-8);
18
+ padding: var(--spacing-2);
19
+ font-family: var(--typography-fontFamily-sans);
20
+ /* body-small: sm / normal / 1.5, which is what this already rendered on all
21
+ three axes. Only the axes this rule declares are adopted -- the role also
22
+ carries a family and a tracking, and importing those would change text
23
+ the rule never spoke for. */
24
+ font-size: var(--typography-body-small-fontSize);
25
+ line-height: var(--typography-body-small-lineHeight);
26
+ color: var(--color-text-primary);
27
+ cursor: pointer;
28
+ outline: none;
29
+ }
30
+
31
+ /* the real control stays in the accessibility tree */
32
+ input {
33
+ position: absolute;
34
+ /* no token: 1px is the clip idiom's own measure, not a border. It was
35
+ spelled --border-width-1, which resolves to the same pixel and reads as
36
+ a category error — the lint already sanctions the literal here, as it
37
+ does the -1px below. */
38
+ width: 1px;
39
+ height: 1px;
40
+ margin: -1px;
41
+ overflow: hidden;
42
+ clip-path: inset(50%);
43
+ }
44
+
45
+ /* neutral-400, not neutral-300: off is a state the user has to be able to
46
+ perceive, so 1.4.11 wants 3:1 against the page. neutral-300 measured 2.27
47
+ and neutral-400 measures 3.23 — the same step bd-custom-input already uses
48
+ for the edge of a control. It is also the boundary the white thumb is read
49
+ against, which was failing for the same reason.
50
+ The disabled track below stays lighter; disabled is exempt under 1.4.3. */
51
+ .track {
52
+ position: relative;
53
+ width: var(--dimension-40);
54
+ height: var(--dimension-24);
55
+ background: var(--color-border-default);
56
+ border-radius: var(--radius-full);
57
+ transition: background-color var(--transition-duration-normal) var(--transition-easing-smooth);
58
+ flex: none;
59
+ }
60
+
61
+ .thumb {
62
+ position: absolute;
63
+ top: var(--spacing-2);
64
+ left: var(--spacing-2);
65
+ width: var(--dimension-20);
66
+ height: var(--dimension-20);
67
+ /* the knob on the track, white on both tracks: --color-action-on-fill,
68
+ like the checkbox mark, not the page colour it happens to equal here */
69
+ background: var(--color-action-on-fill);
70
+ border-radius: var(--radius-full);
71
+ box-shadow: var(--shadow-sm);
72
+ transition: transform var(--transition-duration-normal) var(--transition-easing-smooth);
73
+ }
74
+
75
+ :host([checked]) .track { background: var(--color-action-primary); }
76
+
77
+ /* The off track is --color-border-default and this is one step darker. The
78
+ border roles name no hover step — this is the only track in the system
79
+ that hovers — so the primitive stands rather than a text role being
80
+ borrowed for a background or a role being invented for one consumer.
81
+ If a second component ever needs it, that is when it earns a name. */
82
+ label:hover .track { background: var(--color-neutral-500); }
83
+ :host([checked]) label:hover .track { background: var(--color-action-primary-hover); }
84
+ :host([checked]) .thumb { transform: translateX(var(--spacing-16)); }
85
+
86
+ /* the one focus ring — see Foundations/Focus. On the row rather than the
87
+ track, so the target and the indicator are the same shape here as on
88
+ bd-checkbox and bd-radio. */
89
+ label:has(input:focus-visible) {
90
+ box-shadow: var(--focus-outline-primary);
91
+ border-radius: var(--focus-outline-radius);
92
+ }
93
+
94
+ :host([disabled]) label { cursor: not-allowed; color: var(--color-text-subtle); }
95
+ :host([disabled]) label:hover .track,
96
+ :host([disabled]) .track { background: var(--color-border-subtle); }
97
+
98
+ @media (prefers-reduced-motion: reduce) {
99
+ .track, .thumb { transition: none; }
100
+ }
101
+ `;
102
+
103
+ export default switchCSS;
@@ -0,0 +1,44 @@
1
+ import { LitElement, html, nothing } from 'lit';
2
+ // Installs the design tokens into document scope; see src/tokens/tokens.js
3
+ import '../../tokens/tokens.js';
4
+ import { switchCSS } from './switch.css.js';
5
+
6
+ export class BdSwitch extends LitElement {
7
+ static styles = [switchCSS];
8
+
9
+ static properties = {
10
+ checked : { type: Boolean, reflect: true },
11
+ disabled: { type: Boolean, reflect: true },
12
+ label : { type: String },
13
+ name : { type: String }
14
+ };
15
+
16
+ constructor() {
17
+ super();
18
+ this.checked = false;
19
+ this.disabled = false;
20
+ this.label = '';
21
+ }
22
+
23
+ render() {
24
+ return html`
25
+ <label>
26
+ <input
27
+ type="checkbox"
28
+ role="switch"
29
+ name=${this.name || nothing}
30
+ .checked=${this.checked}
31
+ ?disabled=${this.disabled}
32
+ @change=${e => {
33
+ this.checked = e.target.checked;
34
+ this.dispatchEvent(new CustomEvent('bd-change', { detail: this.checked }));
35
+ }}
36
+ />
37
+ <span class="track"><span class="thumb"></span></span>
38
+ <span>${this.label}<slot></slot></span>
39
+ </label>
40
+ `;
41
+ }
42
+ }
43
+
44
+ customElements.define('bd-switch', BdSwitch);