@repobit/dex-system-design 0.25.12 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +204 -0
- package/README.md +131 -8
- package/package.json +96 -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,24 +1,54 @@
|
|
|
1
1
|
import { LitElement, html } from 'lit';
|
|
2
|
+
// Installs the design tokens into document scope; see src/tokens/tokens.js
|
|
3
|
+
import "../../tokens/tokens.js";
|
|
4
|
+
/* The md boundary comes from the shared breakpoint source so the CSS and the
|
|
5
|
+
JS cannot drift apart again: bd-footer switched at 767 while bd-footer-lp,
|
|
6
|
+
sharing footer-nav-menu.css.js, switched at 768 — so at exactly 768px the
|
|
7
|
+
LP footer rendered its mobile markup under the desktop stylesheet. */
|
|
8
|
+
import { matchesBelow } from '../shared/token-scales.js';
|
|
2
9
|
import '../../components/divider/divider-horizontal.js';
|
|
3
10
|
import '../../components/divider/divider-vertical.js';
|
|
4
11
|
import '../../components/footer/footer-links-group.js';
|
|
5
12
|
import '../../components/footer/footer-nav-menu.js';
|
|
6
13
|
import '../../components/grid/grid.js';
|
|
7
14
|
import '../../components/link/link.js';
|
|
8
|
-
import { tokens } from "../../tokens/tokens.js";
|
|
9
15
|
import "../icons/arrow-down-icon.js";
|
|
10
16
|
import "../icons/arrow-up-icon.js";
|
|
11
17
|
import "../icons/close-icon.js";
|
|
12
18
|
import "../icons/globe-icon.js";
|
|
13
19
|
import footerCSS from './footer.css.js';
|
|
20
|
+
import { ensembleCSS } from '../shared/ensemble.css.js';
|
|
14
21
|
import { localeMap } from './localeMap.js';
|
|
15
22
|
|
|
23
|
+
/* The locale a footer shows when neither the page nor the URL says otherwise. */
|
|
24
|
+
const DEFAULT_LOCALE = 'en';
|
|
25
|
+
|
|
16
26
|
export class BdFooter extends LitElement {
|
|
17
27
|
static properties = {
|
|
18
28
|
_countriesOpen : { state: true },
|
|
19
29
|
selectedCountry : { state: true },
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
/* `current-locale` and `max-columns-per-row`, both documented dash-cased
|
|
31
|
+
and both previously inert for the same reason as bd-header above: Lit
|
|
32
|
+
lowercases a property name to get its observed attribute, so these were
|
|
33
|
+
listening for `currentlocale` and `maxcolumnsperrow`.
|
|
34
|
+
|
|
35
|
+
current-locale is the consequential one, and it did not merely fail --
|
|
36
|
+
it failed into nonsense. The attribute was ignored, so the locale fell
|
|
37
|
+
through to URL detection, and under Storybook the path is /iframe.html:
|
|
38
|
+
measured on Components/Footer Default, Romanian Locale and German
|
|
39
|
+
Locale, all three reported currentLocale "iframe.html" while their
|
|
40
|
+
markup asked for "en", "ro" and "de". Twelve usages in footer.stories.js
|
|
41
|
+
write it, including the documented usage example.
|
|
42
|
+
|
|
43
|
+
max-columns-per-row has a single usage, in the playground, and it passes
|
|
44
|
+
2 -- which is already the default -- so repairing it changes no rendered
|
|
45
|
+
output today. It is fixed with the other one because it is the same
|
|
46
|
+
defect in the same declaration block, not because it was visible.
|
|
47
|
+
|
|
48
|
+
Zero consumers of either working lowercase spelling across src, schemas
|
|
49
|
+
and docs, and no property bindings, so naming the attributes is safe. */
|
|
50
|
+
currentLocale : { type: String, attribute: "current-locale" },
|
|
51
|
+
maxColumnsPerRow : { type: Number, attribute: "max-columns-per-row" },
|
|
22
52
|
_isMobile : { state: true },
|
|
23
53
|
_countriesContainer: { state: true }
|
|
24
54
|
};
|
|
@@ -27,14 +57,21 @@ export class BdFooter extends LitElement {
|
|
|
27
57
|
super();
|
|
28
58
|
this._countriesOpen = false;
|
|
29
59
|
this.maxColumnsPerRow = 2;
|
|
30
|
-
this.currentLocale =
|
|
60
|
+
this.currentLocale = DEFAULT_LOCALE;
|
|
31
61
|
this.selectedCountry = 'Choose your country';
|
|
32
|
-
this._isMobile =
|
|
62
|
+
this._isMobile = matchesBelow('md');
|
|
33
63
|
this._countriesContainer = null;
|
|
34
64
|
}
|
|
35
65
|
|
|
36
66
|
connectedCallback() {
|
|
37
67
|
super.connectedCallback();
|
|
68
|
+
/* Whether the consuming page asked for a locale, captured before inference
|
|
69
|
+
runs. An attribute in the markup counts, and so does a property assigned
|
|
70
|
+
before the element connects -- both are the page stating its intent. A
|
|
71
|
+
page that explicitly asks for 'en' is indistinguishable from one that
|
|
72
|
+
said nothing, and that costs nothing: it asked for the value it gets. */
|
|
73
|
+
this._localeExplicit =
|
|
74
|
+
this.hasAttribute('current-locale') || this.currentLocale !== DEFAULT_LOCALE;
|
|
38
75
|
this._initLocaleFromUrl();
|
|
39
76
|
window.addEventListener('resize', this._handleResize.bind(this));
|
|
40
77
|
}
|
|
@@ -46,12 +83,10 @@ export class BdFooter extends LitElement {
|
|
|
46
83
|
|
|
47
84
|
firstUpdated() {
|
|
48
85
|
super.firstUpdated();
|
|
49
|
-
this._updateNavLinks();
|
|
50
86
|
}
|
|
51
87
|
|
|
52
88
|
updated(changedProps) {
|
|
53
89
|
if (changedProps.has('currentLocale')) {
|
|
54
|
-
this._updateNavLinks();
|
|
55
90
|
this._toggleImpressumVisibility();
|
|
56
91
|
}
|
|
57
92
|
|
|
@@ -61,6 +96,30 @@ export class BdFooter extends LitElement {
|
|
|
61
96
|
}
|
|
62
97
|
}
|
|
63
98
|
|
|
99
|
+
/* maxColumnsPerRow, finally read. The property has been declared here with
|
|
100
|
+
a default of 2 since it was written, the manifest claims it, and
|
|
101
|
+
footer.stories.js documents it as "Max columns per row in the quick-links
|
|
102
|
+
grid" -- and nothing ever looked at it. P7H.1 made the attribute reach the
|
|
103
|
+
property; this makes the property reach the layout.
|
|
104
|
+
|
|
105
|
+
It drives the grid the documentation names, through the cols-* attributes
|
|
106
|
+
bd-grid observes since P7H. Mobile and sm stay at one column because the
|
|
107
|
+
footer stacks there regardless of the cap, and md is capped at 2 because
|
|
108
|
+
that is what md has always shown -- the property raises the ceiling at the
|
|
109
|
+
widest breakpoint rather than redesigning the ladder.
|
|
110
|
+
|
|
111
|
+
The default therefore renders exactly what it rendered before:
|
|
112
|
+
min(2, 2) = 2 at md and 2 at lg, which is the pair that was hard-coded.
|
|
113
|
+
Verified by measurement, not by reading.
|
|
114
|
+
|
|
115
|
+
Clamped because the attribute is public: a 0, a negative or a fractional
|
|
116
|
+
value would otherwise reach grid-template-columns as
|
|
117
|
+
`repeat(0, 1fr)`. */
|
|
118
|
+
get _maxColumns() {
|
|
119
|
+
const n = Math.floor(Number(this.maxColumnsPerRow));
|
|
120
|
+
return Number.isFinite(n) && n >= 1 ? n : 2;
|
|
121
|
+
}
|
|
122
|
+
|
|
64
123
|
_toggleImpressumVisibility() {
|
|
65
124
|
const showImpressum = this.locale === 'de-de' || this.locale === 'de';
|
|
66
125
|
const slot = this.shadowRoot.querySelector('slot[name="secondary-nav"]');
|
|
@@ -101,75 +160,80 @@ export class BdFooter extends LitElement {
|
|
|
101
160
|
}
|
|
102
161
|
|
|
103
162
|
_handleResize() {
|
|
104
|
-
this._isMobile =
|
|
105
|
-
const newIsMobile =
|
|
163
|
+
this._isMobile = matchesBelow('md');
|
|
164
|
+
const newIsMobile = matchesBelow('md');
|
|
106
165
|
|
|
107
166
|
if (this._isMobile !== newIsMobile) {
|
|
108
167
|
this._isMobile = newIsMobile;
|
|
109
168
|
}
|
|
110
169
|
}
|
|
111
170
|
|
|
171
|
+
/* Locale precedence, and it is a precedence rather than a sequence of
|
|
172
|
+
assignments -- which is what went wrong.
|
|
173
|
+
|
|
174
|
+
1. the country selector, when a reader picks one (see _selectCountry)
|
|
175
|
+
2. an explicit current-locale attribute or currentLocale property
|
|
176
|
+
3. a locale inferred from the first path segment, IF it resolves to a
|
|
177
|
+
supported locale
|
|
178
|
+
4. DEFAULT_LOCALE
|
|
179
|
+
|
|
180
|
+
Two defects sat in the old version, both in its closing lines. It ended
|
|
181
|
+
with an unconditional `this.currentLocale = originalKey || urlLocale`,
|
|
182
|
+
so:
|
|
183
|
+
|
|
184
|
+
- an explicit input was silently overwritten by the environment. Measured:
|
|
185
|
+
<bd-footer current-locale="ro"> served from /de/ reported "de".
|
|
186
|
+
- any first path segment became the locale verbatim, supported or not.
|
|
187
|
+
Measured: /iframe.html reported currentLocale "iframe.html", and /zz-zz/
|
|
188
|
+
reported "zz-zz".
|
|
189
|
+
|
|
190
|
+
The second is why Storybook showed "iframe.html" as a locale, and the fix
|
|
191
|
+
is not a Storybook exception -- there is none here. A segment that does
|
|
192
|
+
not resolve against localeMap is simply not a locale, on any host. The
|
|
193
|
+
resolution itself (exact key, then language with a matching region, then
|
|
194
|
+
any key sharing the language) is unchanged; only its authority is. */
|
|
112
195
|
_initLocaleFromUrl() {
|
|
113
|
-
|
|
196
|
+
if (this._localeExplicit) return;
|
|
114
197
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
198
|
+
const urlLocale = window.location.pathname.split('/')[1]?.toLowerCase();
|
|
199
|
+
if (!urlLocale) return;
|
|
119
200
|
|
|
120
|
-
const
|
|
201
|
+
const normalized = {};
|
|
121
202
|
Object.entries(localeMap).forEach(([key, value]) => {
|
|
122
|
-
|
|
203
|
+
normalized[key.toLowerCase()] = value;
|
|
123
204
|
});
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
205
|
+
const originalKeyFor = lower =>
|
|
206
|
+
Object.keys(localeMap).find(k => k.toLowerCase() === lower);
|
|
207
|
+
|
|
208
|
+
let resolvedKey = null;
|
|
209
|
+
let country = null;
|
|
210
|
+
|
|
211
|
+
if (normalized[urlLocale]) {
|
|
212
|
+
resolvedKey = originalKeyFor(urlLocale) || urlLocale;
|
|
213
|
+
country = normalized[urlLocale];
|
|
214
|
+
} else {
|
|
215
|
+
const [language, region] = urlLocale.split('-');
|
|
216
|
+
const sameLanguage = Object.entries(normalized)
|
|
133
217
|
.filter(([key]) => key.startsWith(language));
|
|
134
218
|
|
|
135
|
-
if (
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
const regionMatch = region && keyRegion === region;
|
|
140
|
-
const languageOnlyMatch = !region && keyParts.length === 1;
|
|
141
|
-
|
|
142
|
-
return regionMatch || languageOnlyMatch;
|
|
219
|
+
if (sameLanguage.length) {
|
|
220
|
+
const exactRegion = sameLanguage.find(([key]) => {
|
|
221
|
+
const keyRegion = key.split('-')[1];
|
|
222
|
+
return (region && keyRegion === region) || (!region && !keyRegion);
|
|
143
223
|
});
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const originalKey = Object.keys(localeMap).find(k =>
|
|
148
|
-
k.toLowerCase() === exactRegionMatch[0]
|
|
149
|
-
);
|
|
150
|
-
this.currentLocale = originalKey || exactRegionMatch[0];
|
|
151
|
-
} else {
|
|
152
|
-
country = possibleMatches[0][1];
|
|
153
|
-
const originalKey = Object.keys(localeMap).find(k =>
|
|
154
|
-
k.toLowerCase() === possibleMatches[0][0]
|
|
155
|
-
);
|
|
156
|
-
this.currentLocale = originalKey || possibleMatches[0][0];
|
|
157
|
-
}
|
|
224
|
+
const [matchKey, matchCountry] = exactRegion || sameLanguage[0];
|
|
225
|
+
resolvedKey = originalKeyFor(matchKey) || matchKey;
|
|
226
|
+
country = matchCountry;
|
|
158
227
|
}
|
|
159
228
|
}
|
|
160
229
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (this.currentLocale !== urlLocale) {
|
|
166
|
-
const originalKey = Object.keys(localeMap).find(k =>
|
|
167
|
-
k.toLowerCase() === urlLocale
|
|
168
|
-
);
|
|
169
|
-
this.currentLocale = originalKey || urlLocale;
|
|
170
|
-
}
|
|
230
|
+
/* Nothing resolved: the segment is not a locale, so neither the locale nor
|
|
231
|
+
the country is touched. This is the line that used to assign the raw
|
|
232
|
+
path segment. */
|
|
233
|
+
if (!resolvedKey) return;
|
|
171
234
|
|
|
172
|
-
this.
|
|
235
|
+
this.currentLocale = resolvedKey;
|
|
236
|
+
this.selectedCountry = country;
|
|
173
237
|
}
|
|
174
238
|
|
|
175
239
|
_toggleCountries() {
|
|
@@ -208,7 +272,6 @@ export class BdFooter extends LitElement {
|
|
|
208
272
|
this.currentLocale = localeEntry[0];
|
|
209
273
|
}
|
|
210
274
|
|
|
211
|
-
this._updateNavLinks();
|
|
212
275
|
this._scrollToTop();
|
|
213
276
|
}
|
|
214
277
|
|
|
@@ -225,14 +288,14 @@ export class BdFooter extends LitElement {
|
|
|
225
288
|
}
|
|
226
289
|
|
|
227
290
|
_updateSlotStyles() {
|
|
228
|
-
const isMobile =
|
|
291
|
+
const isMobile = matchesBelow('md');
|
|
229
292
|
const slot = this.shadowRoot.querySelector('slot[name="nav"]');
|
|
230
293
|
const assignedElements = slot.assignedElements();
|
|
231
294
|
|
|
232
295
|
assignedElements.forEach(element => {
|
|
233
296
|
if (isMobile) {
|
|
234
|
-
element.style.color = '
|
|
235
|
-
element.style.setProperty('color', '
|
|
297
|
+
element.style.color = 'var(--color-neutral-900)';
|
|
298
|
+
element.style.setProperty('color', 'var(--color-neutral-900)', 'important');
|
|
236
299
|
} else {
|
|
237
300
|
element.style.color = '';
|
|
238
301
|
element.style.removeProperty('color');
|
|
@@ -240,21 +303,19 @@ export class BdFooter extends LitElement {
|
|
|
240
303
|
});
|
|
241
304
|
}
|
|
242
305
|
|
|
243
|
-
_updateNavLinks
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
});
|
|
257
|
-
}
|
|
306
|
+
/* No _updateNavLinks. It queried '.footer-nav-main bd-link' inside this
|
|
307
|
+
shadow root and wrote a locale into the href of everything it found, and it
|
|
308
|
+
could never find anything: .footer-nav-main is rendered by bd-footer-nav
|
|
309
|
+
into bd-footer-nav's own shadow root, and this template has only
|
|
310
|
+
.footer-nav-main-container, the box its slot sits in. Measured 0 matches
|
|
311
|
+
across the 22 built footer stories.
|
|
312
|
+
|
|
313
|
+
So the four locale-aware nav hrefs it promised -- consumer,
|
|
314
|
+
small-business, business, partners -- were never written, and no story
|
|
315
|
+
depended on them. Localising slotted navigation is real work with a real
|
|
316
|
+
API question (whose hrefs are they, and does a component rewrite markup it
|
|
317
|
+
does not own); it is not this, and leaving this here made it look
|
|
318
|
+
answered. */
|
|
258
319
|
|
|
259
320
|
render() {
|
|
260
321
|
const year = new Date().getFullYear();
|
|
@@ -292,7 +353,7 @@ export class BdFooter extends LitElement {
|
|
|
292
353
|
|
|
293
354
|
return html`
|
|
294
355
|
<div class="footer-top-bleed">
|
|
295
|
-
<div class="container">
|
|
356
|
+
<div class="bd-ensemble container">
|
|
296
357
|
<div class="footer-top">
|
|
297
358
|
<div class="footer-logo">
|
|
298
359
|
<slot name="logo">
|
|
@@ -312,19 +373,19 @@ export class BdFooter extends LitElement {
|
|
|
312
373
|
</div>
|
|
313
374
|
</div>
|
|
314
375
|
|
|
315
|
-
<footer class="container">
|
|
376
|
+
<footer class="bd-ensemble container">
|
|
316
377
|
<div class="footer-nav-main-container">
|
|
317
378
|
<slot name="nav"></slot>
|
|
318
379
|
</div>
|
|
319
|
-
<bd-divider-horizontal width="100%" color="
|
|
380
|
+
<bd-divider-horizontal width="100%" color="inverse" opacity="0.25"></bd-divider-horizontal>
|
|
320
381
|
|
|
321
382
|
<div class="footer-links">
|
|
322
383
|
<div class="footer-links-left">
|
|
323
|
-
<bd-grid
|
|
324
|
-
cols="1"
|
|
325
|
-
cols-sm="1"
|
|
326
|
-
cols-md="2"
|
|
327
|
-
cols-lg="
|
|
384
|
+
<bd-grid
|
|
385
|
+
cols="1"
|
|
386
|
+
cols-sm="1"
|
|
387
|
+
cols-md="${Math.min(2, this._maxColumns)}"
|
|
388
|
+
cols-lg="${this._maxColumns}"
|
|
328
389
|
gap="lg"
|
|
329
390
|
align="start"
|
|
330
391
|
justify="start"
|
|
@@ -333,32 +394,32 @@ export class BdFooter extends LitElement {
|
|
|
333
394
|
<slot name="quick-links"></slot>
|
|
334
395
|
</bd-grid>
|
|
335
396
|
</div>
|
|
336
|
-
<bd-divider-horizontal class="tablet-divider" width="100%" color="
|
|
397
|
+
<bd-divider-horizontal class="tablet-divider" width="100%" color="inverse" opacity="0.25"></bd-divider-horizontal>
|
|
337
398
|
${this._isMobile
|
|
338
|
-
? html`<bd-divider-horizontal width="100%" color="
|
|
399
|
+
? html`<bd-divider-horizontal width="100%" color="inverse" opacity="0.25"></bd-divider-horizontal>`
|
|
339
400
|
: ''}
|
|
340
|
-
|
|
401
|
+
|
|
341
402
|
<div class="footer-links-right social-icons">
|
|
342
403
|
<slot name="social-links">
|
|
343
|
-
<bd-link href="https://www.facebook.com/bitdefender" target="_blank"
|
|
344
|
-
<bd-link href="https://twitter.com/bitdefender" target="_blank"
|
|
345
|
-
<bd-link href="https://www.linkedin.com/company/bitdefender" target="_blank"
|
|
346
|
-
<bd-link href="https://www.youtube.com/c/Bitdefender" target="_blank"
|
|
347
|
-
<bd-link href="https://www.instagram.com/bitdefender/" target="_blank"
|
|
348
|
-
<bd-link href="https://www.tiktok.com/@bitdefender" target="_blank"
|
|
404
|
+
<bd-link href="https://www.facebook.com/bitdefender" target="_blank" variant="secondary" class="bd-facebook">Facebook</bd-link>
|
|
405
|
+
<bd-link href="https://twitter.com/bitdefender" target="_blank" variant="secondary" class="bd-twitter">Twitter</bd-link>
|
|
406
|
+
<bd-link href="https://www.linkedin.com/company/bitdefender" target="_blank" variant="secondary" class="bd-linkedin">LinkedIn</bd-link>
|
|
407
|
+
<bd-link href="https://www.youtube.com/c/Bitdefender" target="_blank" variant="secondary" class="bd-youtube">YouTube</bd-link>
|
|
408
|
+
<bd-link href="https://www.instagram.com/bitdefender/" target="_blank" variant="secondary" class="bd-instagram">Instagram</bd-link>
|
|
409
|
+
<bd-link href="https://www.tiktok.com/@bitdefender" target="_blank" variant="secondary" class="bd-tiktok">TikTok</bd-link>
|
|
349
410
|
</slot>
|
|
350
411
|
</div>
|
|
351
412
|
</div>
|
|
352
413
|
|
|
353
414
|
${!this._isMobile
|
|
354
|
-
? html`<bd-divider-horizontal width="100%" color="
|
|
415
|
+
? html`<bd-divider-horizontal width="100%" color="inverse" opacity="0.25"></bd-divider-horizontal>`
|
|
355
416
|
: ''}
|
|
356
417
|
|
|
357
418
|
<div class="footer-middle-line">
|
|
358
419
|
<div class="secondary-nav-container">
|
|
359
420
|
<slot name="secondary-nav"></slot>
|
|
360
421
|
${this._isMobile
|
|
361
|
-
? html`<bd-divider-horizontal width="100%" color="
|
|
422
|
+
? html`<bd-divider-horizontal width="100%" color="inverse" opacity="0.25"></bd-divider-horizontal>`
|
|
362
423
|
: ''}
|
|
363
424
|
</div>
|
|
364
425
|
<div class="footer-address">
|
|
@@ -371,7 +432,7 @@ export class BdFooter extends LitElement {
|
|
|
371
432
|
</div>
|
|
372
433
|
</div>
|
|
373
434
|
|
|
374
|
-
<bd-divider-horizontal width="100%" color="
|
|
435
|
+
<bd-divider-horizontal width="100%" color="inverse" opacity="0.25"></bd-divider-horizontal>
|
|
375
436
|
|
|
376
437
|
<div class="footer-extra">
|
|
377
438
|
<div class="footer-copy">
|
|
@@ -379,7 +440,7 @@ export class BdFooter extends LitElement {
|
|
|
379
440
|
Copyright © 1997 - ${year} Bitdefender
|
|
380
441
|
</slot>
|
|
381
442
|
</div>
|
|
382
|
-
|
|
443
|
+
|
|
383
444
|
${showAnpc
|
|
384
445
|
? html`
|
|
385
446
|
<div class="footer-anpc">
|
|
@@ -389,7 +450,7 @@ export class BdFooter extends LitElement {
|
|
|
389
450
|
</div>
|
|
390
451
|
`
|
|
391
452
|
: null}
|
|
392
|
-
|
|
453
|
+
|
|
393
454
|
<div class="footer-countries-toggle">
|
|
394
455
|
<button class="country-toggle" @click="${this._toggleCountries}">
|
|
395
456
|
<bd-globe-icon size="20" color="white"></bd-globe-icon>
|
|
@@ -405,17 +466,26 @@ export class BdFooter extends LitElement {
|
|
|
405
466
|
${this._countriesOpen
|
|
406
467
|
? html`
|
|
407
468
|
<div class="footer-countries-container">
|
|
408
|
-
|
|
469
|
+
<!-- The icon is the only content and bd-close-icon's svg is aria-hidden,
|
|
470
|
+
so without a label this button had no accessible name at all: a
|
|
471
|
+
screen reader announced "button" and nothing else. WCAG 2.2 SC
|
|
472
|
+
4.1.2. The name goes on the control, never on the icon -- naming
|
|
473
|
+
both makes it announce twice. -->
|
|
474
|
+
<button
|
|
475
|
+
class="close-countries-button"
|
|
476
|
+
aria-label="Close country list"
|
|
477
|
+
@click="${this._closeCountries}"
|
|
478
|
+
>
|
|
409
479
|
<bd-close-icon size="18" color="white"></bd-close-icon>
|
|
410
480
|
</button>
|
|
411
481
|
${countryChunks.map(chunk => html`
|
|
412
482
|
<bd-footer-links-group slot="countries" title="${chunk === countryChunks[0] ? 'Choose your country' : ''}">
|
|
413
483
|
${chunk.map(c => html`
|
|
414
|
-
<bd-link
|
|
415
|
-
href="/${c.locale.toLowerCase()}/"
|
|
416
|
-
data-locale="${c.locale}"
|
|
417
|
-
|
|
418
|
-
class="${this.selectedCountry === c.label ? 'selected' : ''}"
|
|
484
|
+
<bd-link
|
|
485
|
+
href="/${c.locale.toLowerCase()}/"
|
|
486
|
+
data-locale="${c.locale}"
|
|
487
|
+
variant="light"
|
|
488
|
+
class="${this.selectedCountry === c.label ? 'selected' : ''}"
|
|
419
489
|
@click="${(e) => this._handleCountryClick(e, c.label, c.locale)}">
|
|
420
490
|
${c.label}
|
|
421
491
|
</bd-link>
|
|
@@ -429,7 +499,7 @@ export class BdFooter extends LitElement {
|
|
|
429
499
|
`;
|
|
430
500
|
}
|
|
431
501
|
|
|
432
|
-
static styles = [
|
|
502
|
+
static styles = [ensembleCSS, footerCSS];
|
|
433
503
|
}
|
|
434
504
|
|
|
435
505
|
customElements.define('bd-footer', BdFooter);
|
|
@@ -69,14 +69,14 @@ export default {
|
|
|
69
69
|
|
|
70
70
|
const quickLinks = html`
|
|
71
71
|
<bd-footer-links-group slot="quick-links" title="Products">
|
|
72
|
-
<bd-link href="/antivirus"
|
|
73
|
-
<bd-link href="/total-security"
|
|
74
|
-
<bd-link href="/vpn"
|
|
72
|
+
<bd-link href="/antivirus" variant="light">Antivirus</bd-link>
|
|
73
|
+
<bd-link href="/total-security" variant="light">Total Security</bd-link>
|
|
74
|
+
<bd-link href="/vpn" variant="light">VPN</bd-link>
|
|
75
75
|
</bd-footer-links-group>
|
|
76
76
|
<bd-footer-links-group slot="quick-links" title="Support">
|
|
77
|
-
<bd-link href="/support"
|
|
78
|
-
<bd-link href="/contact"
|
|
79
|
-
<bd-link href="/community"
|
|
77
|
+
<bd-link href="/support" variant="light">Help Center</bd-link>
|
|
78
|
+
<bd-link href="/contact" variant="light">Contact Us</bd-link>
|
|
79
|
+
<bd-link href="/community" variant="light">Community</bd-link>
|
|
80
80
|
</bd-footer-links-group>
|
|
81
81
|
`;
|
|
82
82
|
|
|
@@ -108,11 +108,11 @@ export const GermanLocale = {
|
|
|
108
108
|
<bd-footer current-locale="de">
|
|
109
109
|
${quickLinks}
|
|
110
110
|
<div slot="secondary-nav">
|
|
111
|
-
<bd-link href="/privacy"
|
|
111
|
+
<bd-link href="/privacy" variant="secondary">Privacy Policy</bd-link>
|
|
112
112
|
<bd-divider-vertical></bd-divider-vertical>
|
|
113
|
-
<bd-link href="/terms"
|
|
113
|
+
<bd-link href="/terms" variant="secondary">Terms</bd-link>
|
|
114
114
|
<bd-divider-vertical class="impressum-link"></bd-divider-vertical>
|
|
115
|
-
<bd-link href="/impressum"
|
|
115
|
+
<bd-link href="/impressum" variant="secondary" class="impressum-link">Impressum</bd-link>
|
|
116
116
|
</div>
|
|
117
117
|
</bd-footer>
|
|
118
118
|
`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const localeMap = { "en-AU": "Australia - English", "nl-BE": "België - Nederlands", "fr-BE": "Belgique - Français", "en-BZ": "Belize - English", "pt-BR": "Brasil - Português", "en-BG": "Bulgaria - English", "en-CA": "Canada - English", "es-CL": "Chile - Español", "es-CO": "Colombia - Español", "en-CZ": "Czechia - English", "en-DK": "Denmark - English", "de-DE": "Deutschland - Deutsch", "es-ES": "España - Español", "fr-FR": "France - Français", "zh-HK": "Hong Kong - China", "
|
|
1
|
+
export const localeMap = { "en-AU": "Australia - English", "nl-BE": "België - Nederlands", "fr-BE": "Belgique - Français", "en-BZ": "Belize - English", "pt-BR": "Brasil - Português", "en-BG": "Bulgaria - English", "en-CA": "Canada - English", "es-CL": "Chile - Español", "es-CO": "Colombia - Español", "en-CZ": "Czechia - English", "en-DK": "Denmark - English", "de-DE": "Deutschland - Deutsch", "es-ES": "España - Español", "fr-FR": "France - Français", "zh-HK": "Hong Kong - China", "en-HU": "Hungary - English", "en-IN": "India - English", "en-ID": "Indonesia - English", "en-IL": "Israel - English", "it-IT": "Italia - Italiano", "en-JM": "Jamaica - English", "en-LV": "Latvia - English", "en-MY": "Malaysia - English", "en-MT": "Malta - English", "es-MX": "México - Español", "nl-NL": "Nederland - Nederlands", "en-NZ": "New Zealand - English", "en-NO": "Norway - English", "de-AT": "Österreich - Deutsch", "es-PE": "Perú - Español", "en-PH": "Philippines - English", "en-PL": "Poland - English", "pt-PT": "Portugal - Português", "ro-RO": "România - Română", "en-SA": "Saudi Arabia - English", "de-CH": "Schweiz - Deutsch", "en-SG": "Singapore - English", "en-ZA": "South Africa - English", "en-KR": "South Korea - English", "sv-SE": "Sverige - Svenska", "zh-TW": "Taiwan - 台灣", "en-TH": "Thailand - English", "en-AE": "United Arab Emirates - English", "en-GB": "United Kingdom - English", "en-US": "United States - English", "ja-JP": "日本 - 日本語" };
|
|
@@ -1,13 +1,55 @@
|
|
|
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 gridCSS from "../grid/grid.css.js";
|
|
5
|
+
import { space } from "../shared/token-scales.js";
|
|
4
6
|
|
|
5
7
|
class BdGrid extends LitElement {
|
|
8
|
+
/* The three responsive properties name their attribute, and that is the
|
|
9
|
+
whole fix. Lit derives an observed attribute by LOWERCASING the property
|
|
10
|
+
name -- not by dash-casing it -- so `colsSm` observed `colssm` and the
|
|
11
|
+
`cols-sm` this component documents was not an attribute it had ever been
|
|
12
|
+
listening for. observedAttributes read
|
|
13
|
+
["cols","colssm","colsmd","colslg","gap","align","justify","padding"];
|
|
14
|
+
`cols` worked because it is one word, which is why the failure looked like
|
|
15
|
+
a responsive bug rather than a naming one.
|
|
16
|
+
|
|
17
|
+
So every dash-cased column attribute in the package was inert and the
|
|
18
|
+
properties kept their constructor defaults 1/1/2/3. Those defaults sit one
|
|
19
|
+
step under the 2/3/4 the Responsive columns story asks for, which is why
|
|
20
|
+
the rendered grid looked merely one breakpoint late instead of ignoring
|
|
21
|
+
the markup entirely. Measured across five stories x six viewports, 25 of
|
|
22
|
+
66 readings rendered a column count nobody had asked for:
|
|
23
|
+
|
|
24
|
+
Layout/Grid "Single column" cols-lg="1" -> 3 columns at 992 and 1440
|
|
25
|
+
Layout/Grid "Gap scale" cols-sm="3" -> 1 column at 576-767
|
|
26
|
+
Layout/Grid "Alignment" cols-sm="3" -> 1 column at 576-767
|
|
27
|
+
bd-footer quick links cols-lg="2" -> 3 columns at 992 and 1440
|
|
28
|
+
|
|
29
|
+
The last one is not a story: footer.js writes cols-md/cols-lg in its own
|
|
30
|
+
shadow root, so a shipped component's layout was running on the defaults
|
|
31
|
+
too.
|
|
32
|
+
|
|
33
|
+
Naming the attribute is what this package already does everywhere else --
|
|
34
|
+
94 explicit dash-cased mappings across 40 files, `heading-level`,
|
|
35
|
+
`visual-level`, `max-columns`, `min-card-width` -- and it is what the
|
|
36
|
+
component's own documentation promises: grid.stories.js reads "`cols`
|
|
37
|
+
below 576, then `cols-sm`, `cols-md` at 768 and `cols-lg` at 992", and its
|
|
38
|
+
argTypes map colsSm to the control name "cols-sm". The code was the only
|
|
39
|
+
part that disagreed.
|
|
40
|
+
|
|
41
|
+
An explicit name replaces the lowercase one rather than adding to it, so
|
|
42
|
+
`colssm` stops being observed. Nothing reads it: grepped for colssm,
|
|
43
|
+
colsmd, colslg and fallbacksrc across src, schemas and docs -- zero
|
|
44
|
+
occurrences outside these declarations. The responsive behaviour itself is
|
|
45
|
+
untouched; the media queries in grid.css.js and the 576/768/992 steps are
|
|
46
|
+
the ones that were already there, and this adds no smartness to a layout
|
|
47
|
+
primitive -- it only lets the primitive hear what it is told. */
|
|
6
48
|
static properties = {
|
|
7
49
|
cols : { type: Number }, // default cols
|
|
8
|
-
colsSm : { type: Number },
|
|
9
|
-
colsMd : { type: Number },
|
|
10
|
-
colsLg : { type: Number },
|
|
50
|
+
colsSm : { type: Number, attribute: "cols-sm" }, // optional cols on small screens
|
|
51
|
+
colsMd : { type: Number, attribute: "cols-md" }, // optional cols on medium
|
|
52
|
+
colsLg : { type: Number, attribute: "cols-lg" }, // optional cols on large
|
|
11
53
|
gap : { type: String }, // e.g., 'sm', 'md'
|
|
12
54
|
align : { type: String }, // start, center, end, stretch
|
|
13
55
|
justify: { type: String }, // start, center, end, space-between
|
|
@@ -38,10 +80,10 @@ class BdGrid extends LitElement {
|
|
|
38
80
|
--grid-cols-sm: ${this.colsSm};
|
|
39
81
|
--grid-cols-md: ${this.colsMd};
|
|
40
82
|
--grid-cols-lg: ${this.colsLg};
|
|
41
|
-
gap:
|
|
83
|
+
gap: ${space(this.gap)};
|
|
42
84
|
align-items: ${this.align};
|
|
43
85
|
justify-items: ${this.justify};
|
|
44
|
-
|
|
86
|
+
padding: ${space(this.padding)};
|
|
45
87
|
|
|
46
88
|
"
|
|
47
89
|
>
|
|
@@ -50,6 +92,6 @@ class BdGrid extends LitElement {
|
|
|
50
92
|
`;
|
|
51
93
|
}
|
|
52
94
|
}
|
|
53
|
-
BdGrid.styles = [
|
|
95
|
+
BdGrid.styles = [gridCSS];
|
|
54
96
|
|
|
55
97
|
customElements.define("bd-grid", BdGrid);
|