Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const preview = {
['Base Reset', 'File Organization', 'Selective Imports', 'Tokens', 'Themes', 'Scale Overriding', 'Addons'],
'Tokens',
'Utilities',
['Introduction'],
'Components',
'Recipes',
],
Expand Down
35 changes: 35 additions & 0 deletions src/core/utilities.css
Original file line number Diff line number Diff line change
Expand Up @@ -417,3 +417,38 @@
clip: rect(1px, 1px, 1px, 1px);
inline-size: 1px;
}

/* Advanced Layout Utilities */

/* Equivalent to .flex.flex-col.gap-md */
.op-stack {
display: flex;
flex-direction: column;
}

:where(.op-stack) {
gap: var(--op-space-medium);
}

/* Equivalent to .flex.flex-wrap.items-center.gap-md */
.op-cluster {
display: flex;
flex-wrap: wrap;
}

:where(.op-cluster) {
align-items: center;
gap: var(--op-space-medium);
}

/* Equivalent to .flex.flex-wrap.items-center.justify-between.gap-md */
.op-split {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}

:where(.op-split) {
align-items: center;
gap: var(--op-space-medium);
}
97 changes: 97 additions & 0 deletions src/stories/Recipes/Layout/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,99 @@ const createLoginLayout = () => {
`
}

const createUtilityLayout = () => {
return `
<div class='app-body' style="height: 80rem;"> <!-- This class should be on body. Height is for demo purposed -->
<!-- Alert Flash message here -->
<!-- Confirm here -->
<!-- Modal here -->
<!-- Panel here -->
<div class='app__content'>
<div class='op-stack'>
<h3>Timeline with Icons</h3>
<div class='op-stack'>
<div class='op-split gap-sm'>
<div class='op-cluster'>
<span class='material-symbols-outlined icon icon--x-large'>nature</span>
<span>
Buried by
<strong>Squirrel</strong>
</span>
</div>
<span class='text-right'>Mar 31</span>
</div>
<div class='divider'></div>
<div class='op-split gap-sm'>
<div class='op-cluster'>
<span class='material-symbols-outlined icon icon--x-large'>eco</span>
<span>
Germinated in
<strong>nutrient-rich soil</strong>
</span>
</div>
<span class='text-right'>May 28</span>
</div>
<div class='divider'></div>
<div class='op-split gap-sm'>
<div class='op-cluster'>
<span class='material-symbols-outlined icon icon--x-large'>forest</span>
<span>
Matured by
<strong>water</strong>
and
<strong>sunlight</strong>
</span>
</div>
<span class='text-right'>Sep 14</span>
</div>
</div>
</div>

<div class='divider divider--spacing-large'></div>

<!-- Without the stack, cluster, and split utilities, this would look like: -->
<div class='flex flex-col gap-md'>
<h3>Timeline with Icons</h3>
<div class='flex justify-between gap-sm'>
<div class='flex flex-wrap gap-sm'>
<span class='material-symbols-outlined icon icon--x-large'>nature</span>
<span>
Buried by
<strong>squirrel</strong>
</span>
</div>
<span class='text-right'>Mar 31</span>
</div>
<div class='divider'></div>
<div class='flex justify-between gap-sm'>
<div class='flex flex-wrap gap-sm'>
<span class='material-symbols-outlined icon icon--x-large'>eco</span>
<span>
Germinated in
<strong>nutrient-rich soil</strong>
</span>
</div>
<span class='text-right'>May 28</span>
</div>
<div class='divider'></div>
<div class='flex justify-between gap-sm'>
<div class='flex flex-wrap gap-sm'>
<span class='material-symbols-outlined icon icon--x-large'>forest</span>
<span>
Matured by
<strong>water</strong>
and
<strong>sunlight</strong>
</span>
</div>
<span class='text-right'>Sep 14</span>
</div>
</div>
</div>
</div>
`
}

export const createLayout = ({ style = 'basic', rightSidebar = false }) => {
if (style === 'basic') {
return createBasicLayout()
Expand All @@ -218,5 +311,9 @@ export const createLayout = ({ style = 'basic', rightSidebar = false }) => {
return createLoginLayout()
}

if (style === 'utility') {
return createUtilityLayout()
}

return `<div></div>`
}
6 changes: 6 additions & 0 deletions src/stories/Recipes/Layout/Layout.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,9 @@ A layout with a side panel looks like the following:
A layout for a login page could look like the following:

<Canvas of={LayoutStories.Login} />

## Utility

A layout explaining how the stack, split, and cluster utilities can be used to make flex layouts more readable.

<Canvas of={LayoutStories.Utility} />
8 changes: 7 additions & 1 deletion src/stories/Recipes/Layout/Layout.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default {
argTypes: {
style: {
control: { type: 'select' },
options: ['basic', 'sidebar', 'navbar', 'spinner', 'sidepanel', 'login'],
options: ['basic', 'sidebar', 'navbar', 'spinner', 'sidepanel', 'login', 'utility'],
},
rightSidebar: {
control: { type: 'boolean' },
Expand Down Expand Up @@ -62,3 +62,9 @@ export const Login = {
style: 'login',
},
}

export const Utility = {
args: {
style: 'utility',
},
}
14 changes: 14 additions & 0 deletions src/stories/Utilities/Cluster/Cluster.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createChildren } from '../../helpers/utils'

export const createCluster = ({ cluster = true, alignItems = '', gap = '' }) => {
const wrapper = document.createElement('div')
wrapper.style.height = '15rem'

wrapper.className = [cluster ? 'op-cluster' : '', alignItems ? `items-${alignItems}` : '', gap ? `gap-${gap}` : '']
.filter(Boolean)
.join(' ')

createChildren(wrapper, 35)

return wrapper
}
70 changes: 70 additions & 0 deletions src/stories/Utilities/Cluster/Cluster.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Meta, Story, Canvas, Controls } from '@storybook/addon-docs/blocks'
import * as ClusterStories from './Cluster.stories'
import { createSourceCodeLink } from '../../helpers/sourceCodeLink.js'

<Meta of={ClusterStories} />

# Cluster

<div
dangerouslySetInnerHTML={{
__html: createSourceCodeLink({ link: 'core/utilities.css' }).outerHTML,
}}
></div>

The cluster utility provides a simple way to create a wrapping, group of spaced items. It
works with all of the gap and other flex utilities. It is effectively equivalent to using
`.flex .flex-wrap .items-center .gap-md` together. See [Utility Introduction](?path=/docs/utilities-introduction--docs#higher-order-utilities-vs-components) for more information.

See [Utility Layout](?path=/docs/recipes-layout--docs#utility) for an example of how clusters
can be used to create more readable flex layouts.

Note: This utility uses the `op` prefix to avoid potential naming conflicts with other CSS frameworks.
This is a pattern we hope to move towards for all utilities in the future.

## Playground

<Canvas of={ClusterStories.With} />
<Controls of={ClusterStories.With} />

## Without

A normal `div` without the cluster utility

<Canvas of={ClusterStories.Without} />

## Cluster Property

`.op-cluster` Creates a flex cluster.

<Canvas of={ClusterStories.With} />

## Align Items Stretch

`.items-stretch` Stretches each item across the cross axis. This is the default alignment and doesn't need to be applied unless you are overriding something set differently.

<Canvas of={ClusterStories.AlignStretch} />

## Align Items Start

`.items-start` places each item at the start of the cross axis.

<Canvas of={ClusterStories.AlignStart} />

## Align Items Center

`.items-center` places each item at the center of the cross axis.

<Canvas of={ClusterStories.AlignCenter} />

## Align Items End

`.items-end` places each item at the end of the cross axis.

<Canvas of={ClusterStories.AlignEnd} />

## Align Items Baseline

`.items-baseline` places each item at the text baseline of the cross axis.

<Canvas of={ClusterStories.AlignBaseline} />
64 changes: 64 additions & 0 deletions src/stories/Utilities/Cluster/Cluster.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { createCluster } from './Cluster.js'

export default {
title: 'Utilities/Cluster',
render: ({ cluster, ...args }) => {
return createCluster({ cluster, ...args })
},
argTypes: {
cluster: { control: 'boolean' },
alignItems: {
control: { type: 'select' },
options: ['stretch', 'start', 'center', 'end', 'baseline'],
},
gap: {
control: { type: 'select' },
options: ['xxs', 'xs', 'sm', 'md', 'lg', 'xl'],
},
},
parameters: {
layout: 'fullscreen',
},
}

export const With = {
args: {
cluster: true,
},
}

export const Without = {
args: {
cluster: false,
},
}

export const AlignStretch = {
args: {
alignItems: 'stretch',
},
}

export const AlignStart = {
args: {
alignItems: 'start',
},
}

export const AlignCenter = {
args: {
alignItems: 'center',
},
}

export const AlignEnd = {
args: {
alignItems: 'end',
},
}

export const AlignBaseline = {
args: {
alignItems: 'baseline',
},
}
4 changes: 1 addition & 3 deletions src/stories/Utilities/Flex/Flex.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,7 @@ A normal `div` without the flex utility

`.items-start` places each flex item at the start of the cross axis.

<Canvas withToolbar>
<Canvas of={FlexStories.AlignStart} />
</Canvas>
<Canvas of={FlexStories.AlignStart} />

## Align Items Center

Expand Down
Loading