mirror of
https://github.com/primer/css.git
synced 2024-12-23 14:13:14 +03:00
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 <actions@github.com> Co-authored-by: Katie Langerman <langermank@github.com>
This commit is contained in:
parent
995d790d73
commit
6b4089d8b3
5
.changeset/lemon-games-swim.md
Normal file
5
.changeset/lemon-games-swim.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@primer/css": minor
|
||||
---
|
||||
|
||||
Adds new PageLayout component CSS with Storybook documentation
|
@ -22,6 +22,10 @@
|
||||
margin: -1rem;
|
||||
}
|
||||
|
||||
.sb-main-fullscreen .theme-wrap .story-wrap {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sb-main-padded div:not(.theme-wrap) > [data-dark-theme] {
|
||||
margin: -1rem;
|
||||
padding: 1rem;
|
||||
|
@ -7,6 +7,13 @@ import renderToHTML from '../src/stories/helpers/code-snippet-html-helper'
|
||||
const customViewports = {
|
||||
minXS: {
|
||||
name: 'XS (min)',
|
||||
styles: {
|
||||
width: '320px',
|
||||
height: '100%'
|
||||
}
|
||||
},
|
||||
medXS: {
|
||||
name: 'XS (med)',
|
||||
styles: {
|
||||
width: '375px',
|
||||
height: '100%'
|
||||
|
@ -0,0 +1,257 @@
|
||||
import React from 'react'
|
||||
import clsx from 'clsx'
|
||||
import {DividerTemplate} from './ActionListDivider.stories'
|
||||
import {ListItemTemplate} from './ActionListItem.stories'
|
||||
import {ListTemplate} from './ActionList.stories'
|
||||
|
||||
export default {
|
||||
title: 'Components/ActionList/Examples'
|
||||
}
|
||||
|
||||
export const RepoSettings = ListTemplate.bind({})
|
||||
RepoSettings.storyName = 'Repository settings';
|
||||
RepoSettings.args = {
|
||||
...ListTemplate.args,
|
||||
...ListItemTemplate.args,
|
||||
ariaLabel: 'Main menu description',
|
||||
role: 'menu',
|
||||
showDividers: false,
|
||||
children: (
|
||||
<>
|
||||
<ListItemTemplate
|
||||
text="General"
|
||||
href="#content"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.429 1.525a6.593 6.593 0 011.142 0c.036.003.108.036.137.146l.289 1.105c.147.56.55.967.997 1.189.174.086.341.183.501.29.417.278.97.423 1.53.27l1.102-.303c.11-.03.175.016.195.046.219.31.41.641.573.989.014.031.022.11-.059.19l-.815.806c-.411.406-.562.957-.53 1.456a4.588 4.588 0 010 .582c-.032.499.119 1.05.53 1.456l.815.806c.08.08.073.159.059.19a6.494 6.494 0 01-.573.99c-.02.029-.086.074-.195.045l-1.103-.303c-.559-.153-1.112-.008-1.529.27-.16.107-.327.204-.5.29-.449.222-.851.628-.998 1.189l-.289 1.105c-.029.11-.101.143-.137.146a6.613 6.613 0 01-1.142 0c-.036-.003-.108-.037-.137-.146l-.289-1.105c-.147-.56-.55-.967-.997-1.189a4.502 4.502 0 01-.501-.29c-.417-.278-.97-.423-1.53-.27l-1.102.303c-.11.03-.175-.016-.195-.046a6.492 6.492 0 01-.573-.989c-.014-.031-.022-.11.059-.19l.815-.806c.411-.406.562-.957.53-1.456a4.587 4.587 0 010-.582c.032-.499-.119-1.05-.53-1.456l-.815-.806c-.08-.08-.073-.159-.059-.19a6.44 6.44 0 01.573-.99c.02-.029.086-.075.195-.045l1.103.303c.559.153 1.112.008 1.529-.27.16-.107.327-.204.5-.29.449-.222.851-.628.998-1.189l.289-1.105c.029-.11.101-.143.137-.146zM8 0c-.236 0-.47.01-.701.03-.743.065-1.29.615-1.458 1.261l-.29 1.106c-.017.066-.078.158-.211.224a5.994 5.994 0 00-.668.386c-.123.082-.233.09-.3.071L3.27 2.776c-.644-.177-1.392.02-1.82.63a7.977 7.977 0 00-.704 1.217c-.315.675-.111 1.422.363 1.891l.815.806c.05.048.098.147.088.294a6.084 6.084 0 000 .772c.01.147-.038.246-.088.294l-.815.806c-.474.469-.678 1.216-.363 1.891.2.428.436.835.704 1.218.428.609 1.176.806 1.82.63l1.103-.303c.066-.019.176-.011.299.071.213.143.436.272.668.386.133.066.194.158.212.224l.289 1.106c.169.646.715 1.196 1.458 1.26a8.094 8.094 0 001.402 0c.743-.064 1.29-.614 1.458-1.26l.29-1.106c.017-.066.078-.158.211-.224a5.98 5.98 0 00.668-.386c.123-.082.233-.09.3-.071l1.102.302c.644.177 1.392-.02 1.82-.63.268-.382.505-.789.704-1.217.315-.675.111-1.422-.364-1.891l-.814-.806c-.05-.048-.098-.147-.088-.294a6.1 6.1 0 000-.772c-.01-.147.039-.246.088-.294l.814-.806c.475-.469.679-1.216.364-1.891a7.992 7.992 0 00-.704-1.218c-.428-.609-1.176-.806-1.82-.63l-1.103.303c-.066.019-.176.011-.299-.071a5.991 5.991 0 00-.668-.386c-.133-.066-.194-.158-.212-.224L10.16 1.29C9.99.645 9.444.095 8.701.031A8.094 8.094 0 008 0zm1.5 8a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zM11 8a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>`}
|
||||
/>
|
||||
<DividerTemplate />
|
||||
<DividerTemplate title="Access" id="group-id-1" />
|
||||
<ListItemTemplate
|
||||
containsSubItem
|
||||
children={
|
||||
<ListTemplate
|
||||
subGroup
|
||||
role="menu"
|
||||
ariaLabelledBy="group-id-1"
|
||||
ariaLabel="Sub nav decription"
|
||||
children={
|
||||
<>
|
||||
<ListItemTemplate
|
||||
text="Collaborators"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-people">
|
||||
<path fill-rule="evenodd" d="M5.5 3.5a2 2 0 100 4 2 2 0 000-4zM2 5.5a3.5 3.5 0 115.898 2.549 5.507 5.507 0 013.034 4.084.75.75 0 11-1.482.235 4.001 4.001 0 00-7.9 0 .75.75 0 01-1.482-.236A5.507 5.507 0 013.102 8.05 3.49 3.49 0 012 5.5zM11 4a.75.75 0 100 1.5 1.5 1.5 0 01.666 2.844.75.75 0 00-.416.672v.352a.75.75 0 00.574.73c1.2.289 2.162 1.2 2.522 2.372a.75.75 0 101.434-.44 5.01 5.01 0 00-2.56-3.012A3 3 0 0011 4z"></path>
|
||||
</svg>`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
containsSubItem
|
||||
text="Moderation options"
|
||||
// href="/"
|
||||
collapsible
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment-discussion">
|
||||
<path fill-rule="evenodd" d="M1.5 2.75a.25.25 0 01.25-.25h8.5a.25.25 0 01.25.25v5.5a.25.25 0 01-.25.25h-3.5a.75.75 0 00-.53.22L3.5 11.44V9.25a.75.75 0 00-.75-.75h-1a.25.25 0 01-.25-.25v-5.5zM1.75 1A1.75 1.75 0 000 2.75v5.5C0 9.216.784 10 1.75 10H2v1.543a1.457 1.457 0 002.487 1.03L7.061 10h3.189A1.75 1.75 0 0012 8.25v-5.5A1.75 1.75 0 0010.25 1h-8.5zM14.5 4.75a.25.25 0 00-.25-.25h-.5a.75.75 0 110-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0114.25 12H14v1.543a1.457 1.457 0 01-2.487 1.03L9.22 12.28a.75.75 0 111.06-1.06l2.22 2.22v-2.19a.75.75 0 01.75-.75h1a.25.25 0 00.25-.25v-5.5z"></path>
|
||||
</svg>`}
|
||||
children={
|
||||
<ListTemplate
|
||||
containsSubItem
|
||||
role="menu"
|
||||
subGroup
|
||||
ariaLabel="Sub nav decription"
|
||||
children={
|
||||
<>
|
||||
<ListItemTemplate
|
||||
subItem
|
||||
text="Interaction limits"
|
||||
href="/"
|
||||
ariaCurrent="page"
|
||||
/>
|
||||
<ListItemTemplate
|
||||
subItem
|
||||
text="Blocked users"
|
||||
href="/"
|
||||
/>
|
||||
<ListItemTemplate
|
||||
subItem
|
||||
text="Code review limits"
|
||||
href="/"
|
||||
/>
|
||||
<ListItemTemplate
|
||||
subItem
|
||||
text="Reported content"
|
||||
href="/"
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<DividerTemplate />
|
||||
<DividerTemplate title="Code and automation" id="group-id-2" />
|
||||
<ListItemTemplate
|
||||
containsSubItem
|
||||
children={
|
||||
<ListTemplate
|
||||
subGroup
|
||||
role="menu"
|
||||
ariaLabel="Sub nav decription"
|
||||
ariaLabelledBy="group-id-2"
|
||||
children={
|
||||
<>
|
||||
<ListItemTemplate
|
||||
text="Branches"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M11.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122V6A2.5 2.5 0 0110 8.5H6a1 1 0 00-1 1v1.128a2.251 2.251 0 11-1.5 0V5.372a2.25 2.25 0 111.5 0v1.836A2.492 2.492 0 016 7h4a1 1 0 001-1v-.628A2.25 2.25 0 019.5 3.25zM4.25 12a.75.75 0 100 1.5.75.75 0 000-1.5zM3.5 3.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0z"></path></svg>`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
text="Actions"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zM6.379 5.227A.25.25 0 006 5.442v5.117a.25.25 0 00.379.214l4.264-2.559a.25.25 0 000-.428L6.379 5.227z"></path></svg>`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
text="Webhooks"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-broadcast">
|
||||
<path fill-rule="evenodd" d="M3.267 1.457c.3.286.312.76.026 1.06A6.475 6.475 0 001.5 7a6.472 6.472 0 001.793 4.483.75.75 0 01-1.086 1.034 8.89 8.89 0 01-.276-.304l.569-.49-.569.49A7.971 7.971 0 010 7c0-2.139.84-4.083 2.207-5.517a.75.75 0 011.06-.026zm9.466 0a.75.75 0 011.06.026A7.975 7.975 0 0116 7c0 2.139-.84 4.083-2.207 5.517a.75.75 0 11-1.086-1.034A6.475 6.475 0 0014.5 7a6.475 6.475 0 00-1.793-4.483.75.75 0 01.026-1.06zM8.75 8.582a1.75 1.75 0 10-1.5 0v5.668a.75.75 0 001.5 0V8.582zM5.331 4.736a.75.75 0 10-1.143-.972A4.983 4.983 0 003 7c0 1.227.443 2.352 1.177 3.222a.75.75 0 001.146-.967A3.483 3.483 0 014.5 7c0-.864.312-1.654.831-2.264zm6.492-.958a.75.75 0 00-1.146.967c.514.61.823 1.395.823 2.255 0 .86-.31 1.646-.823 2.255a.75.75 0 101.146.967A4.983 4.983 0 0013 7a4.983 4.983 0 00-1.177-3.222z"></path>
|
||||
</svg>`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
text="Environments"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-server">
|
||||
<path fill-rule="evenodd" d="M1.75 1A1.75 1.75 0 000 2.75v4c0 .372.116.717.314 1a1.742 1.742 0 00-.314 1v4c0 .966.784 1.75 1.75 1.75h12.5A1.75 1.75 0 0016 12.75v-4c0-.372-.116-.717-.314-1 .198-.283.314-.628.314-1v-4A1.75 1.75 0 0014.25 1H1.75zm0 7.5a.25.25 0 00-.25.25v4c0 .138.112.25.25.25h12.5a.25.25 0 00.25-.25v-4a.25.25 0 00-.25-.25H1.75zM1.5 2.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v4a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25v-4zm5.5 2A.75.75 0 017.75 4h4.5a.75.75 0 010 1.5h-4.5A.75.75 0 017 4.75zM7.75 10a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-4.5zM3 4.75A.75.75 0 013.75 4h.5a.75.75 0 010 1.5h-.5A.75.75 0 013 4.75zM3.75 10a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5z"></path>
|
||||
</svg>`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
text="Pages"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-file">
|
||||
<path fill-rule="evenodd" d="M3.75 1.5a.25.25 0 00-.25.25v11.5c0 .138.112.25.25.25h8.5a.25.25 0 00.25-.25V6H9.75A1.75 1.75 0 018 4.25V1.5H3.75zm5.75.56v2.19c0 .138.112.25.25.25h2.19L9.5 2.06zM2 1.75C2 .784 2.784 0 3.75 0h5.086c.464 0 .909.184 1.237.513l3.414 3.414c.329.328.513.773.513 1.237v8.086A1.75 1.75 0 0112.25 15h-8.5A1.75 1.75 0 012 13.25V1.75z"></path>
|
||||
</svg>`}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<DividerTemplate />
|
||||
<DividerTemplate title="Security" id="group-id-3" />
|
||||
<ListItemTemplate
|
||||
containsSubItem
|
||||
children={
|
||||
<ListTemplate
|
||||
subGroup
|
||||
role="menu"
|
||||
ariaLabel="Sub nav decription"
|
||||
ariaLabelledBy="group-id-3"
|
||||
children={
|
||||
<>
|
||||
<ListItemTemplate
|
||||
text="Code security and analysis"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8.533.133a1.75 1.75 0 00-1.066 0l-5.25 1.68A1.75 1.75 0 001 3.48V7c0 1.566.32 3.182 1.303 4.682.983 1.498 2.585 2.813 5.032 3.855a1.7 1.7 0 001.33 0c2.447-1.042 4.049-2.357 5.032-3.855C14.68 10.182 15 8.566 15 7V3.48a1.75 1.75 0 00-1.217-1.667L8.533.133zm-.61 1.429a.25.25 0 01.153 0l5.25 1.68a.25.25 0 01.174.238V7c0 1.358-.275 2.666-1.057 3.86-.784 1.194-2.121 2.34-4.366 3.297a.2.2 0 01-.154 0c-2.245-.956-3.582-2.104-4.366-3.298C2.775 9.666 2.5 8.36 2.5 7V3.48a.25.25 0 01.174-.237l5.25-1.68zM9.5 6.5a1.5 1.5 0 01-.75 1.3v2.45a.75.75 0 01-1.5 0V7.8A1.5 1.5 0 119.5 6.5z"></path></svg>`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
text="Deploy keys"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M6.5 5.5a4 4 0 112.731 3.795.75.75 0 00-.768.18L7.44 10.5H6.25a.75.75 0 00-.75.75v1.19l-.06.06H4.25a.75.75 0 00-.75.75v1.19l-.06.06H1.75a.25.25 0 01-.25-.25v-1.69l5.024-5.023a.75.75 0 00.181-.768A3.995 3.995 0 016.5 5.5zm4-5.5a5.5 5.5 0 00-5.348 6.788L.22 11.72a.75.75 0 00-.22.53v2C0 15.216.784 16 1.75 16h2a.75.75 0 00.53-.22l.5-.5a.75.75 0 00.22-.53V14h.75a.75.75 0 00.53-.22l.5-.5a.75.75 0 00.22-.53V12h.75a.75.75 0 00.53-.22l.932-.932A5.5 5.5 0 1010.5 0zm.5 6a1 1 0 100-2 1 1 0 000 2z"></path></svg>`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
text="Secrets"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M0 2.75A2.75 2.75 0 012.75 0h10.5A2.75 2.75 0 0116 2.75v10.5A2.75 2.75 0 0113.25 16H2.75A2.75 2.75 0 010 13.25V2.75zM2.75 1.5c-.69 0-1.25.56-1.25 1.25v10.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25V2.75c0-.69-.56-1.25-1.25-1.25H2.75z"></path><path d="M8 4a.75.75 0 01.75.75V6.7l1.69-.975a.75.75 0 01.75 1.3L9.5 8l1.69.976a.75.75 0 01-.75 1.298L8.75 9.3v1.951a.75.75 0 01-1.5 0V9.299l-1.69.976a.75.75 0 01-.75-1.3L6.5 8l-1.69-.975a.75.75 0 01.75-1.3l1.69.976V4.75A.75.75 0 018 4z"></path></svg>`}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
RepoSettings.decorators = [
|
||||
Story => (
|
||||
<nav>
|
||||
<Story />
|
||||
</nav>
|
||||
)
|
||||
]
|
||||
|
||||
export const DiscussionsPane = ListTemplate.bind({})
|
||||
DiscussionsPane.storyName = 'Discussions pane';
|
||||
DiscussionsPane.args = {
|
||||
...ListTemplate.args,
|
||||
...ListItemTemplate.args,
|
||||
ariaLabel: 'Categories',
|
||||
role: 'menu',
|
||||
showDividers: false,
|
||||
children: (
|
||||
<>
|
||||
<ListItemTemplate
|
||||
text="All discussions"
|
||||
href="/"
|
||||
ariaCurrent={true}
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 2.75a.25.25 0 01.25-.25h8.5a.25.25 0 01.25.25v5.5a.25.25 0 01-.25.25h-3.5a.75.75 0 00-.53.22L3.5 11.44V9.25a.75.75 0 00-.75-.75h-1a.25.25 0 01-.25-.25v-5.5zM1.75 1A1.75 1.75 0 000 2.75v5.5C0 9.216.784 10 1.75 10H2v1.543a1.457 1.457 0 002.487 1.03L7.061 10h3.189A1.75 1.75 0 0012 8.25v-5.5A1.75 1.75 0 0010.25 1h-8.5zM14.5 4.75a.25.25 0 00-.25-.25h-.5a.75.75 0 110-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0114.25 12H14v1.543a1.457 1.457 0 01-2.487 1.03L9.22 12.28a.75.75 0 111.06-1.06l2.22 2.22v-2.19a.75.75 0 01.75-.75h1a.25.25 0 00.25-.25v-5.5z"></path></svg>`}
|
||||
/>
|
||||
<DividerTemplate />
|
||||
<ListItemTemplate
|
||||
text="Announcements"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`🔔`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
text="General"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`💬`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
text="Ideas"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`🏮`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
text="Questions and answers"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`🌻`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
text="Show and tell"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`👋`}
|
||||
/>
|
||||
<ListItemTemplate
|
||||
text="Polls"
|
||||
href="/"
|
||||
leadingVisualSize="ActionList-content--visual16"
|
||||
leadingVisual={`🍒`}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
};
|
||||
DiscussionsPane.decorators = [
|
||||
Story => (
|
||||
<nav>
|
||||
<Story />
|
||||
</nav>
|
||||
)
|
||||
]
|
@ -152,7 +152,7 @@ NavWithSubItemsLeadingVisual16px.args = {
|
||||
children={
|
||||
<ListTemplate
|
||||
subGroup
|
||||
ariaLabel="Sub nav descrioption"
|
||||
ariaLabel="Sub nav decription"
|
||||
children={
|
||||
<>
|
||||
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic ariaLevel="2" />
|
||||
@ -236,7 +236,7 @@ NavWithSubItemsLeadingVisual20px.args = {
|
||||
children={
|
||||
<ListTemplate
|
||||
subGroup
|
||||
ariaLabel="Sub nav descrioption"
|
||||
ariaLabel="Sub nav decription"
|
||||
children={
|
||||
<>
|
||||
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic ariaLevel="2" />
|
||||
@ -328,7 +328,7 @@ NavWithSubItemsLeadingVisual24px.args = {
|
||||
children={
|
||||
<ListTemplate
|
||||
subGroup
|
||||
ariaLabel="Sub nav descrioption"
|
||||
ariaLabel="Sub nav decription"
|
||||
children={
|
||||
<>
|
||||
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic ariaLevel="2" />
|
||||
@ -671,7 +671,7 @@ NavWithSubItemsLeadingVisual16pxSubSections.args = {
|
||||
<ListTemplate
|
||||
subGroup
|
||||
ariaLabelledBy="group-id-1"
|
||||
ariaLabel="Sub nav descrioption"
|
||||
ariaLabel="Sub nav decription"
|
||||
children={
|
||||
<>
|
||||
<ListItemTemplate
|
||||
@ -701,7 +701,7 @@ NavWithSubItemsLeadingVisual16pxSubSections.args = {
|
||||
containsSubItem
|
||||
containsActiveSubItem
|
||||
subGroup
|
||||
ariaLabel="Sub nav descrioption"
|
||||
ariaLabel="Sub nav decription"
|
||||
children={
|
||||
<>
|
||||
<ListItemTemplate
|
||||
@ -740,7 +740,7 @@ NavWithSubItemsLeadingVisual16pxSubSections.args = {
|
||||
children={
|
||||
<ListTemplate
|
||||
subGroup
|
||||
ariaLabel="Sub nav descrioption"
|
||||
ariaLabel="Sub nav decription"
|
||||
ariaLabelledBy="group-id-2"
|
||||
children={
|
||||
<>
|
||||
|
204
docs/src/stories/components/Layout/LayoutAlpha.stories.jsx
Normal file
204
docs/src/stories/components/Layout/LayoutAlpha.stories.jsx
Normal file
@ -0,0 +1,204 @@
|
||||
import React from 'react'
|
||||
import clsx from 'clsx'
|
||||
|
||||
export default {
|
||||
title: 'Components/Layout/Alpha',
|
||||
excludeStories: ['LayoutAlphaTemplate'],
|
||||
argTypes: {
|
||||
container: {
|
||||
control: { type: 'select' },
|
||||
options: ['fluid', 'md', 'lg', 'xl'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Wrapper around the entire component to define an optional maximum width.',
|
||||
table: {
|
||||
category: 'CSS'
|
||||
}
|
||||
},
|
||||
hasDivider: {
|
||||
control: { type: 'boolean' },
|
||||
description: 'Whether to show a pane line divider.',
|
||||
table: {
|
||||
category: 'CSS'
|
||||
}
|
||||
},
|
||||
gutter: {
|
||||
options: ['default', 'none', 'condensed', 'spacious'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets the gap between columns.',
|
||||
table: {
|
||||
category: 'CSS'
|
||||
}
|
||||
},
|
||||
sidebarPosition: {
|
||||
options: ['start', 'end'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets the position of the sidebar.',
|
||||
table: {
|
||||
category: 'CSS'
|
||||
}
|
||||
},
|
||||
sidebarWidth: {
|
||||
options: ['default', 'narrow', 'wide'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets the width of the sidebar.',
|
||||
table: {
|
||||
category: 'CSS'
|
||||
}
|
||||
},
|
||||
mainWidth: {
|
||||
options: ['fluid', 'md', 'lg', 'xl'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets the width of the main content area.',
|
||||
table: {
|
||||
category: 'CSS'
|
||||
}
|
||||
},
|
||||
flowRowUntil: {
|
||||
options: ['sm', 'md', 'lg'],
|
||||
control: {
|
||||
type: 'inline-radio',
|
||||
},
|
||||
description: 'Sets the maximum breakpoint at which the layout will flow as row.',
|
||||
table: {
|
||||
category: 'CSS'
|
||||
}
|
||||
},
|
||||
mainChildren: {
|
||||
description: 'creates a slot for main children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
},
|
||||
sidebarChildren: {
|
||||
description: 'creates a slot for sidebar children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// build every component case here in the template (private api)
|
||||
export const LayoutAlphaTemplate = ({
|
||||
container,
|
||||
hasDivider,
|
||||
gutter,
|
||||
sidebarPosition,
|
||||
sidebarWidth,
|
||||
mainWidth,
|
||||
flowRowUntil,
|
||||
mainChildren,
|
||||
sidebarChildren
|
||||
}) => {
|
||||
|
||||
// Default values
|
||||
container = container ?? 'xl';
|
||||
hasDivider = hasDivider ?? false;
|
||||
gutter = gutter ?? 'default';
|
||||
sidebarPosition = sidebarPosition ?? 'end';
|
||||
sidebarWidth = sidebarWidth ?? 'default';
|
||||
mainWidth = mainWidth ?? 'full';
|
||||
flowRowUntil = flowRowUntil ?? 'md';
|
||||
|
||||
// Leave `null` values for states that don't require a modifier class
|
||||
container = (container === 'full') ? null : container;
|
||||
hasDivider = (hasDivider === false) ? null : hasDivider;
|
||||
gutter = (gutter === 'default') ? null : gutter;
|
||||
sidebarWidth = (sidebarWidth === 'default') ? null : sidebarWidth;
|
||||
mainWidth = (mainWidth === 'full') ? null : mainWidth;
|
||||
flowRowUntil = (flowRowUntil === 'sm') ? null : flowRowUntil;
|
||||
|
||||
return (
|
||||
<div
|
||||
// use clsx for multiple classnames
|
||||
className={clsx(
|
||||
'Layout',
|
||||
container && 'container-' + `${container}`,
|
||||
gutter && 'Layout--gutter-' + `${gutter}`,
|
||||
sidebarPosition && 'Layout--sidebarPosition-' + `${sidebarPosition}`,
|
||||
sidebarWidth && 'Layout--sidebar-' + `${sidebarWidth}`,
|
||||
hasDivider && 'Layout--divided',
|
||||
flowRowUntil && '' + 'Layout--flowRow-until-' + `${flowRowUntil}`
|
||||
)}
|
||||
// use undefined for values that shouldn't be set if false
|
||||
aria-hidden={hasDivider ? 'true' : undefined}
|
||||
>
|
||||
{/* use {children} for wrapper component templates */}
|
||||
<>
|
||||
<div className="Layout-main">
|
||||
{mainWidth ? (
|
||||
<>
|
||||
<div className={'Layout-main-centered-' + mainWidth}>
|
||||
<div className={clsx( mainWidth && 'container-' + mainWidth)}>
|
||||
{mainChildren}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{mainChildren}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="Layout-divider"></div>
|
||||
<div className="Layout-sidebar">{sidebarChildren}</div>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const sidebarPlaceholder =
|
||||
<>
|
||||
<div style={
|
||||
{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: '#DDF4FF',
|
||||
border: '1px solid #80CCFF',
|
||||
padding: '16px',
|
||||
borderRadius: '6px'
|
||||
}
|
||||
}>
|
||||
sidebar
|
||||
</div>
|
||||
</>;
|
||||
|
||||
const mainPlaceholder =
|
||||
<>
|
||||
<div style={
|
||||
{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: '#FFEFF7',
|
||||
border: '1px solid #FFADDA',
|
||||
padding: '16px',
|
||||
borderRadius: '6px'
|
||||
}
|
||||
}>
|
||||
main
|
||||
</div>
|
||||
</>;
|
||||
|
||||
// create a "playground" demo page that may set some defaults and allow story to access component controls
|
||||
export const Playground = LayoutAlphaTemplate.bind({})
|
||||
Playground.args = {
|
||||
container: 'full',
|
||||
hasDivider: false,
|
||||
gutter: 'default',
|
||||
sidebarPosition: 'end',
|
||||
sidebarWidth: 'default',
|
||||
mainWidth: 'full',
|
||||
flowRowUntil: 'md',
|
||||
mainChildren: mainPlaceholder,
|
||||
sidebarChildren: sidebarPlaceholder
|
||||
}
|
502
docs/src/stories/components/Layout/LayoutBeta.stories.jsx
Normal file
502
docs/src/stories/components/Layout/LayoutBeta.stories.jsx
Normal file
@ -0,0 +1,502 @@
|
||||
import React from 'react'
|
||||
import clsx from 'clsx'
|
||||
import {NavWithSubItems} from '../ActionList/ActionListPatterns.stories'
|
||||
import PageLayoutBehavior from '../../helpers/pageLayoutBehavior.jsx'
|
||||
|
||||
export default {
|
||||
title: 'Components/Layout/Beta',
|
||||
excludeStories: ['LayoutTemplate'],
|
||||
argTypes: {
|
||||
|
||||
// Debug
|
||||
|
||||
_debug: {
|
||||
control: 'boolean',
|
||||
description: 'Show background colors in regions for debugging',
|
||||
},
|
||||
|
||||
// Structure
|
||||
|
||||
wrapperSizing: {
|
||||
options: ['fluid', 'md', 'lg', 'xl'],
|
||||
control: {
|
||||
type: 'inline-radio',
|
||||
labels: ['fluid', 'md', 'lg', 'xl']
|
||||
},
|
||||
description: 'Define the maximum width of the component. `fluid` sets it to full-width. Other values center `Layout` horizontally. Refer to [container utilities](https://primer.style/css/objects/grid#containers) for reference.',
|
||||
table: {
|
||||
category: 'Structure'
|
||||
}
|
||||
},
|
||||
outerSpacing: {
|
||||
options: ['none', 'normal', 'condensed'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets wrapper margins surrounding the component to distance itself from the viewport edges. `normal` sets the margin to 16px, and to 24px on `lg` breakpoints and above. `condensed` keeps the margin at 16px. `none` sets the margin to 0.',
|
||||
table: {
|
||||
category: 'Structure'
|
||||
}
|
||||
},
|
||||
innerSpacing: {
|
||||
options: ['none', 'normal', 'condensed'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets padding to regions individually. `normal` sets padding to 16px, with the `content` region getting 24px horizontal padding on `lg` breakpoints and above. `condensed` keeps the padding always at `16px`. `none` sets the padding to 0.',
|
||||
table: {
|
||||
category: 'Structure'
|
||||
}
|
||||
},
|
||||
columnGap: {
|
||||
options: ['none', 'normal', 'condensed'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets the gap between columns to distance them from each other. `normal` sets the gap to 16px, and to 24px on `lg` breakpoints and above. `condensed` keeps the gap always at 16px. `none` sets the gap to 0.',
|
||||
table: {
|
||||
category: 'Structure'
|
||||
}
|
||||
},
|
||||
rowGap: {
|
||||
options: ['none', 'normal', 'condensed'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets the gap below the header and above the footer. `normal` sets the gap to 16px, and to 24px on `lg` breakpoints and above. `condensed` keeps the gap always at 16px. `none` sets the gap to 0.',
|
||||
table: {
|
||||
category: 'Structure'
|
||||
}
|
||||
},
|
||||
|
||||
// Responsive
|
||||
|
||||
responsiveVariant: {
|
||||
options: ['stackRegions', 'separateRegions'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: '`responsiveVariant` defines how the layout component adapts to smaller viewports. `stackRegions` presents the content in a vertical flow, with `pane` and `content` vertically arranged. `separateRegions` presents `pane` and `content` as different pages on smaller viewports. Change the preview size from the toolbar to test it.',
|
||||
table: {
|
||||
category: 'Responsive'
|
||||
}
|
||||
},
|
||||
primaryRegion: {
|
||||
options: ['content', 'pane'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'When `responsiveVariant` is set to `separateRegions`, defines which region appears first on small viewports. `content` is default.',
|
||||
table: {
|
||||
category: 'Responsive'
|
||||
}
|
||||
},
|
||||
|
||||
// Pane
|
||||
|
||||
paneWidth: {
|
||||
options: ['default', 'narrow', 'wide'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Defines the width of the pane',
|
||||
table: {
|
||||
category: 'Pane'
|
||||
}
|
||||
},
|
||||
panePosition: {
|
||||
options: ['start', 'end'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Defines the position of the pane. `start` renders the pane on the left, and `end` renders it on the right.',
|
||||
table: {
|
||||
category: 'Pane',
|
||||
}
|
||||
},
|
||||
panePositionNarrow: {
|
||||
options: ['inherit', 'start', 'end'],
|
||||
control: {
|
||||
type: 'inline-radio',
|
||||
},
|
||||
description: 'If `responsiveVariant` is set to `stackRegions`, defines the position of the pane in narrow viewports. `start` puts the pane above `content`, and `end` puts it below `content`. `inherit` uses the same value from `panePosition`.',
|
||||
table: {
|
||||
category: 'Pane'
|
||||
}
|
||||
},
|
||||
hasPaneDivider: {
|
||||
control: { type: 'boolean' },
|
||||
description: 'Whether to show a pane line divider.',
|
||||
table: {
|
||||
category: 'Pane'
|
||||
}
|
||||
},
|
||||
paneDividerNarrow: {
|
||||
options: ['inherit', 'none', 'line', 'filled'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Whether to show a divider between `pane` and `content` regions if `responsiveVariant` is set to `stackRegions`. `line` shows a single line. `filled` shows a thicker mobile-frienldy divider.',
|
||||
table: {
|
||||
category: 'Pane'
|
||||
}
|
||||
},
|
||||
paneIsSticky: {
|
||||
control: { type: 'boolean' },
|
||||
description: 'Whether to make the pane sticky.',
|
||||
table: {
|
||||
category: 'Pane'
|
||||
}
|
||||
},
|
||||
|
||||
// Content
|
||||
|
||||
contentWidth: {
|
||||
options: ['fluid', 'sm', 'md', 'lg', 'xl'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Defines the maximum width of the content region. `fluid` sets it to full-width. Other values follow container widths from `sm` to `xl`. With smaller widths, the content region will try to stay centered to the viewport area.',
|
||||
table: {
|
||||
category: 'Content'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Header
|
||||
|
||||
hasHeader: {
|
||||
control: { type: 'boolean' },
|
||||
table: {
|
||||
category: 'Header'
|
||||
}
|
||||
},
|
||||
|
||||
hasHeaderDivider: {
|
||||
control: { type: 'boolean' },
|
||||
description: 'Whether to show a header divider.',
|
||||
table: {
|
||||
category: 'Header'
|
||||
}
|
||||
},
|
||||
|
||||
headerDividerNarrow: {
|
||||
options: ['inherit', 'none', 'line', 'filled'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Defines how the `header` divider should look on narrow viewports. `inherit` renders a `line` if `hasHeaderDivider` is true. `filled` shows a thicker mobile-friendly divider.',
|
||||
table: {
|
||||
category: 'Header'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Footer
|
||||
|
||||
hasFooter: {
|
||||
control: { type: 'boolean' },
|
||||
table: {
|
||||
category: 'Footer'
|
||||
}
|
||||
},
|
||||
|
||||
hasFooterDivider: {
|
||||
control: { type: 'boolean' },
|
||||
description: 'Whether to show a footer divider.',
|
||||
table: {
|
||||
category: 'Footer'
|
||||
}
|
||||
},
|
||||
|
||||
footerDividerNarrow: {
|
||||
options: ['inherit', 'none', 'line', 'filled'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Whether to show a divider above the `footer` region on narrow viewports. `line` shows a single line. `filled` shows a thicker mobile-frienldy divider.',
|
||||
table: {
|
||||
category: 'Footer'
|
||||
}
|
||||
},
|
||||
|
||||
// HTML
|
||||
|
||||
headerChildren: {
|
||||
description: 'creates a slot for header children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
},
|
||||
contentChildren: {
|
||||
description: 'creates a slot for content children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
},
|
||||
paneChildren: {
|
||||
description: 'creates a slot for pane children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
},
|
||||
footerChildren: {
|
||||
description: 'creates a slot for footer children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const layoutClassName = 'PageLayout';
|
||||
|
||||
// build every component case here in the template (private api)
|
||||
export const LayoutTemplate = ({
|
||||
|
||||
// Debug
|
||||
_debug,
|
||||
|
||||
// Wrapper
|
||||
wrapperSizing,
|
||||
|
||||
// Spacing and borders
|
||||
outerSpacing,
|
||||
innerSpacing,
|
||||
columnGap,
|
||||
rowGap,
|
||||
|
||||
// Pane
|
||||
paneWidth,
|
||||
panePosition,
|
||||
panePositionNarrow,
|
||||
hasPaneDivider,
|
||||
paneDividerNarrow,
|
||||
paneIsSticky,
|
||||
|
||||
// Header
|
||||
hasHeader,
|
||||
hasHeaderDivider,
|
||||
headerDividerNarrow,
|
||||
|
||||
// Footer
|
||||
hasFooter,
|
||||
hasFooterDivider,
|
||||
footerDividerNarrow,
|
||||
|
||||
// Content
|
||||
contentWidth,
|
||||
|
||||
// Responsive
|
||||
responsiveVariant,
|
||||
primaryRegion,
|
||||
|
||||
// Children
|
||||
headerChildren,
|
||||
contentChildren,
|
||||
paneChildren,
|
||||
footerChildren
|
||||
}) => {
|
||||
|
||||
const containerClass = {
|
||||
'full': '',
|
||||
'md': 'container-md',
|
||||
'lg': 'container-lg',
|
||||
'xl': 'container-xl'
|
||||
};
|
||||
|
||||
// Default values
|
||||
wrapperSizing = wrapperSizing ?? 'xl';
|
||||
outerSpacing = outerSpacing ?? 'normal';
|
||||
innerSpacing = innerSpacing ?? 'none';
|
||||
columnGap = columnGap ?? 'normal';
|
||||
rowGap = rowGap ?? 'normal';
|
||||
panePosition = panePosition ?? 'end';
|
||||
panePositionNarrow = panePositionNarrow ?? 'inherit';
|
||||
responsiveVariant = responsiveVariant ?? 'stackRegions';
|
||||
primaryRegion = primaryRegion ?? 'content';
|
||||
|
||||
// Leave `null` values for states that don't require a modifier class
|
||||
outerSpacing = (outerSpacing === 'none') ? null : outerSpacing;
|
||||
innerSpacing = (innerSpacing === 'none') ? null : innerSpacing;
|
||||
paneWidth = (paneWidth === 'default') ? null : paneWidth;
|
||||
contentWidth = (contentWidth === 'fluid') ? null : contentWidth;
|
||||
headerDividerNarrow = (headerDividerNarrow === 'none') ? null : headerDividerNarrow;
|
||||
footerDividerNarrow = (footerDividerNarrow === 'none') ? null : footerDividerNarrow;
|
||||
|
||||
// Inherit value for responsive props
|
||||
panePositionNarrow = (panePositionNarrow === 'inherit') ? panePosition : panePositionNarrow;
|
||||
|
||||
if (hasPaneDivider) {
|
||||
paneDividerNarrow = (paneDividerNarrow === 'inherit') ? 'line' : paneDividerNarrow;
|
||||
} else {
|
||||
paneDividerNarrow = null;
|
||||
}
|
||||
|
||||
if (hasHeaderDivider) {
|
||||
headerDividerNarrow = (headerDividerNarrow === 'inherit') ? 'line' : headerDividerNarrow;
|
||||
} else {
|
||||
headerDividerNarrow = null;
|
||||
}
|
||||
|
||||
if (hasFooterDivider) {
|
||||
footerDividerNarrow = (footerDividerNarrow === 'inherit') ? 'line' : footerDividerNarrow;
|
||||
} else {
|
||||
footerDividerNarrow = null;
|
||||
}
|
||||
|
||||
PageLayoutBehavior();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={clsx(
|
||||
layoutClassName,
|
||||
|
||||
outerSpacing && layoutClassName + '--outerSpacing-' + `${outerSpacing}`,
|
||||
innerSpacing && layoutClassName + '--innerSpacing-' + `${innerSpacing}`,
|
||||
columnGap && layoutClassName + '--columnGap-' + `${columnGap}`,
|
||||
rowGap && layoutClassName + '--rowGap-' + `${rowGap}`,
|
||||
|
||||
paneWidth && layoutClassName + '--paneWidth-' + `${paneWidth}`,
|
||||
panePosition && layoutClassName + '--panePos-' + `${panePosition}`,
|
||||
hasPaneDivider && layoutClassName + '--hasPaneDivider',
|
||||
paneIsSticky && layoutClassName + '--isPaneSticky',
|
||||
|
||||
layoutClassName + '--responsive-' + `${responsiveVariant}`,
|
||||
responsiveVariant === 'separateRegions' && layoutClassName + '--responsive-primary-' + `${primaryRegion}`,
|
||||
responsiveVariant === 'stackRegions' && panePositionNarrow && layoutClassName + '--responsive-panePos-' + `${panePositionNarrow}`,
|
||||
)}
|
||||
>
|
||||
<div className={clsx(
|
||||
layoutClassName + '-wrapper',
|
||||
wrapperSizing && containerClass[wrapperSizing]
|
||||
)}>
|
||||
|
||||
{/* Header */}
|
||||
{hasHeader &&
|
||||
<div className={clsx(
|
||||
layoutClassName + '-region',
|
||||
layoutClassName + '-header',
|
||||
hasHeaderDivider && layoutClassName + '-header--hasDivider',
|
||||
headerDividerNarrow && layoutClassName + '-region--dividerNarrow-' + headerDividerNarrow + '-after'
|
||||
)}>
|
||||
{headerChildren}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div className={clsx(
|
||||
layoutClassName + '-columns'
|
||||
)}>
|
||||
|
||||
{/* pane if rendered first */}
|
||||
{panePosition === 'start' &&
|
||||
<div className={clsx(
|
||||
layoutClassName + '-region',
|
||||
layoutClassName + '-pane',
|
||||
paneDividerNarrow && layoutClassName + '-region--dividerNarrow-' + paneDividerNarrow + (panePositionNarrow === 'start' ? '-after' : '-before')
|
||||
)}>
|
||||
{paneChildren}
|
||||
</div>
|
||||
}
|
||||
|
||||
{/* content */}
|
||||
<div className={clsx(
|
||||
layoutClassName + '-region',
|
||||
layoutClassName + '-content'
|
||||
)}>
|
||||
{contentWidth ? (
|
||||
<>
|
||||
<div className={layoutClassName + '-content-centered-' + contentWidth}>
|
||||
<div className={'container-' + contentWidth}>
|
||||
{contentChildren}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{contentChildren}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* pane if rendered last */}
|
||||
{panePosition === 'end' &&
|
||||
<div className={clsx(
|
||||
layoutClassName + '-region',
|
||||
layoutClassName + '-pane',
|
||||
paneDividerNarrow && layoutClassName + '-region--dividerNarrow-' + paneDividerNarrow + (panePositionNarrow === 'start' ? '-after' : '-before')
|
||||
)}>
|
||||
{paneChildren}
|
||||
</div>}
|
||||
</div>
|
||||
|
||||
{/* footer */}
|
||||
{hasFooter && <div className={clsx(
|
||||
layoutClassName + '-region',
|
||||
layoutClassName + '-footer',
|
||||
hasFooterDivider && layoutClassName + '-footer--hasDivider',
|
||||
footerDividerNarrow && layoutClassName + '-region--dividerNarrow-' + footerDividerNarrow + '-before'
|
||||
)}>{footerChildren}</div>}
|
||||
</div>
|
||||
|
||||
{/* debug */}
|
||||
{_debug &&
|
||||
<style type='text/css'>{`
|
||||
.PageLayout-header {
|
||||
background: lightpink;
|
||||
}
|
||||
.PageLayout-content {
|
||||
background: rgb(255, 197, 253);
|
||||
}
|
||||
.PageLayout-pane {
|
||||
background: rgb(215, 255, 233);
|
||||
}
|
||||
.PageLayout-footer {
|
||||
background: lightyellow;
|
||||
}
|
||||
`}</style>
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const Playground = LayoutTemplate.bind({});
|
||||
Playground.storyName = 'Playground';
|
||||
Playground.parameters = {
|
||||
layout: 'fullscreen',
|
||||
};
|
||||
Playground.args = {
|
||||
_debug: true,
|
||||
wrapperSizing: 'xl',
|
||||
outerSpacing: 'normal',
|
||||
innerSpacing: 'none',
|
||||
columnGap: 'normal',
|
||||
rowGap: 'normal',
|
||||
|
||||
responsiveVariant: 'stackRegions',
|
||||
primaryRegion: 'content',
|
||||
|
||||
paneWidth: 'default',
|
||||
panePosition: 'end',
|
||||
panePositionNarrow: 'inherit',
|
||||
hasPaneDivider: false,
|
||||
paneDividerNarrow: 'inherit',
|
||||
paneIsSticky: false,
|
||||
|
||||
contentWidth: 'fluid',
|
||||
|
||||
hasHeader: true,
|
||||
hasHeaderDivider: false,
|
||||
headerDividerNarrow: 'inherit',
|
||||
|
||||
hasFooter: true,
|
||||
hasFooterDivider: false,
|
||||
footerDividerNarrow: 'inherit',
|
||||
|
||||
contentChildren: 'content',
|
||||
paneChildren: 'pane',
|
||||
headerChildren: 'header',
|
||||
footerChildren: 'footer'
|
||||
}
|
167
docs/src/stories/components/Layout/LayoutExamples.stories.jsx
Normal file
167
docs/src/stories/components/Layout/LayoutExamples.stories.jsx
Normal file
@ -0,0 +1,167 @@
|
||||
import React from 'react'
|
||||
import clsx from 'clsx'
|
||||
import { PageLayoutTemplate } from './PageLayout.stories'
|
||||
import {SplitPageLayoutTemplate} from './SplitPageLayout.stories'
|
||||
import {RepoSettings, DiscussionsPane} from '../ActionList/ActionListExamples.stories'
|
||||
import {LayoutAlphaTemplate} from './LayoutAlpha.stories'
|
||||
|
||||
export default {
|
||||
title: 'Components/Layout/Beta/Examples'
|
||||
}
|
||||
|
||||
export const Settings = SplitPageLayoutTemplate.bind({});
|
||||
Settings.storyName = 'Settings';
|
||||
Settings.parameters = {
|
||||
layout: 'fullscreen',
|
||||
};
|
||||
Settings.args = {
|
||||
// Structure
|
||||
innerSpacing: 'normal',
|
||||
|
||||
// Responsive
|
||||
primaryRegion: 'pane',
|
||||
|
||||
// Pane
|
||||
paneWidth: 'wide',
|
||||
paneIsSticky: true,
|
||||
|
||||
// Content
|
||||
contentWidth: 'md',
|
||||
|
||||
paneChildren: (
|
||||
<>
|
||||
<h2 className="h3 ml-2 mr-2">Repository settings</h2>
|
||||
<div className="ml-n2 mr-n2">
|
||||
<RepoSettings {...RepoSettings.args} />
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
|
||||
contentChildren: (
|
||||
<>
|
||||
<h3 className="f3 text-normal">General</h3>
|
||||
<div className="Box mt-3 p-3" style={{minHeight: '200px'}}> </div>
|
||||
<div className="Box mt-3 p-3" style={{minHeight: '400px'}}> </div>
|
||||
<div className="Box mt-3 p-3" style={{minHeight: '600px'}}> </div>
|
||||
</>
|
||||
)
|
||||
};
|
||||
|
||||
export const Discussions = PageLayoutTemplate.bind({});
|
||||
Discussions.parameters = {
|
||||
layout: 'fullscreen',
|
||||
};
|
||||
Discussions.storyName = 'Discussions';
|
||||
Discussions.args = {
|
||||
responsiveVariant: 'separateRegions',
|
||||
panePosition: 'start',
|
||||
paneWidth: 'narrow',
|
||||
hasHeader: true,
|
||||
headerChildren: (
|
||||
<>
|
||||
<div class="d-block d-md-none">
|
||||
<div className="d-flex flex-items-center width-full flex-wrap" style={{gap: '16px'}}>
|
||||
<h2 className="h3 ml-2 mr-2 flex-1">All discussions<span class="no-wrap">
|
||||
{/*
|
||||
I'm using a `no-wrap` class between the heading and the `triangle-down`
|
||||
octicon to make sure it won't be ever rendered as a typographic widow
|
||||
*/}
|
||||
</span><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M4.427 7.427l3.396 3.396a.25.25 0 00.354 0l3.396-3.396A.25.25 0 0011.396 7H4.604a.25.25 0 00-.177.427z"></path></svg>
|
||||
</h2>
|
||||
<button class="btn btn-primary">New</button>
|
||||
<button class="btn btn-octicon" style={{margin: 0, border: '1px solid var(--color-border-default)', width: '32px', height: '32px'}}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M8 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM1.5 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm13 0a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<input className="form-control flex-1 width-full" placeholder="Search discussions" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="hide-md hide-sm">
|
||||
<div className="d-flex flex-items-center width-full flex-wrap" style={{gap: '8px'}}>
|
||||
<input className="form-control flex-1" placeholder="Search discussions" />
|
||||
|
||||
<div class="BtnGroup d-block">
|
||||
<button class="BtnGroup-item btn" type="button">New</button>
|
||||
<button class="BtnGroup-item btn" type="button">Top</button>
|
||||
</div>
|
||||
|
||||
<button class="btn">Labels</button>
|
||||
|
||||
<button class="btn btn-primary">New discussion</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
|
||||
paneChildren: (
|
||||
<>
|
||||
<div className="ml-n2 mr-n2 mt-n2 mb-n2">
|
||||
<DiscussionsPane {...DiscussionsPane.args} />
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
|
||||
contentChildren: (
|
||||
<>
|
||||
<LayoutAlphaTemplate
|
||||
container='xl'
|
||||
sidebarPosition='end'
|
||||
sidebarWidth='narrow'
|
||||
flowRowUntil='lg'
|
||||
mainChildren={
|
||||
<>
|
||||
<div className="Box p-3" style={{minHeight: '800px'}}> </div>
|
||||
</>
|
||||
}
|
||||
sidebarChildren={
|
||||
<>
|
||||
<div className="Box p-3" style={{minHeight: '200px'}}> </div>
|
||||
<div className="Box mt-3 p-3" style={{minHeight: '200px'}}> </div>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
};
|
||||
|
||||
export const IssueDetail = PageLayoutTemplate.bind({});
|
||||
IssueDetail.storyName = 'Issue detail';
|
||||
IssueDetail.parameters = {
|
||||
layout: 'fullscreen',
|
||||
};
|
||||
IssueDetail.args = {
|
||||
|
||||
panePosition: 'end',
|
||||
paneWidth: 'default',
|
||||
hasHeader: true,
|
||||
hasHeaderDivider: true,
|
||||
headerDividerNarrow: 'filled',
|
||||
paneDividerNarrow: 'filled',
|
||||
headerChildren: (
|
||||
<>
|
||||
<h2 className="f2">
|
||||
Traverse does not calculate scope in object deconstructor
|
||||
<span className="f2-light color-fg-muted"> #14024</span>
|
||||
</h2>
|
||||
<div className="d-flex flex-items-center flex-wrap mt-2" style={{gap: '8px'}}>
|
||||
<span title="Status: Open" class="State State--open">
|
||||
<svg height="16" class="octicon octicon-issue-opened" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path d="M8 9.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path><path fill-rule="evenodd" d="M8 0a8 8 0 100 16A8 8 0 008 0zM1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0z"></path></svg> Open
|
||||
</span>
|
||||
<span className="color-fg-muted"><strong class="color-fg-default">monalisa</strong> opened this issue 6 days ago</span>
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
contentChildren: (
|
||||
<>
|
||||
<div className="Box p-3" style={{minHeight: '1200px'}}> </div>
|
||||
</>
|
||||
),
|
||||
paneChildren: (
|
||||
<>
|
||||
<div className="Box p-3" style={{minHeight: '140px'}}> </div>
|
||||
<div className="Box p-3 mt-3" style={{minHeight: '200px'}}> </div>
|
||||
<div className="Box p-3 mt-3" style={{minHeight: '140px'}}> </div>
|
||||
</>
|
||||
)
|
||||
};
|
342
docs/src/stories/components/Layout/PageLayout.stories.jsx
Normal file
342
docs/src/stories/components/Layout/PageLayout.stories.jsx
Normal file
@ -0,0 +1,342 @@
|
||||
// create a "playground" demo page that may set some defaults and allow story to access component controls
|
||||
import React from 'react'
|
||||
import clsx from 'clsx'
|
||||
import {LayoutTemplate} from './LayoutBeta.stories'
|
||||
|
||||
export default {
|
||||
title: 'Components/Layout/Beta/PageLayout',
|
||||
excludeStories: ['PageLayoutTemplate'],
|
||||
argTypes: {
|
||||
|
||||
// Debug
|
||||
|
||||
_debug: {
|
||||
control: 'boolean',
|
||||
description: 'Show background colors in regions for debugging',
|
||||
},
|
||||
|
||||
// Structure
|
||||
|
||||
wrapperSizing: {
|
||||
options: ['fluid', 'md', 'lg', 'xl'],
|
||||
control: {
|
||||
type: 'inline-radio',
|
||||
labels: ['fluid', 'md', 'lg', 'xl']
|
||||
},
|
||||
description: 'Define the maximum width of the component. `fluid` sets it to full-width. Other values center `Layout` horizontally. Refer to [container utilities](https://primer.style/css/objects/grid#containers) for reference.',
|
||||
table: {
|
||||
category: 'Structure'
|
||||
}
|
||||
},
|
||||
|
||||
outerSpacing: {
|
||||
options: ['normal', 'condensed'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets wrapper margins surrounding the component to distance itself from the viewport edges. `normal` sets the margin to 16px, and to 24px on `lg` breakpoints and above. `condensed` keeps the margin at 16px.',
|
||||
table: {
|
||||
category: 'Structure'
|
||||
}
|
||||
},
|
||||
|
||||
columnGap: {
|
||||
options: ['normal', 'condensed'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets the gap between columns to distance them from each other. `normal` sets the gap to 16px, and to 24px on `lg` breakpoints and above. `condensed` keeps the gap always at 16px.',
|
||||
table: {
|
||||
category: 'Structure'
|
||||
}
|
||||
},
|
||||
rowGap: {
|
||||
options: ['normal', 'condensed'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets the gap below the header and above the footer. `normal` sets the gap to 16px, and to 24px on `lg` breakpoints and above. `condensed` keeps the gap always at 16px.',
|
||||
table: {
|
||||
category: 'Structure'
|
||||
}
|
||||
},
|
||||
|
||||
// Responsive
|
||||
|
||||
responsiveVariant: {
|
||||
options: ['stackRegions', 'separateRegions'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: '`responsiveVariant` defines how the layout component adapts to smaller viewports. `stackRegions` presents the content in a vertical flow, with `pane` and `content` vertically arranged. `separateRegions` presents `pane` and `content` as different pages on smaller viewports. Change the preview size from the toolbar to test it.',
|
||||
table: {
|
||||
category: 'Responsive'
|
||||
}
|
||||
},
|
||||
|
||||
primaryRegion: {
|
||||
options: ['content', 'pane'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'When `responsiveVariant` is set to `separateRegions`, defines which region appears first on small viewports. `content` is default.',
|
||||
table: {
|
||||
category: 'Responsive'
|
||||
}
|
||||
},
|
||||
|
||||
// Pane
|
||||
|
||||
panePosition: {
|
||||
options: ['start', 'end'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Defines the position of the pane. `start` renders the pane on the left, and `end` renders it on the right.',
|
||||
table: {
|
||||
category: 'Pane',
|
||||
}
|
||||
},
|
||||
panePositionNarrow: {
|
||||
options: ['inherit', 'start', 'end'],
|
||||
control: {
|
||||
type: 'inline-radio',
|
||||
},
|
||||
description: 'If `responsiveVariant` is set to `stackRegions`, defines the position of the pane in narrow viewports. `start` puts the pane above `content`, and `end` puts it below `content`. `inherit` uses the same value from `panePosition`.',
|
||||
table: {
|
||||
category: 'Pane'
|
||||
}
|
||||
},
|
||||
paneWidth: {
|
||||
options: ['default', 'narrow', 'wide'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Defines the width of the pane',
|
||||
table: {
|
||||
category: 'Pane'
|
||||
}
|
||||
},
|
||||
hasPaneDivider: {
|
||||
control: { type: 'boolean' },
|
||||
description: 'Whether to show a pane line divider.',
|
||||
table: {
|
||||
category: 'Pane'
|
||||
}
|
||||
},
|
||||
paneDividerNarrow: {
|
||||
options: ['inherit', 'none', 'line', 'filled'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Whether to show a divider between `pane` and `content` regions if `responsiveVariant` is set to `stackRegions`. `line` shows a single line. `filled` shows a thicker mobile-frienldy divider.',
|
||||
table: {
|
||||
category: 'Pane'
|
||||
}
|
||||
},
|
||||
|
||||
// Content
|
||||
|
||||
contentWidth: {
|
||||
options: ['fluid', 'sm', 'md', 'lg', 'xl'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Defines the maximum width of the content region. `fluid` sets it to full-width. Other values follow container widths from `sm` to `xl`. With smaller widths, the content region will try to stay centered to the viewport area.',
|
||||
table: {
|
||||
category: 'Content'
|
||||
}
|
||||
},
|
||||
|
||||
// Header
|
||||
|
||||
hasHeader: {
|
||||
control: { type: 'boolean' },
|
||||
table: {
|
||||
category: 'Header'
|
||||
}
|
||||
},
|
||||
|
||||
hasHeaderDivider: {
|
||||
control: { type: 'boolean' },
|
||||
description: 'Whether to show a header divider.',
|
||||
table: {
|
||||
category: 'Header'
|
||||
}
|
||||
},
|
||||
|
||||
headerDividerNarrow: {
|
||||
options: ['inherit', 'none', 'line', 'filled'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Defines how the `header` divider should look on narrow viewports. `inherit` renders a `line` if `hasHeaderDivider` is true. `filled` shows a thicker mobile-friendly divider.',
|
||||
table: {
|
||||
category: 'Header'
|
||||
}
|
||||
},
|
||||
|
||||
// Footer
|
||||
|
||||
hasFooter: {
|
||||
control: { type: 'boolean' },
|
||||
table: {
|
||||
category: 'Footer'
|
||||
}
|
||||
},
|
||||
|
||||
hasFooterDivider: {
|
||||
control: { type: 'boolean' },
|
||||
description: 'Whether to show a footer divider.',
|
||||
table: {
|
||||
category: 'Footer'
|
||||
}
|
||||
},
|
||||
|
||||
footerDividerNarrow: {
|
||||
options: ['inherit', 'none', 'line', 'filled'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Whether to show a divider above the `footer` region on narrow viewports. `line` shows a single line. `filled` shows a thicker mobile-frienldy divider.',
|
||||
table: {
|
||||
category: 'Footer'
|
||||
}
|
||||
},
|
||||
|
||||
// HTML
|
||||
|
||||
headerChildren: {
|
||||
description: 'creates a slot for header children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
},
|
||||
contentChildren: {
|
||||
description: 'creates a slot for content children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
},
|
||||
paneChildren: {
|
||||
description: 'creates a slot for pane children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
},
|
||||
footerChildren: {
|
||||
description: 'creates a slot for footer children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const PageLayoutTemplate = ({
|
||||
_debug,
|
||||
wrapperSizing,
|
||||
outerSpacing,
|
||||
columnGap,
|
||||
rowGap,
|
||||
responsiveVariant,
|
||||
primaryRegion,
|
||||
paneWidth,
|
||||
panePosition,
|
||||
panePositionNarrow,
|
||||
hasPaneDivider,
|
||||
paneDividerNarrow,
|
||||
contentWidth,
|
||||
hasHeader,
|
||||
hasHeaderDivider,
|
||||
headerDividerNarrow,
|
||||
hasFooter,
|
||||
hasFooterDivider,
|
||||
footerDividerNarrow,
|
||||
contentChildren,
|
||||
paneChildren,
|
||||
headerChildren,
|
||||
footerChildren
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<LayoutTemplate
|
||||
_debug={_debug}
|
||||
wrapperSizing={wrapperSizing}
|
||||
outerSpacing={outerSpacing}
|
||||
innerSpacing='none'
|
||||
columnGap={columnGap}
|
||||
rowGap={rowGap}
|
||||
|
||||
responsiveVariant={responsiveVariant}
|
||||
primaryRegion={primaryRegion}
|
||||
|
||||
paneWidth={paneWidth}
|
||||
panePosition={panePosition}
|
||||
panePositionNarrow={panePositionNarrow}
|
||||
hasPaneDivider={hasPaneDivider}
|
||||
paneDividerNarrow={paneDividerNarrow}
|
||||
|
||||
contentWidth={contentWidth}
|
||||
|
||||
hasHeader={hasHeader}
|
||||
hasHeaderDivider={hasHeaderDivider}
|
||||
headerDividerNarrow={headerDividerNarrow}
|
||||
|
||||
hasFooter={hasFooter}
|
||||
hasFooterDivider={hasFooterDivider}
|
||||
footerDividerNarrow={footerDividerNarrow}
|
||||
|
||||
contentChildren={contentChildren}
|
||||
paneChildren={paneChildren}
|
||||
headerChildren={headerChildren}
|
||||
footerChildren={footerChildren}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const Playground = PageLayoutTemplate.bind({});
|
||||
Playground.storyName = 'Playground';
|
||||
Playground.parameters = {
|
||||
layout: 'fullscreen',
|
||||
};
|
||||
Playground.args = {
|
||||
_debug: true,
|
||||
|
||||
// Structure
|
||||
wrapperSizing: 'xl',
|
||||
outerSpacing: 'normal',
|
||||
columnGap: 'normal',
|
||||
rowGap: 'normal',
|
||||
|
||||
// Responsive
|
||||
responsiveVariant: 'stackRegions',
|
||||
primaryRegion: 'content',
|
||||
|
||||
// Pane
|
||||
panePosition: 'end',
|
||||
panePositionNarrow: 'inherit',
|
||||
paneWidth: 'default',
|
||||
hasPaneDivider: false,
|
||||
paneDividerNarrow: 'inherit',
|
||||
|
||||
// Content
|
||||
contentWidth: 'fluid',
|
||||
|
||||
// Header
|
||||
hasHeader: false,
|
||||
hasHeaderDivider: false,
|
||||
headerDividerNarrow: 'inherit',
|
||||
|
||||
// Footer
|
||||
hasFooter: false,
|
||||
hasFooterDivider: false,
|
||||
footerDividerNarrow: 'inherit',
|
||||
|
||||
contentChildren: 'content',
|
||||
paneChildren: 'pane',
|
||||
headerChildren: 'header',
|
||||
footerChildren: 'footer'
|
||||
|
||||
}
|
143
docs/src/stories/components/Layout/SplitPageLayout.stories.jsx
Normal file
143
docs/src/stories/components/Layout/SplitPageLayout.stories.jsx
Normal file
@ -0,0 +1,143 @@
|
||||
// create a "playground" demo page that may set some defaults and allow story to access component controls
|
||||
import React from 'react'
|
||||
import clsx from 'clsx'
|
||||
import {LayoutTemplate} from './LayoutBeta.stories'
|
||||
import {NavWithSubItems} from '../ActionList/ActionListPatterns.stories'
|
||||
|
||||
|
||||
export default {
|
||||
title: 'Components/Layout/Beta/SplitPageLayout',
|
||||
excludeStories: ['SplitPageLayoutTemplate'],
|
||||
argTypes: {
|
||||
|
||||
// Structure
|
||||
|
||||
innerSpacing: {
|
||||
options: ['normal', 'condensed'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Sets padding to regions individually. `normal` sets padding to 16px, with the `content` region getting 24px horizontal padding on `lg` breakpoints and above. `condensed` keeps the padding always at `16px`.',
|
||||
table: {
|
||||
category: 'Structure'
|
||||
}
|
||||
},
|
||||
|
||||
primaryRegion: {
|
||||
options: ['content', 'pane'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Defines which region appears first on small viewports. `content` is default.',
|
||||
table: {
|
||||
category: 'Responsive'
|
||||
}
|
||||
},
|
||||
|
||||
// Pane
|
||||
|
||||
paneWidth: {
|
||||
options: ['default', 'narrow', 'wide'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Defines the width of the pane.',
|
||||
table: {
|
||||
category: 'Pane'
|
||||
}
|
||||
},
|
||||
|
||||
// Content
|
||||
|
||||
contentWidth: {
|
||||
options: ['fluid', 'sm', 'md', 'lg', 'xl'],
|
||||
control: {
|
||||
type: 'inline-radio'
|
||||
},
|
||||
description: 'Defines the maximum width of the content region. `fluid` sets it to full-width. Other values follow container widths from `sm` to `xl`. With smaller widths, the content region will try to stay centered to the viewport area.',
|
||||
table: {
|
||||
category: 'Content'
|
||||
}
|
||||
},
|
||||
|
||||
// HTML
|
||||
|
||||
contentChildren: {
|
||||
description: 'creates a slot for content children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
},
|
||||
paneChildren: {
|
||||
description: 'creates a slot for pane children',
|
||||
table: {
|
||||
category: 'HTML'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const SplitPageLayoutTemplate = ({
|
||||
_debug,
|
||||
innerSpacing,
|
||||
primaryRegion,
|
||||
paneWidth,
|
||||
paneIsSticky,
|
||||
contentWidth,
|
||||
contentChildren,
|
||||
paneChildren
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<LayoutTemplate
|
||||
_debug={_debug}
|
||||
wrapperSizing='full'
|
||||
outerSpacing='none'
|
||||
innerSpacing={innerSpacing}
|
||||
columnGap='none'
|
||||
rowGap='none'
|
||||
|
||||
responsiveVariant='separateRegions'
|
||||
primaryRegion={primaryRegion}
|
||||
|
||||
paneWidth={paneWidth}
|
||||
paneIsSticky={paneIsSticky}
|
||||
panePosition='start'
|
||||
hasPaneDivider={true}
|
||||
contentWidth={contentWidth}
|
||||
|
||||
hasHeader={false}
|
||||
|
||||
hasFooter={false}
|
||||
|
||||
contentChildren={contentChildren}
|
||||
paneChildren={paneChildren}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const Playground = SplitPageLayoutTemplate.bind({});
|
||||
Playground.storyName = 'Playground';
|
||||
Playground.parameters = {
|
||||
layout: 'fullscreen',
|
||||
};
|
||||
Playground.args = {
|
||||
_debug: true,
|
||||
|
||||
// Structure
|
||||
innerSpacing: 'normal',
|
||||
|
||||
// Responsive
|
||||
primaryRegion: 'content',
|
||||
|
||||
// Pane
|
||||
paneWidth: 'wide',
|
||||
|
||||
// Content
|
||||
contentWidth: 'fluid',
|
||||
|
||||
// Children
|
||||
contentChildren: 'content',
|
||||
paneChildren: 'pane'
|
||||
};
|
45
docs/src/stories/helpers/pageLayoutBehavior.jsx
Normal file
45
docs/src/stories/helpers/pageLayoutBehavior.jsx
Normal file
@ -0,0 +1,45 @@
|
||||
import React from 'react'
|
||||
export default function PageLayoutBehavior() {
|
||||
|
||||
const pageLayoutSelector = '.PageLayout.PageLayout--responsive-separateRegions';
|
||||
const primaryRegionSelector = 'PageLayout--responsive-primary';
|
||||
|
||||
const detectPageLayoutHash = () => {
|
||||
|
||||
const pageLayout = document.querySelector(pageLayoutSelector);
|
||||
|
||||
let dest;
|
||||
if (location.hash === '') {
|
||||
dest = pageLayout.getAttribute('data-primary-region');
|
||||
} else if (location.hash === '#pane') {
|
||||
dest = 'pane';
|
||||
} else if (location.hash === '#content') {
|
||||
dest = 'content';
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
pageLayout.setAttribute('data-current-region', dest);
|
||||
|
||||
if (dest === 'pane') {
|
||||
pageLayout.classList.replace(primaryRegionSelector + '-content', primaryRegionSelector + '-pane');
|
||||
} else {
|
||||
pageLayout.classList.replace(primaryRegionSelector + '-pane', primaryRegionSelector + '-content');
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("hashchange", () => {
|
||||
detectPageLayoutHash();
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
const pageLayout = document.querySelector(pageLayoutSelector);
|
||||
const primaryRegion = pageLayout.classList.contains(primaryRegionSelector + '-pane') ? 'pane' : 'content';
|
||||
|
||||
if (pageLayout.getAttribute('data-primary-region') === null) {
|
||||
pageLayout.setAttribute('data-primary-region', primaryRegion);
|
||||
}
|
||||
|
||||
detectPageLayoutHash();
|
||||
});
|
||||
}
|
@ -4,3 +4,4 @@
|
||||
@import './grid.scss';
|
||||
@import './grid-offset.scss';
|
||||
@import './layout.scss';
|
||||
@import './page-layout.scss';
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Layout mixins
|
||||
// Layout alpha mixins
|
||||
|
||||
@mixin flow-as-row {
|
||||
grid-auto-flow: row;
|
||||
@ -77,3 +77,29 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Layout beta mixins
|
||||
|
||||
// responsive region dividers
|
||||
|
||||
@mixin Layout-line-divider {
|
||||
position: absolute;
|
||||
left: calc(var(--Layout-outer-spacing-x) * -1);
|
||||
display: block;
|
||||
width: calc(100% + (var(--Layout-outer-spacing-x) * 2));
|
||||
height: 1px;
|
||||
content: '';
|
||||
background-color: $Layout-divider-color;
|
||||
}
|
||||
|
||||
@mixin Layout-filled-divider {
|
||||
position: absolute;
|
||||
bottom: calc(#{$spacer-2} * -1); // -8px
|
||||
left: calc(var(--Layout-outer-spacing-x) * -1);
|
||||
display: block;
|
||||
width: calc(100% + (var(--Layout-outer-spacing-x) * 2));
|
||||
height: #{$spacer-2}; // 8px
|
||||
content: '';
|
||||
background-color: var(--color-canvas-inset);
|
||||
box-shadow: inset 0 1px $Layout-divider-color, inset 0 -1px $Layout-divider-color;
|
||||
}
|
||||
|
380
src/layout/page-layout.scss
Normal file
380
src/layout/page-layout.scss
Normal file
@ -0,0 +1,380 @@
|
||||
// stylelint-disable max-nesting-depth
|
||||
// stylelint-disable selector-max-specificity
|
||||
// stylelint-disable no-duplicate-selectors
|
||||
|
||||
$Layout-divider-color: var(--color-border-default) !default;
|
||||
$Layout-responsive-variant-max-breakpoint: 'md' !default;
|
||||
|
||||
:root {
|
||||
--Layout-pane-width: #{map-get($sidebar-width, 'sm')};
|
||||
--Layout-content-width: 100%;
|
||||
--Layout-template-columns: 1fr var(--Layout-pane-width);
|
||||
--Layout-template-areas: 'content pane';
|
||||
--Layout-column-gap: #{$spacer-3};
|
||||
--Layout-row-gap: #{$spacer-3};
|
||||
|
||||
// the `px` unit is mandatory for `calc()` execution. See https://stackoverflow.com/a/32518348
|
||||
// stylelint-disable length-zero-no-unit
|
||||
--Layout-outer-spacing-x: 0px; // wrapper margin x
|
||||
--Layout-outer-spacing-y: 0px; // wrapper margin y
|
||||
--Layout-inner-spacing-min: 0px; // default region padding
|
||||
--Layout-inner-spacing-max: 0px; // relaxed content horizontal padding
|
||||
// stylelint-enable length-zero-no-unit
|
||||
}
|
||||
|
||||
.PageLayout {
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
margin: var(--Layout-outer-spacing-y) var(--Layout-outer-spacing-x);
|
||||
|
||||
// multi-column desktop-friendly layout
|
||||
|
||||
@include breakpoint($Layout-responsive-variant-max-breakpoint) {
|
||||
|
||||
// Set a `content` region width, to work with loading states when
|
||||
// `pane` is not yet loaded. See https://github.com/primer/css/pull/1818
|
||||
$Layout-content-full-width: minmax(0, calc(100% - var(--Layout-pane-width) - var(--Layout-column-gap)));
|
||||
|
||||
&.PageLayout--panePos-start {
|
||||
--Layout-template-columns: var(--Layout-pane-width) #{$Layout-content-full-width};
|
||||
--Layout-template-areas: 'pane content';
|
||||
}
|
||||
|
||||
&.PageLayout--panePos-end {
|
||||
--Layout-template-columns: #{$Layout-content-full-width} var(--Layout-pane-width);
|
||||
--Layout-template-areas: 'content pane';
|
||||
}
|
||||
|
||||
// header divider
|
||||
|
||||
.PageLayout-header--hasDivider {
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
padding-bottom: max(var(--Layout-row-gap), var(--Layout-inner-spacing-min));
|
||||
// stylelint-disable-next-line primer/borders
|
||||
border-bottom: $border-width solid $Layout-divider-color;
|
||||
}
|
||||
|
||||
// footer divider
|
||||
|
||||
.PageLayout-footer--hasDivider {
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
padding-top: max(var(--Layout-row-gap), var(--Layout-inner-spacing-min));
|
||||
// stylelint-disable-next-line primer/borders
|
||||
border-top: $border-width solid $Layout-divider-color;
|
||||
}
|
||||
|
||||
// pane divider
|
||||
|
||||
&.PageLayout--hasPaneDivider {
|
||||
&.PageLayout--panePos-start {
|
||||
.PageLayout-pane {
|
||||
// stylelint-disable-next-line primer/borders
|
||||
border-right: $border-width solid $Layout-divider-color;
|
||||
}
|
||||
|
||||
&:not(.PageLayout--columnGap-none) {
|
||||
.PageLayout-pane {
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
padding-right: calc(var(--Layout-column-gap) - #{$border-width});
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
margin-right: calc(var(--Layout-column-gap) * -1);
|
||||
}
|
||||
|
||||
.PageLayout-content {
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
margin-left: var(--Layout-column-gap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.PageLayout--panePos-end {
|
||||
.PageLayout-pane {
|
||||
// stylelint-disable-next-line primer/borders
|
||||
border-left: $border-width solid $Layout-divider-color;
|
||||
}
|
||||
|
||||
&:not(.PageLayout--columnGap-none) {
|
||||
.PageLayout-pane {
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
padding-left: calc(var(--Layout-column-gap) - #{$border-width});
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
margin-left: calc(var(--Layout-column-gap) * -1);
|
||||
}
|
||||
|
||||
.PageLayout-content {
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
margin-right: var(--Layout-column-gap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sticky pane
|
||||
|
||||
&.PageLayout--isPaneSticky {
|
||||
.PageLayout-pane {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
max-height: 100vh;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// content width
|
||||
|
||||
[class^='PageLayout-content-centered-'] {
|
||||
max-width: calc(var(--Layout-content-width) + var(--Layout-pane-width) + var(--Layout-column-gap));
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
&.PageLayout--hasPaneDivider {
|
||||
[class^='PageLayout-content-centered-'] {
|
||||
max-width: calc(var(--Layout-content-width) + var(--Layout-pane-width) + (var(--Layout-column-gap) * 2));
|
||||
}
|
||||
}
|
||||
|
||||
&.PageLayout--panePos-start {
|
||||
[class^='PageLayout-content-centered-'] > [class^='container-'] {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.PageLayout--panePos-end {
|
||||
[class^='PageLayout-content-centered-'] > [class^='container-'] {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@each $breakpoint in map-keys($breakpoints) {
|
||||
.PageLayout-content-centered-#{$breakpoint} {
|
||||
--Layout-content-width: #{map-get($breakpoints, $breakpoint)};
|
||||
}
|
||||
}
|
||||
|
||||
// pane width
|
||||
|
||||
@each $breakpoint in map-keys($sidebar-width) {
|
||||
@include breakpoint($breakpoint) {
|
||||
--Layout-pane-width: #{map-get($sidebar-width, $breakpoint)};
|
||||
}
|
||||
}
|
||||
|
||||
&.PageLayout--paneWidth-narrow {
|
||||
@each $breakpoint in map-keys($sidebar-narrow-width) {
|
||||
@include breakpoint($breakpoint) {
|
||||
--Layout-pane-width: #{map-get($sidebar-narrow-width, $breakpoint)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.PageLayout--paneWidth-wide {
|
||||
@each $breakpoint in map-keys($sidebar-wide-width) {
|
||||
@include breakpoint($breakpoint) {
|
||||
--Layout-pane-width: #{map-get($sidebar-wide-width, $breakpoint)};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// responsive behaviors on narrow viewports
|
||||
|
||||
@media (max-width: #{map-get($breakpoints, $Layout-responsive-variant-max-breakpoint) - 0.02px}) {
|
||||
|
||||
// variant: stackRegions
|
||||
|
||||
&.PageLayout--responsive-stackRegions {
|
||||
--Layout-template-columns: 1fr;
|
||||
|
||||
// responsive-panePos: end (default)
|
||||
--Layout-template-areas: 'content' 'pane';
|
||||
|
||||
// responsive-panePos: start
|
||||
&.PageLayout--responsive-panePos-start {
|
||||
--Layout-template-areas: 'pane' 'content';
|
||||
}
|
||||
}
|
||||
|
||||
// variant: separateRegions
|
||||
|
||||
&.PageLayout--responsive-separateRegions {
|
||||
--Layout-template-columns: 1fr;
|
||||
--Layout-template-areas: 'content';
|
||||
|
||||
&.PageLayout--responsive-primary-content {
|
||||
--Layout-template-areas: 'content';
|
||||
|
||||
.PageLayout-pane {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.PageLayout--responsive-primary-pane {
|
||||
--Layout-template-areas: 'pane';
|
||||
|
||||
.PageLayout-content {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// region dividers on narrow viewports
|
||||
|
||||
.PageLayout-region--dividerNarrow-line-before {
|
||||
position: relative;
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
margin-top: var(--Layout-row-gap);
|
||||
|
||||
&::before {
|
||||
@include Layout-line-divider;
|
||||
|
||||
top: calc(#{$border-width * -1} - var(--Layout-row-gap));
|
||||
}
|
||||
}
|
||||
|
||||
.PageLayout-region--dividerNarrow-line-after {
|
||||
position: relative;
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
margin-bottom: var(--Layout-row-gap);
|
||||
|
||||
&::after {
|
||||
@include Layout-line-divider;
|
||||
|
||||
bottom: calc(#{$border-width * -1} - var(--Layout-row-gap));
|
||||
}
|
||||
}
|
||||
|
||||
.PageLayout-region--dividerNarrow-filled-before {
|
||||
position: relative;
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
margin-top: calc(#{$spacer-2} + var(--Layout-row-gap));
|
||||
|
||||
&::after {
|
||||
@include Layout-filled-divider;
|
||||
|
||||
top: calc(#{$spacer-2 * -1} - var(--Layout-row-gap));
|
||||
}
|
||||
}
|
||||
|
||||
.PageLayout-region--dividerNarrow-filled-after {
|
||||
position: relative;
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
margin-bottom: calc(#{$spacer-2} + var(--Layout-row-gap));
|
||||
|
||||
&::before {
|
||||
@include Layout-filled-divider;
|
||||
|
||||
bottom: calc(#{$spacer-2 * -1} - var(--Layout-row-gap));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.PageLayout-wrapper {
|
||||
display: grid;
|
||||
grid: auto-flow / 1fr;
|
||||
row-gap: var(--Layout-row-gap);
|
||||
}
|
||||
|
||||
.PageLayout-columns {
|
||||
display: grid;
|
||||
column-gap: var(--Layout-column-gap);
|
||||
row-gap: var(--Layout-row-gap);
|
||||
grid-template-columns: var(--Layout-template-columns);
|
||||
grid-template-rows: 1fr;
|
||||
grid-template-areas: var(--Layout-template-areas);
|
||||
}
|
||||
|
||||
// outer spacing
|
||||
|
||||
.PageLayout--outerSpacing-normal {
|
||||
--Layout-outer-spacing-x: #{$spacer-3};
|
||||
--Layout-outer-spacing-y: #{$spacer-3};
|
||||
|
||||
@include breakpoint(lg) {
|
||||
--Layout-outer-spacing-x: #{$spacer-4};
|
||||
--Layout-outer-spacing-y: #{$spacer-4};
|
||||
}
|
||||
}
|
||||
|
||||
.PageLayout--outerSpacing-condensed {
|
||||
--Layout-outer-spacing-x: #{$spacer-3};
|
||||
--Layout-outer-spacing-y: #{$spacer-3};
|
||||
}
|
||||
|
||||
// inner spacing
|
||||
|
||||
.PageLayout--innerSpacing-normal {
|
||||
--Layout-inner-spacing-min: #{$spacer-3};
|
||||
--Layout-inner-spacing-max: #{$spacer-3};
|
||||
|
||||
@include breakpoint(lg) {
|
||||
--Layout-inner-spacing-max: #{$spacer-4};
|
||||
}
|
||||
}
|
||||
|
||||
.PageLayout--innerSpacing-condensed {
|
||||
--Layout-inner-spacing-min: #{$spacer-3};
|
||||
--Layout-inner-spacing-max: #{$spacer-3};
|
||||
}
|
||||
|
||||
// column gap
|
||||
|
||||
.PageLayout--columnGap-normal {
|
||||
--Layout-column-gap: #{$spacer-3};
|
||||
|
||||
@include breakpoint(lg) {
|
||||
--Layout-column-gap: #{$spacer-4};
|
||||
}
|
||||
}
|
||||
|
||||
.PageLayout--columnGap-condensed {
|
||||
--Layout-column-gap: #{$spacer-3};
|
||||
}
|
||||
|
||||
.PageLayout--columnGap-none {
|
||||
// the `px` unit is mandatory for `calc()` execution. See https://stackoverflow.com/a/32518348
|
||||
// stylelint-disable-next-line length-zero-no-unit
|
||||
--Layout-column-gap: 0px;
|
||||
}
|
||||
|
||||
// row gap
|
||||
|
||||
.PageLayout--rowGap-normal {
|
||||
--Layout-row-gap: #{$spacer-3};
|
||||
|
||||
@include breakpoint(lg) {
|
||||
--Layout-row-gap: #{$spacer-4};
|
||||
}
|
||||
}
|
||||
|
||||
.PageLayout--rowGap-none {
|
||||
// the `px` unit is mandatory for `calc()` execution. See https://stackoverflow.com/a/32518348
|
||||
// stylelint-disable length-zero-no-unit
|
||||
--Layout-row-gap: 0px;
|
||||
}
|
||||
|
||||
.PageLayout--rowGap-condensed {
|
||||
--Layout-row-gap: #{$spacer-3};
|
||||
}
|
||||
|
||||
// regions
|
||||
|
||||
.PageLayout-header,
|
||||
.PageLayout-content,
|
||||
.PageLayout-pane,
|
||||
.PageLayout-footer {
|
||||
// stylelint-disable-next-line primer/spacing
|
||||
padding: var(--Layout-inner-spacing-min);
|
||||
}
|
||||
|
||||
.PageLayout-content {
|
||||
// stylelint-disable primer/spacing
|
||||
padding-right: var(--Layout-inner-spacing-max);
|
||||
padding-left: var(--Layout-inner-spacing-max);
|
||||
// stylelint-enable primer/spacing
|
||||
grid-area: content;
|
||||
}
|
||||
|
||||
.PageLayout-pane {
|
||||
grid-area: pane;
|
||||
}
|
@ -178,9 +178,8 @@ $sidebar-narrow-width: (
|
||||
) !default;
|
||||
|
||||
$sidebar-wide-width: (
|
||||
md: 296px,
|
||||
lg: 320px,
|
||||
xl: 344px
|
||||
xl: 336px
|
||||
) !default;
|
||||
|
||||
$gutter: (
|
||||
|
Loading…
Reference in New Issue
Block a user