Skip to content

Commit

Permalink
feat(styles): implement gutter classes (#4378)
Browse files Browse the repository at this point in the history
Co-authored-by: Alizé Debray <[email protected]>
  • Loading branch information
myrta2302 and alizedebray authored Jan 8, 2025
1 parent 5a8b256 commit bf95c9b
Show file tree
Hide file tree
Showing 9 changed files with 306 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changeset/chatty-pigs-hear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@swisspost/design-system-documentation': minor
'@swisspost/design-system-styles': minor
---

Implemented gutter utility classes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
describe('Gutters', () => {
it('Gutters', () => {
cy.visit('/iframe.html?id=snapshots--gutters');
cy.get('.gutters-example', { timeout: 30000 }).should('be.visible');
cy.percySnapshot('Gutters', { widths: [320, 780, 1024, 1440] });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ To control the space between your columns, add either `.g-*` (horizontal and ver

<Canvas of={GridStories.Gutters} />

<div className="banner banner-info my-24">
You can find additional information and examples of grid gutters{' '}
<a href="/?path=/docs/64b63483-79fa-4e9f-9441-f7d6b2eabae2--docs">here</a>.
</div>

## Nesting

To nest your content with the default grid, add a new `.row` and set of `.col-*` columns within an existing `.col-*` column. Nested rows should include a set of columns that add up to 12 or fewer.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Canvas, Controls, Meta } from '@storybook/blocks';
import * as GutterStories from './gutters.stories';

export const firstBreakpoint = Object.values(GutterStories.SCSS_VARIABLES.firstBreakpoint)[0];
export const breakpoints = Object.values(GutterStories.SCSS_VARIABLES.breakpoints).map(
(breakpoint, i, arr) => [breakpoint, i !== arr.length - 1],
);

<Meta of={GutterStories} />

# Gutters

Gutters are the spaces between column content in grid elements (e.g., `.row`, `.col`, `.col-*`). They are implemented by applying an inline-padding to each column, along with matching negative margins to offset the padding at the row's edges.

## Horizontal gutters

The `.gx-{size}` classes can be used to set the horizontal gutters within the columns (`.col`) of a `.row`.

### Example

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

## Vertical gutters

The `.gy-{size}` classes can be used to set the vertical gutter width when a `.row` wraps to new lines.

### Example

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

## Horizontal and vertical gutters

The `.g-{size}` classes can be used to set both the horizontal and vertical gutter widths.

### Example

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

## No gutters

Gutters can be eliminated by applying the classes `.g-0`, `.gx-0`, or `.gy-0`, which remove all gutters, horizontal gutters, or vertical gutters, respectively.

## Relative to breakpoints

Breakpoint-specific classes allow precise control of horizontal, vertical, and general gutters at various screen sizes.

- `.gx-{breakpoint}-{size}` (e.g. `gx-lg-24`)
- `.gy-{breakpoint}-{size}` (e.g. `gy-sm-32`)
- `.g-{breakpoint}-{size}` (e.g. `g-md-12`)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@use 'sass:list';
@use 'sass:map';
@use '@swisspost/design-system-styles/core' as post;
@use '@swisspost/design-system-styles/tokens/utilities' as tokens;

:export {
@each $key, $value in tokens.$post-spacing {
spacing_#{$key}: #{$value};
}
@each $breakpoint in post.$grid-breakpoints-list {
@if (map.get(post.$grid-breakpoints, $breakpoint) == 0) {
firstBreakpoint_#{$breakpoint}: $breakpoint;
}
@if (map.get(post.$grid-breakpoints, $breakpoint) != 0) {
breakpoints_#{$breakpoint}: $breakpoint;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { Args, StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import { COLOR_SCHEMES, schemes } from '@/shared/snapshots/schemes';
import meta from './gutters.stories';
import './gutters.styles.scss';
import { bombArgs } from '@/utils';

const { id, ...metaWithoutId } = meta;

export default {
...metaWithoutId,
title: 'Snapshots',
};

const sizes = ['0', '1', '2', '4', '8', '12', '24', '32', '48'];
const gutterType = ['g', 'gx', 'gy'];

export const Gutters: StoryObj = {
render: () => {
return schemes(
() => {
return html`
${bombArgs({
gutterType: gutterType,
sizes: sizes,
}).map(
(args: Args) =>
html`
<div class="container my-24 mx-0">
<div class="row ${args.gutterType}-${args.sizes}">
<div class="col-6">${args.gutterType}-${args.sizes}</div>
<div class="col-6">${args.gutterType}-${args.sizes}</div>
<div class="col-6">${args.gutterType}-${args.sizes}</div>
<div class="col-6">${args.gutterType}-${args.sizes}</div>
</div>
</div>
`,
)}
`;
},
{ filter: scheme => scheme === COLOR_SCHEMES.light },
);
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import type { Args, StoryContext, StoryFn, StoryObj } from '@storybook/web-components';
import { html } from 'lit/static-html.js';
import { MetaExtended } from '@root/types';
import { parse } from '@/utils/sass-export';
import scss from './gutters.module.scss';
import './gutters.styles.scss';

/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
export const SCSS_VARIABLES: any = parse(scss);

const properties = ['gap'];

const sizes = properties.reduce((options, property) => {
return {
...options,
[property]: Object.keys(SCSS_VARIABLES.spacing)
.filter((key: string) => key.startsWith(`post-utility-${property}-`))
.map((key: string) => key.replace(`post-utility-${property}-`, '')),
};
}, {} as { [property: string]: string[] });

const meta: MetaExtended = {
id: '64b63483-79fa-4e9f-9441-f7d6b2eabae2',
title: 'Foundations/Layout/Gutters',
decorators: [
(story: StoryFn, context: StoryContext) => {
const storyTemplate = html`<div class="gutters-example">
${story(context.args, context)}
</div>`;
return storyTemplate;
},
],
};

export default meta;

type Story = StoryObj;

export const HorizontalGutters: Story = {
argTypes: {
gutterX: {
name: 'Horizontal gutter (gx)',
description: 'Sets the horizontal gutter size.',
control: {
type: 'select',
},
options: sizes.gap,
},
},
args: {
gutterX: '12',
},
render: (args: Args) => {
// used only for the snapshots
const breakpointClass = args.breakpointClass ? `-${args.breakpointClass}` : '';
return html`
<div class="container">
<div class="row gx${breakpointClass}-${args.gutterX}">
<div class="col">col</div>
<div class="col">col</div>
<div class="col">col</div>
<div class="col">col</div>
</div>
</div>
</div>
`;
},
};

export const VerticalGutters: Story = {
argTypes: {
gutterY: {
name: 'Vertical gutter (gy)',
description: 'Sets the vertical gutter size.',
control: {
type: 'select',
},
options: sizes.gap,
},
},
args: {
gutterY: '32',
},
render: (args: Args) => {
// used only for the snapshots
const breakpointClass = args.breakpointClass ? `-${args.breakpointClass}` : '';
return html`
<div class="container">
<div class="row gy${breakpointClass}-${args.gutterY}">
<div class="col-6">col</div>
<div class="col-6">col</div>
<div class="col-6">col</div>
<div class="col-6">col</div>
</div>
</div>
</div>
`;
},
};

export const GeneralGutters: Story = {
argTypes: {
gutter: {
name: 'General gutter (g)',
description: 'Sets the general gutter size.',
control: {
type: 'select',
},
options: sizes.gap,
},
},
args: {
gutter: '64',
},
render: (args: Args) => {
// used only for the snapshots
const breakpointClass = args.breakpointClass ? `-${args.breakpointClass}` : '';
return html`
<div class="container">
<div class="row g${breakpointClass}-${args.gutter}">
<div class="col-6">col</div>
<div class="col-6">col</div>
<div class="col-6">col</div>
<div class="col-6">col</div>
</div>
</div>
</div>
`;
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.gutters-example,
.gutters-snapshot-example {
text-align: center;

.container {
overflow: hidden;
}

.row {
.col,
.col-6 {
background: linear-gradient(#b8e2f3, #b8e2f3), linear-gradient(#a69ce1, #a69ce1);
background-clip: content-box, border-box;
color: #59718b;
}
}
.row:has(.col-6) {
background: linear-gradient(#a69ce1, #a69ce1);
}
}
18 changes: 18 additions & 0 deletions packages/styles/src/utilities/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,24 @@ $position-values: (
);

$utilities: (
'grid-gutter': (
responsive: true,
property: --post-grid-gutter-x --post-grid-gutter-y,
class: g,
values: from-tokens('spacing', 'gap'),
),
'grid-gutter-x': (
responsive: true,
property: --post-grid-gutter-x,
class: gx,
values: from-tokens('spacing', 'gap'),
),
'grid-gutter-y': (
responsive: true,
property: --post-grid-gutter-y,
class: gy,
values: from-tokens('spacing', 'gap'),
),
'width': (
responsive: true,
property: width,
Expand Down

0 comments on commit bf95c9b

Please sign in to comment.