-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
feat: Adds a `Stack` layout primitive #779
- Loading branch information
1 parent
e9213a1
commit 304140e
Showing
13 changed files
with
292 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { generateLabel } from '../../../../.storybook/helpers'; | ||
|
||
const StackItem = ({ | ||
children, | ||
backgroundColor = 'var(--bs-color-grayscale-light-2)', | ||
}) => { | ||
const stackItem = document.createElement('div'); | ||
stackItem.style.backgroundColor = backgroundColor; | ||
stackItem.style.padding = 'var(--bs-content-padding-base)'; | ||
stackItem.style.borderRadius = 'var(--bs-size-s3)'; | ||
stackItem.style.minHeight = '6rem'; | ||
stackItem.innerHTML = children; | ||
return stackItem; | ||
}; | ||
|
||
const Stack = ({ | ||
length = 3, | ||
classname = [], | ||
sizeVariant = '', | ||
itemColor, | ||
labelPrefix = 'stack', | ||
children = [], | ||
}) => { | ||
const stack = document.createElement('div'); | ||
stack.classList.add('a-stack'); | ||
if (sizeVariant) { | ||
stack.classList.add(`a-stack--${sizeVariant}`); | ||
} | ||
|
||
classname.forEach((cls) => { | ||
stack.classList.add(cls); | ||
}); | ||
|
||
if (children.length) { | ||
children.forEach((child) => stack.append(child)); | ||
} else { | ||
for (let child = 0; child < length; child += 1) { | ||
stack.append( | ||
StackItem({ | ||
children: generateLabel([labelPrefix, 'child', child + 1]), | ||
backgroundColor: itemColor, | ||
}) | ||
); | ||
} | ||
} | ||
|
||
return stack; | ||
}; | ||
|
||
export { StackItem, Stack }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
@forward 'settings'; | ||
@use './settings'; | ||
@use '../../tools/classname'; | ||
@use '../../tools/design-token'; | ||
@use '../../tools/media-query'; | ||
|
||
#{classname.get($classname-items: 'stack', $layer: 'atom')} { | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: flex-start; | ||
|
||
&:only-child { | ||
height: 100%; | ||
} | ||
|
||
> * { | ||
margin-top: 0; | ||
margin-bottom: 0; | ||
} | ||
|
||
> * + * { | ||
margin-top: var(design-token.get('stack', 'spacing')); | ||
} | ||
} | ||
|
||
@each $breakpoint, $size-variants in settings.$size-variants { | ||
@include media-query.get($breakpoint) { | ||
@each $size-variant-name, $padding in ($size-variants) { | ||
$class: ''; | ||
@if $size-variant-name == '' { | ||
$class: 'stack'; | ||
} @else { | ||
$class: 'stack--#{$size-variant-name}'; | ||
} | ||
|
||
#{classname.get($classname-items: $class, $layer: 'atom')} { | ||
/* stylelint-disable max-nesting-depth */ | ||
> * + * { | ||
#{design-token.get('stack', 'spacing')}: $padding; | ||
} | ||
/* stylelint-enable max-nesting-depth */ | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
@use '../../settings/setup'; | ||
@use '../../tools/design-token'; | ||
|
||
$size-variants: ( | ||
'#{setup.$no-media-query}': ( | ||
'': var(design-token.get('content', 'padding', 'base')), | ||
), | ||
'm': ( | ||
'': var(design-token.get('content', 'padding', 'l')), | ||
), | ||
) !default; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Stack, StackItem } from './Stack'; | ||
import { generateLabel } from '../../../../.storybook/helpers'; | ||
|
||
export default { | ||
title: 'Atoms/Stack', | ||
component: Stack, | ||
argTypes: {}, | ||
}; | ||
|
||
const Template = (args) => Stack(args); | ||
|
||
// ***** Size variants ****************** // | ||
|
||
export const Base = Template.bind({}); | ||
Base.args = { length: 4 }; | ||
|
||
export const Nested = () => { | ||
const innerStack = Stack({ | ||
length: 2, | ||
itemColor: 'var(--bs-color-grayscale-light-4)', | ||
labelPrefix: 'stack 1 child 3 — stack 2', | ||
}); | ||
const children = [ | ||
StackItem({ children: generateLabel(['stack 1', 'child 1']) }), | ||
StackItem({ children: generateLabel(['stack 1', 'child 2']) }), | ||
innerStack, | ||
StackItem({ children: generateLabel(['stack 1', 'child 4']) }), | ||
StackItem({ children: generateLabel(['stack 1', 'child 5']) }), | ||
]; | ||
const outerStack = Stack({ children }); | ||
|
||
outerStack.insertBefore(innerStack, outerStack.childNodes[2]); | ||
return outerStack; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { Canvas, Meta, Story } from '@storybook/addon-docs'; | ||
|
||
<Meta title="Atoms/Stack/Overview" /> | ||
|
||
<Canvas> | ||
<Story id="atoms-stack--base" /> | ||
</Canvas> | ||
|
||
# Stack | ||
|
||
A layout atom that stacks its children vertically and ensures consistent space between each. This component is responsive, applying larger spacing between children when rendered on larger viewports. | ||
|
||
This layout is suitable for large blocks of content, such as the sections in the main content of a page. | ||
|
||
The spacing and the breakpoints the component responds to can be [customized](#customization). You can also add extra size variants of the stack, that apply different spacing, but the default configuration provides only one. | ||
|
||
Stacks can be nested — children of a stack can themselves be stacks — while the spacing will remain consistent: | ||
|
||
<Canvas> | ||
<Story id="atoms-stack--nested" /> | ||
</Canvas> | ||
|
||
## Customization | ||
|
||
The component expects a Sass list of Sass maps, with the keys being the name of the breakpoint (use `setup.$no-media-query` for the base mobile-first styles) and the values being the name of the stack variant. You can change the breakpoint names or add new breakpoints if you want the component to apply different spacing at extra breakpoints (in which case you probably also want to [edit the available `content` padding design tokens](/docs/design-tokens-content--page) available to you, though you can also pass `size` design tokens directly) | ||
|
||
```scss | ||
@use '~bitstyles/scss/bitstyles/atoms/stack' with ( | ||
$size-variants: ( | ||
'#{setup.$no-media-query}': ( | ||
'': var(design-token.get('content', 'padding', 'base')), | ||
), | ||
'm': ( | ||
'': var(design-token.get('content', 'padding', 'l')), | ||
), | ||
'l': ( | ||
'': var(design-token.get('content', 'padding', 'xl')), | ||
// this value of content-padding would need to be added to the content design tokens | ||
), | ||
) | ||
); | ||
``` | ||
|
||
### Extra size variants | ||
|
||
The keys of the spacing values above are deliberately left blank — that results in those spacing values being applied to the base `a-stack` component. If you provide a key, that will be used to create a stack variant: | ||
|
||
```scss | ||
@use '~bitstyles/scss/bitstyles/atoms/stack' with ( | ||
$size-variants: ( | ||
'#{setup.$no-media-query}': ( | ||
'': var(design-token.get('content', 'padding', 'base')), | ||
'large': var(design-token.get('content', 'padding', 'l')), | ||
), | ||
) | ||
); | ||
``` | ||
|
||
Produces CSS similar to the following: | ||
|
||
```css | ||
.a-stack > * + * { | ||
margin-top: var(--bs-content-padding-base); | ||
} | ||
|
||
.a-stack--large > * + * { | ||
margin-top: var(--bs-content-padding-l); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters