Skip to content

Commit 6b4089d

Browse files
vdepizzolactions-userlangermank
authored
PageLayout component / Layout beta + storybook (#1737)
* storybook for layout alpha * the beginning of layout beta * simplify spacing structure and other things this is a reminder that all the abstraction can happen in the viewComponent; there's no need to flood the css with constricted behaviors * add rowGap & dividers, clean spacing props * content-width support, sticky pane * cleanup props * add preset property * !default * component name & settings example * typo, cleaner header & footer template * fix preset options * mobile-friendly responsive behavior * ongoing flowVertical breakpoint behavior * finish panePosition + responsive pos & dividers * panePosition fix * add splitAsPage, finish responsive divider * Layout beta ongoing updates (#1779) - simplify component with better names - rename it to `PageLayout` - stylelint cleanup - finalize responsive variants - finalize variant-specific region dividers * add minimum 320px viewport * fix layout alpha, add layout patterns * cleanup bg colors, stylint pass * enable debug bg colors * colorful regions by default for dubugging * "Needless disable for primer/no-undefined-vars" * Stylelint auto-fixes * line breaks a EOF * introduce page layout behavior as a sb helper * children props in specialized components * cleanup * typo * discussions responsive temporary example * layout alpha descriptions * pageLayout prop descriptions * cleanup * fix conflict * copy * responsiveVariant storybook description * 0 padding on fullscreen storybook layout * has__divider for boolean props * cleanup, copy * cleanup * cleanup * cleanup chained selections/descendants * Stylelint auto-fixes * inherit values for responsive divider props * consolidate modifier names for responsive props Changelog: ### CSS classes - `PageLayout--variant-stackRegions` → `PageLayout--responsive-stackRegions` - `PageLayout--variant-separateRegions` → `PageLayout--responsive-separateRegions` - `PageLayout--variant-stackRegions-panePos-*` →`PageLayout--responsive-panePos-*` - `PageLayout--variant-separateRegions-primary-*` →`PageLayout--responsive-primary-*` - `PageLayout-region--hasDivider-*` → `PageLayout-region--dividerNarrow-*` ### Prop names - `responsivePrimaryRegion` → `primaryRegion` - `paneResponsivePosition` → `panePositionNarrow` - `paneResponsiveDivider` → `paneDividerNarrow` - `headerResponsiveDivider`→ `headerDividerNarrow` - `footerResponsiveDivider`→ `footerDividerNarrow` ### Args - `*DividerNarrow` props have new `inherit` value by default * Create lemon-games-swim.md * Update lemon-games-swim.md * cleanup, header+footer dividers as local modifiers * hasFooterDivider instead of footerDivider * fix primaryRegion selector Co-authored-by: Actions Auto Build <[email protected]> Co-authored-by: Katie Langerman <[email protected]>
1 parent 995d790 commit 6b4089d

15 files changed

+2091
-9
lines changed

.changeset/lemon-games-swim.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@primer/css": minor
3+
---
4+
5+
Adds new PageLayout component CSS with Storybook documentation

docs/.storybook/preview-head.html

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
margin: -1rem;
2323
}
2424

25+
.sb-main-fullscreen .theme-wrap .story-wrap {
26+
padding: 0;
27+
}
28+
2529
.sb-main-padded div:not(.theme-wrap) > [data-dark-theme] {
2630
margin: -1rem;
2731
padding: 1rem;

docs/.storybook/preview.js

+7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ import renderToHTML from '../src/stories/helpers/code-snippet-html-helper'
77
const customViewports = {
88
minXS: {
99
name: 'XS (min)',
10+
styles: {
11+
width: '320px',
12+
height: '100%'
13+
}
14+
},
15+
medXS: {
16+
name: 'XS (med)',
1017
styles: {
1118
width: '375px',
1219
height: '100%'

docs/src/stories/components/ActionList/ActionListExamples.stories.jsx

+257
Large diffs are not rendered by default.

docs/src/stories/components/ActionList/ActionListPatterns.stories.jsx

+6-6
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ NavWithSubItemsLeadingVisual16px.args = {
152152
children={
153153
<ListTemplate
154154
subGroup
155-
ariaLabel="Sub nav descrioption"
155+
ariaLabel="Sub nav decription"
156156
children={
157157
<>
158158
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic ariaLevel="2" />
@@ -236,7 +236,7 @@ NavWithSubItemsLeadingVisual20px.args = {
236236
children={
237237
<ListTemplate
238238
subGroup
239-
ariaLabel="Sub nav descrioption"
239+
ariaLabel="Sub nav decription"
240240
children={
241241
<>
242242
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic ariaLevel="2" />
@@ -328,7 +328,7 @@ NavWithSubItemsLeadingVisual24px.args = {
328328
children={
329329
<ListTemplate
330330
subGroup
331-
ariaLabel="Sub nav descrioption"
331+
ariaLabel="Sub nav decription"
332332
children={
333333
<>
334334
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic ariaLevel="2" />
@@ -671,7 +671,7 @@ NavWithSubItemsLeadingVisual16pxSubSections.args = {
671671
<ListTemplate
672672
subGroup
673673
ariaLabelledBy="group-id-1"
674-
ariaLabel="Sub nav descrioption"
674+
ariaLabel="Sub nav decription"
675675
children={
676676
<>
677677
<ListItemTemplate
@@ -701,7 +701,7 @@ NavWithSubItemsLeadingVisual16pxSubSections.args = {
701701
containsSubItem
702702
containsActiveSubItem
703703
subGroup
704-
ariaLabel="Sub nav descrioption"
704+
ariaLabel="Sub nav decription"
705705
children={
706706
<>
707707
<ListItemTemplate
@@ -740,7 +740,7 @@ NavWithSubItemsLeadingVisual16pxSubSections.args = {
740740
children={
741741
<ListTemplate
742742
subGroup
743-
ariaLabel="Sub nav descrioption"
743+
ariaLabel="Sub nav decription"
744744
ariaLabelledBy="group-id-2"
745745
children={
746746
<>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
import React from 'react'
2+
import clsx from 'clsx'
3+
4+
export default {
5+
title: 'Components/Layout/Alpha',
6+
excludeStories: ['LayoutAlphaTemplate'],
7+
argTypes: {
8+
container: {
9+
control: { type: 'select' },
10+
options: ['fluid', 'md', 'lg', 'xl'],
11+
control: {
12+
type: 'inline-radio'
13+
},
14+
description: 'Wrapper around the entire component to define an optional maximum width.',
15+
table: {
16+
category: 'CSS'
17+
}
18+
},
19+
hasDivider: {
20+
control: { type: 'boolean' },
21+
description: 'Whether to show a pane line divider.',
22+
table: {
23+
category: 'CSS'
24+
}
25+
},
26+
gutter: {
27+
options: ['default', 'none', 'condensed', 'spacious'],
28+
control: {
29+
type: 'inline-radio'
30+
},
31+
description: 'Sets the gap between columns.',
32+
table: {
33+
category: 'CSS'
34+
}
35+
},
36+
sidebarPosition: {
37+
options: ['start', 'end'],
38+
control: {
39+
type: 'inline-radio'
40+
},
41+
description: 'Sets the position of the sidebar.',
42+
table: {
43+
category: 'CSS'
44+
}
45+
},
46+
sidebarWidth: {
47+
options: ['default', 'narrow', 'wide'],
48+
control: {
49+
type: 'inline-radio'
50+
},
51+
description: 'Sets the width of the sidebar.',
52+
table: {
53+
category: 'CSS'
54+
}
55+
},
56+
mainWidth: {
57+
options: ['fluid', 'md', 'lg', 'xl'],
58+
control: {
59+
type: 'inline-radio'
60+
},
61+
description: 'Sets the width of the main content area.',
62+
table: {
63+
category: 'CSS'
64+
}
65+
},
66+
flowRowUntil: {
67+
options: ['sm', 'md', 'lg'],
68+
control: {
69+
type: 'inline-radio',
70+
},
71+
description: 'Sets the maximum breakpoint at which the layout will flow as row.',
72+
table: {
73+
category: 'CSS'
74+
}
75+
},
76+
mainChildren: {
77+
description: 'creates a slot for main children',
78+
table: {
79+
category: 'HTML'
80+
}
81+
},
82+
sidebarChildren: {
83+
description: 'creates a slot for sidebar children',
84+
table: {
85+
category: 'HTML'
86+
}
87+
},
88+
}
89+
}
90+
91+
// build every component case here in the template (private api)
92+
export const LayoutAlphaTemplate = ({
93+
container,
94+
hasDivider,
95+
gutter,
96+
sidebarPosition,
97+
sidebarWidth,
98+
mainWidth,
99+
flowRowUntil,
100+
mainChildren,
101+
sidebarChildren
102+
}) => {
103+
104+
// Default values
105+
container = container ?? 'xl';
106+
hasDivider = hasDivider ?? false;
107+
gutter = gutter ?? 'default';
108+
sidebarPosition = sidebarPosition ?? 'end';
109+
sidebarWidth = sidebarWidth ?? 'default';
110+
mainWidth = mainWidth ?? 'full';
111+
flowRowUntil = flowRowUntil ?? 'md';
112+
113+
// Leave `null` values for states that don't require a modifier class
114+
container = (container === 'full') ? null : container;
115+
hasDivider = (hasDivider === false) ? null : hasDivider;
116+
gutter = (gutter === 'default') ? null : gutter;
117+
sidebarWidth = (sidebarWidth === 'default') ? null : sidebarWidth;
118+
mainWidth = (mainWidth === 'full') ? null : mainWidth;
119+
flowRowUntil = (flowRowUntil === 'sm') ? null : flowRowUntil;
120+
121+
return (
122+
<div
123+
// use clsx for multiple classnames
124+
className={clsx(
125+
'Layout',
126+
container && 'container-' + `${container}`,
127+
gutter && 'Layout--gutter-' + `${gutter}`,
128+
sidebarPosition && 'Layout--sidebarPosition-' + `${sidebarPosition}`,
129+
sidebarWidth && 'Layout--sidebar-' + `${sidebarWidth}`,
130+
hasDivider && 'Layout--divided',
131+
flowRowUntil && '' + 'Layout--flowRow-until-' + `${flowRowUntil}`
132+
)}
133+
// use undefined for values that shouldn't be set if false
134+
aria-hidden={hasDivider ? 'true' : undefined}
135+
>
136+
{/* use {children} for wrapper component templates */}
137+
<>
138+
<div className="Layout-main">
139+
{mainWidth ? (
140+
<>
141+
<div className={'Layout-main-centered-' + mainWidth}>
142+
<div className={clsx( mainWidth && 'container-' + mainWidth)}>
143+
{mainChildren}
144+
</div>
145+
</div>
146+
</>
147+
) : (
148+
<>
149+
{mainChildren}
150+
</>
151+
)}
152+
</div>
153+
<div className="Layout-divider"></div>
154+
<div className="Layout-sidebar">{sidebarChildren}</div>
155+
</>
156+
</div>
157+
);
158+
};
159+
160+
const sidebarPlaceholder =
161+
<>
162+
<div style={
163+
{
164+
width: '100%',
165+
height: '100%',
166+
backgroundColor: '#DDF4FF',
167+
border: '1px solid #80CCFF',
168+
padding: '16px',
169+
borderRadius: '6px'
170+
}
171+
}>
172+
sidebar
173+
</div>
174+
</>;
175+
176+
const mainPlaceholder =
177+
<>
178+
<div style={
179+
{
180+
width: '100%',
181+
height: '100%',
182+
backgroundColor: '#FFEFF7',
183+
border: '1px solid #FFADDA',
184+
padding: '16px',
185+
borderRadius: '6px'
186+
}
187+
}>
188+
main
189+
</div>
190+
</>;
191+
192+
// create a "playground" demo page that may set some defaults and allow story to access component controls
193+
export const Playground = LayoutAlphaTemplate.bind({})
194+
Playground.args = {
195+
container: 'full',
196+
hasDivider: false,
197+
gutter: 'default',
198+
sidebarPosition: 'end',
199+
sidebarWidth: 'default',
200+
mainWidth: 'full',
201+
flowRowUntil: 'md',
202+
mainChildren: mainPlaceholder,
203+
sidebarChildren: sidebarPlaceholder
204+
}

0 commit comments

Comments
 (0)