@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,166 +1,220 @@
|
|
|
1
|
-
import { LitElement, html } from "lit";
|
|
2
|
-
|
|
3
|
-
import "
|
|
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
4
|
import buttonsCSS from "./button.css.js";
|
|
5
|
+
import { fontSize, fontWeight } from "../shared/token-scales.js";
|
|
6
|
+
// the trailing arrow on bd-contact-button; an atom now, not a local registry
|
|
7
|
+
import "../icons/arrow-icon.js";
|
|
8
|
+
|
|
9
|
+
// "white" and "outline-white" are ButtonLink-only presets (no bd-button
|
|
10
|
+
// equivalent) used on a solid-colour banner (e.g. cta-banner) where a
|
|
11
|
+
// surface="dark" primary/tertiary button would still be too close in tone —
|
|
12
|
+
// they render a plain white fill / white 2px outline regardless of surface.
|
|
13
|
+
const VARIANTS = ["primary", "secondary", "tertiary", "ghost", "accent", "white", "outline-white"];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Pre-ds-button kind values, mapped onto the variant that reproduces them, so
|
|
17
|
+
* existing markup keeps rendering the same thing.
|
|
18
|
+
*/
|
|
19
|
+
const LEGACY_KINDS = {
|
|
20
|
+
"outline" : "ghost", // dark 2px outline
|
|
21
|
+
"primary-outline": "tertiary", // blue 2px outline
|
|
22
|
+
// red is this system's conversion colour, not a danger signal, so both of
|
|
23
|
+
// these earlier names described the wrong thing
|
|
24
|
+
"danger" : "accent",
|
|
25
|
+
"destructive" : "accent"
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const SIZE_CLASS = { sm: "button--small", md: "button--medium", lg: "button--large" };
|
|
29
|
+
const SURFACES = ["light", "dark"];
|
|
30
|
+
const SHAPES = ["default", "rounded"];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Everything bd-button and bd-button-link share.
|
|
34
|
+
*
|
|
35
|
+
* They differ only in the element they render, and that difference is
|
|
36
|
+
* semantic rather than visual: <button> performs an action in place, <a href>
|
|
37
|
+
* navigates. No CSS substitutes for it — only the link appears in a screen
|
|
38
|
+
* reader's list of links and offers open-in-new-tab, and only the button
|
|
39
|
+
* responds to Space as well as Enter.
|
|
40
|
+
*/
|
|
41
|
+
class BdButtonBase extends LitElement {
|
|
42
|
+
static styles = [buttonsCSS];
|
|
5
43
|
|
|
6
|
-
const arrowIcon = html`
|
|
7
|
-
<bd-arrow-right-icon class="button__arrow" width="100%" height="100%" aria-hidden="true"></bd-arrow-right-icon>
|
|
8
|
-
`;
|
|
9
|
-
|
|
10
|
-
class Button extends LitElement {
|
|
11
44
|
static properties = {
|
|
12
|
-
label
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
45
|
+
label : { type: String },
|
|
46
|
+
size : { type: String },
|
|
47
|
+
variant : { type: String, reflect: true },
|
|
48
|
+
/** @deprecated pass `variant`. kind meant four different things across the
|
|
49
|
+
atoms; on this one it always meant appearance. */
|
|
50
|
+
kind : { type: String },
|
|
51
|
+
fullWidth : { type: Boolean, attribute: "fullwidth" },
|
|
52
|
+
strong : { type: Boolean },
|
|
53
|
+
disabled : { type: Boolean, reflect: true },
|
|
54
|
+
loading : { type: Boolean, reflect: true },
|
|
55
|
+
fontSize : { type: String, attribute: "font-size" },
|
|
56
|
+
fontWeight: { type: String, attribute: "font-weight" },
|
|
57
|
+
align : { type: String },
|
|
58
|
+
surface : { type: String, reflect: true },
|
|
59
|
+
/** "rounded" takes the pill corner; see .button--rounded. */
|
|
60
|
+
shape : { type: String, reflect: true },
|
|
61
|
+
/** The accent variant reveals a trailing arrow on hover; this opts out. */
|
|
62
|
+
noArrow : { type: Boolean, attribute: "no-arrow" },
|
|
63
|
+
/* A circle holding one icon instead of a label: the homepage's audience
|
|
64
|
+
cards and the mobile menu toggle. A mode, not a variant, because every
|
|
65
|
+
variant, size, surface and state applies to it unchanged -- which is how
|
|
66
|
+
the Button icon sets in the foundation Figma file are drawn. With no
|
|
67
|
+
visible text there is nothing to name the control, so label becomes
|
|
68
|
+
required rather than optional. */
|
|
69
|
+
iconOnly : { type: Boolean, attribute: "icon-only", reflect: true }
|
|
24
70
|
};
|
|
25
71
|
|
|
26
72
|
constructor() {
|
|
27
73
|
super();
|
|
28
|
-
|
|
29
|
-
|
|
74
|
+
// label is only an accessible name, never the visible text: defaulting it
|
|
75
|
+
// to a word like "Buy now" would override whatever the caller slotted
|
|
76
|
+
this.label = "";
|
|
30
77
|
this.size = "md";
|
|
78
|
+
this.variant = "primary";
|
|
79
|
+
this.kind = "";
|
|
80
|
+
this.fullWidth = false;
|
|
81
|
+
this.strong = false;
|
|
82
|
+
this.disabled = false;
|
|
83
|
+
this.loading = false;
|
|
31
84
|
this.fontSize = "";
|
|
32
85
|
this.fontWeight = "";
|
|
33
86
|
this.align = "left";
|
|
34
|
-
|
|
87
|
+
// "dark" retunes every variant for a hero or panel with a full background
|
|
88
|
+
// colour; see the SURFACE block in button.css.js
|
|
89
|
+
this.surface = "light";
|
|
35
90
|
this.shape = "default";
|
|
91
|
+
this.noArrow = false;
|
|
92
|
+
this.iconOnly = false;
|
|
36
93
|
}
|
|
37
94
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
_onFocusout() {
|
|
50
|
-
this.removeAttribute('data-bd-button-focus');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
_handleClick() {
|
|
54
|
-
this.dispatchEvent(new Event("custom-click"));
|
|
95
|
+
willUpdate(changed) {
|
|
96
|
+
if (changed.has("kind") && this.kind) this.variant = this.kind;
|
|
97
|
+
if (changed.has("variant") || changed.has("kind")) {
|
|
98
|
+
if (LEGACY_KINDS[this.variant]) this.variant = LEGACY_KINDS[this.variant];
|
|
99
|
+
if (!VARIANTS.includes(this.variant)) this.variant = "primary";
|
|
100
|
+
}
|
|
101
|
+
if (changed.has("size") && !SIZE_CLASS[this.size]) this.size = "md";
|
|
102
|
+
if (changed.has("surface") && !SURFACES.includes(this.surface)) this.surface = "light";
|
|
103
|
+
if (changed.has("shape") && !SHAPES.includes(this.shape)) this.shape = "default";
|
|
55
104
|
}
|
|
56
105
|
|
|
57
|
-
get
|
|
58
|
-
|
|
59
|
-
case "lg":
|
|
60
|
-
return "button--large";
|
|
61
|
-
case "md":
|
|
62
|
-
return "button--medium";
|
|
63
|
-
case "sm":
|
|
64
|
-
return "button--small";
|
|
65
|
-
default:
|
|
66
|
-
return "";
|
|
67
|
-
}
|
|
106
|
+
get _inert() {
|
|
107
|
+
return this.disabled || this.loading;
|
|
68
108
|
}
|
|
69
109
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return "button--outline";
|
|
76
|
-
case "secondary":
|
|
77
|
-
return "button--secondary";
|
|
78
|
-
case "primary":
|
|
79
|
-
return "button--primary";
|
|
80
|
-
case "danger":
|
|
81
|
-
return "button--danger";
|
|
82
|
-
case "white":
|
|
83
|
-
return "button--white";
|
|
84
|
-
case "outline-white":
|
|
85
|
-
return "button--outline-white";
|
|
86
|
-
default:
|
|
87
|
-
return "";
|
|
88
|
-
}
|
|
110
|
+
/* The hover arrow belongs to the conversion CTA -- what "danger" meant before
|
|
111
|
+
it became accent -- and never to a control that cannot be pressed. */
|
|
112
|
+
get _hasArrow() {
|
|
113
|
+
// an icon-only circle has no label to slide aside
|
|
114
|
+
return this.variant === "accent" && !this.noArrow && !this._inert && !this.iconOnly;
|
|
89
115
|
}
|
|
90
116
|
|
|
91
|
-
get
|
|
92
|
-
return
|
|
117
|
+
get _classes() {
|
|
118
|
+
return [
|
|
119
|
+
"button",
|
|
120
|
+
`button--${this.variant}`,
|
|
121
|
+
SIZE_CLASS[this.size],
|
|
122
|
+
this.iconOnly ? "button--icon-only" : "",
|
|
123
|
+
// a circle stretched to the container is a pill, not this control
|
|
124
|
+
this.fullWidth && !this.iconOnly ? "max--width" : "",
|
|
125
|
+
this.strong ? "button--bold" : "",
|
|
126
|
+
// the circle is already the roundest shape there is
|
|
127
|
+
this.shape === "rounded" && !this.iconOnly ? "button--rounded" : "",
|
|
128
|
+
this._hasArrow ? "button--with-arrow" : "",
|
|
129
|
+
this.loading ? "button--loading" : ""
|
|
130
|
+
].filter(Boolean).join(" ");
|
|
93
131
|
}
|
|
94
132
|
|
|
95
|
-
|
|
96
|
-
|
|
133
|
+
/**
|
|
134
|
+
* font-size and font-weight are step names resolved to token references by
|
|
135
|
+
* shared/token-scales.js; anything off-scale is dropped.
|
|
136
|
+
*/
|
|
137
|
+
get _inlineStyle() {
|
|
138
|
+
return [
|
|
139
|
+
["font-size", fontSize(this.fontSize)],
|
|
140
|
+
["font-weight", fontWeight(this.fontWeight)]
|
|
141
|
+
].filter(([, v]) => v).map(([p, v]) => `${p}: ${v};`)
|
|
142
|
+
.join(" ");
|
|
97
143
|
}
|
|
98
144
|
|
|
99
|
-
|
|
100
|
-
|
|
145
|
+
/** The spinner is decorative — aria-busy on the control carries the state. */
|
|
146
|
+
get _content() {
|
|
147
|
+
if (this.iconOnly) return this._iconContent;
|
|
148
|
+
return html`${this.loading
|
|
149
|
+
? html`<span class="spinner" aria-hidden="true"></span>`
|
|
150
|
+
: nothing}<span class="button__label"><slot>${this.label}</slot></span>${this._hasArrow
|
|
151
|
+
? html`<bd-arrow-icon class="button__arrow" aria-hidden="true"></bd-arrow-icon>`
|
|
152
|
+
: nothing}`;
|
|
101
153
|
}
|
|
102
154
|
|
|
103
|
-
|
|
104
|
-
|
|
155
|
+
/**
|
|
156
|
+
* One glyph, never a glyph and a spinner side by side: the circle holds a
|
|
157
|
+
* single item, so loading replaces the icon rather than joining it.
|
|
158
|
+
*
|
|
159
|
+
* The icon is a slot so any bd-*-icon can go in; with nothing slotted it is
|
|
160
|
+
* the arrow, the system's only true shafted arrow and the default the Figma
|
|
161
|
+
* sets draw. The button and icon scales share step names -- sm 16, md 20,
|
|
162
|
+
* lg 24 against padding 8, 12 and 16 -- so the size passes straight through
|
|
163
|
+
* and the circle comes out 32, 44 and 56.
|
|
164
|
+
*/
|
|
165
|
+
get _iconContent() {
|
|
166
|
+
if (this.loading) return html`<span class="spinner" aria-hidden="true"></span>`;
|
|
167
|
+
return html`<slot><bd-arrow-icon size="${this.size}" aria-hidden="true"></bd-arrow-icon></slot>`;
|
|
105
168
|
}
|
|
106
169
|
|
|
107
|
-
|
|
108
|
-
|
|
170
|
+
_handleClick(e) {
|
|
171
|
+
if (this._inert) {
|
|
172
|
+
e.preventDefault();
|
|
173
|
+
e.stopPropagation();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this.dispatchEvent(new Event("custom-click"));
|
|
109
177
|
}
|
|
178
|
+
}
|
|
110
179
|
|
|
180
|
+
/** Performs an action in place. */
|
|
181
|
+
class Button extends BdButtonBase {
|
|
111
182
|
render() {
|
|
112
183
|
return html`
|
|
113
184
|
<button
|
|
185
|
+
type="button"
|
|
186
|
+
class="${this._classes}"
|
|
187
|
+
aria-label="${this.label || nothing}"
|
|
188
|
+
aria-busy="${this.loading ? "true" : nothing}"
|
|
189
|
+
?disabled="${this.disabled}"
|
|
190
|
+
style="${this._inlineStyle}"
|
|
114
191
|
@click=${this._handleClick}
|
|
115
|
-
|
|
116
|
-
@focusout=${this._onFocusout}
|
|
117
|
-
class="button ${this.kindClass} ${this.sizeClass} ${this.shapeClass} ${this.fullWidthClass} ${this.strongClass} ${this.arrowClass}"
|
|
118
|
-
aria-label="${this.label}"
|
|
119
|
-
style="
|
|
120
|
-
${this.fontSize ? `font-size: ${this.fontSize};` : ""}
|
|
121
|
-
${this.fontWeight ? `font-weight: ${this.fontWeight};` : ""}
|
|
122
|
-
"
|
|
123
|
-
>
|
|
124
|
-
<span class="button__label"><slot></slot></span>
|
|
125
|
-
${this.hasArrow ? arrowIcon : ""}
|
|
126
|
-
</button>
|
|
192
|
+
>${this._content}</button>
|
|
127
193
|
`;
|
|
128
194
|
}
|
|
129
195
|
}
|
|
130
196
|
|
|
131
|
-
|
|
197
|
+
/** Navigates. Looks identical; is not the same control. */
|
|
198
|
+
class ButtonLink extends BdButtonBase {
|
|
132
199
|
static properties = {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
fontWeight : { type: String, attribute: "font-weight" },
|
|
142
|
-
buyLink : { type: Boolean },
|
|
143
|
-
shadow : { type: Boolean, reflect: true },
|
|
144
|
-
align : { type: String },
|
|
145
|
-
noArrow : { type: Boolean, attribute: "no-arrow" },
|
|
146
|
-
shape : { type: String, reflect: true }
|
|
200
|
+
href : { type: String },
|
|
201
|
+
buyLink: { type: Boolean },
|
|
202
|
+
/* The base class comment calls <a href> the element that navigates and
|
|
203
|
+
"offers open-in-new-tab" -- and until now the atom could not express
|
|
204
|
+
that, so a consumer needing a new tab had to hand-roll the anchor and
|
|
205
|
+
lost the button's focus ring, disabled state and typography with it. */
|
|
206
|
+
target : { type: String },
|
|
207
|
+
rel : { type: String }
|
|
147
208
|
};
|
|
148
209
|
|
|
149
210
|
constructor() {
|
|
150
211
|
super();
|
|
151
|
-
this.label = "Buy now";
|
|
152
212
|
this.href = "";
|
|
153
|
-
this.size = "md";
|
|
154
|
-
this.kind = "primary";
|
|
155
|
-
this.fullWidth = false;
|
|
156
|
-
this.strong = false;
|
|
157
|
-
this.fontSize = "";
|
|
158
|
-
this.fontWeight = "";
|
|
159
213
|
this.buyLink = false;
|
|
160
214
|
this.shadow = true;
|
|
161
215
|
this.align = "left";
|
|
162
|
-
this.
|
|
163
|
-
this.
|
|
216
|
+
this.target = "";
|
|
217
|
+
this.rel = "";
|
|
164
218
|
}
|
|
165
219
|
|
|
166
220
|
_onFocusin(e) {
|
|
@@ -178,44 +232,6 @@ class ButtonLink extends LitElement {
|
|
|
178
232
|
this.removeAttribute('data-bd-button-focus');
|
|
179
233
|
}
|
|
180
234
|
|
|
181
|
-
get sizeClass() {
|
|
182
|
-
switch (this.size) {
|
|
183
|
-
case "lg":
|
|
184
|
-
return "button--large";
|
|
185
|
-
case "md":
|
|
186
|
-
return "button--medium";
|
|
187
|
-
case "sm":
|
|
188
|
-
return "button--small";
|
|
189
|
-
default:
|
|
190
|
-
return "";
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
get kindClass() {
|
|
195
|
-
switch (this.kind) {
|
|
196
|
-
case "primary-outline":
|
|
197
|
-
return "button--primary--outline";
|
|
198
|
-
case "outline":
|
|
199
|
-
return "button--outline";
|
|
200
|
-
case "secondary":
|
|
201
|
-
return "button--secondary";
|
|
202
|
-
case "primary":
|
|
203
|
-
return "button--primary";
|
|
204
|
-
case "danger":
|
|
205
|
-
return "button--danger";
|
|
206
|
-
case "white":
|
|
207
|
-
return "button--white";
|
|
208
|
-
case "outline-white":
|
|
209
|
-
return "button--outline-white";
|
|
210
|
-
default:
|
|
211
|
-
return "";
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
get shapeClass() {
|
|
216
|
-
return this.shape === "rounded" ? "button--rounded" : "";
|
|
217
|
-
}
|
|
218
|
-
|
|
219
235
|
get fullWidthClass() {
|
|
220
236
|
return this.fullWidth ? "max--width" : "";
|
|
221
237
|
}
|
|
@@ -224,42 +240,47 @@ class ButtonLink extends LitElement {
|
|
|
224
240
|
return this.strong ? "button--bold" : "";
|
|
225
241
|
}
|
|
226
242
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
return this.
|
|
243
|
+
/* Reverse tabnabbing is the reason rather than convention: a new tab opened
|
|
244
|
+
from here keeps a window.opener handle back unless rel says otherwise. An
|
|
245
|
+
explicit rel always wins, so a consumer can still opt out deliberately. */
|
|
246
|
+
get _rel() {
|
|
247
|
+
if (this.rel) return this.rel;
|
|
248
|
+
return this.target === "_blank" ? "noopener noreferrer" : "";
|
|
233
249
|
}
|
|
234
250
|
|
|
235
251
|
render() {
|
|
252
|
+
// A link has no native disabled state. Dropping the href stops it being a
|
|
253
|
+
// link at all, so the state is announced with aria-disabled and the role
|
|
254
|
+
// is restored explicitly; tabindex keeps it out of the tab order.
|
|
255
|
+
const href = this._inert || !this.href ? nothing : this.href;
|
|
256
|
+
|
|
236
257
|
return html`
|
|
237
258
|
<a
|
|
238
|
-
href="${
|
|
239
|
-
|
|
240
|
-
|
|
259
|
+
href="${href}"
|
|
260
|
+
target="${this.target || nothing}"
|
|
261
|
+
rel="${this._rel || nothing}"
|
|
262
|
+
role="${this._inert ? "link" : nothing}"
|
|
263
|
+
tabindex="${this._inert ? "-1" : nothing}"
|
|
264
|
+
class="${this._classes}"
|
|
265
|
+
aria-label="${this.label || nothing}"
|
|
266
|
+
aria-busy="${this.loading ? "true" : nothing}"
|
|
267
|
+
aria-disabled="${this.disabled ? "true" : nothing}"
|
|
268
|
+
style="${this._inlineStyle}"
|
|
241
269
|
@click=${this._handleClick}
|
|
242
|
-
@focusin=${this._onFocusin}
|
|
243
|
-
@focusout=${this._onFocusout}
|
|
244
|
-
style="
|
|
245
|
-
${this.fontSize ? `font-size: ${this.fontSize};` : ""}
|
|
246
|
-
${this.fontWeight ? `font-weight: ${this.fontWeight};` : ""}
|
|
247
|
-
"
|
|
248
270
|
?data-store-render="${this.buyLink}"
|
|
249
271
|
?data-store-buy-link="${this.buyLink}"
|
|
250
|
-
>
|
|
251
|
-
<span class="button__label"><slot>${this.label}</slot></span>
|
|
252
|
-
${this.hasArrow ? arrowIcon : ""}
|
|
253
|
-
</a>
|
|
272
|
+
>${this._content}</a>
|
|
254
273
|
`;
|
|
255
274
|
}
|
|
256
|
-
|
|
257
|
-
_handleClick() {
|
|
258
|
-
this.dispatchEvent(new Event("custom-click"));
|
|
259
|
-
}
|
|
260
275
|
}
|
|
261
276
|
|
|
277
|
+
/**
|
|
278
|
+
* A fixed "Contact us" CTA — a preset rather than a variant, with no size or
|
|
279
|
+
* kind axis. Its trailing arrow is bd-arrow-icon, an atom.
|
|
280
|
+
*/
|
|
262
281
|
class ContactButton extends LitElement {
|
|
282
|
+
static styles = [buttonsCSS];
|
|
283
|
+
|
|
263
284
|
static properties = {
|
|
264
285
|
label: { type: String },
|
|
265
286
|
href : { type: String },
|
|
@@ -270,59 +291,30 @@ class ContactButton extends LitElement {
|
|
|
270
291
|
constructor() {
|
|
271
292
|
super();
|
|
272
293
|
this.label = "Contact us";
|
|
273
|
-
this.href = "
|
|
294
|
+
this.href = "";
|
|
274
295
|
this.align = "left";
|
|
275
296
|
this.shape = "default";
|
|
276
297
|
}
|
|
277
298
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
requestAnimationFrame(() =>
|
|
281
|
-
requestAnimationFrame(() => {
|
|
282
|
-
if (el.matches(':focus-visible')) {
|
|
283
|
-
this.setAttribute('data-bd-button-focus', '');
|
|
284
|
-
}
|
|
285
|
-
})
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
_onFocusout() {
|
|
290
|
-
this.removeAttribute('data-bd-button-focus');
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
get shapeClass() {
|
|
294
|
-
return this.shape === "rounded" ? "button--rounded" : "";
|
|
299
|
+
_handleClick() {
|
|
300
|
+
this.dispatchEvent(new Event("custom-click"));
|
|
295
301
|
}
|
|
296
302
|
|
|
297
303
|
render() {
|
|
298
304
|
return html`
|
|
299
|
-
<a
|
|
300
|
-
class="button bd-contact-btn ${this.
|
|
301
|
-
href="${this.href}"
|
|
302
|
-
aria-label="${this.label}"
|
|
305
|
+
<a
|
|
306
|
+
class="button bd-contact-btn ${this.shape === "rounded" ? "button--rounded" : ""}"
|
|
307
|
+
href="${this.href || nothing}"
|
|
308
|
+
aria-label="${this.label || nothing}"
|
|
303
309
|
@click=${this._handleClick}
|
|
304
|
-
@focusin=${this._onFocusin}
|
|
305
|
-
@focusout=${this._onFocusout}
|
|
306
|
-
style="
|
|
307
|
-
${this.fontSize ? `font-size: ${this.fontSize};` : ""}
|
|
308
|
-
${this.fontWeight ? `font-weight: ${this.fontWeight};` : ""}
|
|
309
|
-
"
|
|
310
310
|
>
|
|
311
311
|
${this.label}
|
|
312
|
-
<arrow-icon aria-hidden="true"></arrow-icon>
|
|
312
|
+
<bd-arrow-icon aria-hidden="true"></bd-arrow-icon>
|
|
313
313
|
</a>
|
|
314
314
|
`;
|
|
315
315
|
}
|
|
316
|
-
|
|
317
|
-
_handleClick() {
|
|
318
|
-
this.dispatchEvent(new Event("custom-click"));
|
|
319
|
-
}
|
|
320
316
|
}
|
|
321
317
|
|
|
322
|
-
Button.styles = [tokens, buttonsCSS];
|
|
323
|
-
ButtonLink.styles = [tokens, buttonsCSS];
|
|
324
|
-
ContactButton.styles = [tokens, buttonsCSS];
|
|
325
|
-
|
|
326
318
|
customElements.define("bd-button", Button);
|
|
327
319
|
customElements.define("bd-button-link", ButtonLink);
|
|
328
320
|
customElements.define("bd-contact-button", ContactButton);
|