@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
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import { css } from "lit";
|
|
1
|
+
import { css, unsafeCSS } from "lit";
|
|
2
|
+
import { below } from "../shared/token-scales.js";
|
|
2
3
|
|
|
3
4
|
export const anchorNavStyles = css`
|
|
4
5
|
:host {
|
|
5
6
|
display: block;
|
|
6
7
|
width: 100%;
|
|
7
|
-
background: var(--color-
|
|
8
|
-
--bd-accesibility-focus: var(--color-blue-500);
|
|
9
|
-
--anchor-nav-max-width: 1290px;
|
|
10
|
-
border-top: var(--border-width-1) solid var(--color-neutral-100);
|
|
11
|
-
border-bottom: var(--border-width-1) solid var(--color-neutral-100);
|
|
8
|
+
background: var(--color-surface-default);
|
|
12
9
|
}
|
|
13
10
|
|
|
14
11
|
:host(.is-sticky) {
|
|
@@ -17,11 +14,7 @@ export const anchorNavStyles = css`
|
|
|
17
14
|
left: var(--sticky-left, 0);
|
|
18
15
|
width: var(--sticky-width, 100%);
|
|
19
16
|
box-shadow: var(--shadow-sm);
|
|
20
|
-
z-index:
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
:host(.is-sticky) nav {
|
|
24
|
-
background: var(--color-neutral-0);
|
|
17
|
+
z-index: var(--z-sticky);
|
|
25
18
|
}
|
|
26
19
|
|
|
27
20
|
nav {
|
|
@@ -30,6 +23,13 @@ export const anchorNavStyles = css`
|
|
|
30
23
|
padding: var(--spacing-0);
|
|
31
24
|
width: 100%;
|
|
32
25
|
box-sizing: border-box;
|
|
26
|
+
border-top: var(--border-width-1) solid var(--color-border-container);
|
|
27
|
+
border-bottom: var(--border-width-1) solid var(--color-border-container);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Când e sticky, păstrăm aceleași border-uri */
|
|
31
|
+
:host(.is-sticky) nav {
|
|
32
|
+
background: var(--color-surface-default);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
.bd-anchor-nav__inner {
|
|
@@ -39,20 +39,30 @@ export const anchorNavStyles = css`
|
|
|
39
39
|
align-items: center;
|
|
40
40
|
gap: var(--spacing-32);
|
|
41
41
|
width: 100%;
|
|
42
|
-
max-width: var(--anchor-nav-max-width);
|
|
43
42
|
padding-block: var(--spacing-10);
|
|
44
|
-
padding-inline: var(--layout-ensemble-inline-padding, var(--spacing-24));
|
|
45
|
-
margin-inline: auto;
|
|
46
43
|
box-sizing: border-box;
|
|
47
44
|
}
|
|
48
45
|
|
|
49
|
-
.anchor-link:focus-visible
|
|
50
|
-
|
|
46
|
+
/* No .anchor-link:focus-visible. .anchor-link is the class this component
|
|
47
|
+
puts on a bd-link HOST, and the focusable anchor lives inside bd-link's own
|
|
48
|
+
shadow root -- a host without delegatesFocus matches :focus and
|
|
49
|
+
:focus-within when focus is inside it, and never :focus-visible. Measured
|
|
50
|
+
with a real keyboard Tab at 1440: 4 .anchor-link hosts, 1 matching :focus,
|
|
51
|
+
0 matching :focus-visible, box-shadow none on all four. bd-link carries the
|
|
52
|
+
one ring and the links get it; the two selectors left here are a real
|
|
53
|
+
button and a real anchor in this shadow root. */
|
|
51
54
|
.bd-anchor-nav__dropdown-toggle:focus-visible,
|
|
52
55
|
.bd-anchor-nav__dropdown-option:focus-visible {
|
|
53
|
-
|
|
54
|
-
outline
|
|
55
|
-
|
|
56
|
+
/* the one focus ring — see Foundations/Focus */
|
|
57
|
+
outline: none;
|
|
58
|
+
box-shadow: var(--focus-outline-primary);
|
|
59
|
+
/* No border-radius here, for the reason back.css.js records: the ring is a
|
|
60
|
+
box-shadow and already follows the shape of what it sits on, and both of
|
|
61
|
+
these have a radius of their own -- --radius-lg on the toggle,
|
|
62
|
+
--radius-md on the option. Setting --focus-outline-radius as well pulled
|
|
63
|
+
the toggle's corners from 8px to 4px, and the option's from 6px to 4px,
|
|
64
|
+
for as long as either was focused. That token is the default for an
|
|
65
|
+
element with NO radius, which is what Foundations/Focus says. */
|
|
56
66
|
}
|
|
57
67
|
|
|
58
68
|
.anchor-links {
|
|
@@ -60,7 +70,11 @@ export const anchorNavStyles = css`
|
|
|
60
70
|
display: flex;
|
|
61
71
|
flex-wrap: wrap;
|
|
62
72
|
align-items: center;
|
|
63
|
-
gap
|
|
73
|
+
/* Column gap and row gap say different things here, so they are spelled
|
|
74
|
+
apart. The shorthand carried a --spacing-16 row gap that the next
|
|
75
|
+
declaration overrode on the following line: measured row-gap 8px, so the
|
|
76
|
+
16 was never a value anyone could read off the screen. */
|
|
77
|
+
column-gap: var(--spacing-32);
|
|
64
78
|
row-gap: var(--spacing-8);
|
|
65
79
|
flex: 1 1 auto;
|
|
66
80
|
min-width: 0;
|
|
@@ -71,61 +85,92 @@ export const anchorNavStyles = css`
|
|
|
71
85
|
.anchor-link {
|
|
72
86
|
position: relative;
|
|
73
87
|
text-decoration: none;
|
|
74
|
-
color: var(--color-
|
|
75
|
-
font-weight:
|
|
76
|
-
|
|
88
|
+
color: var(--color-text-primary);
|
|
89
|
+
/* No font-weight: body-regular, whose size this rule already asks for, is
|
|
90
|
+
normal -- and the inherited weight here is 400 too, measured, so the
|
|
91
|
+
declaration said nothing. .anchor-link.active still sets its own. */
|
|
77
92
|
display: inline-block;
|
|
78
93
|
font-size: var(--typography-body-regular-fontSize);
|
|
79
94
|
font-family: var(--typography-body-regular-fontFamily);
|
|
80
95
|
transition: color var(--transition-duration-fast) var(--transition-easing-smooth);
|
|
81
96
|
}
|
|
82
97
|
|
|
98
|
+
/* The padding belongs to the PART, not to the host.
|
|
99
|
+
|
|
100
|
+
A host's padding does not extend the anchor inside it, so this rule used
|
|
101
|
+
to build a 44px-tall row around a 24px-tall target: measured 63x44 on the
|
|
102
|
+
host with a 63x24 <a> inside it, and elementsFromPoint 4px below the top
|
|
103
|
+
edge came back bd-anchor-nav > bd-root > div with no <a> in the stack at
|
|
104
|
+
all. The top and bottom 10px of every item were dead, 45% of the height a
|
|
105
|
+
reader aims at.
|
|
106
|
+
|
|
107
|
+
It is also why the focus ring wrapped the glyphs rather than the item: the
|
|
108
|
+
ring is drawn on whatever element is focusable, and that was the 24px
|
|
109
|
+
anchor. One boundary, two symptoms.
|
|
110
|
+
|
|
111
|
+
bd-breadcrumb already fixed exactly this by moving its padding onto
|
|
112
|
+
::part(link) -- its comment records a 343x40 row whose focusable anchor
|
|
113
|
+
was 43x24 -- and this is the same move. Layout is unchanged: the host has
|
|
114
|
+
no padding now but wraps an anchor that does, so it still measures 44px
|
|
115
|
+
and the indicator's offset still lands on the bar's bottom edge. */
|
|
116
|
+
.anchor-link::part(link) {
|
|
117
|
+
padding: var(--spacing-10) var(--spacing-0);
|
|
118
|
+
}
|
|
119
|
+
|
|
83
120
|
.anchor-link.active {
|
|
121
|
+
/* no role: the active item in the anchor nav -- a state or modifier weight, not a text-content
|
|
122
|
+
type. See button.css.js's .button--bold for the argument. */
|
|
84
123
|
font-weight: var(--typography-fontWeight-semibold);
|
|
85
|
-
color: var(--color-
|
|
124
|
+
color: var(--color-text-primary);
|
|
86
125
|
}
|
|
87
126
|
|
|
88
|
-
.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
127
|
+
/* The .bd-link--primary / --secondary selectors that used to accompany these
|
|
128
|
+
matched nothing: bd-link is a custom element and those classes live inside
|
|
129
|
+
its shadow root, unreachable from here. Measured zero matches for
|
|
130
|
+
.bd-link--primary, .bd-link--secondary and .anchor-link.bd-link, against
|
|
131
|
+
four live .anchor-link elements. Only the reachable selectors remain. */
|
|
132
|
+
.anchor-link {
|
|
92
133
|
text-decoration: none !important;
|
|
93
134
|
}
|
|
94
135
|
|
|
95
|
-
.anchor-link:hover
|
|
96
|
-
.anchor-link.bd-link:hover,
|
|
97
|
-
.anchor-link.bd-link--primary:hover,
|
|
98
|
-
.anchor-link.bd-link--secondary:hover {
|
|
136
|
+
.anchor-link:hover {
|
|
99
137
|
text-decoration: none !important;
|
|
100
138
|
}
|
|
101
139
|
|
|
102
|
-
.anchor-link.
|
|
103
|
-
color: var(--color-
|
|
140
|
+
.anchor-link.active:hover {
|
|
141
|
+
color: var(--color-text-primary) !important;
|
|
142
|
+
text-decoration: none !important;
|
|
104
143
|
}
|
|
105
144
|
|
|
106
|
-
|
|
107
|
-
color: var(--color-neutral-900) !important;
|
|
108
|
-
}
|
|
145
|
+
/* The offset has to equal the inner's padding-bottom, and it did not.
|
|
109
146
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
147
|
+
The indicator is absolute inside the link box, and what it is aiming for
|
|
148
|
+
is the bar's bottom edge -- so the distance it has to travel is exactly
|
|
149
|
+
the padding the inner adds below the link. This rule said 14, which is
|
|
150
|
+
bd-page-switcher's number and not this component's: the inner here pads
|
|
151
|
+
10, so the indicator overshot by 4 and rendered BELOW the nav's bottom
|
|
152
|
+
border, detached from the bar it belongs to.
|
|
153
|
+
|
|
154
|
+
Measured before, at 1440 with the nav 66px tall including its borders:
|
|
155
|
+
link box bottom at 55, indicator occupying 66-69, nav bottom edge at 66.
|
|
156
|
+
After: 62-65, sitting directly on the border.
|
|
116
157
|
|
|
117
|
-
|
|
158
|
+
The indicator is now one element that slides between items rather than
|
|
159
|
+
an ::after per link, so the offset lives in _updateIndicator(), which
|
|
160
|
+
reads the inner's padding-bottom instead of a number -- the two move
|
|
161
|
+
together. */
|
|
162
|
+
.anchor-indicator {
|
|
118
163
|
position: absolute;
|
|
119
|
-
left: 0;
|
|
120
|
-
top: 0;
|
|
164
|
+
left: var(--spacing-0);
|
|
165
|
+
top: var(--spacing-0);
|
|
121
166
|
width: 0;
|
|
122
|
-
height: var(--
|
|
123
|
-
background-color: var(--color
|
|
167
|
+
height: var(--indicator-underline-height);
|
|
168
|
+
background-color: var(--indicator-color);
|
|
124
169
|
transform: translateX(0);
|
|
125
170
|
transition:
|
|
126
|
-
transform var(--
|
|
127
|
-
top var(--
|
|
128
|
-
width var(--
|
|
171
|
+
transform var(--indicator-underline-duration) var(--indicator-underline-easing),
|
|
172
|
+
top var(--indicator-underline-duration) var(--indicator-underline-easing),
|
|
173
|
+
width var(--indicator-underline-duration) var(--indicator-underline-easing);
|
|
129
174
|
pointer-events: none;
|
|
130
175
|
}
|
|
131
176
|
|
|
@@ -143,16 +188,34 @@ export const anchorNavStyles = css`
|
|
|
143
188
|
justify-content: space-between;
|
|
144
189
|
gap: var(--spacing-12);
|
|
145
190
|
width: 100%;
|
|
146
|
-
min-height: var(--dimension-
|
|
191
|
+
min-height: var(--dimension-48);
|
|
147
192
|
padding-block: var(--spacing-10);
|
|
148
193
|
padding-inline: var(--spacing-16);
|
|
149
194
|
box-sizing: border-box;
|
|
150
195
|
font-family: var(--typography-fontFamily-sans);
|
|
151
196
|
font-size: var(--typography-body-regular-fontSize);
|
|
197
|
+
/* The leading that belongs to the size above. It was absent, so the label
|
|
198
|
+
and the ellipsised text inside it were laid out on IBM Plex Sans's own
|
|
199
|
+
"normal" metric -- a leading nobody chose, and one that stops being 1.25
|
|
200
|
+
the moment the font falls back. */
|
|
201
|
+
line-height: var(--typography-body-regular-lineHeight);
|
|
202
|
+
/* no role: the weight of a control, not a text-content type -- see
|
|
203
|
+
button.css.js's .button--bold. Nothing in the vocabulary carries semibold
|
|
204
|
+
at a body size anyway: all ten heavy-weight roles are headings or display
|
|
205
|
+
steps at 2xl and up. */
|
|
152
206
|
font-weight: var(--typography-fontWeight-semibold);
|
|
153
|
-
color: var(--color-
|
|
207
|
+
color: var(--color-text-primary);
|
|
208
|
+
/* no role: --color-surface-container is neutral-25 exactly, and it is the
|
|
209
|
+
wrong role -- it means "the ground of a self-contained object, a card, a
|
|
210
|
+
tile, a panel", and this is a control somebody operates. The control
|
|
211
|
+
families cannot say it either: --form-input-default-backgroundColor is
|
|
212
|
+
white, and this toggle deliberately sits one step off it. A ground for a
|
|
213
|
+
bordered control at rest has no role, and this is its one consumer. */
|
|
154
214
|
background: var(--color-neutral-25);
|
|
155
|
-
|
|
215
|
+
/* A control edge, so it takes the role the form-field atom uses for one.
|
|
216
|
+
neutral-200 is border-subtle's value, which is documented as the wrong
|
|
217
|
+
role for the edge of something a person operates. */
|
|
218
|
+
border: var(--border-width-1) solid var(--color-border-default);
|
|
156
219
|
border-radius: var(--radius-lg);
|
|
157
220
|
cursor: pointer;
|
|
158
221
|
text-align: left;
|
|
@@ -163,12 +226,34 @@ export const anchorNavStyles = css`
|
|
|
163
226
|
}
|
|
164
227
|
|
|
165
228
|
.bd-anchor-nav__dropdown-toggle:hover {
|
|
166
|
-
background: var(--color-
|
|
167
|
-
|
|
229
|
+
background: var(--color-surface-subtle);
|
|
230
|
+
/* The edge of a bordered control under the pointer, and this package
|
|
231
|
+
already had an answer for it: radio.css.js and checkbox.css.js both take
|
|
232
|
+
--color-action-primary-hover for exactly this job, four declarations
|
|
233
|
+
across two atoms. This rule was the only one on a primitive.
|
|
234
|
+
.
|
|
235
|
+
Measured against this toggle's own hover ground (--color-surface-subtle):
|
|
236
|
+
neutral-500 was 4.17:1 and blue-600 is 5.51:1, so the adoption improves
|
|
237
|
+
the edge rather than trading contrast for consistency. The visible change
|
|
238
|
+
is that the hover edge goes from grey to blue, which is what radio and
|
|
239
|
+
checkbox already do.
|
|
240
|
+
.
|
|
241
|
+
Note the token is an ACTION role rather than a --color-border-* one. That
|
|
242
|
+
is deliberate and is how the two atoms use it too: an interaction state
|
|
243
|
+
is the job, and the border roles describe permanence -- default, subtle,
|
|
244
|
+
strong -- not what a control does under a pointer. */
|
|
245
|
+
border-color: var(--color-action-primary-hover);
|
|
168
246
|
}
|
|
169
247
|
|
|
170
248
|
.bd-anchor-nav__dropdown-toggle[aria-expanded="true"] {
|
|
171
|
-
background: var(--color-
|
|
249
|
+
background: var(--color-surface-subtle);
|
|
250
|
+
/* no role: the edge while the panel is open. No border role sits at
|
|
251
|
+
blue-200 -- only --status-brand-border and --status-info-border, and an
|
|
252
|
+
open disclosure is neither a brand nor an information STATUS. The nearest
|
|
253
|
+
control token is --form-input-focus-borderColor, which is blue-500 and
|
|
254
|
+
means focused rather than expanded; the two states are independent here,
|
|
255
|
+
since the toggle can be focused and closed. Expanded has no vocabulary
|
|
256
|
+
in either control family. */
|
|
172
257
|
border-color: var(--color-blue-200);
|
|
173
258
|
}
|
|
174
259
|
|
|
@@ -181,16 +266,26 @@ export const anchorNavStyles = css`
|
|
|
181
266
|
transform-origin: left center;
|
|
182
267
|
}
|
|
183
268
|
|
|
269
|
+
/* The mark inside is bd-arrow-down-icon, the same atom bd-custom-dropdown's
|
|
270
|
+
caret and the accordion's toggle use. It was an inline stroked svg written
|
|
271
|
+
into the template -- stroke-width 2 with round caps, so a visibly different
|
|
272
|
+
chevron from the filled one the rest of the package draws, and invisible to
|
|
273
|
+
check:icons. This span keeps the colour and the rotation; the icon reads
|
|
274
|
+
currentColor from it, which is what every icon site here does. */
|
|
184
275
|
.bd-anchor-nav__dropdown-chevron {
|
|
185
276
|
flex: 0 0 auto;
|
|
186
277
|
display: flex;
|
|
187
|
-
color: var(--color-
|
|
278
|
+
color: var(--color-text-muted);
|
|
188
279
|
transition: transform var(--transition-duration-normal) var(--transition-easing-smooth);
|
|
189
280
|
}
|
|
190
281
|
|
|
191
282
|
.bd-anchor-nav__dropdown-toggle[aria-expanded="true"] .bd-anchor-nav__dropdown-chevron {
|
|
192
283
|
transform: rotate(180deg);
|
|
193
|
-
|
|
284
|
+
/* The brand ink, matching the resting state three rules up, which already reads
|
|
285
|
+
--color-text-muted. A chevron is a currentColor glyph, so it takes the ink role
|
|
286
|
+
of its context -- the answer ten other icon sites in this package already give.
|
|
287
|
+
Visible: 4.05:1 -> 5.51:1 on the toggle's grey tint. */
|
|
288
|
+
color: var(--color-text-brand);
|
|
194
289
|
}
|
|
195
290
|
|
|
196
291
|
.bd-anchor-nav__dropdown-panel {
|
|
@@ -198,13 +293,13 @@ export const anchorNavStyles = css`
|
|
|
198
293
|
left: var(--spacing-0);
|
|
199
294
|
right: var(--spacing-0);
|
|
200
295
|
top: 100%;
|
|
201
|
-
z-index:
|
|
296
|
+
z-index: var(--z-overlay);
|
|
202
297
|
max-height: min(50vh, 20rem);
|
|
203
298
|
overflow-y: auto;
|
|
204
|
-
background: var(--color-
|
|
299
|
+
background: var(--color-surface-default);
|
|
205
300
|
border: var(--border-width-1) solid var(--color-blue-200);
|
|
206
301
|
border-top: none;
|
|
207
|
-
border-radius: var(--
|
|
302
|
+
border-radius: var(--radius-none) var(--radius-none) var(--radius-lg) var(--radius-lg);
|
|
208
303
|
box-shadow: var(--shadow-md);
|
|
209
304
|
}
|
|
210
305
|
|
|
@@ -221,14 +316,26 @@ export const anchorNavStyles = css`
|
|
|
221
316
|
display: flex;
|
|
222
317
|
align-items: center;
|
|
223
318
|
width: 100%;
|
|
224
|
-
|
|
319
|
+
text-decoration: none;
|
|
320
|
+
min-height: var(--dimension-48);
|
|
225
321
|
padding-block: var(--spacing-12);
|
|
226
322
|
padding-inline: var(--spacing-16);
|
|
227
323
|
box-sizing: border-box;
|
|
228
324
|
font-family: var(--typography-fontFamily-sans);
|
|
229
325
|
font-size: var(--typography-body-regular-fontSize);
|
|
230
|
-
|
|
231
|
-
|
|
326
|
+
/* As the toggle above: the size named its role and the leading did not
|
|
327
|
+
follow it. This one can wrap -- a long section title in a narrow
|
|
328
|
+
dropdown -- and CLAUDE.md asks for at least 1.25 on anything that can. */
|
|
329
|
+
line-height: var(--typography-body-regular-lineHeight);
|
|
330
|
+
/* No font-weight: as .anchor-link above -- body-regular is normal and so is
|
|
331
|
+
the inherited value. The --active variant sets its own. */
|
|
332
|
+
/* text/brand, the same resting ink the desktop items take. This is the
|
|
333
|
+
same component below md showing the same items, so it expresses the same
|
|
334
|
+
meaning: colour is AVAILABLE and neutral is current. It read
|
|
335
|
+
text/primary here, which made the current option the only blue one --
|
|
336
|
+
the inverse of the family, and the arrangement the desktop bar was just
|
|
337
|
+
moved off. */
|
|
338
|
+
color: var(--color-text-brand);
|
|
232
339
|
background: transparent;
|
|
233
340
|
border: none;
|
|
234
341
|
border-radius: var(--radius-md);
|
|
@@ -239,19 +346,40 @@ export const anchorNavStyles = css`
|
|
|
239
346
|
background var(--transition-duration-fast) var(--transition-easing-smooth);
|
|
240
347
|
}
|
|
241
348
|
|
|
349
|
+
/* Hover on a dropdown option is the action responsibility, and it is now the
|
|
350
|
+
same step the desktop items hover to -- action/primary-active rather than
|
|
351
|
+
-hover, so brand darkens the same way in both presentations. blue-700 on
|
|
352
|
+
the --color-neutral-25 this hover sets measures 8.19:1; the blue-500 that
|
|
353
|
+
stood here before either role measured 4.34 and failed. The background is
|
|
354
|
+
the dropdown's own affordance and is not part of the ink contract. */
|
|
242
355
|
.bd-anchor-nav__dropdown-option:hover:not(.bd-anchor-nav__dropdown-option--active) {
|
|
243
|
-
color: var(--color-
|
|
356
|
+
color: var(--color-action-primary-active);
|
|
244
357
|
background: var(--color-neutral-25);
|
|
245
358
|
}
|
|
246
359
|
|
|
360
|
+
/* The current option, in the family's terms: neutral ink at the weight the
|
|
361
|
+
other two use for the same job, and the blue-50 fill is this presentation's
|
|
362
|
+
indicator -- a dropdown row has no bottom edge to underline, so the fill
|
|
363
|
+
carries what the 3px line carries on the bars.
|
|
364
|
+
|
|
365
|
+
It used to be action/primary-active, which was defensible on its own
|
|
366
|
+
terms -- an option with aria-current, a click handler and a tinted fill is
|
|
367
|
+
an interactive element in an engaged state -- but it made the current item
|
|
368
|
+
the bluest thing in the list while every other item was neutral. Under one
|
|
369
|
+
contract for the whole family that reading is inverted: colour marks what
|
|
370
|
+
you can go to, neutral marks where you are. */
|
|
247
371
|
.bd-anchor-nav__dropdown-option--active {
|
|
248
|
-
|
|
372
|
+
/* no role: the weight that marks the current option -- a state or modifier
|
|
373
|
+
weight, not a text-content type. 700, the same as bd-link's
|
|
374
|
+
.bd-link--active and bd-tab-list's selected tab. */
|
|
375
|
+
font-weight: var(--typography-fontWeight-bold);
|
|
249
376
|
background: var(--color-blue-50);
|
|
250
|
-
color: var(--color-
|
|
377
|
+
color: var(--color-text-primary);
|
|
251
378
|
}
|
|
252
379
|
|
|
380
|
+
/* The current option does not move under the pointer, as on the bars. */
|
|
253
381
|
.bd-anchor-nav__dropdown-option--active:hover {
|
|
254
|
-
color: var(--color-
|
|
382
|
+
color: var(--color-text-primary);
|
|
255
383
|
background: var(--color-blue-50);
|
|
256
384
|
}
|
|
257
385
|
|
|
@@ -259,33 +387,13 @@ export const anchorNavStyles = css`
|
|
|
259
387
|
flex-shrink: 0;
|
|
260
388
|
}
|
|
261
389
|
|
|
262
|
-
.bd-anchor-nav__cta
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
border-radius: var(--radius-md);
|
|
270
|
-
cursor: pointer;
|
|
271
|
-
background: var(--color-red-500);
|
|
272
|
-
color: var(--color-neutral-0);
|
|
273
|
-
text-decoration: none !important;
|
|
274
|
-
transition: background var(--transition-duration-fast) var(--transition-easing-smooth);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
.bd-anchor-nav__cta:hover {
|
|
278
|
-
background: var(--color-red-600);
|
|
279
|
-
color: var(--color-neutral-0);
|
|
280
|
-
text-decoration: none !important;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
.bd-anchor-nav__cta:active {
|
|
284
|
-
background: var(--color-red-700);
|
|
285
|
-
color: var(--color-neutral-0);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
.bd-anchor-nav__cta::after {
|
|
390
|
+
/* The .bd-anchor-nav__cta rules stood here: a base rule, hover, active,
|
|
391
|
+
focus-visible, an ::after reset and a full-width rule below md. The class
|
|
392
|
+
appears nowhere but this stylesheet -- not in anchor-nav.js, not in a story
|
|
393
|
+
-- because the CTA became a slot, and ::slotted([slot="cta"]) one rule up
|
|
394
|
+
is what styles it now. Measured across 556 stories: 0 matches in 14 shadow
|
|
395
|
+
roots. */
|
|
396
|
+
.bd-anchor-nav__dropdown-option::after {
|
|
289
397
|
display: none;
|
|
290
398
|
}
|
|
291
399
|
|
|
@@ -302,9 +410,17 @@ export const anchorNavStyles = css`
|
|
|
302
410
|
transition: none !important;
|
|
303
411
|
animation: none !important;
|
|
304
412
|
}
|
|
413
|
+
|
|
414
|
+
/* The underline grows via a transition, not an animation, so the rule
|
|
415
|
+
above never reached it. Same for the chevron and the option hover. */
|
|
416
|
+
.anchor-link,
|
|
417
|
+
.bd-anchor-nav__dropdown-chevron,
|
|
418
|
+
.bd-anchor-nav__dropdown-option {
|
|
419
|
+
transition: none !important;
|
|
420
|
+
}
|
|
305
421
|
}
|
|
306
422
|
|
|
307
|
-
@media (
|
|
423
|
+
@media ${unsafeCSS(below('md'))} {
|
|
308
424
|
.bd-anchor-nav__inner {
|
|
309
425
|
flex-direction: column;
|
|
310
426
|
align-items: stretch;
|
|
@@ -344,9 +460,5 @@ export const anchorNavStyles = css`
|
|
|
344
460
|
margin-top: var(--spacing-0);
|
|
345
461
|
}
|
|
346
462
|
|
|
347
|
-
.bd-anchor-nav__cta {
|
|
348
|
-
width: 100%;
|
|
349
|
-
box-sizing: border-box;
|
|
350
|
-
}
|
|
351
463
|
}
|
|
352
464
|
`;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { LitElement, html, nothing } from "lit";
|
|
2
|
+
// Installs the design tokens into document scope; see src/tokens/tokens.js
|
|
3
|
+
import "../../tokens/tokens.js";
|
|
4
|
+
import "../icons/arrow-down-icon.js";
|
|
3
5
|
import "../button/button.js";
|
|
4
6
|
import "../link/link.js";
|
|
5
7
|
import { anchorNavStyles } from "./anchor-nav.css.js";
|
|
8
|
+
import { ensembleCSS } from "../shared/ensemble.css.js";
|
|
9
|
+
import { matchesBelow } from "../shared/token-scales.js";
|
|
6
10
|
|
|
7
11
|
function parseLengthToPx(value) {
|
|
8
12
|
const s = (value || "").trim();
|
|
@@ -37,7 +41,7 @@ class BdAnchorNav extends LitElement {
|
|
|
37
41
|
stickyTop : { type: String, attribute: "sticky-top" }
|
|
38
42
|
};
|
|
39
43
|
|
|
40
|
-
static styles = [
|
|
44
|
+
static styles = [ensembleCSS, anchorNavStyles];
|
|
41
45
|
|
|
42
46
|
constructor() {
|
|
43
47
|
super();
|
|
@@ -122,11 +126,6 @@ class BdAnchorNav extends LitElement {
|
|
|
122
126
|
const links = this.renderRoot?.querySelector(".anchor-links--desktop");
|
|
123
127
|
if (links && "ResizeObserver" in window) {
|
|
124
128
|
this._indicatorResizeObserver = new ResizeObserver(() => {
|
|
125
|
-
console.log("[anchor-nav] ResizeObserver fired", {
|
|
126
|
-
isSticky : this.classList.contains("is-sticky"),
|
|
127
|
-
navRect : this.getBoundingClientRect(),
|
|
128
|
-
linksRect: links.getBoundingClientRect()
|
|
129
|
-
});
|
|
130
129
|
this._updateIndicator("ResizeObserver");
|
|
131
130
|
});
|
|
132
131
|
this._indicatorResizeObserver.observe(links);
|
|
@@ -143,7 +142,10 @@ class BdAnchorNav extends LitElement {
|
|
|
143
142
|
|
|
144
143
|
const left = activeLink.offsetLeft;
|
|
145
144
|
const width = activeLink.offsetWidth;
|
|
146
|
-
|
|
145
|
+
// The bar's bottom edge is the inner's padding-bottom below the link.
|
|
146
|
+
const inner = this.renderRoot.querySelector(".bd-anchor-nav__inner");
|
|
147
|
+
const gap = inner ? parseFloat(getComputedStyle(inner).paddingBottom) || 0 : 0;
|
|
148
|
+
const top = activeLink.offsetTop + activeLink.offsetHeight + gap;
|
|
147
149
|
|
|
148
150
|
if (!this._indicatorReady) {
|
|
149
151
|
indicator.style.transition = "none";
|
|
@@ -167,7 +169,7 @@ class BdAnchorNav extends LitElement {
|
|
|
167
169
|
}
|
|
168
170
|
|
|
169
171
|
_handleMobileFullWidth() {
|
|
170
|
-
const isMobile =
|
|
172
|
+
const isMobile = matchesBelow('md');
|
|
171
173
|
const ctaSlot = this.shadowRoot?.querySelector('slot[name="cta"]');
|
|
172
174
|
|
|
173
175
|
if (!ctaSlot) return;
|
|
@@ -242,17 +244,6 @@ class BdAnchorNav extends LitElement {
|
|
|
242
244
|
this._onStickyScroll();
|
|
243
245
|
};
|
|
244
246
|
|
|
245
|
-
this._onStickyResize = () => {
|
|
246
|
-
this._stickyOriginalTop = null;
|
|
247
|
-
if (this.classList.contains("is-sticky")) {
|
|
248
|
-
const parent = this.parentElement;
|
|
249
|
-
const parentRect = parent.getBoundingClientRect();
|
|
250
|
-
this.style.setProperty("--sticky-left", `${parentRect.left}px`);
|
|
251
|
-
this.style.setProperty("--sticky-width", `${parentRect.width}px`);
|
|
252
|
-
}
|
|
253
|
-
this._onStickyScroll();
|
|
254
|
-
};
|
|
255
|
-
|
|
256
247
|
window.addEventListener("scroll", this._onStickyScroll, { passive: true });
|
|
257
248
|
window.addEventListener("resize", this._onStickyResize, { passive: true });
|
|
258
249
|
requestAnimationFrame(() => this._onStickyScroll());
|
|
@@ -318,6 +309,8 @@ class BdAnchorNav extends LitElement {
|
|
|
318
309
|
if (e.key === "Escape" && this._dropdownOpen) {
|
|
319
310
|
this._dropdownOpen = false;
|
|
320
311
|
this.requestUpdate();
|
|
312
|
+
this.updateComplete.then(() =>
|
|
313
|
+
this.renderRoot?.querySelector(".bd-anchor-nav__dropdown-toggle")?.focus());
|
|
321
314
|
}
|
|
322
315
|
}
|
|
323
316
|
|
|
@@ -372,7 +365,7 @@ class BdAnchorNav extends LitElement {
|
|
|
372
365
|
}
|
|
373
366
|
}
|
|
374
367
|
|
|
375
|
-
const isMobile =
|
|
368
|
+
const isMobile = matchesBelow('md');
|
|
376
369
|
const firstHref = resolved[0]?.href.replace(/^#/, "") || "anchor-1-section";
|
|
377
370
|
const first = document.getElementById(firstHref);
|
|
378
371
|
let nextCta;
|
|
@@ -390,7 +383,7 @@ class BdAnchorNav extends LitElement {
|
|
|
390
383
|
_playMobileDropdownLabelSwap() {
|
|
391
384
|
if (typeof window === "undefined") return;
|
|
392
385
|
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
|
393
|
-
if (!
|
|
386
|
+
if (!matchesBelow('md')) return;
|
|
394
387
|
const el = this.renderRoot?.querySelector(".bd-anchor-nav__dropdown-label");
|
|
395
388
|
if (!el) return;
|
|
396
389
|
el.classList.remove("bd-anchor-nav__dropdown-label--swap");
|
|
@@ -475,12 +468,11 @@ class BdAnchorNav extends LitElement {
|
|
|
475
468
|
return html`
|
|
476
469
|
<bd-link
|
|
477
470
|
href="${href}"
|
|
478
|
-
|
|
471
|
+
variant="primary"
|
|
479
472
|
no-underline
|
|
480
473
|
class="anchor-link ${isActive ? "active" : ""}"
|
|
481
|
-
color="var(--color-neutral-900)"
|
|
482
474
|
?active=${isActive}
|
|
483
|
-
aria-current=${isActive ? "
|
|
475
|
+
aria-current=${isActive ? "location" : nothing}
|
|
484
476
|
@click=${(e) => this.handleClick(e, id, href)}
|
|
485
477
|
>${title}</bd-link>
|
|
486
478
|
`;
|
|
@@ -494,7 +486,7 @@ class BdAnchorNav extends LitElement {
|
|
|
494
486
|
return html`
|
|
495
487
|
<nav aria-label=${this.navLabel}>
|
|
496
488
|
<div
|
|
497
|
-
class="bd-anchor-nav__inner"
|
|
489
|
+
class="bd-ensemble bd-anchor-nav__inner"
|
|
498
490
|
part="inner"
|
|
499
491
|
style="${innerStyle}"
|
|
500
492
|
?data-mobile-cta-visible=${this._mobileCtaRevealed}
|
|
@@ -507,35 +499,29 @@ class BdAnchorNav extends LitElement {
|
|
|
507
499
|
class="bd-anchor-nav__dropdown-toggle"
|
|
508
500
|
aria-expanded=${this._dropdownOpen ? "true" : "false"}
|
|
509
501
|
aria-controls=${this._panelId}
|
|
510
|
-
aria-haspopup="listbox"
|
|
511
502
|
@click=${this._toggleDropdown}
|
|
512
503
|
>
|
|
513
504
|
<span class="bd-anchor-nav__dropdown-label">${dropdownLabel}</span>
|
|
514
505
|
<span class="bd-anchor-nav__dropdown-chevron" aria-hidden="true">
|
|
515
|
-
<
|
|
516
|
-
<path d="M5 8l5 5 5-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
517
|
-
</svg>
|
|
506
|
+
<bd-arrow-down-icon size="md"></bd-arrow-down-icon>
|
|
518
507
|
</span>
|
|
519
508
|
</button>
|
|
520
509
|
<div
|
|
521
510
|
class="bd-anchor-nav__dropdown-panel"
|
|
522
511
|
id=${this._panelId}
|
|
523
|
-
role="listbox"
|
|
524
|
-
aria-label=${this.navLabel}
|
|
525
512
|
?hidden=${!this._dropdownOpen}
|
|
526
513
|
>
|
|
527
|
-
<ul class="bd-anchor-nav__dropdown-list"
|
|
514
|
+
<ul class="bd-anchor-nav__dropdown-list">
|
|
528
515
|
${resolved.map(({ id, title, href }) => {
|
|
529
516
|
const isActive = this.activeId === id;
|
|
530
517
|
return html`
|
|
531
|
-
<li
|
|
532
|
-
<
|
|
533
|
-
|
|
534
|
-
role="option"
|
|
518
|
+
<li>
|
|
519
|
+
<a
|
|
520
|
+
href="${href}"
|
|
535
521
|
class="bd-anchor-nav__dropdown-option ${isActive ? "bd-anchor-nav__dropdown-option--active" : ""}"
|
|
536
|
-
aria-
|
|
522
|
+
aria-current=${isActive ? "location" : nothing}
|
|
537
523
|
@click=${(e) => this._selectFromDropdown(e, id, href)}
|
|
538
|
-
>${title}</
|
|
524
|
+
>${title}</a>
|
|
539
525
|
</li>
|
|
540
526
|
`;
|
|
541
527
|
})}
|