@repobit/dex-system-design 0.25.11 → 0.26.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.
- package/CHANGELOG.md +195 -0
- package/README.md +131 -8
- package/package.json +95 -13
- package/schemas/component-manifest.json +3294 -405
- package/schemas/manifest-omissions.json +173 -0
- package/src/blog/src/breakpoints.js +6 -6
- package/src/blog/src/content/blog-atoms-showcase.js +1 -1
- package/src/blog/src/content/blog-page-layout.js +2 -2
- package/src/blog/src/lib/article-toc.js +7 -7
- package/src/blog/src/shell/blog-shell.js +1 -1
- package/src/blog/src/tokens/blog.js +2 -2
- package/src/blog/src/tokens/core.js +34 -35
- package/src/blog/src/tokens/legacy.js +0 -9
- package/src/blog/tokens/blog.js +2 -2
- package/src/blog/tokens/core.js +34 -35
- package/src/blog/tokens/legacy.js +0 -9
- package/src/blog/tokens.css +36 -46
- package/src/components/accordion/accordion-bg.css.js +83 -59
- package/src/components/accordion/accordion-bg.js +29 -10
- package/src/components/accordion/accordion-bg.stories.js +67 -67
- package/src/components/accordion/accordion-keyboard.js +80 -0
- package/src/components/accordion/accordion.css.js +142 -80
- package/src/components/accordion/accordion.js +37 -10
- package/src/components/accordion/accordion.stories.js +7 -7
- package/src/components/agent-endpoints/agent-endpoints.css.js +36 -39
- package/src/components/agent-endpoints/agent-endpoints.js +30 -20
- package/src/components/agent-endpoints/agent-endpoints.stories.js +1 -1
- package/src/components/ai-guardian-demo.stories.js +91 -91
- package/src/components/alert/alert.css.js +198 -0
- package/src/components/alert/alert.js +103 -0
- package/src/components/alert/alert.stories.js +206 -0
- package/src/components/anchor/anchor-nav.css.js +213 -101
- package/src/components/anchor/anchor-nav.js +26 -40
- package/src/components/anchor/anchor.stories.js +22 -12
- package/src/components/annotation/annotation.css.js +58 -0
- package/src/components/annotation/annotation.js +67 -0
- package/src/components/annotation/annotation.stories.js +63 -0
- package/src/components/architecture.stories.js +285 -0
- package/src/components/atoms.stories.js +342 -0
- package/src/components/avatar/avatar.css.js +67 -0
- package/src/components/avatar/avatar.js +42 -0
- package/src/components/avatar/avatar.stories.js +95 -0
- package/src/components/awards/awards-flex.css.js +209 -23
- package/src/components/awards/awards-flex.js +66 -7
- package/src/components/awards/awards-flex.stories.js +1 -1
- package/src/components/awards/{awards-light.stories.js → awards-summary.stories.js} +54 -64
- package/src/components/awards/awards.css.js +116 -58
- package/src/components/awards/awards.js +102 -28
- package/src/components/awards/awards.stories.js +1 -1
- package/src/components/back/back.css.js +51 -22
- package/src/components/back/back.js +28 -7
- package/src/components/back/back.stories.js +9 -3
- package/src/components/badge/badge.css.js +158 -46
- package/src/components/badge/badge.js +62 -74
- package/src/components/badge/badge.stories.js +176 -248
- package/src/components/bento-grid/bento-grid.css.js +21 -16
- package/src/components/bento-grid/bento-grid.js +16 -4
- package/src/components/bento-grid/bento-grid.stories.js +19 -18
- package/src/components/bento-grid/bento-item.css.js +52 -28
- package/src/components/bento-grid/bento-item.js +2 -2
- package/src/components/blockquote/blockquote.css.js +47 -0
- package/src/components/blockquote/blockquote.js +29 -0
- package/src/components/blockquote/blockquote.stories.js +62 -0
- package/src/components/breadcrumb/breadcrumb.css.js +92 -22
- package/src/components/breadcrumb/breadcrumb.js +56 -11
- package/src/components/button/button.css.js +531 -161
- package/src/components/button/button.js +206 -214
- package/src/components/button/button.stories.js +322 -174
- package/src/components/caption/caption.css.js +21 -0
- package/src/components/caption/caption.js +31 -0
- package/src/components/caption/caption.stories.js +62 -0
- package/src/components/card-features/card-features.css.js +14 -22
- package/src/components/card-features/card-features.js +68 -9
- package/src/components/card-features/card-features.stories.js +11 -11
- package/src/components/cards/card.css.js +60 -81
- package/src/components/cards/card.js +56 -25
- package/src/components/cards/card.stories.js +39 -39
- package/src/components/carousel/carousel.css.js +93 -99
- package/src/components/carousel/carousel.js +32 -4
- package/src/components/checkbox/checkbox.css.js +111 -93
- package/src/components/checkbox/checkbox.js +64 -90
- package/src/components/checkbox/checkbox.stories.js +96 -29
- package/src/components/code/code.css.js +70 -0
- package/src/components/code/code.js +40 -0
- package/src/components/code/code.stories.js +73 -0
- package/src/components/compare/compare.css.js +179 -43
- package/src/components/compare/compare.js +52 -25
- package/src/components/compare/compare.stories.js +61 -4
- package/src/components/comparison-panel/comparison-panel.css.js +38 -51
- package/src/components/comparison-panel/comparison-panel.js +5 -4
- package/src/components/comparison-panel/comparison-panel.stories.js +1 -1
- package/src/components/compatibility-table/compatibility-table.css.js +180 -80
- package/src/components/compatibility-table/compatibility-table.js +37 -9
- package/src/components/control-alignment.stories.js +393 -0
- package/src/components/cta-banner/cta-banner.css.js +41 -13
- package/src/components/cta-banner/cta-banner.js +6 -5
- package/src/components/cta-banner/cta-banner.stories.js +43 -98
- package/src/components/display/display.css.js +25 -1
- package/src/components/display/display.js +46 -13
- package/src/components/display/display.stories.js +270 -40
- package/src/components/divider/divider-horizontal.js +21 -5
- package/src/components/divider/divider-vertical.js +15 -7
- package/src/components/divider/divider.css.js +2 -2
- package/src/components/divider/divider.stories.js +38 -34
- package/src/components/dropdown/dropdown.css.js +93 -126
- package/src/components/dropdown/dropdown.js +114 -34
- package/src/components/dropdown/dropdown.stories.js +56 -24
- package/src/components/features/features.css.js +24 -11
- package/src/components/features/features.js +7 -3
- package/src/components/features/features.stories.js +37 -37
- package/src/components/features-tab/features-tab.css.js +19 -8
- package/src/components/features-tab/features-tab.js +6 -5
- package/src/components/features-tab/features-tab.stories.js +23 -23
- package/src/components/fieldset/fieldset.css.js +30 -0
- package/src/components/fieldset/fieldset.js +28 -0
- package/src/components/fieldset/fieldset.stories.js +84 -0
- package/src/components/footer/footer-links-group.css.js +10 -14
- package/src/components/footer/footer-links-group.js +4 -3
- package/src/components/footer/footer-lp.css.js +59 -30
- package/src/components/footer/footer-lp.js +17 -12
- package/src/components/footer/footer-lp.stories.js +63 -75
- package/src/components/footer/footer-nav-menu.css.js +26 -4
- package/src/components/footer/footer-nav-menu.js +3 -2
- package/src/components/footer/footer.css.js +146 -264
- package/src/components/footer/footer.js +176 -106
- package/src/components/footer/footer.stories.js +9 -9
- package/src/components/footer/localeMap.js +1 -1
- package/src/components/grid/grid.css.js +1 -1
- package/src/components/grid/grid.js +49 -7
- package/src/components/grid/grid.stories.js +111 -0
- package/src/components/header/header-code.css.js +61 -51
- package/src/components/header/header-code.js +28 -14
- package/src/components/header/header-code.stories.js +5 -5
- package/src/components/header/header.css.js +655 -176
- package/src/components/header/header.js +269 -36
- package/src/components/header/header.stories.js +841 -18
- package/src/components/heading/heading.css.js +14 -17
- package/src/components/heading/heading.js +48 -33
- package/src/components/heading/heading.stories.js +27 -25
- package/src/components/help-text/help-text.css.js +21 -0
- package/src/components/help-text/help-text.js +25 -0
- package/src/components/help-text/help-text.stories.js +66 -0
- package/src/components/highlight/highlight.css.js +86 -64
- package/src/components/highlight/highlight.js +18 -27
- package/src/components/highlight/highlight.stories.js +14 -3
- package/src/components/icons/analysis-icon.js +6 -16
- package/src/components/icons/arrow-down-icon.js +6 -19
- package/src/components/icons/arrow-icon.js +44 -0
- package/src/components/icons/arrow-right-icon.js +30 -23
- package/src/components/icons/arrow-up-icon.js +19 -18
- package/src/components/icons/bd-ai-icon.js +1 -1
- package/src/components/icons/brand-marks.stories.js +279 -0
- package/src/components/icons/brand-signature-icon.js +42 -0
- package/src/components/icons/check-icon.js +27 -0
- package/src/components/icons/circle-info-icon.js +33 -0
- package/src/components/icons/close-icon.js +6 -18
- package/src/components/icons/family-icon.js +8 -20
- package/src/components/icons/globe-icon.js +6 -18
- package/src/components/icons/guide-icon.js +6 -18
- package/src/components/icons/icon-element.js +99 -0
- package/src/components/icons/icons.js +36 -0
- package/src/components/icons/icons.stories.js +184 -52
- package/src/components/icons/individual-icon.js +6 -18
- package/src/components/icons/laurel-icon.js +9 -19
- package/src/components/icons/machine-learning-icon.js +6 -17
- package/src/components/icons/marks.js +41 -0
- package/src/components/icons/minus-icon.js +7 -21
- package/src/components/icons/missing-icon.js +52 -0
- package/src/components/icons/plus-icon.js +7 -21
- package/src/components/icons/quote-icon.js +19 -19
- package/src/components/image/image.css.js +72 -25
- package/src/components/image/image.js +11 -6
- package/src/components/image/image.stories.js +2 -2
- package/src/components/input/custom-form.stories.js +214 -62
- package/src/components/input/input-clipboard.css.js +51 -144
- package/src/components/input/input-clipboard.js +31 -15
- package/src/components/input/input.css.js +8 -146
- package/src/components/input/input.js +93 -38
- package/src/components/install-options/install-options.css.js +84 -77
- package/src/components/install-options/install-options.js +33 -30
- package/src/components/install-options/install-options.stories.js +3 -3
- package/src/components/label/label.css.js +35 -0
- package/src/components/label/label.js +38 -0
- package/src/components/label/label.stories.js +82 -0
- package/src/components/light-carousel/light-carousel.css.js +111 -63
- package/src/components/light-carousel/light-carousel.js +85 -11
- package/src/components/light-carousel/light-carousel.stories.js +126 -82
- package/src/components/link/link.css.js +150 -99
- package/src/components/link/link.js +86 -11
- package/src/components/link/link.stories.js +124 -30
- package/src/components/list/list-item/list-item.css.js +74 -22
- package/src/components/list/list-item/list-item.js +32 -10
- package/src/components/list/list-item/list-item.stories.js +23 -23
- package/src/components/list/list.css.js +8 -2
- package/src/components/list/list.js +3 -2
- package/src/components/list/list.stories.js +222 -0
- package/src/components/modal/modal.css.js +114 -24
- package/src/components/modal/modal.js +83 -7
- package/src/components/modal/modal.stories.js +9 -9
- package/src/components/overview/overview.css.js +19 -14
- package/src/components/overview/overview.js +6 -5
- package/src/components/overview/overview.stories.js +10 -10
- package/src/components/page-switcher/page-switcher.css.js +97 -40
- package/src/components/page-switcher/page-switcher.js +28 -5
- package/src/components/page-switcher/page-switcher.stories.js +95 -0
- package/src/components/paragraph/paragraph.css.js +15 -10
- package/src/components/paragraph/paragraph.js +41 -44
- package/src/components/paragraph/paragraph.stories.js +56 -21
- package/src/components/picture/picture.css.js +103 -44
- package/src/components/picture/picture.js +100 -30
- package/src/components/picture/picture.stories.js +1 -1
- package/src/components/pricing-cards/new-pricing-card.js +3 -3
- package/src/components/pricing-cards/new-pricing.css.js +24 -15
- package/src/components/pricing-cards/pricing-card-actions.css.js +1 -1
- package/src/components/pricing-cards/pricing-card-actions.js +3 -4
- package/src/components/pricing-cards/pricing-card-container.css.js +3 -3
- package/src/components/pricing-cards/pricing-card-container.js +3 -2
- package/src/components/pricing-cards/pricing-card-header.css.js +10 -8
- package/src/components/pricing-cards/pricing-card-header.js +6 -7
- package/src/components/pricing-cards/pricing-card-pricing.css.js +16 -9
- package/src/components/pricing-cards/pricing-card-pricing.js +8 -6
- package/src/components/pricing-cards/pricing-card-show-more.css.js +11 -3
- package/src/components/pricing-cards/pricing-card-show-more.js +8 -3
- package/src/components/pricing-cards/pricing-card.css.js +244 -190
- package/src/components/pricing-cards/pricing-card.js +54 -70
- package/src/components/pricing-cards/pricing-feature-item.css.js +25 -8
- package/src/components/pricing-cards/pricing-feature-item.js +8 -3
- package/src/components/process-steps/process-steps.css.js +26 -14
- package/src/components/process-steps/process-steps.js +23 -6
- package/src/components/process-steps/process-steps.stories.js +1 -1
- package/src/components/progress/progress.css.js +80 -0
- package/src/components/progress/progress.js +42 -0
- package/src/components/progress/progress.stories.js +79 -0
- package/src/components/quick-answer/quick-answer.css.js +75 -13
- package/src/components/quick-answer/quick-answer.js +8 -3
- package/src/components/radio/radio.css.js +92 -128
- package/src/components/radio/radio.js +106 -127
- package/src/components/radio/radio.stories.js +54 -19
- package/src/components/review/review-grid.css.js +5 -6
- package/src/components/review/review-grid.js +14 -11
- package/src/components/review/review.css.js +11 -6
- package/src/components/review/review.js +3 -8
- package/src/components/shared/ensemble.css.js +93 -0
- package/src/components/shared/form-field.css.js +206 -0
- package/src/components/shared/prop-vocabulary.js +48 -0
- package/src/components/shared/token-scales.js +306 -0
- package/src/components/skeleton/skeleton.css.js +34 -0
- package/src/components/skeleton/skeleton.js +32 -0
- package/src/components/skeleton/skeleton.stories.js +70 -0
- package/src/components/spinner/spinner.css.js +62 -0
- package/src/components/spinner/spinner.js +38 -0
- package/src/components/spinner/spinner.stories.js +92 -0
- package/src/components/spotlight-section/spotlight-section.css.js +14 -13
- package/src/components/spotlight-section/spotlight-section.js +42 -39
- package/src/components/switch/switch.css.js +103 -0
- package/src/components/switch/switch.js +44 -0
- package/src/components/switch/switch.stories.js +86 -0
- package/src/components/tab-list/content-switcher.stories.js +189 -0
- package/src/components/tab-list/tab-list.css.js +250 -0
- package/src/components/tab-list/tab-list.js +184 -0
- package/src/components/tab-list/tab-list.stories.js +221 -0
- package/src/components/tabs/tabs.css.js +14 -123
- package/src/components/tabs/tabs.js +16 -19
- package/src/components/tabs/tabs.stories.js +95 -95
- package/src/components/tag/tag.css.js +54 -0
- package/src/components/tag/tag.js +32 -0
- package/src/components/tag/tag.stories.js +126 -0
- package/src/components/terminal/terminal-message.css.js +164 -60
- package/src/components/terminal/terminal-message.js +5 -5
- package/src/components/terminal/terminal-message.stories.js +70 -1
- package/src/components/termsOfUse/terms.css.js +25 -20
- package/src/components/termsOfUse/terms.js +13 -9
- package/src/components/termsOfUse/terms.stories.js +1 -1
- package/src/components/textarea/textarea.css.js +51 -0
- package/src/components/textarea/textarea.js +136 -0
- package/src/components/textarea/textarea.stories.js +191 -0
- package/src/components/tooltip/tooltip.css.js +75 -0
- package/src/components/tooltip/tooltip.js +156 -0
- package/src/components/tooltip/tooltip.stories.js +161 -0
- package/src/components/trust-panel/trust-panel.css.js +85 -33
- package/src/components/trust-panel/trust-panel.js +18 -10
- package/src/components/trust-panel/trust-panel.stories.js +1 -1
- package/src/components/ultimate-security-demo.stories.js +431 -0
- package/src/components/video/video.css.js +17 -0
- package/src/components/video/video.js +40 -0
- package/src/components/video/video.stories.js +106 -0
- package/src/components/video-player/video-player.css.js +67 -11
- package/src/components/video-player/video-player.js +35 -4
- package/src/components/video-player/video-player.stories.js +1 -1
- package/src/components/visual-alignment.stories.js +411 -0
- package/src/components/visually-hidden/visually-hidden.css.js +24 -0
- package/src/components/visually-hidden/visually-hidden.js +16 -0
- package/src/components/visually-hidden/visually-hidden.stories.js +56 -0
- package/src/stories/Button.stories.js +17 -17
- package/src/stories/Header.stories.js +10 -10
- package/src/stories/Page.js +1 -1
- package/src/stories/Page.stories.js +6 -6
- package/src/tokens/borders.stories.js +339 -0
- package/src/tokens/color-responsibilities.stories.js +227 -0
- package/src/tokens/dark-derivation.js +309 -0
- package/src/tokens/dark-findings.js +197 -0
- package/src/tokens/dark-mode.stories.js +207 -0
- package/src/tokens/dimension.stories.js +251 -0
- package/src/tokens/elevation.stories.js +143 -0
- package/src/tokens/focus.stories.js +276 -0
- package/src/tokens/fonts.css +20 -20
- package/src/tokens/fonts.stories.js +354 -374
- package/src/tokens/layout.css +25 -11
- package/src/tokens/motion.stories.js +231 -0
- package/src/tokens/shape.stories.js +272 -0
- package/src/tokens/spacing-rhythm.stories.js +359 -0
- package/src/tokens/spacing.stories.js +208 -703
- package/src/tokens/story-chrome.js +503 -0
- package/src/tokens/surfaces.stories.js +224 -0
- package/src/tokens/text-on-surface.stories.js +164 -0
- package/src/tokens/token-map.js +220 -0
- package/src/tokens/token-map.stories.js +257 -0
- package/src/tokens/token-purposes.js +266 -0
- package/src/tokens/tokens-grid.stories.js +388 -900
- package/src/tokens/tokens.css +1633 -1045
- package/src/tokens/tokens.js +1130 -492
- package/src/tokens/tokens.stories.js +137 -47
- package/src/tokens/type-ceiling-words.js +299 -0
- package/src/tokens/typography.stories.js +1003 -965
- package/src/tokens/vertical-rhythm.stories.js +224 -0
- package/src/components/awards/awards-icon.js +0 -56
- package/src/components/awards/awards-light.js +0 -240
- package/src/components/banner/banner.js +0 -60
- package/src/components/banner/banner.stories.js +0 -51
- package/src/components/button/icons.js +0 -24
- package/src/components/input/index.js +0 -0
- package/src/components/light-carousel/light-carousel-simple.css.js +0 -183
- package/src/components/light-carousel/light-carousel-simple.js +0 -74
- package/src/tokens/colors.js +0 -121
- package/src/tokens/typography.css.js +0 -207
- package/src/tokens/typography.js +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { LitElement, html } from "lit";
|
|
2
|
-
|
|
2
|
+
// Installs the design tokens into document scope; see src/tokens/tokens.js
|
|
3
|
+
import "../../tokens/tokens.js";
|
|
3
4
|
import carouselCSS from "../carousel/carousel.css.js";
|
|
5
|
+
import "../heading/heading.js";
|
|
4
6
|
import "../modal/modal.js";
|
|
5
7
|
export class CarouselItem extends LitElement {
|
|
6
8
|
static properties = {
|
|
@@ -52,12 +54,13 @@ export class CarouselItem extends LitElement {
|
|
|
52
54
|
`;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
static styles = [
|
|
57
|
+
static styles = [carouselCSS];
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
class CustomCarousel extends LitElement {
|
|
59
61
|
static properties = {
|
|
60
62
|
title : { type: String },
|
|
63
|
+
headingLevel: { type: Number, attribute: "heading-level" },
|
|
61
64
|
selectedItem: { type: Object }
|
|
62
65
|
};
|
|
63
66
|
|
|
@@ -65,6 +68,31 @@ class CustomCarousel extends LitElement {
|
|
|
65
68
|
super();
|
|
66
69
|
this.selectedItem = null;
|
|
67
70
|
this.title = "";
|
|
71
|
+
this.headingLevel = 2;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The heading element this section renders. Level is the document-outline
|
|
76
|
+
* question and belongs to whoever composes the page; the type scale is this
|
|
77
|
+
* component's own and does not move with it. Defaults to h2, because a
|
|
78
|
+
* reusable section cannot know it is the only thing on the page, and two of
|
|
79
|
+
* these used to put two h1s on one.
|
|
80
|
+
*/
|
|
81
|
+
get _headingTag() {
|
|
82
|
+
const n = Number(this.headingLevel);
|
|
83
|
+
return Number.isInteger(n) && n >= 1 && n <= 6 ? `h${n}` : "h2";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* bd-h already builds the dynamic tag, and it keeps the two questions apart
|
|
87
|
+
the way this component needs: as= is the outline level the page composes,
|
|
88
|
+
visual-level= is the type role, which is ours. Building the element here
|
|
89
|
+
meant re-implementing bd-h and then hand-writing the type on top of it --
|
|
90
|
+
and the hand-written type carried no line-height and no margin, so the
|
|
91
|
+
title rendered with the browser's own h2 margins. */
|
|
92
|
+
_renderTitle(className) {
|
|
93
|
+
return html`<bd-h as=${this._headingTag} visual-level="h3" class=${className}
|
|
94
|
+
>${this.title}</bd-h
|
|
95
|
+
>`;
|
|
68
96
|
}
|
|
69
97
|
|
|
70
98
|
firstUpdated() {
|
|
@@ -224,7 +252,7 @@ class CustomCarousel extends LitElement {
|
|
|
224
252
|
<div class="bd-carousel">
|
|
225
253
|
${this.title
|
|
226
254
|
? html`<div class="bd-header-carousel">
|
|
227
|
-
|
|
255
|
+
${this._renderTitle("bd-section-title")}
|
|
228
256
|
</div>`
|
|
229
257
|
: ""}
|
|
230
258
|
|
|
@@ -265,7 +293,7 @@ class CustomCarousel extends LitElement {
|
|
|
265
293
|
`;
|
|
266
294
|
}
|
|
267
295
|
|
|
268
|
-
static styles = [
|
|
296
|
+
static styles = [carouselCSS];
|
|
269
297
|
}
|
|
270
298
|
|
|
271
299
|
customElements.define("bd-carousel-item", CarouselItem);
|
|
@@ -1,132 +1,150 @@
|
|
|
1
1
|
import { css } from "lit";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Styled entirely from src/tokens/tokens.js — see CLAUDE.md, "The foundation
|
|
5
|
+
* rule". Measurements were matched to the ds-checkbox design by finding the
|
|
6
|
+
* token that already carries each value.
|
|
7
|
+
*
|
|
8
|
+
* The whole row is the control, not just the box. That makes clicking the
|
|
9
|
+
* label work (it did nothing before) and gives the target the 24px minimum
|
|
10
|
+
* WCAG 2.5.8 asks for, which a 20px box alone cannot reach.
|
|
11
|
+
*/
|
|
3
12
|
export default css`
|
|
4
13
|
:host {
|
|
5
14
|
display: inline-block;
|
|
6
15
|
}
|
|
7
16
|
|
|
8
|
-
.bd-checkbox
|
|
9
|
-
.bd-radio {
|
|
17
|
+
.bd-checkbox {
|
|
10
18
|
display: inline-flex;
|
|
11
19
|
align-items: center;
|
|
12
|
-
cursor: pointer;
|
|
13
20
|
gap: var(--spacing-8);
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
/* padding rather than a min-height: a min-height adds its slack only
|
|
22
|
+
above and below, which left the focus ring 2px from the content at the
|
|
23
|
+
sides and 4px at the top and bottom. Padding insets all four edges
|
|
24
|
+
equally, and still carries the row past the 24px WCAG 2.5.8 asks for. */
|
|
25
|
+
padding: var(--spacing-2);
|
|
26
|
+
cursor: pointer;
|
|
27
|
+
font-family: var(--typography-fontFamily-sans);
|
|
28
|
+
/* body-small: sm / normal / 1.5, which is what this already rendered on all
|
|
29
|
+
three axes. Only the axes this rule declares are adopted -- the role also
|
|
30
|
+
carries a family and a tracking, and importing those would change text
|
|
31
|
+
the rule never spoke for. */
|
|
32
|
+
font-size: var(--typography-body-small-fontSize);
|
|
33
|
+
line-height: var(--typography-body-small-lineHeight);
|
|
34
|
+
color: var(--color-text-primary);
|
|
16
35
|
vertical-align: middle;
|
|
36
|
+
outline: none;
|
|
17
37
|
}
|
|
18
38
|
|
|
19
|
-
.bd-checkbox
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
.radio-label {
|
|
27
|
-
font-size: 14px;
|
|
28
|
-
color: black;
|
|
39
|
+
.bd-checkbox:focus-visible {
|
|
40
|
+
/* the one focus ring — see Foundations/Focus. A two-colour ring whose
|
|
41
|
+
white inner band keeps it visible on a coloured or dark surface, which a
|
|
42
|
+
single-colour outline cannot do. */
|
|
43
|
+
outline: none;
|
|
44
|
+
box-shadow: var(--focus-outline-primary);
|
|
45
|
+
border-radius: var(--focus-outline-radius);
|
|
29
46
|
}
|
|
30
47
|
|
|
31
|
-
/*
|
|
32
|
-
.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
48
|
+
/* ---- the box ---------------------------------------------------------- */
|
|
49
|
+
.box {
|
|
50
|
+
flex: none;
|
|
51
|
+
width: var(--dimension-20);
|
|
52
|
+
height: var(--dimension-20);
|
|
53
|
+
box-sizing: border-box;
|
|
54
|
+
border: var(--border-width-2) solid var(--color-action-primary);
|
|
55
|
+
border-radius: var(--radius-sm);
|
|
56
|
+
background: var(--color-surface-default);
|
|
57
|
+
display: inline-flex;
|
|
38
58
|
align-items: center;
|
|
39
59
|
justify-content: center;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
60
|
+
/* the mark is drawn in currentColor, so one declaration moves both. It is
|
|
61
|
+
ink on an action fill, not "the page colour" -- the two are both white
|
|
62
|
+
here, and only one of them stays white in a dark theme */
|
|
63
|
+
color: var(--color-action-on-fill);
|
|
64
|
+
transition: background-color var(--transition-duration-normal) var(--transition-easing-smooth),
|
|
65
|
+
border-color var(--transition-duration-normal) var(--transition-easing-smooth);
|
|
43
66
|
}
|
|
44
67
|
|
|
45
|
-
.bd-checkbox .
|
|
46
|
-
|
|
47
|
-
height: var(--spacing-12);
|
|
48
|
-
background-color: var(--color-blue-500);
|
|
49
|
-
border-radius: var(--spacing-2);
|
|
50
|
-
transform: scale(0);
|
|
51
|
-
transition: transform 0.2s ease, background-color 0.2s ease;
|
|
68
|
+
.bd-checkbox:hover .box {
|
|
69
|
+
border-color: var(--color-action-primary-hover);
|
|
52
70
|
}
|
|
53
71
|
|
|
54
|
-
|
|
55
|
-
|
|
72
|
+
/* ---- checked and indeterminate: the box fills, the mark is white ------ */
|
|
73
|
+
:host([checked]) .box,
|
|
74
|
+
:host([indeterminate]) .box {
|
|
75
|
+
background: var(--color-action-primary);
|
|
76
|
+
border-color: var(--color-action-primary);
|
|
56
77
|
}
|
|
57
78
|
|
|
58
|
-
.bd-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
border: var(--
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
outline: none;
|
|
79
|
+
:host([checked]) .bd-checkbox:hover .box,
|
|
80
|
+
:host([indeterminate]) .bd-checkbox:hover .box {
|
|
81
|
+
background: var(--color-action-primary-hover);
|
|
82
|
+
border-color: var(--color-action-primary-hover);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.mark {
|
|
86
|
+
width: var(--dimension-12);
|
|
87
|
+
height: var(--dimension-12);
|
|
88
|
+
display: block;
|
|
69
89
|
}
|
|
70
90
|
|
|
71
|
-
.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
91
|
+
.mark path {
|
|
92
|
+
fill: none;
|
|
93
|
+
stroke: currentColor;
|
|
94
|
+
stroke-width: var(--border-width-2);
|
|
95
|
+
/* flat ends and a mitred vertex: the tick and the dash read as sharp,
|
|
96
|
+
matching the square corners of the box rather than softening them */
|
|
97
|
+
stroke-linecap: butt;
|
|
98
|
+
stroke-linejoin: miter;
|
|
78
99
|
}
|
|
79
100
|
|
|
80
|
-
|
|
81
|
-
|
|
101
|
+
/* ---- disabled --------------------------------------------------------
|
|
102
|
+
Grey throughout, and the label greys too rather than the whole row
|
|
103
|
+
dropping to an opacity, which is what the design specifies. Exempt from
|
|
104
|
+
contrast under WCAG 1.4.3.
|
|
105
|
+
|
|
106
|
+
The disabled edge is --color-border-disabled, the role named for the
|
|
107
|
+
state it expresses. It was --color-border-subtle, a hierarchy role, and
|
|
108
|
+
the family carried two answers: five controls drew neutral-200 for a
|
|
109
|
+
disabled edge and four drew neutral-300, so a disabled checkbox and a
|
|
110
|
+
disabled text field did not agree on what one looks like. The state role
|
|
111
|
+
wins because the state is what the colour means, and because neutral-300
|
|
112
|
+
measures 2.27:1 against the page where neutral-200 measures 1.66. A
|
|
113
|
+
disabled control is exempt under 1.4.11, so this is perceptibility rather
|
|
114
|
+
than conformance -- but it moves the right way, and it stays subordinate
|
|
115
|
+
to every enabled edge.
|
|
116
|
+
|
|
117
|
+
The fills below still draw neutral-200. A fill is not an edge, and whether
|
|
118
|
+
a disabled checked box should darken along with its border is a separate
|
|
119
|
+
question that has not been put yet. */
|
|
120
|
+
:host([disabled]) .bd-checkbox {
|
|
121
|
+
cursor: not-allowed;
|
|
122
|
+
color: var(--color-text-subtle);
|
|
82
123
|
}
|
|
83
124
|
|
|
84
|
-
.
|
|
85
|
-
|
|
86
|
-
|
|
125
|
+
:host([disabled]) .box {
|
|
126
|
+
border-color: var(--color-border-disabled);
|
|
127
|
+
background: var(--color-surface-default);
|
|
87
128
|
}
|
|
88
129
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
background
|
|
130
|
+
:host([disabled][checked]) .box,
|
|
131
|
+
:host([disabled][indeterminate]) .box {
|
|
132
|
+
background: var(--color-border-subtle);
|
|
133
|
+
border-color: var(--color-border-disabled);
|
|
92
134
|
}
|
|
93
135
|
|
|
94
|
-
.bd-checkbox.
|
|
95
|
-
|
|
96
|
-
border-color: #b0b0b0;
|
|
136
|
+
:host([disabled]) .bd-checkbox:hover .box {
|
|
137
|
+
border-color: var(--color-border-disabled);
|
|
97
138
|
}
|
|
98
139
|
|
|
99
|
-
.bd-checkbox
|
|
100
|
-
|
|
101
|
-
border-
|
|
140
|
+
:host([disabled][checked]) .bd-checkbox:hover .box,
|
|
141
|
+
:host([disabled][indeterminate]) .bd-checkbox:hover .box {
|
|
142
|
+
background: var(--color-border-subtle);
|
|
102
143
|
}
|
|
103
144
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
145
|
+
@media (prefers-reduced-motion: reduce) {
|
|
146
|
+
.box {
|
|
147
|
+
transition: none;
|
|
148
|
+
}
|
|
107
149
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
.bd-checkbox .bd-outer:focus {
|
|
111
|
-
outline: none;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.bd-checkbox .bd-outer:focus-visible {
|
|
115
|
-
outline: var(--spacing-2) solid var(--color-blue-500);
|
|
116
|
-
outline-offset: var(--spacing-2);
|
|
117
|
-
}
|
|
118
|
-
.bd-checkbox .bd-outer.checked:focus-visible {
|
|
119
|
-
border-color: var(--color-blue-700);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
.bd-checkbox .bd-outer.checked:focus-visible .bd-inner.visible {
|
|
123
|
-
background-color: var(--color-blue-700);
|
|
124
|
-
}
|
|
125
|
-
.bd-checkbox .bd-outer.checked.kbd-activate {
|
|
126
|
-
border-color: var(--color-blue-700);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.bd-checkbox .bd-outer.checked.kbd-activate .bd-inner.visible {
|
|
130
|
-
background-color: var(--color-blue-700);
|
|
131
|
-
}
|
|
132
150
|
`;
|
|
@@ -1,129 +1,103 @@
|
|
|
1
1
|
import { LitElement, html } from "lit";
|
|
2
|
-
|
|
3
|
-
import
|
|
2
|
+
// Installs the design tokens into document scope; see src/tokens/tokens.js
|
|
3
|
+
import "../../tokens/tokens.js";
|
|
4
|
+
// the extension matters: "./checkbox.css" only resolved because Vite appends
|
|
5
|
+
// .js for us, and failed outright under native ESM
|
|
6
|
+
import checkboxCSS from "./checkbox.css.js";
|
|
4
7
|
|
|
5
8
|
export class BdCheckbox extends LitElement {
|
|
6
|
-
static styles = [
|
|
9
|
+
static styles = [checkboxCSS];
|
|
7
10
|
|
|
8
11
|
static properties = {
|
|
9
|
-
name
|
|
10
|
-
value
|
|
11
|
-
checked
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
name : { type: String },
|
|
13
|
+
value : { type: String },
|
|
14
|
+
checked : { type: Boolean, reflect: true },
|
|
15
|
+
indeterminate: { type: Boolean, reflect: true },
|
|
16
|
+
disabled : { type: Boolean, reflect: true },
|
|
17
|
+
label : { type: String }
|
|
14
18
|
};
|
|
15
19
|
|
|
16
20
|
constructor() {
|
|
17
21
|
super();
|
|
18
22
|
this.name = "";
|
|
19
23
|
this.value = "";
|
|
24
|
+
// checked was left undefined, which rendered aria-checked="" — an invalid
|
|
25
|
+
// value, so an unchecked box announced no state at all
|
|
26
|
+
this.checked = false;
|
|
27
|
+
this.indeterminate = false;
|
|
20
28
|
this.disabled = false;
|
|
21
29
|
this.label = "";
|
|
22
|
-
this._hadKeyboardFocus = false;
|
|
23
|
-
|
|
24
|
-
this._handleDocumentKeydown = (e) => {
|
|
25
|
-
if (e.key === "Tab") {
|
|
26
|
-
this._hadKeyboardFocus = true;
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
this._handleDocumentMousedown = this._handleDocumentMousedown.bind(this);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
_handleDocumentMousedown(e) {
|
|
34
|
-
const path = e.composedPath();
|
|
35
|
-
const target = path.find(
|
|
36
|
-
(el) =>
|
|
37
|
-
el instanceof HTMLElement &&
|
|
38
|
-
el.classList &&
|
|
39
|
-
el.classList.contains("bd-outer")
|
|
40
|
-
);
|
|
41
|
-
if (target) {
|
|
42
|
-
target.classList.remove("focus");
|
|
43
|
-
}
|
|
44
|
-
setTimeout(() => {
|
|
45
|
-
this._hadKeyboardFocus = false;
|
|
46
|
-
}, 0);
|
|
47
30
|
}
|
|
48
31
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
32
|
+
/** true | false | mixed — mixed wins, as it does natively. */
|
|
33
|
+
get _ariaChecked() {
|
|
34
|
+
if (this.indeterminate) return "mixed";
|
|
35
|
+
return this.checked ? "true" : "false";
|
|
53
36
|
}
|
|
54
37
|
|
|
55
|
-
|
|
56
|
-
super.disconnectedCallback();
|
|
57
|
-
document.removeEventListener("keydown", this._handleDocumentKeydown);
|
|
58
|
-
document.removeEventListener("mousedown", this._handleDocumentMousedown);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
handleClick() {
|
|
38
|
+
_toggle() {
|
|
62
39
|
if (this.disabled) return;
|
|
63
|
-
|
|
40
|
+
|
|
41
|
+
// clicking an indeterminate box resolves it to checked, as it does natively
|
|
42
|
+
if (this.indeterminate) {
|
|
43
|
+
this.indeterminate = false;
|
|
44
|
+
this.checked = true;
|
|
45
|
+
} else {
|
|
46
|
+
this.checked = !this.checked;
|
|
47
|
+
}
|
|
64
48
|
|
|
65
49
|
this.dispatchEvent(
|
|
66
50
|
new CustomEvent("change", {
|
|
67
|
-
detail : { value: this.checked ? this.value : null },
|
|
51
|
+
detail : { checked: this.checked, value: this.checked ? this.value : null },
|
|
68
52
|
bubbles : true,
|
|
69
53
|
composed: true
|
|
70
54
|
})
|
|
71
55
|
);
|
|
72
56
|
}
|
|
73
57
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
handleKeydown(e) {
|
|
81
|
-
if (this.disabled) return;
|
|
82
|
-
|
|
58
|
+
_handleKeydown(e) {
|
|
59
|
+
// Space is the native activation key. Enter is kept as a convenience: this
|
|
60
|
+
// control is not form-associated, so Enter has nothing else to do here.
|
|
83
61
|
if (e.key === " " || e.key === "Enter") {
|
|
84
62
|
e.preventDefault();
|
|
85
|
-
this.
|
|
86
|
-
|
|
87
|
-
const outer = e.target;
|
|
88
|
-
|
|
89
|
-
if (this._hadKeyboardFocus) {
|
|
90
|
-
outer.classList.add("focus", "kbd-activate");
|
|
91
|
-
|
|
92
|
-
setTimeout(() => {
|
|
93
|
-
outer.classList.remove("kbd-activate");
|
|
94
|
-
}, 150);
|
|
95
|
-
}
|
|
63
|
+
this._toggle();
|
|
96
64
|
}
|
|
97
65
|
}
|
|
98
66
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
67
|
+
_renderMark() {
|
|
68
|
+
if (this.indeterminate) {
|
|
69
|
+
return html`<svg class="mark" viewBox="0 0 12 12" aria-hidden="true" focusable="false">
|
|
70
|
+
<path d="M2.5 6H9.5" />
|
|
71
|
+
</svg>`;
|
|
72
|
+
}
|
|
73
|
+
if (this.checked) {
|
|
74
|
+
return html`<svg class="mark" viewBox="0 0 12 12" aria-hidden="true" focusable="false">
|
|
75
|
+
<path d="M2.5 6.5L4.75 8.75L9.5 3.5" />
|
|
76
|
+
</svg>`;
|
|
77
|
+
}
|
|
78
|
+
return "";
|
|
107
79
|
}
|
|
108
80
|
|
|
109
81
|
render() {
|
|
82
|
+
// The row carries the role, the focus and the click target, so the label is
|
|
83
|
+
// part of the control rather than decoration beside it. The previous markup
|
|
84
|
+
// put role and tabindex on the box alone, which meant clicking the label
|
|
85
|
+
// did nothing and the only target was 20px — under the 24px WCAG 2.5.8 asks
|
|
86
|
+
// for. There is no native input to associate a <label> with, so <div> is
|
|
87
|
+
// honest about what this is.
|
|
110
88
|
return html`
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
<span class="bd-inner ${this.checked ? "visible" : ""}"></span>
|
|
124
|
-
</span>
|
|
125
|
-
<span class="checkbox-label">${this.label}</span>
|
|
126
|
-
</label>
|
|
89
|
+
<div
|
|
90
|
+
class="bd-checkbox"
|
|
91
|
+
role="checkbox"
|
|
92
|
+
aria-checked="${this._ariaChecked}"
|
|
93
|
+
aria-disabled="${this.disabled ? "true" : "false"}"
|
|
94
|
+
tabindex="${this.disabled ? -1 : 0}"
|
|
95
|
+
@click=${this._toggle}
|
|
96
|
+
@keydown=${this._handleKeydown}
|
|
97
|
+
>
|
|
98
|
+
<span class="box" part="box">${this._renderMark()}</span>
|
|
99
|
+
<span class="label" part="label"><slot>${this.label}</slot></span>
|
|
100
|
+
</div>
|
|
127
101
|
`;
|
|
128
102
|
}
|
|
129
103
|
}
|