Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(documentation): add docs page on how to use columns #2062

Merged
merged 13 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
5 changes: 5 additions & 0 deletions .changeset/gorgeous-clouds-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@swisspost/design-system-documentation': minor
---

Added docs page on how to use columns.
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { Meta, Canvas, Source, Controls } from '@storybook/blocks';
import * as ColumnStories from './columns.stories';
import './columns.styles.scss';

<Meta of={ColumnStories} />

# Columns

Learn how to modify columns with a handful of options for alignment, ordering, and offsetting thanks to our flexbox grid system. Plus, see how to use column classes to manage widths of non-grid elements.

### How they work

{/* prettier-ignore */}
<ul>
<li><b>Columns build on the grid’s flexbox architecture.</b> Flexbox means we have options for changing individual columns and modifying groups of columns at the row level. You choose how columns grow, shrink, or otherwise change.</li>
<br/>
<li><b>When building grid layouts, all content goes in columns.</b> The hierarchy of our grid goes from container to row to column to your content.</li>
<br/>
<li><b>The Swiss Post Design System includes predefined classes for creating fast, responsive layouts.</b> With [seven breakpoints](/?path=/docs/foundations-layout-breakpoints--docs) and a dozen columns at each grid tier, we have dozens of classes already built for you to create your desired layouts.</li>
</ul>

### Alignment

Use flexbox alignment utilities to vertically and horizontally align columns.

#### Vertical alignment

Change the vertical alignment with any of the responsive <code>align-items-\*</code> classes.

Or, change the alignment of each column individually with any of the responsive <code>align-self-\*</code> classes.

<Canvas sourceState="shown" of={ColumnStories.VerticalExample} />
<div className="hide-col-default">
<Controls of={ColumnStories.VerticalExample} />
</div>

#### Horizontal alignment

Change the horizontal alignment with any of the responsive <code>justify-content-\*</code> classes.

<Canvas of={ColumnStories.HorizontalExample} />
<div className="hide-col-default">
<Controls of={ColumnStories.HorizontalExample} />
</div>

#### Column wrapping

If more than 12 columns are placed within a single row, each group of extra columns will, as one unit, wrap onto a new line.

<Canvas of={ColumnStories.ColumnWrapping} />

#### Column breaks

Breaking columns to a new line in flexbox requires a small hack: add an element with <code>width: 100%</code> wherever you want to wrap your columns to a new line. Normally this is accomplished with multiple <code>.rows</code>, but not every implementation method can account for this.

<Canvas of={ColumnStories.ColumnBreakExample} />

### Reorderning

#### Order classes

Use <code>.order-</code> classes for controlling the visual order of your content. These classes are responsive, so you can set the order by breakpoint (e.g. <code>.order-1</code><code>.order-md-2</code>). Includes support for 1 through 5 across all seven grid tiers. If you need more <code>.order-\*</code> classes.

<Canvas of={ColumnStories.OrderExample} />

There are also responsive <code>.order-first</code> and <code>.order-last</code> classes that change the order of an element by applying <code>order: -1</code> and <code>order: 6</code>, respectively. These classes can also be intermixed with the numbered <code>.order-\*</code> classes as needed.

<Canvas of={ColumnStories.OrderMaxExample} />

### Offsetting columns

You can offset grid columns in two ways: our responsive <code>.offset-</code> grid classes and our margin utilities. Grid classes are sized to match columns while margins are more useful for quick layouts where the width of the offset is variable.

#### Offset classes

Move columns to the right using <code>.offset-\*</code> classes. These classes increase the left margin of a column by \* columns. For example, <code>.offset-4</code> moves <code>.col-1</code> over four columns. You can also apply the offset above a certain breakpoint with the breakpoint infixes e.g. <code>offset-md-4</code>.

<Canvas of={ColumnStories.OffsetExample} />
<div className="hide-col-default">
<Controls of={ColumnStories.OffsetExample} />
</div>

In addition to column clearing at responsive breakpoints, you may need to reset offsets.

<Canvas of={ColumnStories.ResetOffsetExample} />

### Standalone column classes

The <code>.col-\*</code> classes can also be used outside a <code>.row</code> to give an element a specific width. Whenever column classes are used as non-direct children of a row, the paddings are omitted.

<Canvas of={ColumnStories.StandaloneColumnExample} />
davidritter-dotcom marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
import type { Args, Meta, StoryFn, StoryObj, StoryContext } from '@storybook/web-components';
import { BADGE } from '../../../../../.storybook/constants';
import { html } from 'lit';

const meta: Meta = {
title: 'Foundations/Layout/Columns',
parameters: {
badges: [BADGE.NEEDS_REVISION],
},
decorators: [
(story: StoryFn, { args, context }: StoryContext) => html`
<div class="p-regular column-example text-center">${story(args, context)}</div>
`,
],
args: {
alignItems: 'align-items-start',
alignSelf: 'no self alignment',
justifyContent: 'justify-content-start',
offsetItem: 'offset-1',
},
argTypes: {
alignItems: {
name: 'Align Items',
description: 'Aligns the whole row vertically.',
control: {
type: 'select',
},
options: ['align-items-start', 'align-items-center', 'align-items-end'],
table: {
category: 'General',
},
},
alignSelf: {
name: 'Align Item 1',
description: 'Aligns the Item 1 vertically.',
control: {
type: 'select',
},
options: ['no self alignment', 'align-self-start', 'align-self-center', 'align-self-end'],
table: {
category: 'General',
},
},
justifyContent: {
name: 'Horizontal Alignement',
description: 'Aligns the Items horizontally.',
control: {
type: 'select',
},
options: [
'justify-content-start',
'justify-content-center',
'justify-content-end',
'justify-content-around',
'justify-content-between',
'justify-content-evenly',
],
table: {
category: 'General',
},
},
offsetItem: {
name: 'Offset classes',
description: 'Increases the left margin of a column',
control: {
type: 'select',
},
options: [
'offset-1',
'offset-2',
'offset-3',
'offset-4',
'offset-5',
'offset-6',
'offset-7',
'offset-8',
'offset-9',
'offset-10',
'offset-11',
],
table: {
category: 'General',
},
},
},
};

export default meta;

type Story = StoryObj;

export const VerticalExample: Story = {
parameters: {
controls: { exclude: ['Horizontal Alignement', 'Offset classes'] },
},
render: (args: Args) => html`
<div class="container">
<div class="row-height row ${args.alignItems}">
<div class="col${args.alignSelf === 'no self alignment' ? '' : ` ${args.alignSelf}`}">
Item 1
</div>
<div class="col">Item 2</div>
<div class="col">Item 3</div>
</div>
</div>
`,
};

export const HorizontalExample: Story = {
parameters: {
controls: { exclude: ['Align Items', 'Align Item 1', 'Offset classes'] },
},
render: (args: Args) => html`
<div class="container">
<div class="row ${args.justifyContent}">
<div class="col-4">Item 1</div>
<div class="col-4">Item 2</div>
</div>
</div>
`,
};

export const OrderExample: Story = {
render: () => html`
<div class="container">
<div class="row">
<div class="col">First in DOM, no order applied</div>
<div class="col order-5">Second in DOM, with a larger order</div>
<div class="col order-1">Third in DOM, with an order of 1</div>
</div>
</div>
`,
};
davidritter-dotcom marked this conversation as resolved.
Show resolved Hide resolved

export const OrderMaxExample: Story = {
render: () => html`
<div class="container">
<div class="row">
<div class="col order-last">First in DOM, ordered last</div>
<div class="col">Second in DOM, unordered</div>
<div class="col order-first">Third in DOM, ordered first</div>
</div>
</div>
`,
};

export const OffsetExample: Story = {
parameters: {
controls: { exclude: ['Align Items', 'Align Item 1', 'Horizontal Alignement'] },
},
render: (args: Args) => html`
<div class="row">
<div class="col-1 ${args.offsetItem}">.col-1 .${args.offsetItem}</div>
davidritter-dotcom marked this conversation as resolved.
Show resolved Hide resolved
</div>
`,
};

export const ColumnBreakExample: Story = {
render: () => html`
<div class="row">
<div class="col-3">.col-3</div>
<div class="col-3">.col-3</div>

<!-- Force next columns to break to new line -->
davidritter-dotcom marked this conversation as resolved.
Show resolved Hide resolved
<div class="w-100"></div>

<div class="col-3">.col-3</div>
<div class="col-3">.col-3</div>
</div>
`,
};
davidritter-dotcom marked this conversation as resolved.
Show resolved Hide resolved

export const ResetOffsetExample: Story = {
decorators: [
(story: StoryFn, { args, context }: StoryContext) => html`
${story(args, context)}
<p class="mt-regular"><small>Resize the browser window to see changes.</small></p>
`,
],
render: () => html`
<div class="row">
<div class="col-sm-5 col-md-6">.col-sm-5 .col-md-6</div>
<div class="col-sm-5 offset-sm-2 col-md-6 offset-md-0">
.col-sm-5 .offset-sm-2 .col-md-6 .offset-md-0
</div>
</div>
<div class="row">
<div class="col-sm-6 col-md-5 col-lg-6">.col-sm-6 .col-md-5 .col-lg-6</div>
<div class="col-sm-6 col-md-5 offset-md-2 col-lg-6 offset-lg-0">
.col-sm-6 .col-md-5 .offset-md-2 .col-lg-6 .offset-lg-0
</div>
</div>
davidritter-dotcom marked this conversation as resolved.
Show resolved Hide resolved
`,
};

export const MarginUtilitiesExample: Story = {
decorators: [
(story: StoryFn, { args, context }: StoryContext) => html`
${story(args, context)}
<p class="mt-regular"><small>Resize the browser window to see changes.</small></p>
`,
],
render: () => html`
<div class="row">
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4 ms-auto">.col-md-4 .ms-auto</div>
</div>
<div class="row">
<div class="col-md-3 ms-md-auto">.col-md-3 .ms-md-auto</div>
<div class="col-md-3 ms-md-auto">.col-md-3 .ms-md-auto</div>
</div>
<div class="row">
<div class="col-auto me-auto">.col-auto .me-auto</div>
<div class="col-auto">.col-auto</div>
</div>
`,
};
davidritter-dotcom marked this conversation as resolved.
Show resolved Hide resolved

export const StandaloneColumnExample: Story = {
decorators: [
(story: StoryFn, { args, context }: StoryContext) => html`
<div class="standalone-columns">
${story(args, context)}
<p class="mt-regular"><small>Resize the browser window to see changes.</small></p>
</div>
`,
],
render: () => html`
<div class="col-3 p-3 mb-2">.col-3: width of 25%</div>

<div class="col-md-9 p-3">.col-md-9: width of 75% above md breakpoint</div>
`,
};
davidritter-dotcom marked this conversation as resolved.
Show resolved Hide resolved

export const ColumnWrapping: Story = {
render: () => html`
<div class="row">
<div class="col-9">.col-9</div>
<div class="col-4">
.col-4
<br />
Since 9 + 4 = 13 &gt; 12, this 4-column-wide div gets wrapped onto a new line as one
contiguous unit.
</div>
<div class="col-6">
.col-6
<br />
Subsequent columns continue along the new line.
</div>
</div>
`,
};
davidritter-dotcom marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@use '@swisspost/design-system-styles/core' as post;

.column-example {
font-size: post.$font-size-sm;

.row > *:not(.w-100) {
padding-block: 0.75rem;
background-color: lighten(post.$nightblue-bright, 55%);
border: 1px solid lighten(post.$nightblue-dark, 45%);
}

.row {
background-color: lighten(post.$nightblue-bright, 61.5%);
}

.row-height {
min-height: 10rem;
}

.standalone-columns > *:not(p){
padding-block: 0.75rem;
background-color: lighten(post.$nightblue-bright, 55%);
border: 1px solid lighten(post.$nightblue-dark, 45%);
}
}
Loading