@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
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared chrome for the Design Tokens stories.
|
|
3
|
+
*
|
|
4
|
+
* Every page in that section uses this module so they stay consistent by
|
|
5
|
+
* construction rather than by five copies of the same CSS. It also carries the
|
|
6
|
+
* token-discovery and contrast helpers, so a docs page never hardcodes a scale
|
|
7
|
+
* that could drift from the tokens themselves.
|
|
8
|
+
*
|
|
9
|
+
* Not a story file: Storybook only globs *.stories.js.
|
|
10
|
+
*/
|
|
11
|
+
import { html } from 'lit';
|
|
12
|
+
|
|
13
|
+
/* ============================================================
|
|
14
|
+
Token discovery — read the real values out of the loaded CSS
|
|
15
|
+
============================================================ */
|
|
16
|
+
|
|
17
|
+
/** Concatenated text of every readable stylesheet in the document. */
|
|
18
|
+
export function readAllCssText() {
|
|
19
|
+
let text = '';
|
|
20
|
+
for (const sheet of Array.from(document.styleSheets)) {
|
|
21
|
+
let rules;
|
|
22
|
+
try {
|
|
23
|
+
rules = sheet.cssRules;
|
|
24
|
+
} catch {
|
|
25
|
+
continue; // cross-origin sheet, skip
|
|
26
|
+
}
|
|
27
|
+
for (const rule of Array.from(rules)) text += `${rule.cssText}\n`;
|
|
28
|
+
}
|
|
29
|
+
return text;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Resolves a custom property to its computed value on :root. */
|
|
33
|
+
export function resolve(token) {
|
|
34
|
+
return getComputedStyle(document.documentElement).getPropertyValue(token)
|
|
35
|
+
.trim();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Finds every custom property whose name matches `pattern`, in declaration
|
|
40
|
+
* order, de-duplicated. `pattern` must have the token name as group 1.
|
|
41
|
+
*/
|
|
42
|
+
export function discoverTokens(cssText, pattern) {
|
|
43
|
+
const seen = new Set();
|
|
44
|
+
const found = [];
|
|
45
|
+
for (const match of cssText.matchAll(pattern)) {
|
|
46
|
+
const token = match[1];
|
|
47
|
+
if (seen.has(token)) continue;
|
|
48
|
+
seen.add(token);
|
|
49
|
+
found.push(match);
|
|
50
|
+
}
|
|
51
|
+
return found;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Maps each palette/primitive token to the tokens that reference it. */
|
|
55
|
+
export function discoverConsumers(cssText) {
|
|
56
|
+
const consumers = new Map();
|
|
57
|
+
const pattern = /(--[A-Za-z0-9-]+)\s*:\s*var\(\s*(--[A-Za-z0-9-]+)\s*\)/g;
|
|
58
|
+
for (const [, token, referenced] of cssText.matchAll(pattern)) {
|
|
59
|
+
if (!consumers.has(referenced)) consumers.set(referenced, new Set());
|
|
60
|
+
consumers.get(referenced).add(token);
|
|
61
|
+
}
|
|
62
|
+
return consumers;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* ============================================================
|
|
66
|
+
Colour maths — WCAG 2.1 relative luminance and contrast
|
|
67
|
+
============================================================ */
|
|
68
|
+
|
|
69
|
+
export const INK = '#151719'; // --color-neutral-900
|
|
70
|
+
export const PAPER = '#ffffff'; // --color-neutral-0
|
|
71
|
+
|
|
72
|
+
/** Resolves any CSS colour notation to [r, g, b] via the browser. */
|
|
73
|
+
export function toRgb(value) {
|
|
74
|
+
const probe = document.createElement('span');
|
|
75
|
+
probe.style.cssText = 'position:absolute;visibility:hidden';
|
|
76
|
+
probe.style.color = value;
|
|
77
|
+
document.body.appendChild(probe);
|
|
78
|
+
const computed = getComputedStyle(probe).color;
|
|
79
|
+
probe.remove();
|
|
80
|
+
const parts = computed.match(/-?[\d.]+/g);
|
|
81
|
+
return parts ? parts.slice(0, 3).map(Number) : [0, 0, 0];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function luminance([r, g, b]) {
|
|
85
|
+
const [lr, lg, lb] = [r, g, b]
|
|
86
|
+
.map(channel => channel / 255)
|
|
87
|
+
.map(channel => (channel <= 0.03928 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4));
|
|
88
|
+
return 0.2126 * lr + 0.7152 * lg + 0.0722 * lb;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function contrast(a, b) {
|
|
92
|
+
const [hi, lo] = [luminance(toRgb(a)), luminance(toRgb(b))].sort((x, y) => y - x);
|
|
93
|
+
return (hi + 0.05) / (lo + 0.05);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function toHex(value) {
|
|
97
|
+
return `#${toRgb(value)
|
|
98
|
+
.map(channel => Math.round(channel).toString(16)
|
|
99
|
+
.padStart(2, '0'))
|
|
100
|
+
.join('')}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** WCAG level reached by a contrast ratio for normal-size body text. */
|
|
104
|
+
export function wcagLevel(ratio) {
|
|
105
|
+
if (ratio >= 7) return { label: 'AAA', pass: true };
|
|
106
|
+
if (ratio >= 4.5) return { label: 'AA', pass: true };
|
|
107
|
+
if (ratio >= 3) return { label: '18pt', pass: true }; // large text / UI edges only
|
|
108
|
+
return { label: 'fail', pass: false };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function levelBadge(ratio) {
|
|
112
|
+
const { label, pass } = wcagLevel(ratio);
|
|
113
|
+
return html`<span class="level" data-pass=${pass}>${label}</span>`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* ============================================================
|
|
117
|
+
Shared styles
|
|
118
|
+
============================================================ */
|
|
119
|
+
|
|
120
|
+
export const chromeStyles = html`
|
|
121
|
+
<style>
|
|
122
|
+
/* The Storybook canvas is transparent, so it inherits the OS colour
|
|
123
|
+
scheme. Paint an explicit surface: there are no dark-mode tokens yet. */
|
|
124
|
+
.docs {
|
|
125
|
+
font-family: var(--typography-fontFamily-sans);
|
|
126
|
+
color: var(--color-neutral-900);
|
|
127
|
+
background: var(--color-neutral-0);
|
|
128
|
+
padding: var(--spacing-24);
|
|
129
|
+
box-sizing: border-box;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.docs-inner {
|
|
133
|
+
max-width: 1180px;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.docs h1 {
|
|
137
|
+
font-size: var(--typography-fontSize-2xl);
|
|
138
|
+
font-weight: var(--typography-fontWeight-semibold);
|
|
139
|
+
margin: 0 0 var(--spacing-8);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.docs-lede {
|
|
143
|
+
font-size: var(--typography-fontSize-sm);
|
|
144
|
+
line-height: var(--typography-lineHeight-normal);
|
|
145
|
+
color: var(--color-neutral-600);
|
|
146
|
+
margin: 0 0 var(--spacing-16);
|
|
147
|
+
max-width: 68ch;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.docs-note {
|
|
151
|
+
font-size: var(--typography-fontSize-xs);
|
|
152
|
+
line-height: var(--typography-lineHeight-normal);
|
|
153
|
+
color: var(--color-neutral-700);
|
|
154
|
+
background: var(--color-neutral-50);
|
|
155
|
+
border-radius: var(--radius-md);
|
|
156
|
+
padding: var(--spacing-12) var(--spacing-16);
|
|
157
|
+
margin-bottom: var(--spacing-32);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.docs-note b {
|
|
161
|
+
font-weight: var(--typography-fontWeight-semibold);
|
|
162
|
+
color: var(--color-neutral-900);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.docs-note code,
|
|
166
|
+
.docs-lede code {
|
|
167
|
+
font-family: var(--typography-fontFamily-mono);
|
|
168
|
+
font-size: var(--typography-code-inline-fontSize);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* --- sections --- */
|
|
172
|
+
.section {
|
|
173
|
+
margin-bottom: var(--spacing-40);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.section-head {
|
|
177
|
+
display: flex;
|
|
178
|
+
align-items: baseline;
|
|
179
|
+
gap: var(--spacing-8);
|
|
180
|
+
margin-bottom: var(--spacing-12);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.section-name {
|
|
184
|
+
font-size: var(--typography-fontSize-lg);
|
|
185
|
+
font-weight: var(--typography-fontWeight-semibold);
|
|
186
|
+
margin: 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.section-meta {
|
|
190
|
+
font-size: var(--typography-fontSize-xs);
|
|
191
|
+
font-family: var(--typography-fontFamily-mono);
|
|
192
|
+
color: var(--color-neutral-500);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/* --- reference tables --- */
|
|
196
|
+
/* Wide content scrolls inside its own container, never the page. */
|
|
197
|
+
.table-scroll {
|
|
198
|
+
overflow-x: auto;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.docs table {
|
|
202
|
+
border-collapse: collapse;
|
|
203
|
+
width: 100%;
|
|
204
|
+
font-size: var(--typography-fontSize-xs);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.docs caption {
|
|
208
|
+
/* the visible heading is .section-head; this is for screen readers */
|
|
209
|
+
position: absolute;
|
|
210
|
+
width: 1px;
|
|
211
|
+
height: 1px;
|
|
212
|
+
overflow: hidden;
|
|
213
|
+
clip-path: inset(50%);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.docs th {
|
|
217
|
+
text-align: left;
|
|
218
|
+
font-weight: var(--typography-fontWeight-semibold);
|
|
219
|
+
color: var(--color-neutral-600);
|
|
220
|
+
font-size: var(--typography-fontSize-xxs);
|
|
221
|
+
text-transform: uppercase;
|
|
222
|
+
letter-spacing: var(--typography-letterSpacing-wide);
|
|
223
|
+
padding: 0 var(--spacing-12) var(--spacing-8);
|
|
224
|
+
border-bottom: var(--border-width-1) solid var(--color-neutral-200);
|
|
225
|
+
white-space: nowrap;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.docs td {
|
|
229
|
+
padding: var(--spacing-8) var(--spacing-12);
|
|
230
|
+
border-bottom: var(--border-width-1) solid var(--color-neutral-100);
|
|
231
|
+
vertical-align: middle;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.docs tbody tr:last-child td {
|
|
235
|
+
border-bottom: 0;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/* --- cell primitives --- */
|
|
239
|
+
.mono {
|
|
240
|
+
font-family: var(--typography-fontFamily-mono);
|
|
241
|
+
white-space: nowrap;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.num {
|
|
245
|
+
font-family: var(--typography-fontFamily-mono);
|
|
246
|
+
font-variant-numeric: tabular-nums;
|
|
247
|
+
white-space: nowrap;
|
|
248
|
+
color: var(--color-neutral-700);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/* the rendered pixel value beside a rem one, so a step is recognisable
|
|
252
|
+
without doing the arithmetic */
|
|
253
|
+
.px-hint {
|
|
254
|
+
margin-left: var(--spacing-8);
|
|
255
|
+
color: var(--color-neutral-500);
|
|
256
|
+
font-size: var(--typography-fontSize-xxs);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.muted {
|
|
260
|
+
color: var(--color-neutral-500);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.unused {
|
|
264
|
+
color: var(--color-neutral-400);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.token-copy {
|
|
268
|
+
font-family: var(--typography-fontFamily-mono);
|
|
269
|
+
font-size: var(--typography-fontSize-xs);
|
|
270
|
+
color: var(--color-neutral-900);
|
|
271
|
+
background: none;
|
|
272
|
+
border: 0;
|
|
273
|
+
padding: 0;
|
|
274
|
+
cursor: copy;
|
|
275
|
+
text-align: left;
|
|
276
|
+
white-space: nowrap;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.token-copy:hover {
|
|
280
|
+
color: var(--color-blue-600);
|
|
281
|
+
text-decoration: underline;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.token-copy:focus-visible {
|
|
285
|
+
outline: var(--focus-outline-traditional);
|
|
286
|
+
outline-offset: var(--focus-outline-offset);
|
|
287
|
+
border-radius: var(--radius-sm);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.copied {
|
|
291
|
+
color: var(--color-green-700);
|
|
292
|
+
font-weight: var(--typography-fontWeight-semibold);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* --- WCAG level badge --- */
|
|
296
|
+
.level {
|
|
297
|
+
display: inline-block;
|
|
298
|
+
min-width: 3.2em;
|
|
299
|
+
margin-left: var(--spacing-6);
|
|
300
|
+
padding: 1px var(--spacing-6);
|
|
301
|
+
border-radius: var(--radius-sm);
|
|
302
|
+
font-family: var(--typography-fontFamily-sans);
|
|
303
|
+
font-size: var(--typography-fontSize-xxs);
|
|
304
|
+
font-weight: var(--typography-fontWeight-semibold);
|
|
305
|
+
text-align: center;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.level[data-pass='true'] {
|
|
309
|
+
color: var(--color-green-800);
|
|
310
|
+
background: var(--color-green-50);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.level[data-pass='false'] {
|
|
314
|
+
color: var(--color-red-800);
|
|
315
|
+
background: var(--color-red-50);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/* --- usage disclosure --- */
|
|
319
|
+
details.usage summary {
|
|
320
|
+
cursor: pointer;
|
|
321
|
+
white-space: nowrap;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
details.usage summary:focus-visible {
|
|
325
|
+
outline: var(--focus-outline-traditional);
|
|
326
|
+
outline-offset: var(--focus-outline-offset);
|
|
327
|
+
border-radius: var(--radius-sm);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
details.usage ul {
|
|
331
|
+
margin: var(--spacing-6) 0 0;
|
|
332
|
+
padding-left: var(--spacing-16);
|
|
333
|
+
font-family: var(--typography-fontFamily-mono);
|
|
334
|
+
font-size: var(--typography-fontSize-xxs);
|
|
335
|
+
color: var(--color-neutral-600);
|
|
336
|
+
line-height: var(--typography-lineHeight-normal);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.usage-count {
|
|
340
|
+
font-weight: var(--typography-fontWeight-semibold);
|
|
341
|
+
color: var(--color-blue-700);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* --- specimen frame, for stories that show rendered output --- */
|
|
345
|
+
.specimen {
|
|
346
|
+
background: var(--color-neutral-25);
|
|
347
|
+
border: var(--border-width-1) solid var(--color-neutral-100);
|
|
348
|
+
border-radius: var(--radius-md);
|
|
349
|
+
padding: var(--spacing-16);
|
|
350
|
+
}
|
|
351
|
+
</style>
|
|
352
|
+
`;
|
|
353
|
+
|
|
354
|
+
/* ============================================================
|
|
355
|
+
Page and section shells
|
|
356
|
+
============================================================ */
|
|
357
|
+
|
|
358
|
+
export function docsPage({ title, lede, note, children }) {
|
|
359
|
+
return html`
|
|
360
|
+
${chromeStyles}
|
|
361
|
+
<div class="docs">
|
|
362
|
+
<div class="docs-inner">
|
|
363
|
+
<h1>${title}</h1>
|
|
364
|
+
${lede ? html`<p class="docs-lede">${lede}</p>` : ''}
|
|
365
|
+
${note ? html`<div class="docs-note">${note}</div>` : ''}
|
|
366
|
+
${children}
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
369
|
+
`;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export function refSection({ name, meta, children }) {
|
|
373
|
+
return html`
|
|
374
|
+
<section class="section">
|
|
375
|
+
<div class="section-head">
|
|
376
|
+
<h2 class="section-name">${name}</h2>
|
|
377
|
+
${meta ? html`<span class="section-meta">${meta}</span>` : ''}
|
|
378
|
+
</div>
|
|
379
|
+
${children}
|
|
380
|
+
</section>
|
|
381
|
+
`;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** A token name that copies its var() reference when clicked. */
|
|
385
|
+
export function copyToken(token) {
|
|
386
|
+
const copy = async event => {
|
|
387
|
+
const button = event.currentTarget;
|
|
388
|
+
const original = button.textContent;
|
|
389
|
+
try {
|
|
390
|
+
// Rejects in an insecure context, on denied permission, or when the
|
|
391
|
+
// document is not focused.
|
|
392
|
+
await navigator.clipboard.writeText(`var(${token})`);
|
|
393
|
+
button.innerHTML = '<span class="copied">copied</span>';
|
|
394
|
+
} catch {
|
|
395
|
+
button.innerHTML = '<span class="copied">copy blocked</span>';
|
|
396
|
+
}
|
|
397
|
+
setTimeout(() => {
|
|
398
|
+
button.textContent = original;
|
|
399
|
+
}, 1200);
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
return html`
|
|
403
|
+
<button class="token-copy" @click=${copy} title="Copy var(${token})">${token}</button>
|
|
404
|
+
`;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/** Lists the tokens that consume a given token, behind a disclosure. */
|
|
408
|
+
export function usageCell(consumerSet) {
|
|
409
|
+
if (!consumerSet || !consumerSet.size) return html`<span class="unused">unused</span>`;
|
|
410
|
+
const names = [...consumerSet].sort();
|
|
411
|
+
return html`
|
|
412
|
+
<details class="usage">
|
|
413
|
+
<summary>
|
|
414
|
+
<span class="usage-count">${names.length}</span> token${names.length === 1 ? '' : 's'}
|
|
415
|
+
</summary>
|
|
416
|
+
<ul>
|
|
417
|
+
${names.map(name => html`<li>${name}</li>`)}
|
|
418
|
+
</ul>
|
|
419
|
+
</details>
|
|
420
|
+
`;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Standard caveat for the "Referenced by" column.
|
|
425
|
+
*
|
|
426
|
+
* This page can only see stylesheets in the document. Component CSS lives
|
|
427
|
+
* inside shadow roots and is unreachable, so the column counts token-to-token
|
|
428
|
+
* references only — a primitive with no listed references may still be used
|
|
429
|
+
* directly by components.
|
|
430
|
+
*/
|
|
431
|
+
export const referenceNote = html`<b>Referenced by</b> counts other
|
|
432
|
+
<em>tokens</em> that point at this one. Component CSS lives inside shadow
|
|
433
|
+
roots and cannot be read from this page, so a token listed as unreferenced
|
|
434
|
+
may still be used directly in a component.`;
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Token / value / optional visual / references table, shared by the primitive
|
|
438
|
+
* pages. `visual` receives (token, value) and returns the cell contents.
|
|
439
|
+
*/
|
|
440
|
+
export function primitiveTable({ caption, tokens, consumers, visual, visualHeader = 'Preview', valueClass = 'num' }) {
|
|
441
|
+
const rows = tokens
|
|
442
|
+
.map(token => {
|
|
443
|
+
const value = resolve(token);
|
|
444
|
+
return { token, value, px: toPx(value) };
|
|
445
|
+
})
|
|
446
|
+
.filter(row => row.value);
|
|
447
|
+
|
|
448
|
+
return html`
|
|
449
|
+
<div class="table-scroll">
|
|
450
|
+
<table>
|
|
451
|
+
<caption>${caption}</caption>
|
|
452
|
+
<thead>
|
|
453
|
+
<tr>
|
|
454
|
+
<th scope="col">Token</th>
|
|
455
|
+
<th scope="col">Value</th>
|
|
456
|
+
${visual ? html`<th scope="col">${visualHeader}</th>` : ''}
|
|
457
|
+
<th scope="col">Referenced by</th>
|
|
458
|
+
</tr>
|
|
459
|
+
</thead>
|
|
460
|
+
<tbody>
|
|
461
|
+
${rows.map(
|
|
462
|
+
({ token, value, px }) => html`
|
|
463
|
+
<tr>
|
|
464
|
+
<td>${copyToken(token)}</td>
|
|
465
|
+
<td class=${valueClass}>
|
|
466
|
+
${value}${px ? html`<span class="px-hint">${px}</span>` : ''}
|
|
467
|
+
</td>
|
|
468
|
+
${visual ? html`<td>${visual(token, value)}</td>` : ''}
|
|
469
|
+
<td>${usageCell(consumers.get(token))}</td>
|
|
470
|
+
</tr>
|
|
471
|
+
`
|
|
472
|
+
)}
|
|
473
|
+
</tbody>
|
|
474
|
+
</table>
|
|
475
|
+
</div>
|
|
476
|
+
`;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* The rendered pixel value of a rem length, measured rather than assumed, so a
|
|
481
|
+
* browser at a non-default root font size reports its own truth.
|
|
482
|
+
*
|
|
483
|
+
* rem only. An em value is relative to the element's own font size, so there
|
|
484
|
+
* is no single pixel equivalent to state — quoting one would be wrong rather
|
|
485
|
+
* than merely imprecise. px values, 0, unitless numbers, keywords and colours
|
|
486
|
+
* are left alone too.
|
|
487
|
+
*/
|
|
488
|
+
export function toPx(value) {
|
|
489
|
+
const v = String(value ?? '').trim();
|
|
490
|
+
if (!/^[\d.]+rem$/.test(v)) return '';
|
|
491
|
+
const probe = document.createElement('div');
|
|
492
|
+
probe.style.cssText = `position:absolute;visibility:hidden;height:0;width:${v}`;
|
|
493
|
+
document.body.appendChild(probe);
|
|
494
|
+
const px = getComputedStyle(probe).width;
|
|
495
|
+
probe.remove();
|
|
496
|
+
return px === v ? '' : px;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/** Tokens matching a prefix, in declaration order, read from the loaded CSS. */
|
|
500
|
+
export function tokensFor(cssText, prefix) {
|
|
501
|
+
const pattern = new RegExp(`(--${prefix}[A-Za-z0-9-]*)\\s*:`, 'g');
|
|
502
|
+
return discoverTokens(cssText, pattern).map(match => match[1]);
|
|
503
|
+
}
|