@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,932 +1,420 @@
|
|
|
1
1
|
import { html } from 'lit';
|
|
2
|
+
import {
|
|
3
|
+
copyToken,
|
|
4
|
+
discoverConsumers,
|
|
5
|
+
discoverTokens,
|
|
6
|
+
docsPage,
|
|
7
|
+
readAllCssText,
|
|
8
|
+
refSection,
|
|
9
|
+
resolve,
|
|
10
|
+
usageCell
|
|
11
|
+
} from './story-chrome.js';
|
|
2
12
|
|
|
3
13
|
export default {
|
|
4
|
-
title
|
|
5
|
-
tags
|
|
6
|
-
parameters: {
|
|
7
|
-
layout: 'fullscreen',
|
|
8
|
-
docs : {
|
|
9
|
-
description: {
|
|
10
|
-
component: `
|
|
11
|
-
# Grid System
|
|
12
|
-
|
|
13
|
-
A responsive, mobile-first grid system based on CSS Grid with semantic classes and design tokens.
|
|
14
|
-
|
|
15
|
-
## Overview
|
|
16
|
-
|
|
17
|
-
The grid system provides a flexible layout foundation using CSS Grid Layout. It supports responsive design, fixed and fluid columns, and consistent spacing through design tokens.
|
|
18
|
-
|
|
19
|
-
## Core Concepts
|
|
20
|
-
|
|
21
|
-
### 1. Container
|
|
22
|
-
The outermost wrapper that centers content and sets maximum width.
|
|
23
|
-
|
|
24
|
-
### 2. Row
|
|
25
|
-
Horizontal containers that hold columns. Uses CSS Grid for layout.
|
|
26
|
-
|
|
27
|
-
### 3. Column
|
|
28
|
-
Content containers that span across the grid. Can be fixed or fluid.
|
|
29
|
-
|
|
30
|
-
## Usage
|
|
31
|
-
|
|
32
|
-
### Basic Grid Structure
|
|
33
|
-
\`\`\`html
|
|
34
|
-
<div class="grid-container">
|
|
35
|
-
<div class="grid-row">
|
|
36
|
-
<div class="grid-col">
|
|
37
|
-
<!-- Column content -->
|
|
38
|
-
</div>
|
|
39
|
-
<div class="grid-col">
|
|
40
|
-
<!-- Column content -->
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
</div>
|
|
44
|
-
\`\`\`
|
|
45
|
-
|
|
46
|
-
### Fixed Width Columns
|
|
47
|
-
\`\`\`html
|
|
48
|
-
<div class="grid-container">
|
|
49
|
-
<div class="grid-row">
|
|
50
|
-
<div class="col-6">
|
|
51
|
-
<!-- 50% width column -->
|
|
52
|
-
</div>
|
|
53
|
-
<div class="col-6">
|
|
54
|
-
<!-- 50% width column -->
|
|
55
|
-
</div>
|
|
56
|
-
</div>
|
|
57
|
-
</div>
|
|
58
|
-
\`\`\`
|
|
59
|
-
|
|
60
|
-
### Responsive Grid
|
|
61
|
-
\`\`\`html
|
|
62
|
-
<div class="grid-container">
|
|
63
|
-
<div class="grid-row">
|
|
64
|
-
<div class="col-12 col-md-8 col-lg-6">
|
|
65
|
-
<!-- Responsive column -->
|
|
66
|
-
</div>
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
\`\`\`
|
|
70
|
-
|
|
71
|
-
## Grid Classes Reference
|
|
72
|
-
|
|
73
|
-
### Container Classes
|
|
74
|
-
| Class | Description | CSS Equivalent |
|
|
75
|
-
|-------|-------------|----------------|
|
|
76
|
-
| \`.grid-container\` | Centers content with max-width | \`max-width: var(--container-max-width)\` |
|
|
77
|
-
| \`.container-fluid\` | Full-width container | \`width: 100%\` |
|
|
78
|
-
|
|
79
|
-
### Row Classes
|
|
80
|
-
| Class | Description | CSS Equivalent |
|
|
81
|
-
|-------|-------------|----------------|
|
|
82
|
-
| \`.grid-row\` | Grid container row | \`display: grid; grid-template-columns: repeat(auto-fit, minmax(min-content, 1fr))\` |
|
|
83
|
-
| \`.row-gap-sm\` | Small row gap | \`row-gap: var(--space-sm)\` |
|
|
84
|
-
| \`.row-gap-md\` | Medium row gap | \`row-gap: var(--space-md)\` |
|
|
85
|
-
| \`.row-gap-lg\` | Large row gap | \`row-gap: var(--space-lg)\` |
|
|
86
|
-
|
|
87
|
-
### Column Classes
|
|
88
|
-
#### Fluid Columns
|
|
89
|
-
| Class | Description | Behavior |
|
|
90
|
-
|-------|-------------|----------|
|
|
91
|
-
| \`.grid-col\` | Auto-sizing column | Fills available space equally |
|
|
92
|
-
| \`.col-auto\` | Content-based width | Width based on content size |
|
|
93
|
-
|
|
94
|
-
#### Fixed Columns (12-column grid)
|
|
95
|
-
| Class | Width | Columns |
|
|
96
|
-
|-------|-------|---------|
|
|
97
|
-
| \`.col-1\` | 8.33% | 1 of 12 |
|
|
98
|
-
| \`.col-2\` | 16.66% | 2 of 12 |
|
|
99
|
-
| \`.col-3\` | 25% | 3 of 12 |
|
|
100
|
-
| \`.col-4\` | 33.33% | 4 of 12 |
|
|
101
|
-
| \`.col-5\` | 41.66% | 5 of 12 |
|
|
102
|
-
| \`.col-6\` | 50% | 6 of 12 |
|
|
103
|
-
| \`.col-7\` | 58.33% | 7 of 12 |
|
|
104
|
-
| \`.col-8\` | 66.66% | 8 of 12 |
|
|
105
|
-
| \`.col-9\` | 75% | 9 of 12 |
|
|
106
|
-
| \`.col-10\` | 83.33% | 10 of 12 |
|
|
107
|
-
| \`.col-11\` | 91.66% | 11 of 12 |
|
|
108
|
-
| \`.col-12\` | 100% | 12 of 12 |
|
|
109
|
-
|
|
110
|
-
#### Responsive Columns
|
|
111
|
-
| Class | Breakpoint | Description |
|
|
112
|
-
|-------|------------|-------------|
|
|
113
|
-
| \`.col-sm-*\` | ≥576px | Small devices |
|
|
114
|
-
| \`.col-md-*\` | ≥768px | Medium devices |
|
|
115
|
-
| \`.col-lg-*\` | ≥992px | Large devices |
|
|
116
|
-
| \`.col-xl-*\` | ≥1200px | Extra large devices |
|
|
117
|
-
|
|
118
|
-
## Design Tokens
|
|
119
|
-
|
|
120
|
-
The grid system uses CSS custom properties for consistent spacing and sizing:
|
|
121
|
-
|
|
122
|
-
\`\`\`css
|
|
123
|
-
:root {
|
|
124
|
-
/* Container */
|
|
125
|
-
--container-max-width: 1200px;
|
|
126
|
-
--container-padding: var(--space-lg);
|
|
127
|
-
|
|
128
|
-
/* Grid */
|
|
129
|
-
--grid-columns: 12;
|
|
130
|
-
--grid-gap: var(--space-md);
|
|
131
|
-
|
|
132
|
-
/* Breakpoints */
|
|
133
|
-
--breakpoint-sm: 576px;
|
|
134
|
-
--breakpoint-md: 768px;
|
|
135
|
-
--breakpoint-lg: 992px;
|
|
136
|
-
--breakpoint-xl: 1200px;
|
|
137
|
-
}
|
|
138
|
-
\`\`\`
|
|
139
|
-
|
|
140
|
-
## Examples
|
|
141
|
-
|
|
142
|
-
### Equal Width Columns
|
|
143
|
-
\`\`\`html
|
|
144
|
-
<div class="grid-container">
|
|
145
|
-
<div class="grid-row">
|
|
146
|
-
<div class="grid-col">Column 1</div>
|
|
147
|
-
<div class="grid-col">Column 2</div>
|
|
148
|
-
<div class="grid-col">Column 3</div>
|
|
149
|
-
</div>
|
|
150
|
-
</div>
|
|
151
|
-
\`\`\`
|
|
152
|
-
|
|
153
|
-
### Mixed Fixed and Fluid
|
|
154
|
-
\`\`\`html
|
|
155
|
-
<div class="grid-container">
|
|
156
|
-
<div class="grid-row">
|
|
157
|
-
<div class="col-4">Fixed 33%</div>
|
|
158
|
-
<div class="grid-col">Fluid remaining</div>
|
|
159
|
-
</div>
|
|
160
|
-
</div>
|
|
161
|
-
\`\`\`
|
|
162
|
-
|
|
163
|
-
### Nested Grids
|
|
164
|
-
\`\`\`html
|
|
165
|
-
<div class="grid-container">
|
|
166
|
-
<div class="grid-row">
|
|
167
|
-
<div class="col-8">
|
|
168
|
-
<div class="grid-row">
|
|
169
|
-
<div class="col-6">Nested 50%</div>
|
|
170
|
-
<div class="col-6">Nested 50%</div>
|
|
171
|
-
</div>
|
|
172
|
-
</div>
|
|
173
|
-
<div class="col-4">Sidebar</div>
|
|
174
|
-
</div>
|
|
175
|
-
</div>
|
|
176
|
-
\`\`\`
|
|
177
|
-
|
|
178
|
-
### Responsive Layout
|
|
179
|
-
\`\`\`html
|
|
180
|
-
<div class="grid-container">
|
|
181
|
-
<div class="grid-row">
|
|
182
|
-
<div class="col-12 col-md-8 col-lg-6">
|
|
183
|
-
Content adjusts based on screen size
|
|
184
|
-
</div>
|
|
185
|
-
<div class="col-12 col-md-4 col-lg-6">
|
|
186
|
-
Sidebar adjusts accordingly
|
|
187
|
-
</div>
|
|
188
|
-
</div>
|
|
189
|
-
</div>
|
|
190
|
-
\`\`\`
|
|
191
|
-
|
|
192
|
-
## Best Practices
|
|
193
|
-
|
|
194
|
-
### 1. Always Use Container
|
|
195
|
-
Wrap your grid in a container for proper centering and padding:
|
|
196
|
-
\`\`\`html
|
|
197
|
-
<!-- Good ✅ -->
|
|
198
|
-
<div class="grid-container">
|
|
199
|
-
<div class="grid-row">...</div>
|
|
200
|
-
</div>
|
|
201
|
-
|
|
202
|
-
<!-- Bad ❌ -->
|
|
203
|
-
<div class="grid-row">...</div>
|
|
204
|
-
\`\`\`
|
|
205
|
-
|
|
206
|
-
### 2. Column Sum Should Equal 12 (for fixed grids)
|
|
207
|
-
\`\`\`html
|
|
208
|
-
<!-- Good ✅ -->
|
|
209
|
-
<div class="col-8">...</div>
|
|
210
|
-
<div class="col-4">...</div>
|
|
211
|
-
<!-- Total: 12 -->
|
|
212
|
-
|
|
213
|
-
<!-- Bad ❌ -->
|
|
214
|
-
<div class="col-7">...</div>
|
|
215
|
-
<div class="col-6">...</div>
|
|
216
|
-
<!-- Total: 13, will wrap -->
|
|
217
|
-
\`\`\`
|
|
218
|
-
|
|
219
|
-
### 3. Use Semantic Class Names
|
|
220
|
-
\`\`\`html
|
|
221
|
-
<!-- Good ✅ -->
|
|
222
|
-
<div class="grid-col">Main Content</div>
|
|
223
|
-
<div class="col-4">Sidebar</div>
|
|
224
|
-
|
|
225
|
-
<!-- Avoid ❌ -->
|
|
226
|
-
<div style="grid-column: span 8;">Main Content</div>
|
|
227
|
-
\`\`\`
|
|
228
|
-
|
|
229
|
-
### 4. Responsive Considerations
|
|
230
|
-
- Test on multiple screen sizes
|
|
231
|
-
- Use responsive column classes
|
|
232
|
-
- Consider mobile-first approach
|
|
233
|
-
- Ensure touch targets are adequate
|
|
234
|
-
|
|
235
|
-
## Browser Support
|
|
236
|
-
|
|
237
|
-
CSS Grid is supported in:
|
|
238
|
-
- Chrome 57+
|
|
239
|
-
- Firefox 52+
|
|
240
|
-
- Safari 10.1+
|
|
241
|
-
- Edge 16+
|
|
242
|
-
|
|
243
|
-
For older browsers, consider using feature detection with \`@supports\`:
|
|
244
|
-
\`\`\`css
|
|
245
|
-
@supports (display: grid) {
|
|
246
|
-
.grid-row {
|
|
247
|
-
display: grid;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
@supports not (display: grid) {
|
|
252
|
-
.grid-row {
|
|
253
|
-
display: flex;
|
|
254
|
-
flex-wrap: wrap;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
\`\`\`
|
|
258
|
-
|
|
259
|
-
## Performance
|
|
260
|
-
|
|
261
|
-
- CSS Grid has excellent performance in modern browsers
|
|
262
|
-
- Avoid deeply nested grids when possible
|
|
263
|
-
- Use \`grid-auto-flow: dense\` for complex layouts
|
|
264
|
-
- Consider \`will-change: transform\` for animated grids
|
|
265
|
-
|
|
266
|
-
## Accessibility
|
|
267
|
-
|
|
268
|
-
- Maintain logical source order
|
|
269
|
-
- Ensure proper heading hierarchy within grids
|
|
270
|
-
- Test keyboard navigation
|
|
271
|
-
- Verify screen reader announcements
|
|
272
|
-
- Maintain sufficient color contrast
|
|
273
|
-
`
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
},
|
|
277
|
-
|
|
278
|
-
argTypes: {
|
|
279
|
-
backgroundColor: {
|
|
280
|
-
control : 'color',
|
|
281
|
-
description: 'Background color for container',
|
|
282
|
-
table : {
|
|
283
|
-
type : { summary: 'string' },
|
|
284
|
-
defaultValue: { summary: '#f4f4f4' }
|
|
285
|
-
}
|
|
286
|
-
},
|
|
287
|
-
padding: {
|
|
288
|
-
control : 'text',
|
|
289
|
-
description: 'Padding for container and columns',
|
|
290
|
-
table : {
|
|
291
|
-
type : { summary: 'string' },
|
|
292
|
-
defaultValue: { summary: 'var(--space-md)' }
|
|
293
|
-
}
|
|
294
|
-
},
|
|
295
|
-
gutter: {
|
|
296
|
-
control : 'text',
|
|
297
|
-
description: 'Gap between columns',
|
|
298
|
-
table : {
|
|
299
|
-
type : { summary: 'string' },
|
|
300
|
-
defaultValue: { summary: 'var(--grid-gap, var(--space-md))' }
|
|
301
|
-
}
|
|
302
|
-
},
|
|
303
|
-
colBg1: {
|
|
304
|
-
control : 'color',
|
|
305
|
-
description: 'Background color for first column',
|
|
306
|
-
table : {
|
|
307
|
-
type : { summary: 'string' },
|
|
308
|
-
defaultValue: { summary: '#bbb' }
|
|
309
|
-
}
|
|
310
|
-
},
|
|
311
|
-
colBg2: {
|
|
312
|
-
control : 'color',
|
|
313
|
-
description: 'Background color for second column',
|
|
314
|
-
table : {
|
|
315
|
-
type : { summary: 'string' },
|
|
316
|
-
defaultValue: { summary: '#999' }
|
|
317
|
-
}
|
|
318
|
-
},
|
|
319
|
-
maxWidth: {
|
|
320
|
-
control : 'text',
|
|
321
|
-
description: 'Maximum width of container',
|
|
322
|
-
table : {
|
|
323
|
-
type : { summary: 'string' },
|
|
324
|
-
defaultValue: { summary: 'var(--container-max-width, 1200px)' }
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
14
|
+
title: 'Foundations/Grid System',
|
|
15
|
+
tags : ['autodocs']
|
|
328
16
|
};
|
|
329
17
|
|
|
330
|
-
const
|
|
18
|
+
const gridStyles = html`
|
|
331
19
|
<style>
|
|
332
|
-
|
|
333
|
-
--
|
|
334
|
-
--
|
|
335
|
-
--
|
|
336
|
-
--
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
.story-container {
|
|
340
|
-
padding: 2rem;
|
|
341
|
-
background: #f8f9fa;
|
|
342
|
-
min-height: 100vh;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
.grid-container {
|
|
346
|
-
max-width: ${args.maxWidth};
|
|
347
|
-
margin: 0 auto;
|
|
348
|
-
padding: ${args.padding};
|
|
349
|
-
background: ${args.backgroundColor};
|
|
350
|
-
border-radius: 8px;
|
|
351
|
-
border: 2px solid #dee2e6;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
.grid-row {
|
|
355
|
-
display: grid;
|
|
356
|
-
grid-template-columns: repeat(auto-fit, minmax(min-content, 1fr));
|
|
357
|
-
gap: ${args.gutter};
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
.grid-col {
|
|
361
|
-
min-height: 100px;
|
|
362
|
-
display: flex;
|
|
363
|
-
align-items: center;
|
|
364
|
-
justify-content: center;
|
|
365
|
-
border-radius: 4px;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
.col-6 {
|
|
369
|
-
grid-column: span 6;
|
|
370
|
-
min-height: 100px;
|
|
371
|
-
display: flex;
|
|
372
|
-
align-items: center;
|
|
373
|
-
justify-content: center;
|
|
374
|
-
border-radius: 4px;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
.col-4 {
|
|
378
|
-
grid-column: span 4;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
.col-8 {
|
|
382
|
-
grid-column: span 8;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
.col-12 {
|
|
386
|
-
grid-column: span 12;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
.info-panel {
|
|
390
|
-
background: white;
|
|
391
|
-
padding: 1.5rem;
|
|
392
|
-
border-radius: 8px;
|
|
393
|
-
margin-bottom: 2rem;
|
|
394
|
-
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
.info-title {
|
|
398
|
-
font-family: var(--font-family-sans, sans-serif);
|
|
399
|
-
font-size: 1.25rem;
|
|
400
|
-
font-weight: 600;
|
|
401
|
-
margin: 0 0 1rem 0;
|
|
402
|
-
color: #212529;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
.info-grid {
|
|
406
|
-
display: grid;
|
|
407
|
-
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
408
|
-
gap: 1rem;
|
|
409
|
-
margin-top: 1rem;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
.info-item {
|
|
413
|
-
padding: 1rem;
|
|
414
|
-
background: #f8f9fa;
|
|
415
|
-
border-radius: 4px;
|
|
416
|
-
border-left: 4px solid #007bff;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
.info-label {
|
|
420
|
-
font-family: var(--font-family-sans, sans-serif);
|
|
421
|
-
font-weight: 600;
|
|
422
|
-
color: #495057;
|
|
423
|
-
margin: 0 0 0.25rem 0;
|
|
424
|
-
font-size: 0.9rem;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
.info-value {
|
|
428
|
-
font-family: var(--font-family-mono, monospace);
|
|
429
|
-
color: #6c757d;
|
|
430
|
-
margin: 0;
|
|
431
|
-
font-size: 0.85rem;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
.code-block {
|
|
435
|
-
background: #1a1a1a;
|
|
436
|
-
color: #f8f8f2;
|
|
437
|
-
padding: 1.5rem;
|
|
438
|
-
border-radius: 4px;
|
|
439
|
-
font-family: var(--font-family-mono, monospace);
|
|
440
|
-
font-size: 0.85rem;
|
|
441
|
-
line-height: 1.5;
|
|
20
|
+
.demo-frame {
|
|
21
|
+
background: var(--color-neutral-25);
|
|
22
|
+
border: var(--border-width-1) solid var(--color-neutral-100);
|
|
23
|
+
border-radius: var(--radius-md);
|
|
24
|
+
padding: var(--spacing-16);
|
|
25
|
+
/* the demos are width-sensitive; keep them off the page scrollbar */
|
|
442
26
|
overflow-x: auto;
|
|
443
|
-
margin-top: 1rem;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
.code-comment { color: #6272a4; }
|
|
447
|
-
.code-class { color: #50fa7b; }
|
|
448
|
-
.code-property { color: #f1fa8c; }
|
|
449
|
-
.code-value { color: #ff79c6; }
|
|
450
|
-
</style>
|
|
451
|
-
|
|
452
|
-
<div class="story-container">
|
|
453
|
-
<div class="info-panel">
|
|
454
|
-
<h3 class="info-title">Grid System Configuration</h3>
|
|
455
|
-
<div class="info-grid">
|
|
456
|
-
<div class="info-item">
|
|
457
|
-
<p class="info-label">Container Max Width</p>
|
|
458
|
-
<p class="info-value">${args.maxWidth}</p>
|
|
459
|
-
</div>
|
|
460
|
-
<div class="info-item">
|
|
461
|
-
<p class="info-label">Container Padding</p>
|
|
462
|
-
<p class="info-value">${args.padding}</p>
|
|
463
|
-
</div>
|
|
464
|
-
<div class="info-item">
|
|
465
|
-
<p class="info-label">Grid Gutter</p>
|
|
466
|
-
<p class="info-value">${args.gutter}</p>
|
|
467
|
-
</div>
|
|
468
|
-
</div>
|
|
469
|
-
</div>
|
|
470
|
-
|
|
471
|
-
<div class="grid-container">
|
|
472
|
-
<div class="grid-row" style="gap: ${args.gutter};">
|
|
473
|
-
<div class="grid-col" style="background: ${args.colBg1}; padding: ${args.padding};">
|
|
474
|
-
.grid-col (auto width)
|
|
475
|
-
</div>
|
|
476
|
-
<div class="grid-col" style="background: ${args.colBg2}; padding: ${args.padding};">
|
|
477
|
-
.grid-col (auto width)
|
|
478
|
-
</div>
|
|
479
|
-
</div>
|
|
480
|
-
</div>
|
|
481
|
-
|
|
482
|
-
<div class="code-block">
|
|
483
|
-
<span class="code-comment">HTML Structure:</span><br>
|
|
484
|
-
<<span class="code-class">div</span> <span class="code-property">class</span>=<span class="code-value">"grid-container"</span>><br>
|
|
485
|
-
<<span class="code-class">div</span> <span class="code-property">class</span>=<span class="code-value">"grid-row"</span>><br>
|
|
486
|
-
<<span class="code-class">div</span> <span class="code-property">class</span>=<span class="code-value">"grid-col"</span>>Column 1</<span class="code-class">div</span>><br>
|
|
487
|
-
<<span class="code-class">div</span> <span class="code-property">class</span>=<span class="code-value">"grid-col"</span>>Column 2</<span class="code-class">div</span>><br>
|
|
488
|
-
</<span class="code-class">div</span>><br>
|
|
489
|
-
</<span class="code-class">div</span>>
|
|
490
|
-
</div>
|
|
491
|
-
</div>
|
|
492
|
-
`;
|
|
493
|
-
|
|
494
|
-
export const GridContainer = Template.bind({});
|
|
495
|
-
GridContainer.args = {
|
|
496
|
-
backgroundColor: '#f4f4f4',
|
|
497
|
-
padding : 'var(--space-lg)',
|
|
498
|
-
gutter : 'var(--space-md)',
|
|
499
|
-
colBg1 : '#bbb',
|
|
500
|
-
colBg2 : '#999',
|
|
501
|
-
maxWidth : 'var(--container-max-width, 1200px)'
|
|
502
|
-
};
|
|
503
|
-
GridContainer.storyName = 'Basic Grid';
|
|
504
|
-
GridContainer.parameters = {
|
|
505
|
-
docs: {
|
|
506
|
-
description: {
|
|
507
|
-
story: 'Basic grid container with auto-sizing columns. Demonstrates the foundational grid structure with container, row, and columns.'
|
|
508
27
|
}
|
|
509
|
-
}
|
|
510
|
-
};
|
|
511
28
|
|
|
512
|
-
export const FixedColumns = (args) => html`
|
|
513
|
-
<style>
|
|
514
29
|
.demo-container {
|
|
515
|
-
padding: 2rem;
|
|
516
|
-
background: #f8f9fa;
|
|
517
|
-
min-height: 100vh;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
.grid-container {
|
|
521
|
-
max-width: ${args.maxWidth};
|
|
522
30
|
margin: 0 auto;
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
border-radius:
|
|
526
|
-
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
.grid-row {
|
|
530
|
-
display: grid;
|
|
531
|
-
grid-template-columns: repeat(12, 1fr);
|
|
532
|
-
gap: ${args.gutter};
|
|
533
|
-
margin-bottom: 2rem;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
.col {
|
|
537
|
-
min-height: 80px;
|
|
538
|
-
display: flex;
|
|
539
|
-
align-items: center;
|
|
540
|
-
justify-content: center;
|
|
541
|
-
border-radius: 4px;
|
|
542
|
-
font-family: var(--font-family-sans, sans-serif);
|
|
543
|
-
font-weight: 600;
|
|
544
|
-
color: white;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
.col-1 { grid-column: span 1; background: #007bff; }
|
|
548
|
-
.col-2 { grid-column: span 2; background: #6f42c1; }
|
|
549
|
-
.col-3 { grid-column: span 3; background: #e83e8c; }
|
|
550
|
-
.col-4 { grid-column: span 4; background: #fd7e14; }
|
|
551
|
-
.col-5 { grid-column: span 5; background: #20c997; }
|
|
552
|
-
.col-6 { grid-column: span 6; background: #17a2b8; }
|
|
553
|
-
.col-7 { grid-column: span 7; background: #ffc107; color: #212529; }
|
|
554
|
-
.col-8 { grid-column: span 8; background: #dc3545; }
|
|
555
|
-
.col-9 { grid-column: span 9; background: #343a40; }
|
|
556
|
-
.col-10 { grid-column: span 10; background: #28a745; }
|
|
557
|
-
.col-11 { grid-column: span 11; background: #6c757d; }
|
|
558
|
-
.col-12 { grid-column: span 12; background: #6610f2; }
|
|
559
|
-
|
|
560
|
-
.grid-example {
|
|
561
|
-
margin-bottom: 3rem;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
.example-title {
|
|
565
|
-
font-family: var(--font-family-sans, sans-serif);
|
|
566
|
-
font-size: 1.1rem;
|
|
567
|
-
font-weight: 600;
|
|
568
|
-
margin: 0 0 1rem 0;
|
|
569
|
-
color: #212529;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
.example-description {
|
|
573
|
-
font-family: var(--font-family-sans, sans-serif);
|
|
574
|
-
color: #6c757d;
|
|
575
|
-
margin: 0 0 1.5rem 0;
|
|
576
|
-
font-size: 0.9rem;
|
|
31
|
+
background: var(--color-blue-50);
|
|
32
|
+
border: var(--border-width-1) dashed var(--color-blue-300);
|
|
33
|
+
border-radius: var(--radius-sm);
|
|
577
34
|
}
|
|
578
|
-
</style>
|
|
579
35
|
|
|
580
|
-
|
|
581
|
-
<div class="grid-container">
|
|
582
|
-
<div class="grid-example">
|
|
583
|
-
<h3 class="example-title">12-Column Grid System</h3>
|
|
584
|
-
<p class="example-description">All available fixed-width column classes:</p>
|
|
585
|
-
<div class="grid-row">
|
|
586
|
-
${[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map(num => html`
|
|
587
|
-
<div class="col col-1">.col-1</div>
|
|
588
|
-
`)}
|
|
589
|
-
</div>
|
|
590
|
-
|
|
591
|
-
<div class="grid-row">
|
|
592
|
-
<div class="col col-6">.col-6 (50%)</div>
|
|
593
|
-
<div class="col col-6">.col-6 (50%)</div>
|
|
594
|
-
</div>
|
|
595
|
-
|
|
596
|
-
<div class="grid-row">
|
|
597
|
-
<div class="col col-4">.col-4 (33%)</div>
|
|
598
|
-
<div class="col col-4">.col-4 (33%)</div>
|
|
599
|
-
<div class="col col-4">.col-4 (33%)</div>
|
|
600
|
-
</div>
|
|
601
|
-
|
|
602
|
-
<div class="grid-row">
|
|
603
|
-
<div class="col col-8">.col-8 (66%)</div>
|
|
604
|
-
<div class="col col-4">.col-4 (33%)</div>
|
|
605
|
-
</div>
|
|
606
|
-
|
|
607
|
-
<div class="grid-row">
|
|
608
|
-
<div class="col col-3">.col-3 (25%)</div>
|
|
609
|
-
<div class="col col-6">.col-6 (50%)</div>
|
|
610
|
-
<div class="col col-3">.col-3 (25%)</div>
|
|
611
|
-
</div>
|
|
612
|
-
</div>
|
|
613
|
-
</div>
|
|
614
|
-
</div>
|
|
615
|
-
`;
|
|
616
|
-
FixedColumns.args = {
|
|
617
|
-
padding : 'var(--space-lg)',
|
|
618
|
-
gutter : 'var(--space-sm)',
|
|
619
|
-
maxWidth: 'var(--container-max-width, 1200px)'
|
|
620
|
-
};
|
|
621
|
-
FixedColumns.storyName = 'Fixed Columns';
|
|
622
|
-
FixedColumns.parameters = {
|
|
623
|
-
docs: {
|
|
624
|
-
description: {
|
|
625
|
-
story: 'Fixed-width column system based on a 12-column grid. Demonstrates all available column classes from .col-1 to .col-12.'
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
};
|
|
629
|
-
|
|
630
|
-
export const ResponsiveGrid = () => html`
|
|
631
|
-
<style>
|
|
632
|
-
.responsive-demo {
|
|
633
|
-
padding: 2rem;
|
|
634
|
-
background: #f8f9fa;
|
|
635
|
-
min-height: 100vh;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
.grid-container {
|
|
639
|
-
max-width: 1200px;
|
|
640
|
-
margin: 0 auto;
|
|
641
|
-
padding: 2rem;
|
|
642
|
-
background: white;
|
|
643
|
-
border-radius: 8px;
|
|
644
|
-
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
.grid-row {
|
|
36
|
+
.demo-grid {
|
|
648
37
|
display: grid;
|
|
649
|
-
|
|
650
|
-
margin-bottom: 2rem;
|
|
38
|
+
grid-template-columns: repeat(var(--demo-cols, 12), 1fr);
|
|
651
39
|
}
|
|
652
|
-
|
|
653
|
-
.
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
display: flex;
|
|
659
|
-
align-items: center;
|
|
660
|
-
justify-content: center;
|
|
40
|
+
|
|
41
|
+
.demo-cell {
|
|
42
|
+
background: var(--color-blue-500);
|
|
43
|
+
color: var(--color-neutral-0);
|
|
44
|
+
border-radius: var(--radius-sm);
|
|
45
|
+
padding: var(--spacing-8) 0;
|
|
661
46
|
text-align: center;
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
.col-1 { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; }
|
|
666
|
-
.col-2 { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; }
|
|
667
|
-
.col-3 { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; }
|
|
668
|
-
|
|
669
|
-
.breakpoint-info {
|
|
670
|
-
display: grid;
|
|
671
|
-
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
672
|
-
gap: 1rem;
|
|
673
|
-
margin-bottom: 2rem;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
.breakpoint-card {
|
|
677
|
-
padding: 1rem;
|
|
678
|
-
background: #f8f9fa;
|
|
679
|
-
border-radius: 6px;
|
|
680
|
-
border-left: 4px solid #007bff;
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
.breakpoint-title {
|
|
684
|
-
font-family: var(--font-family-sans, sans-serif);
|
|
685
|
-
font-weight: 600;
|
|
686
|
-
margin: 0 0 0.5rem 0;
|
|
687
|
-
color: #212529;
|
|
47
|
+
font-family: var(--typography-fontFamily-mono);
|
|
48
|
+
font-size: var(--typography-fontSize-xxs);
|
|
49
|
+
font-weight: var(--typography-fontWeight-semibold);
|
|
688
50
|
}
|
|
689
|
-
|
|
690
|
-
.
|
|
691
|
-
|
|
692
|
-
color: #6c757d;
|
|
693
|
-
margin: 0;
|
|
694
|
-
font-size: 0.9rem;
|
|
51
|
+
|
|
52
|
+
.demo-cell--alt {
|
|
53
|
+
background: var(--color-neutral-400);
|
|
695
54
|
}
|
|
696
|
-
|
|
697
|
-
.
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
margin: 1rem 0;
|
|
703
|
-
background: #f8f9fa;
|
|
55
|
+
|
|
56
|
+
.demo-label {
|
|
57
|
+
font-family: var(--typography-fontFamily-mono);
|
|
58
|
+
font-size: var(--typography-fontSize-xxs);
|
|
59
|
+
color: var(--color-neutral-600);
|
|
60
|
+
margin: 0 0 var(--spacing-8);
|
|
704
61
|
}
|
|
705
|
-
|
|
706
|
-
.
|
|
707
|
-
|
|
708
|
-
top: -12px;
|
|
709
|
-
left: 1rem;
|
|
710
|
-
background: #007bff;
|
|
711
|
-
color: white;
|
|
712
|
-
padding: 2px 8px;
|
|
713
|
-
border-radius: 4px;
|
|
714
|
-
font-family: var(--font-family-sans, sans-serif);
|
|
715
|
-
font-size: 0.8rem;
|
|
716
|
-
font-weight: 600;
|
|
62
|
+
|
|
63
|
+
.demo-label + .demo-frame {
|
|
64
|
+
margin-bottom: var(--spacing-24);
|
|
717
65
|
}
|
|
718
|
-
|
|
719
|
-
.
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
font-family: var(--font-family-mono, monospace);
|
|
725
|
-
font-size: 0.85rem;
|
|
726
|
-
line-height: 1.5;
|
|
727
|
-
margin-top: 2rem;
|
|
66
|
+
|
|
67
|
+
.ruler {
|
|
68
|
+
height: var(--spacing-8);
|
|
69
|
+
background: var(--color-blue-500);
|
|
70
|
+
border-radius: var(--radius-sm);
|
|
71
|
+
min-width: 1px;
|
|
728
72
|
}
|
|
729
73
|
</style>
|
|
74
|
+
`;
|
|
730
75
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
</
|
|
744
|
-
<
|
|
745
|
-
<
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
<
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
</div>
|
|
773
|
-
</div>
|
|
774
|
-
|
|
775
|
-
<div class="responsive-code">
|
|
776
|
-
<span style="color: #6272a4;">/* Responsive column example */</span><br>
|
|
777
|
-
<div class="col-12 col-md-6 col-lg-4"><br>
|
|
778
|
-
<span style="color: #6272a4;"><!-- Stacked on mobile, 2 columns on tablet, 3 columns on desktop --></span><br>
|
|
779
|
-
</div>
|
|
780
|
-
</div>
|
|
76
|
+
function tokensFor(cssText, prefix) {
|
|
77
|
+
const pattern = new RegExp(`(--${prefix}[A-Za-z0-9-]*)\\s*:`, 'g');
|
|
78
|
+
return discoverTokens(cssText, pattern).map(match => match[1]);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function tokenTable({ caption, tokens, consumers, ruler = false }) {
|
|
82
|
+
const rows = tokens.map(token => ({ token, value: resolve(token) })).filter(r => r.value);
|
|
83
|
+
const max = ruler ? Math.max(...rows.map(r => parseFloat(r.value) || 0), 1) : 0;
|
|
84
|
+
|
|
85
|
+
return html`
|
|
86
|
+
<div class="table-scroll">
|
|
87
|
+
<table>
|
|
88
|
+
<caption>${caption}</caption>
|
|
89
|
+
<thead>
|
|
90
|
+
<tr>
|
|
91
|
+
<th scope="col">Token</th>
|
|
92
|
+
<th scope="col">Value</th>
|
|
93
|
+
${ruler ? html`<th scope="col">Scale</th>` : ''}
|
|
94
|
+
<th scope="col">Used by</th>
|
|
95
|
+
</tr>
|
|
96
|
+
</thead>
|
|
97
|
+
<tbody>
|
|
98
|
+
${rows.map(
|
|
99
|
+
({ token, value }) => html`
|
|
100
|
+
<tr>
|
|
101
|
+
<td>${copyToken(token)}</td>
|
|
102
|
+
<td class="num">${value}</td>
|
|
103
|
+
${ruler
|
|
104
|
+
? html`<td style="width: 40%">
|
|
105
|
+
<div
|
|
106
|
+
class="ruler"
|
|
107
|
+
style="width: ${((parseFloat(value) || 0) / max) * 100}%"
|
|
108
|
+
></div>
|
|
109
|
+
</td>`
|
|
110
|
+
: ''}
|
|
111
|
+
<td>${usageCell(consumers.get(token))}</td>
|
|
112
|
+
</tr>
|
|
113
|
+
`
|
|
114
|
+
)}
|
|
115
|
+
</tbody>
|
|
116
|
+
</table>
|
|
781
117
|
</div>
|
|
782
|
-
|
|
118
|
+
`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* ---------------------------------------------------------------------------
|
|
122
|
+
The one table everything else in this system rests on, and it was missing.
|
|
123
|
+
|
|
124
|
+
Type, images and controls never get the viewport -- they get what is left
|
|
125
|
+
after the gutters. Until this was written down, the number had to be
|
|
126
|
+
re-derived by whoever needed it, and at least once it was got wrong by
|
|
127
|
+
MEASURING a Storybook story instead: the harness adds 16px of body padding
|
|
128
|
+
either side, so a 288px column was recorded as 256 and moved a typography
|
|
129
|
+
conclusion by a whole step of the scale. Derive it from the tokens. */
|
|
130
|
+
const COLUMN_TABLE = [
|
|
131
|
+
['320', 'xs', '100%', 16],
|
|
132
|
+
['375', 'xs', '100%', 16],
|
|
133
|
+
['576', 'sm', '540px', 24],
|
|
134
|
+
['768', 'md', '720px', 32],
|
|
135
|
+
['992', 'lg', '960px', 40],
|
|
136
|
+
['1200', 'xl', '1140px', 40],
|
|
137
|
+
['1400', 'xxl', '1320px', 40]
|
|
138
|
+
];
|
|
139
|
+
const columnOf = (vw, cmax, padding) => {
|
|
140
|
+
const box = cmax === '100%' ? Number(vw) : parseInt(cmax, 10);
|
|
141
|
+
return Math.min(box, Number(vw)) - padding * 2;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export const TheColumn = () => html`
|
|
145
|
+
${gridStyles}
|
|
146
|
+
${docsPage({
|
|
147
|
+
title: 'The column',
|
|
148
|
+
lede : html`What content actually gets at each viewport:
|
|
149
|
+
<code>--grid-container-max-*</code> capped by the viewport, minus
|
|
150
|
+
<b>twice</b> <code>--grid-padding-*</code>. Every sizing decision in the
|
|
151
|
+
system — type, media, controls — is really a decision against this
|
|
152
|
+
number, not against the viewport.`,
|
|
153
|
+
note: html`<b>Derive it, do not measure it.</b> A Storybook story sits inside 16px of
|
|
154
|
+
harness body padding either side, so measuring one understates the column at the
|
|
155
|
+
<code>xs</code> tier. That mistake recorded a 288px column as 256 and moved a typography
|
|
156
|
+
conclusion by a whole step of the type scale.`,
|
|
157
|
+
children: html`
|
|
158
|
+
${refSection({
|
|
159
|
+
name : 'Viewport to column',
|
|
160
|
+
meta : '7 widths · container − 2 × gutter',
|
|
161
|
+
children: html`
|
|
162
|
+
<div style="overflow-x: auto">
|
|
163
|
+
<table class="tokens-table">
|
|
164
|
+
<caption>The column at each breakpoint, and what the gutters cost</caption>
|
|
165
|
+
<thead>
|
|
166
|
+
<tr>
|
|
167
|
+
<th>viewport</th><th>tier</th><th>container max</th>
|
|
168
|
+
<th>gutter × 2</th><th>column</th><th>lost to gutters</th>
|
|
169
|
+
</tr>
|
|
170
|
+
</thead>
|
|
171
|
+
<tbody>
|
|
172
|
+
${COLUMN_TABLE.map(([vw, tier, cmax, padding]) => {
|
|
173
|
+
const col = columnOf(vw, cmax, padding);
|
|
174
|
+
return html`
|
|
175
|
+
<tr>
|
|
176
|
+
<td>${vw}px</td>
|
|
177
|
+
<td><code>${tier}</code></td>
|
|
178
|
+
<td>${cmax === '100%' ? html`<code>100%</code> → ${vw}px` : cmax}</td>
|
|
179
|
+
<td>${padding} × 2 = ${padding * 2}px</td>
|
|
180
|
+
<td><b>${col}px</b></td>
|
|
181
|
+
<td>${Math.round((padding * 2 / Number(vw)) * 100)}%</td>
|
|
182
|
+
</tr>
|
|
183
|
+
`;
|
|
184
|
+
})}
|
|
185
|
+
</tbody>
|
|
186
|
+
</table>
|
|
187
|
+
</div>
|
|
188
|
+
<p>
|
|
189
|
+
<b><code>xl</code> and <code>xxl</code> inherit <code>--grid-padding-lg</code>.</b>
|
|
190
|
+
<code>ensemble.css.js</code> raises <code>max-width</code> above <code>lg</code> but
|
|
191
|
+
never the padding, so <b>40px is the widest gutter this system has</b> — and the
|
|
192
|
+
column therefore grows more slowly than the screen does. At 320 the gutters are 10%
|
|
193
|
+
of the screen; at 1400 they are 6%.
|
|
194
|
+
</p>
|
|
195
|
+
<p>
|
|
196
|
+
<b>Why it matters most at the narrow end.</b> A 320px phone gives type 288px. Against
|
|
197
|
+
that column the largest size at which the longest realistic compound word still fits
|
|
198
|
+
is <b>31px</b> — which is why nine type roles are fluid. See
|
|
199
|
+
<i>Foundations/Typography → Fluid type</i>.
|
|
200
|
+
</p>
|
|
201
|
+
`
|
|
202
|
+
})}
|
|
203
|
+
`
|
|
204
|
+
})}
|
|
783
205
|
`;
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
206
|
+
|
|
207
|
+
export const GridTokens = () => {
|
|
208
|
+
const cssText = readAllCssText();
|
|
209
|
+
const consumers = discoverConsumers(cssText);
|
|
210
|
+
|
|
211
|
+
const groups = [
|
|
212
|
+
{ name: 'Breakpoints', prefix: 'breakpoint-', ruler: true, caption: 'Breakpoint tokens' },
|
|
213
|
+
{ name: 'Container max widths', prefix: 'grid-container-max-', ruler: true, caption: 'Container max widths' },
|
|
214
|
+
{ name: 'Gutters', prefix: 'grid-gutter-', ruler: true, caption: 'Gutter tokens' },
|
|
215
|
+
{ name: 'Container padding', prefix: 'grid-padding-', ruler: true, caption: 'Grid padding tokens' },
|
|
216
|
+
{ name: 'Columns', prefix: 'grid-columns', ruler: false, caption: 'Column count' },
|
|
217
|
+
{ name: 'Content widths', prefix: 'content-width-', ruler: false, caption: 'Content width tokens' }
|
|
218
|
+
];
|
|
219
|
+
|
|
220
|
+
return html`
|
|
221
|
+
${gridStyles}
|
|
222
|
+
${docsPage({
|
|
223
|
+
title: 'Grid system',
|
|
224
|
+
lede : html`The layout tokens, read from the loaded token CSS at render time so this page
|
|
225
|
+
always matches <code>src/tokens/tokens.css</code>. Click a token name to copy its
|
|
226
|
+
<code>var()</code> reference.`,
|
|
227
|
+
note: html`<b>Breakpoint tokens cannot be used in a media query.</b>
|
|
228
|
+
<code>@media (min-width: var(--breakpoint-md))</code> does not work — custom properties are
|
|
229
|
+
not allowed in media conditions. Write the value literally, or import the breakpoint map
|
|
230
|
+
from JavaScript (<code>src/blog/src/breakpoints.js</code> does this for Lit
|
|
231
|
+
<code>css</code> templates). Note also that components currently hardcode several widths
|
|
232
|
+
that are not on this scale, so check the <b>Used by</b> column before assuming a
|
|
233
|
+
breakpoint is authoritative.`,
|
|
234
|
+
children: groups.map(({ name, prefix, ruler, caption }) => {
|
|
235
|
+
const tokens = tokensFor(cssText, prefix);
|
|
236
|
+
if (!tokens.length) return html``;
|
|
237
|
+
return refSection({
|
|
238
|
+
name,
|
|
239
|
+
meta : `${tokens.length} token${tokens.length === 1 ? '' : 's'} · --${prefix}*`,
|
|
240
|
+
children: tokenTable({ caption, tokens, consumers, ruler })
|
|
241
|
+
});
|
|
242
|
+
})
|
|
243
|
+
})}
|
|
244
|
+
`;
|
|
791
245
|
};
|
|
792
246
|
|
|
793
|
-
export const
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
padding: 1rem;
|
|
840
|
-
border-radius: 4px;
|
|
841
|
-
font-family: var(--font-family-sans, sans-serif);
|
|
842
|
-
text-align: center;
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
.no-gap { gap: 0; }
|
|
846
|
-
.gap-sm { gap: var(--space-sm); }
|
|
847
|
-
.gap-md { gap: var(--space-md); }
|
|
848
|
-
.gap-lg { gap: var(--space-lg); }
|
|
849
|
-
|
|
850
|
-
.gutter-preview {
|
|
851
|
-
height: 60px;
|
|
852
|
-
background: repeating-linear-gradient(
|
|
853
|
-
90deg,
|
|
854
|
-
#dee2e6,
|
|
855
|
-
#dee2e6 1px,
|
|
856
|
-
transparent 1px,
|
|
857
|
-
transparent calc(${args.gutter} - 1px)
|
|
858
|
-
);
|
|
859
|
-
margin: 1rem 0;
|
|
860
|
-
border-radius: 4px;
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
.gutter-value {
|
|
864
|
-
font-family: var(--font-family-mono, monospace);
|
|
865
|
-
background: #f8f9fa;
|
|
866
|
-
padding: 0.5rem;
|
|
867
|
-
border-radius: 4px;
|
|
868
|
-
margin: 0.5rem 0;
|
|
869
|
-
}
|
|
870
|
-
</style>
|
|
247
|
+
export const GridContainer = () => {
|
|
248
|
+
const sizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'];
|
|
249
|
+
|
|
250
|
+
return html`
|
|
251
|
+
${gridStyles}
|
|
252
|
+
${docsPage({
|
|
253
|
+
title: 'Containers',
|
|
254
|
+
lede : html`Each container caps content at its breakpoint's max width and applies the
|
|
255
|
+
matching horizontal padding. Widths are the real token values, so the bars below are to
|
|
256
|
+
scale with each other.`,
|
|
257
|
+
children: html`${refSection({
|
|
258
|
+
name : 'Container max widths',
|
|
259
|
+
meta : '--grid-container-max-* with --grid-padding-*',
|
|
260
|
+
children: html`
|
|
261
|
+
${sizes.map(size => {
|
|
262
|
+
const maxToken = `--grid-container-max-${size}`;
|
|
263
|
+
const padToken = `--grid-padding-${['xs', 'sm', 'md', 'lg'].includes(size) ? size : 'lg'}`;
|
|
264
|
+
return html`
|
|
265
|
+
<p class="demo-label">${maxToken} = ${resolve(maxToken)} · ${padToken} = ${resolve(padToken)}</p>
|
|
266
|
+
<div class="demo-frame">
|
|
267
|
+
<div
|
|
268
|
+
class="demo-container"
|
|
269
|
+
style="max-width: var(${maxToken}); padding: var(--spacing-12) var(${padToken})"
|
|
270
|
+
>
|
|
271
|
+
<div class="demo-cell">${size}</div>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
`;
|
|
275
|
+
})}
|
|
276
|
+
`
|
|
277
|
+
})}${refSection({
|
|
278
|
+
name : 'The page column',
|
|
279
|
+
meta : '.bd-ensemble · src/components/shared/ensemble.css.js',
|
|
280
|
+
children: html`
|
|
281
|
+
<p class="demo-label">
|
|
282
|
+
This container is implemented once, as <code>ensembleCSS</code>. Every page-level
|
|
283
|
+
module composes it and puts <code>bd-ensemble</code> on the element that holds its
|
|
284
|
+
content, so a page assembled from independent sections has its content on one pair
|
|
285
|
+
of edges. A column nested inside another collapses on its own. See
|
|
286
|
+
<code>check:ensemble</code>, and the page column section of CLAUDE.md.
|
|
287
|
+
</p>
|
|
288
|
+
`
|
|
289
|
+
})}`
|
|
290
|
+
})}
|
|
291
|
+
`;
|
|
292
|
+
};
|
|
871
293
|
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
294
|
+
export const FixedColumns = () => {
|
|
295
|
+
const columnCount = Number(resolve('--grid-columns')) || 12;
|
|
296
|
+
const spans = [
|
|
297
|
+
[12],
|
|
298
|
+
[6, 6],
|
|
299
|
+
[4, 4, 4],
|
|
300
|
+
[3, 3, 3, 3],
|
|
301
|
+
[8, 4],
|
|
302
|
+
[2, 8, 2]
|
|
303
|
+
];
|
|
304
|
+
|
|
305
|
+
return html`
|
|
306
|
+
${gridStyles}
|
|
307
|
+
${docsPage({
|
|
308
|
+
title: 'Columns',
|
|
309
|
+
lede : html`The grid is <b>${columnCount}</b> columns
|
|
310
|
+
(<code>--grid-columns</code>), with <code>--grid-gutter-md</code> between them.`,
|
|
311
|
+
children: refSection({
|
|
312
|
+
name : 'Common splits',
|
|
313
|
+
meta : `${columnCount} columns · --grid-gutter-md`,
|
|
314
|
+
children: html`
|
|
315
|
+
${spans.map(
|
|
316
|
+
row => html`
|
|
317
|
+
<p class="demo-label">${row.join(' + ')}</p>
|
|
318
|
+
<div class="demo-frame">
|
|
319
|
+
<div
|
|
320
|
+
class="demo-grid"
|
|
321
|
+
style="--demo-cols: ${columnCount}; gap: var(--grid-gutter-md)"
|
|
322
|
+
>
|
|
323
|
+
${row.map(
|
|
324
|
+
(span, index) => html`
|
|
325
|
+
<div
|
|
326
|
+
class="demo-cell ${index % 2 ? 'demo-cell--alt' : ''}"
|
|
327
|
+
style="grid-column: span ${span}"
|
|
328
|
+
>
|
|
329
|
+
${span}
|
|
330
|
+
</div>
|
|
331
|
+
`
|
|
332
|
+
)}
|
|
333
|
+
</div>
|
|
334
|
+
</div>
|
|
335
|
+
`
|
|
336
|
+
)}
|
|
337
|
+
`
|
|
338
|
+
})
|
|
339
|
+
})}
|
|
340
|
+
`;
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
export const ResponsiveGrid = () => html`
|
|
344
|
+
${gridStyles}
|
|
345
|
+
${docsPage({
|
|
346
|
+
title: 'Responsive columns',
|
|
347
|
+
lede : html`Resize the canvas to see the column count change. The media queries below use the
|
|
348
|
+
literal breakpoint values, because <code>var(--breakpoint-*)</code> is not valid inside a
|
|
349
|
+
media condition — this is the gap the token scale cannot close on its own.`,
|
|
350
|
+
children: refSection({
|
|
351
|
+
name : 'One / two / three / four up',
|
|
352
|
+
meta : '576px · 768px · 992px — mirrors --breakpoint-sm/md/lg',
|
|
353
|
+
children: html`
|
|
354
|
+
<style>
|
|
355
|
+
.responsive-demo {
|
|
356
|
+
display: grid;
|
|
357
|
+
gap: var(--grid-gutter-md);
|
|
358
|
+
grid-template-columns: 1fr;
|
|
359
|
+
}
|
|
360
|
+
/* literal values, matching --breakpoint-sm/md/lg */
|
|
361
|
+
@media (min-width: 576px) {
|
|
362
|
+
.responsive-demo { grid-template-columns: repeat(2, 1fr); }
|
|
363
|
+
}
|
|
364
|
+
@media (min-width: 768px) {
|
|
365
|
+
.responsive-demo { grid-template-columns: repeat(3, 1fr); }
|
|
366
|
+
}
|
|
367
|
+
@media (min-width: 992px) {
|
|
368
|
+
.responsive-demo { grid-template-columns: repeat(4, 1fr); }
|
|
369
|
+
}
|
|
370
|
+
</style>
|
|
371
|
+
<div class="demo-frame">
|
|
372
|
+
<div class="responsive-demo">
|
|
373
|
+
${Array.from(
|
|
374
|
+
{ length: 8 },
|
|
375
|
+
(_unused, index) => html`
|
|
376
|
+
<div class="demo-cell ${index % 2 ? 'demo-cell--alt' : ''}">${index + 1}</div>
|
|
377
|
+
`
|
|
378
|
+
)}
|
|
909
379
|
</div>
|
|
910
|
-
<div class="gutter-value">gap: var(--space-lg)</div>
|
|
911
380
|
</div>
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
<h4 style="font-family: var(--font-family-sans, sans-serif); margin: 0 0 1rem 0;">Current Gutter Preview</h4>
|
|
916
|
-
<div class="gutter-preview"></div>
|
|
917
|
-
<div class="gutter-value">Current gutter value: ${args.gutter}</div>
|
|
918
|
-
</div>
|
|
919
|
-
</div>
|
|
920
|
-
</div>
|
|
381
|
+
`
|
|
382
|
+
})
|
|
383
|
+
})}
|
|
921
384
|
`;
|
|
922
|
-
|
|
923
|
-
|
|
385
|
+
|
|
386
|
+
export const GutterExample = () => {
|
|
387
|
+
const gutters = ['xs', 'sm', 'md', 'lg'];
|
|
388
|
+
|
|
389
|
+
return html`
|
|
390
|
+
${gridStyles}
|
|
391
|
+
${docsPage({
|
|
392
|
+
title : 'Gutters',
|
|
393
|
+
lede : 'The four gutter steps applied to the same four-column grid, so the difference is judged against identical content.',
|
|
394
|
+
children: refSection({
|
|
395
|
+
name : 'Gutter scale',
|
|
396
|
+
meta : '--grid-gutter-*',
|
|
397
|
+
children: html`
|
|
398
|
+
${gutters.map(size => {
|
|
399
|
+
const token = `--grid-gutter-${size}`;
|
|
400
|
+
return html`
|
|
401
|
+
<p class="demo-label">${token} = ${resolve(token)}</p>
|
|
402
|
+
<div class="demo-frame">
|
|
403
|
+
<div class="demo-grid" style="--demo-cols: 4; gap: var(${token})">
|
|
404
|
+
${Array.from(
|
|
405
|
+
{ length: 4 },
|
|
406
|
+
(_unused, index) => html`
|
|
407
|
+
<div class="demo-cell ${index % 2 ? 'demo-cell--alt' : ''}">
|
|
408
|
+
${index + 1}
|
|
409
|
+
</div>
|
|
410
|
+
`
|
|
411
|
+
)}
|
|
412
|
+
</div>
|
|
413
|
+
</div>
|
|
414
|
+
`;
|
|
415
|
+
})}
|
|
416
|
+
`
|
|
417
|
+
})
|
|
418
|
+
})}
|
|
419
|
+
`;
|
|
924
420
|
};
|
|
925
|
-
GutterExample.storyName = 'Grid Gutter';
|
|
926
|
-
GutterExample.parameters = {
|
|
927
|
-
docs: {
|
|
928
|
-
description: {
|
|
929
|
-
story: 'Grid gutter (gap) system demonstrating different spacing options between columns. Shows visual comparison of no gutter, small, medium, and large gutters.'
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
};
|