@repobit/dex-system-design 0.25.12 → 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 +187 -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
|
@@ -32,16 +32,22 @@ export default css`
|
|
|
32
32
|
|
|
33
33
|
.bd-list[type="ordered"].vertical ::slotted(li)::before {
|
|
34
34
|
content: counter(bd-ordered-counter) ". ";
|
|
35
|
+
/* no role: the ordered-list number -- a glyph/marker/placeholder box, not running
|
|
36
|
+
prose. See list-item.css.js's .bd-list-item-marker::before for the
|
|
37
|
+
argument. */
|
|
35
38
|
font-weight: var(--typography-fontWeight-semibold);
|
|
36
|
-
color: var(--color-
|
|
39
|
+
color: var(--color-text-muted);
|
|
37
40
|
margin-right: var(--spacing-8);
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
/* Unordered list markers for vertical */
|
|
41
44
|
.bd-list[type="unordered"].vertical ::slotted(li)::before {
|
|
42
45
|
content: "•";
|
|
46
|
+
/* no role: the unordered-list bullet -- a glyph/marker/placeholder box, not running
|
|
47
|
+
prose. See list-item.css.js's .bd-list-item-marker::before for the
|
|
48
|
+
argument. */
|
|
43
49
|
font-weight: var(--typography-fontWeight-semibold);
|
|
44
|
-
color: var(--color-
|
|
50
|
+
color: var(--color-text-muted);
|
|
45
51
|
margin-right: var(--spacing-8);
|
|
46
52
|
}
|
|
47
53
|
|
|
@@ -1,5 +1,6 @@
|
|
|
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 listCSS from "./list.css.js";
|
|
4
5
|
|
|
5
6
|
export class BdList extends LitElement {
|
|
@@ -38,7 +39,7 @@ export class BdList extends LitElement {
|
|
|
38
39
|
`;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
static styles = [
|
|
42
|
+
static styles = [listCSS];
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
customElements.define("bd-list", BdList);
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import "./list.js";
|
|
3
|
+
import "./list-item/list-item.js";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title : "Atoms/List",
|
|
7
|
+
component : "bd-list",
|
|
8
|
+
tags : ["autodocs"],
|
|
9
|
+
parameters: {
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component: `
|
|
13
|
+
**\`bd-list\`** renders the real \`<ul>\` or \`<ol>\` and lays its items out. What
|
|
14
|
+
it does **not** currently do is draw markers or apply its own outer spacing —
|
|
15
|
+
three of its five properties are largely inert, and this story exists partly to
|
|
16
|
+
make that visible. Every claim below was measured in the browser, not read off
|
|
17
|
+
the stylesheet.
|
|
18
|
+
|
|
19
|
+
### The \`type\` axis only chooses the tag
|
|
20
|
+
|
|
21
|
+
\`type\` is reflected on the host, but every rule that depends on it targets the
|
|
22
|
+
**inner** element — \`.bd-list[type="ordered"]\`. The inner \`<ol>\` carries
|
|
23
|
+
\`class\` and \`start\` and no \`type\` attribute at all, so
|
|
24
|
+
\`inner.matches('.bd-list[type="ordered"]')\` is **false** and none of those
|
|
25
|
+
rules apply. Measured on the Ordered story: \`::before\` content is \`none\`,
|
|
26
|
+
\`counter-increment\` is \`none\`, and all three items sit at the same left offset.
|
|
27
|
+
Combined with \`list-style: none\` on the base rule, **no marker is drawn for
|
|
28
|
+
either type.**
|
|
29
|
+
|
|
30
|
+
The bullet and counter rules also reach through \`::slotted(li)::before\`, and a
|
|
31
|
+
pseudo-element of slotted content is not stylable in browsers today — so they
|
|
32
|
+
would still not paint even with the attribute fixed.
|
|
33
|
+
|
|
34
|
+
### \`spacing\` and \`variant\` do not move the outer margin
|
|
35
|
+
|
|
36
|
+
\`.bd-list.md\` sets \`margin: 16px 0\`, but two rules later in the same sheet —
|
|
37
|
+
\`.bd-list:first-child { margin-top: 0 }\` and \`.bd-list:last-child
|
|
38
|
+
{ margin-bottom: 0 }\` — carry the same specificity and win on order. The inner
|
|
39
|
+
list is the **only** child of the shadow root, so it is always both, and the
|
|
40
|
+
margin is always zero. Measured: \`0px\` top and bottom at every \`spacing\` and
|
|
41
|
+
\`variant\` value.
|
|
42
|
+
|
|
43
|
+
What is still live, measured: **\`variant\`** sets the gap between items in both
|
|
44
|
+
orientations — the \`::slotted(li)\` bottom margin vertically (default 8, compact
|
|
45
|
+
4, spacious 12) and \`gap\` horizontally. **\`spacing\`** is live *only* when
|
|
46
|
+
horizontal, where it sets \`gap\` to 8/16/24; vertically it does nothing at all,
|
|
47
|
+
because no rule ties it to the item margin and its own outer margin is
|
|
48
|
+
cancelled.
|
|
49
|
+
|
|
50
|
+
### So what is it good for
|
|
51
|
+
|
|
52
|
+
The semantics and the layout, which are real: a genuine \`<ul>\`/\`<ol>\` for
|
|
53
|
+
assistive technology, \`start\` on the \`<ol>\`, vertical or horizontal flow, and
|
|
54
|
+
the gap between items. For a visible marker, fill it with \`<bd-li>\`, which
|
|
55
|
+
draws its own — a bullet, a number, or the green tick — and is what
|
|
56
|
+
\`bd-terms-section\` and \`bd-accordion-bg\` actually do.
|
|
57
|
+
|
|
58
|
+
**Do not "fix" the bullets without checking the consumers first.** Every live
|
|
59
|
+
consumer fills this element with \`<bd-li>\`, so making \`bd-list\` draw its own
|
|
60
|
+
markers would give those pages two markers per row.
|
|
61
|
+
`
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
argTypes: {
|
|
66
|
+
type: {
|
|
67
|
+
control : { type: "inline-radio" },
|
|
68
|
+
options : ["unordered", "ordered"],
|
|
69
|
+
description: "Chooses the tag. Does NOT change the marker -- none is drawn."
|
|
70
|
+
},
|
|
71
|
+
spacing: {
|
|
72
|
+
control : { type: "inline-radio" },
|
|
73
|
+
options : ["sm", "md", "lg"],
|
|
74
|
+
description: "Intended as the outer margin (8/16/24) but cancelled by the "
|
|
75
|
+
+ "first-child/last-child reset. Its only live effect is gap when horizontal; "
|
|
76
|
+
+ "vertically it does nothing."
|
|
77
|
+
},
|
|
78
|
+
variant: {
|
|
79
|
+
control : { type: "inline-radio" },
|
|
80
|
+
options : ["default", "compact", "spacious"],
|
|
81
|
+
description: "Its outer margin is cancelled too; the per-item gap it sets is live."
|
|
82
|
+
},
|
|
83
|
+
orientation: {
|
|
84
|
+
control : { type: "inline-radio" },
|
|
85
|
+
options : ["vertical", "horizontal"],
|
|
86
|
+
description: "horizontal lays items in a row AND removes the markers."
|
|
87
|
+
},
|
|
88
|
+
start: {
|
|
89
|
+
control : { type: "number" },
|
|
90
|
+
description: "First number of an ordered list."
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
args: { type: "unordered", spacing: "md", variant: "default", orientation: "vertical", start: 1 }
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const ITEMS = [
|
|
97
|
+
"Real-time protection for every device on the plan",
|
|
98
|
+
"A VPN with no traffic limit",
|
|
99
|
+
"Password manager across desktop and mobile"
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
export const Default = {
|
|
103
|
+
render: ({ type, spacing, variant, orientation, start }) => html`
|
|
104
|
+
<bd-list
|
|
105
|
+
type=${type}
|
|
106
|
+
spacing=${spacing}
|
|
107
|
+
variant=${variant}
|
|
108
|
+
orientation=${orientation}
|
|
109
|
+
start=${start}
|
|
110
|
+
>
|
|
111
|
+
${ITEMS.map(t => html`<li>${t}</li>`)}
|
|
112
|
+
</bd-list>
|
|
113
|
+
`,
|
|
114
|
+
parameters: {
|
|
115
|
+
docs: {
|
|
116
|
+
description: {
|
|
117
|
+
story: "Plain `<li>` children. Note there is no bullet: the rule that would "
|
|
118
|
+
+ "draw one is gated on an attribute the inner element does not carry, and "
|
|
119
|
+
+ "`list-style` is none — see the component notes above. Every axis is on the "
|
|
120
|
+
+ "controls, so you can confirm that changing `spacing` or `variant` moves "
|
|
121
|
+
+ "nothing on the outside of the list."
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export const Ordered = {
|
|
128
|
+
args : { type: "ordered" },
|
|
129
|
+
render: ({ type, spacing, variant, orientation, start }) => html`
|
|
130
|
+
<bd-list
|
|
131
|
+
type=${type}
|
|
132
|
+
spacing=${spacing}
|
|
133
|
+
variant=${variant}
|
|
134
|
+
orientation=${orientation}
|
|
135
|
+
start=${start}
|
|
136
|
+
>
|
|
137
|
+
${ITEMS.map(t => html`<li>${t}</li>`)}
|
|
138
|
+
</bd-list>
|
|
139
|
+
`,
|
|
140
|
+
parameters: {
|
|
141
|
+
docs: {
|
|
142
|
+
description: {
|
|
143
|
+
story: "A real `<ol>` — the tag and `start` are correct and reach assistive "
|
|
144
|
+
+ "technology. The numbers are NOT drawn, for the reason in the component "
|
|
145
|
+
+ "notes: the counter rules never match. Measured here, `counter-increment` "
|
|
146
|
+
+ "is none on every item."
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export const WithListItemAtoms = {
|
|
153
|
+
name : "Filled with bd-li",
|
|
154
|
+
render: () => html`
|
|
155
|
+
<bd-list type="unordered" spacing="md">
|
|
156
|
+
<bd-li variant="check" size="md">Included in this plan</bd-li>
|
|
157
|
+
<bd-li variant="check" size="md">Also included</bd-li>
|
|
158
|
+
<bd-li variant="none" size="md">Not part of this tier</bd-li>
|
|
159
|
+
</bd-list>
|
|
160
|
+
`,
|
|
161
|
+
parameters: {
|
|
162
|
+
docs: {
|
|
163
|
+
description: {
|
|
164
|
+
story: "The `<bd-li>` form, and the only one that shows a marker at all. "
|
|
165
|
+
+ "Each item draws its own, so you get the `variant` markers including the "
|
|
166
|
+
+ "green tick. This is what `bd-terms-section` and `bd-accordion-bg` use."
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export const Horizontal = {
|
|
173
|
+
args : { orientation: "horizontal" },
|
|
174
|
+
render: ({ spacing, variant }) => html`
|
|
175
|
+
<bd-list type="unordered" orientation="horizontal" spacing=${spacing} variant=${variant}>
|
|
176
|
+
<li>Windows</li>
|
|
177
|
+
<li>macOS</li>
|
|
178
|
+
<li>Android</li>
|
|
179
|
+
<li>iOS</li>
|
|
180
|
+
</bd-list>
|
|
181
|
+
`,
|
|
182
|
+
parameters: {
|
|
183
|
+
docs: {
|
|
184
|
+
description: {
|
|
185
|
+
story: "A row, with the markers removed on purpose — bullets in a horizontal "
|
|
186
|
+
+ "run read as separators rather than markers. `spacing` becomes the gap here "
|
|
187
|
+
+ "instead of a margin."
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
export const SpacingAndVariant = {
|
|
194
|
+
name : "spacing vs variant",
|
|
195
|
+
render: () => html`
|
|
196
|
+
<div style="display:grid;gap:var(--spacing-32);font-family:var(--typography-fontFamily-sans)">
|
|
197
|
+
${[
|
|
198
|
+
["spacing=sm", { spacing: "sm", variant: "default" }],
|
|
199
|
+
["spacing=lg", { spacing: "lg", variant: "default" }],
|
|
200
|
+
["variant=compact", { spacing: "md", variant: "compact" }],
|
|
201
|
+
["variant=spacious", { spacing: "md", variant: "spacious" }]
|
|
202
|
+
].map(([label, a]) => html`
|
|
203
|
+
<div>
|
|
204
|
+
<div style="font-size:var(--typography-fontSize-sm);color:var(--color-text-muted)">${label}</div>
|
|
205
|
+
<bd-list type="unordered" spacing=${a.spacing} variant=${a.variant}>
|
|
206
|
+
${ITEMS.slice(0, 2).map(t => html`<li>${t}</li>`)}
|
|
207
|
+
</bd-list>
|
|
208
|
+
</div>
|
|
209
|
+
`)}
|
|
210
|
+
</div>
|
|
211
|
+
`,
|
|
212
|
+
parameters: {
|
|
213
|
+
docs: {
|
|
214
|
+
description: {
|
|
215
|
+
story: "The two spacing axes side by side — and the point of the story is "
|
|
216
|
+
+ "that the four look almost identical. The outer margins they set are "
|
|
217
|
+
+ "cancelled by the first-child/last-child reset; what little separates them "
|
|
218
|
+
+ "is the per-item bottom margin that `variant` still controls."
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
};
|
|
@@ -1,26 +1,37 @@
|
|
|
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
|
-
:host {
|
|
5
|
-
--bd-blue-color: var(--color-blue-500);
|
|
6
|
-
--bd-accesibility-focus: var(--color-blue-800);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
5
|
.bd-modal {
|
|
10
6
|
position: fixed;
|
|
11
7
|
top: var(--spacing-0);
|
|
12
8
|
left: var(--spacing-0);
|
|
13
9
|
width: 100%;
|
|
14
10
|
height: 100%;
|
|
15
|
-
|
|
11
|
+
/* The scrim. Expressed as a mix over the palette rather than a raw rgba,
|
|
12
|
+
which is the house pattern -- --color-border-container-inverse and
|
|
13
|
+
spinner's two private aliases are written the same way. A raw
|
|
14
|
+
rgba(0,0,0,0.5) is a black no theme can reach; this one follows
|
|
15
|
+
--color-neutral-1000. Verified pixel-identical to the rgba it replaces.
|
|
16
|
+
.
|
|
17
|
+
no role: a page scrim has no role, and with one consumer it should not
|
|
18
|
+
have one yet. If a second component ever needs to darken the page behind
|
|
19
|
+
itself, that is the point to name it. */
|
|
20
|
+
background: color-mix(in srgb, var(--color-neutral-1000) 50%, transparent);
|
|
16
21
|
display: flex;
|
|
17
22
|
justify-content: center;
|
|
18
23
|
align-items: center;
|
|
19
|
-
z-index:
|
|
24
|
+
z-index: var(--z-modal);
|
|
20
25
|
backdrop-filter: blur(var(--spacing-12));
|
|
21
26
|
opacity: 0;
|
|
22
27
|
transform: scale(0.9);
|
|
23
|
-
transition: opacity
|
|
28
|
+
transition: opacity var(--transition-duration-slow) var(--transition-easing-ease), transform var(--transition-duration-slow) var(--transition-easing-ease);
|
|
29
|
+
/* The counterpart of the pointer-events: auto in the [open] rule below,
|
|
30
|
+
which was written without it. A closed modal is still a full-viewport
|
|
31
|
+
fixed layer at this z-index, so without this it sits invisibly over the
|
|
32
|
+
whole page and swallows every click: elementsFromPoint at the centre of
|
|
33
|
+
the viewport returned [BD-MODAL, HTML] with the modal closed. */
|
|
34
|
+
pointer-events: none;
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
:host([open]) .bd-modal {
|
|
@@ -29,38 +40,117 @@ export default css`
|
|
|
29
40
|
pointer-events: auto;
|
|
30
41
|
}
|
|
31
42
|
|
|
43
|
+
/* max-height and overflow, because without them the bottom of a tall dialog
|
|
44
|
+
is simply gone. Measured on Components/Modal "Long Modal Text": the panel
|
|
45
|
+
is 506px tall at every viewport height, so at 500px and at 360px its
|
|
46
|
+
bottom edge -- and the Close button on it -- sat past the viewport with
|
|
47
|
+
nothing scrollable anywhere. The panel could not scroll (overflow
|
|
48
|
+
visible, no max-height) and neither could the page (the scrim is
|
|
49
|
+
position: fixed at 100% height, so the document never grows), which left
|
|
50
|
+
the only control in the dialog unreachable by any means.
|
|
51
|
+
|
|
52
|
+
--spacing-128 rather than --spacing-64, and the arithmetic is the reason.
|
|
53
|
+
This box is content-box, so the cap applies to the content and the 2em
|
|
54
|
+
padding is added outside it: subtracting 64 produced a panel of exactly
|
|
55
|
+
the viewport height at every constrained height -- 436 + 64 = 500 at a
|
|
56
|
+
500px viewport, 296 + 64 = 360 at 360 -- with no scrim band at all.
|
|
57
|
+
128 is that 64 of padding plus the 64 of scrim the band wants, which
|
|
58
|
+
lands the panel 32px from the top and bottom edges.
|
|
59
|
+
|
|
60
|
+
box-sizing: border-box would express the same thing more directly and is
|
|
61
|
+
deliberately not used here: it also makes max-width mean the border box,
|
|
62
|
+
which took the panel from 564px wide to 500 and rewrapped its text a line
|
|
63
|
+
taller. That is a visible change to an axis this fix has no business
|
|
64
|
+
touching, so the arithmetic goes in the calc instead. */
|
|
32
65
|
.bd-modal-content {
|
|
33
|
-
|
|
66
|
+
/* --color-surface-default, the role, not --color-neutral-0, the primitive
|
|
67
|
+
it resolves to. Same value; the category is the point, and CLAUDE.md's
|
|
68
|
+
"same primitive value is not same semantic meaning" section exists for
|
|
69
|
+
exactly this. Found by check:color-coverage once the background shorthand came into
|
|
70
|
+
its scope -- it had been invisible because the check counted
|
|
71
|
+
background-color: and this package almost never writes that. */
|
|
72
|
+
background: var(--color-surface-default);
|
|
34
73
|
padding: 2em;
|
|
35
|
-
border-radius: var(--
|
|
74
|
+
border-radius: var(--radius-xl);
|
|
36
75
|
max-width: 500px;
|
|
76
|
+
max-height: calc(100vh - var(--spacing-128));
|
|
77
|
+
overflow-y: auto;
|
|
37
78
|
text-align: start;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
79
|
+
/* --shadow-md, the role this package already uses for a floating overlay
|
|
80
|
+
surface: bd-tooltip's bubble and bd-anchor-nav's dropdown panel both name
|
|
81
|
+
it, and this panel is the third of the same kind.
|
|
82
|
+
|
|
83
|
+
The shadow was built out of --spacing-0/2/8, which is a spacing scale
|
|
84
|
+
doing a depth role's job -- and spacing is rem, so it grew with the
|
|
85
|
+
reader. Measured at a 24px root: this panel's shadow went from
|
|
86
|
+
0 2px 8px to 0 3px 12px while the tooltip's --shadow-md held exactly
|
|
87
|
+
still. A drop shadow is a fixed optical depth, not a distance that
|
|
88
|
+
should scale with text.
|
|
41
89
|
|
|
42
|
-
|
|
43
|
-
|
|
90
|
+
Visible, and intended: the shadow becomes the two-layer --shadow-md
|
|
91
|
+
rather than a single 8px blur at 0.2 alpha. The panel's separation from
|
|
92
|
+
the page is carried by the scrim above it -- 0.5 alpha and a 12px
|
|
93
|
+
backdrop blur -- so the shadow is doing detail work here, not the
|
|
94
|
+
heavy lifting. */
|
|
95
|
+
box-shadow: var(--shadow-md);
|
|
44
96
|
font-family: var(--typography-fontFamily-sans);
|
|
45
97
|
}
|
|
46
98
|
|
|
99
|
+
/* The title's spacing is set through bd-h's own paddingBottom prop, in
|
|
100
|
+
modal.js. A ".bd-modal-content h2" rule stood here and could never match:
|
|
101
|
+
the h2 is inside bd-h's shadow root, so a descendant selector from this
|
|
102
|
+
stylesheet does not reach it. The declared 1em resolved to 0 in all 80
|
|
103
|
+
measured story x viewport combinations, which is why the title sat flush
|
|
104
|
+
on its description. */
|
|
105
|
+
/* This is a <button> the component renders itself rather than a slotted
|
|
106
|
+
bd-button, and that is not going to change here: the element owns the
|
|
107
|
+
close behaviour and there is nothing for a page to pass in. What it can
|
|
108
|
+
stop doing is disagreeing with the atom about the shape of a button.
|
|
109
|
+
|
|
110
|
+
Measured against Atoms/Button, variant=primary size=md: the fill is the
|
|
111
|
+
same step, and every other axis was different. The padding was em
|
|
112
|
+
literals -- 0.5em/1em -- which is the spacing scale spelled in a unit that
|
|
113
|
+
is not on it, and the radius was --radius-lg against the atom's
|
|
114
|
+
--radius-sm, so the same fill came out with 8px corners here and 4px two
|
|
115
|
+
components over. The margin-top was a third em literal.
|
|
116
|
+
|
|
117
|
+
The values now match the atom's md size (8/16 at --radius-sm) and are
|
|
118
|
+
spelled with the tokens it uses. Visible: corners tighten from 8px to
|
|
119
|
+
4px. */
|
|
47
120
|
.bd-modal-content button {
|
|
48
|
-
margin-top:
|
|
49
|
-
padding:
|
|
50
|
-
background: var(--
|
|
51
|
-
color:
|
|
121
|
+
margin-top: var(--spacing-16);
|
|
122
|
+
padding: var(--spacing-8) var(--spacing-16);
|
|
123
|
+
background: var(--color-surface-brand);
|
|
124
|
+
color: var(--color-text-inverse);
|
|
52
125
|
border: none;
|
|
53
|
-
border-radius: var(--
|
|
126
|
+
border-radius: var(--radius-sm);
|
|
54
127
|
cursor: pointer;
|
|
55
128
|
font-family: var(--typography-fontFamily-sans);
|
|
56
129
|
}
|
|
57
130
|
|
|
58
131
|
.bd-modal-content button:focus-visible {
|
|
59
|
-
|
|
60
|
-
outline
|
|
132
|
+
/* the one focus ring — see Foundations/Focus */
|
|
133
|
+
outline: none;
|
|
134
|
+
box-shadow: var(--focus-outline-primary);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* The scrim scales and fades in. Measured before this: with
|
|
138
|
+
prefers-reduced-motion: reduce the transition still reported
|
|
139
|
+
0.3s on opacity and transform, so a reader who asked for less motion got
|
|
140
|
+
the panel zooming in anyway. Every other animated component in this
|
|
141
|
+
package honours the query -- see the tooltip two files over. */
|
|
142
|
+
@media (prefers-reduced-motion: reduce) {
|
|
143
|
+
.bd-modal {
|
|
144
|
+
transition: none;
|
|
145
|
+
transform: none;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
:host([open]) .bd-modal {
|
|
149
|
+
transform: none;
|
|
150
|
+
}
|
|
61
151
|
}
|
|
62
152
|
|
|
63
|
-
@media (
|
|
153
|
+
@media ${unsafeCSS(below('md'))} {
|
|
64
154
|
.bd-modal-content {
|
|
65
155
|
max-width: 90%;
|
|
66
156
|
padding: 1.5em;
|
|
@@ -1,9 +1,35 @@
|
|
|
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 "../heading/heading.js";
|
|
4
|
-
import modalCSS from "../modal/modal.css";
|
|
5
|
+
import modalCSS from "../modal/modal.css.js";
|
|
5
6
|
import "../paragraph/paragraph.js";
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* A dialog surface: a scrim, a centred panel, a title, a description and a
|
|
10
|
+
* close control. The consuming page owns `open` and reacts to close-modal.
|
|
11
|
+
*
|
|
12
|
+
* `role="dialog"` is on the panel, and it is what makes the two labels this
|
|
13
|
+
* element has always declared mean anything. Measured before it: the full
|
|
14
|
+
* accessibility tree for an open modal was RootWebArea, image, heading,
|
|
15
|
+
* paragraph, button -- no dialog node at any level, so `aria-labelledby` and
|
|
16
|
+
* `aria-describedby` pointed at real targets from an element with no role to
|
|
17
|
+
* name. With the role, the dialog is exposed and named "VPN Protection" from
|
|
18
|
+
* the bd-h it already pointed at; the name resolves across bd-h's shadow
|
|
19
|
+
* boundary because the title is slotted light-DOM text.
|
|
20
|
+
*
|
|
21
|
+
* `aria-modal="true"` is deliberately NOT set. It is a claim that the rest of
|
|
22
|
+
* the page is unavailable, and it is not: measured with a real keyboard, one
|
|
23
|
+
* Tab reaches the close button and the next leaves the dialog entirely, with
|
|
24
|
+
* seven focusable elements still reachable outside it. Setting the attribute
|
|
25
|
+
* without focus containment would tell a screen reader something untrue.
|
|
26
|
+
* Making it true is a dialog rework -- containment, an opener to restore focus
|
|
27
|
+
* to, and a scroll lock -- and that is a decision with more than one valid
|
|
28
|
+
* shape, so P6C.4 reports it rather than picking one.
|
|
29
|
+
*
|
|
30
|
+
* The icon is `alt=""`. It was `alt="icon"`, which a screen reader announced
|
|
31
|
+
* as the word "icon" beside a title that already says what the dialog is.
|
|
32
|
+
*/
|
|
7
33
|
export class BdModal extends LitElement {
|
|
8
34
|
static properties = {
|
|
9
35
|
open : { type: Boolean, reflect: true },
|
|
@@ -16,20 +42,70 @@ export class BdModal extends LitElement {
|
|
|
16
42
|
this.dispatchEvent(new CustomEvent("close-modal", { bubbles: true, composed: true }));
|
|
17
43
|
}
|
|
18
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Escape closes through the same channel as the backdrop click: this element
|
|
47
|
+
* does not own `open`, the consuming page does, so both gestures dispatch
|
|
48
|
+
* close-modal and let the page decide. The channel already existed and
|
|
49
|
+
* Escape was the one way in that was missing -- measured, Escape on an open
|
|
50
|
+
* modal left open true and did nothing at all.
|
|
51
|
+
*
|
|
52
|
+
* On the document, guarded on `open`, because focus is normally NOT inside
|
|
53
|
+
* this dialog: nothing moves it there when the dialog opens, so a listener
|
|
54
|
+
* on the host would only fire after the user had already Tabbed in. Measured
|
|
55
|
+
* with the host-scoped version first -- Escape with focus on body left open
|
|
56
|
+
* true, which is every real case. The guard means a closed modal listens for
|
|
57
|
+
* nothing, and propagation is left alone so a page that wants to react to
|
|
58
|
+
* the same Escape still can.
|
|
59
|
+
*/
|
|
60
|
+
connectedCallback() {
|
|
61
|
+
super.connectedCallback();
|
|
62
|
+
this._onKeydown = e => {
|
|
63
|
+
if (e.key !== "Escape" || !this.open) return;
|
|
64
|
+
this._onClose();
|
|
65
|
+
};
|
|
66
|
+
document.addEventListener("keydown", this._onKeydown);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
disconnectedCallback() {
|
|
70
|
+
document.removeEventListener("keydown", this._onKeydown);
|
|
71
|
+
super.disconnectedCallback();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Closing makes the dialog inert, which stops anything inside being reached
|
|
76
|
+
* — but focus that was ALREADY inside stays there, on a subtree the user can
|
|
77
|
+
* no longer see or operate. Measured: after close, document.activeElement was
|
|
78
|
+
* still BD-MODAL with the close button active inside it.
|
|
79
|
+
*
|
|
80
|
+
* This releases that focus. It is deliberately not focus *restoration*:
|
|
81
|
+
* returning focus to whatever opened the dialog needs the opener recorded,
|
|
82
|
+
* which is part of the dialog rework this fix is scoped out of.
|
|
83
|
+
*/
|
|
84
|
+
updated(changed) {
|
|
85
|
+
if (!changed.has("open") || this.open) return;
|
|
86
|
+
if (this.renderRoot?.activeElement) this.renderRoot.activeElement.blur();
|
|
87
|
+
}
|
|
88
|
+
|
|
19
89
|
render() {
|
|
20
90
|
return html`
|
|
21
|
-
<div
|
|
91
|
+
<div
|
|
92
|
+
class="bd-modal"
|
|
93
|
+
@click="${this._onClose}"
|
|
94
|
+
aria-hidden="${!this.open}"
|
|
95
|
+
?inert="${!this.open}"
|
|
96
|
+
>
|
|
22
97
|
<div
|
|
23
98
|
class="bd-modal-content"
|
|
24
99
|
@click="${(e) => e.stopPropagation()}"
|
|
100
|
+
role="dialog"
|
|
25
101
|
aria-labelledby="modal-title"
|
|
26
102
|
aria-describedby="modal-description"
|
|
27
103
|
>
|
|
28
104
|
${this.icon
|
|
29
|
-
? html`<img src="${this.icon}" alt="
|
|
105
|
+
? html`<img src="${this.icon}" alt="" class="bd-carousel-modal-icon" />`
|
|
30
106
|
: ""}
|
|
31
|
-
<bd-h as="h2" id="modal-title">${this.title}</bd-h>
|
|
32
|
-
<bd-p
|
|
107
|
+
<bd-h as="h2" id="modal-title" paddingBottom="16">${this.title}</bd-h>
|
|
108
|
+
<bd-p variant="regular" id="modal-description">${this.modalText}</bd-p>
|
|
33
109
|
<button @click="${this._onClose}" aria-label="Close modal">Close</button>
|
|
34
110
|
</div>
|
|
35
111
|
</div>
|
|
@@ -37,6 +113,6 @@ export class BdModal extends LitElement {
|
|
|
37
113
|
}
|
|
38
114
|
}
|
|
39
115
|
|
|
40
|
-
BdModal.styles = [
|
|
116
|
+
BdModal.styles = [modalCSS];
|
|
41
117
|
|
|
42
118
|
customElements.define("bd-modal", BdModal);
|
|
@@ -15,7 +15,7 @@ export default {
|
|
|
15
15
|
<bd-modal
|
|
16
16
|
.open="${true}"
|
|
17
17
|
title="VPN Protection"
|
|
18
|
-
icon="/
|
|
18
|
+
icon="/icons/privacy_protection.png"
|
|
19
19
|
modalText="Our VPN encrypts your connection."
|
|
20
20
|
@close-modal="${() => {}}"
|
|
21
21
|
></bd-modal>
|
|
@@ -50,7 +50,7 @@ export default {
|
|
|
50
50
|
},
|
|
51
51
|
modalText: {
|
|
52
52
|
control : 'text',
|
|
53
|
-
description: 'Modal body text rendered as `<bd-p
|
|
53
|
+
description: 'Modal body text rendered as `<bd-p variant="regular">`',
|
|
54
54
|
table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Content' }
|
|
55
55
|
},
|
|
56
56
|
icon: {
|
|
@@ -65,7 +65,7 @@ const defaultArgs = {
|
|
|
65
65
|
open : true,
|
|
66
66
|
title : 'VPN Protection',
|
|
67
67
|
modalText: 'Our VPN encrypts your internet traffic and hides your IP address, keeping you safe on public networks.',
|
|
68
|
-
icon : '/
|
|
68
|
+
icon : '/icons/privacy_protection.png'
|
|
69
69
|
};
|
|
70
70
|
|
|
71
71
|
const render = (args) => html`
|
|
@@ -86,7 +86,7 @@ export const Default = {
|
|
|
86
86
|
.open="${true}"
|
|
87
87
|
title="VPN Protection"
|
|
88
88
|
modalText="Our VPN encrypts your internet traffic and hides your IP address, keeping you safe on public Wi-Fi networks and preventing tracking."
|
|
89
|
-
icon="/
|
|
89
|
+
icon="/icons/privacy_protection.png"
|
|
90
90
|
></bd-modal>
|
|
91
91
|
`,
|
|
92
92
|
parameters: { docs: { description: { story: 'Modal rendered in the open state with icon, title, and body text.' } } }
|
|
@@ -100,7 +100,7 @@ export const Closed = {
|
|
|
100
100
|
.open="${false}"
|
|
101
101
|
title="VPN Protection"
|
|
102
102
|
modalText="This modal is closed."
|
|
103
|
-
icon="/
|
|
103
|
+
icon="/icons/privacy_protection.png"
|
|
104
104
|
></bd-modal>
|
|
105
105
|
`,
|
|
106
106
|
parameters: { docs: { description: { story: 'Modal with `open=false` — renders in the DOM with `aria-hidden="true"`. Visibility depends on CSS handling of the open state.' } } }
|
|
@@ -124,7 +124,7 @@ export const LongText = {
|
|
|
124
124
|
<bd-modal
|
|
125
125
|
.open="${true}"
|
|
126
126
|
title="Behavioral Analysis"
|
|
127
|
-
icon="/
|
|
127
|
+
icon="/icons/device_protection.png"
|
|
128
128
|
modalText="Bitdefender's behavioral detection technology monitors active applications in real time for suspicious activity. Unlike traditional signature-based detection, behavioral analysis can identify zero-day threats and novel malware variants by observing what a program does, not just what it looks like. When suspicious behavior is detected — such as a process attempting to encrypt files, modify system registries, or communicate with known malicious servers — Bitdefender immediately quarantines the threat before damage can occur."
|
|
129
129
|
></bd-modal>
|
|
130
130
|
`,
|
|
@@ -135,9 +135,9 @@ export const DifferentTitles = {
|
|
|
135
135
|
name : 'Various Content Types',
|
|
136
136
|
render: () => html`
|
|
137
137
|
<div style="display:flex; flex-direction:column; gap:32px;">
|
|
138
|
-
<bd-modal .open="${true}" title="VPN Protection" icon="/
|
|
138
|
+
<bd-modal .open="${true}" title="VPN Protection" icon="/icons/privacy_protection.png" modalText="Unlimited encrypted VPN traffic across 200+ servers."></bd-modal>
|
|
139
139
|
<bd-modal .open="${true}" title="Password Manager" modalText="Store and autofill passwords securely across all your devices."></bd-modal>
|
|
140
|
-
<bd-modal .open="${true}" title="Parental Controls" icon="/
|
|
140
|
+
<bd-modal .open="${true}" title="Parental Controls" icon="/icons/bd-icon-family.png" modalText="Monitor your children's online activity and set screen time limits."></bd-modal>
|
|
141
141
|
</div>
|
|
142
142
|
`,
|
|
143
143
|
parameters: { docs: { description: { story: 'Three modals stacked for visual comparison of different content configurations.' } } }
|
|
@@ -169,7 +169,7 @@ export const MobileView = {
|
|
|
169
169
|
.open="${true}"
|
|
170
170
|
title="VPN Protection"
|
|
171
171
|
modalText="Unlimited encrypted VPN traffic and IP masking."
|
|
172
|
-
icon="/
|
|
172
|
+
icon="/icons/privacy_protection.png"
|
|
173
173
|
></bd-modal>
|
|
174
174
|
`,
|
|
175
175
|
parameters: {
|