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(styles): add palettes #3850

Merged
merged 11 commits into from
Nov 25, 2024
6 changes: 6 additions & 0 deletions .changeset/weak-jars-rhyme.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
---

Added color palettes to easily apply colors to a page section using predefined color sets.
13 changes: 13 additions & 0 deletions packages/documentation/cypress/e2e/components/palette.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
describe('Palette', () => {
describe('Accessibility', () => {
beforeEach(() => {
cy.visit('/iframe.html?id=snapshots--palette');
cy.get('.palette-default', { timeout: 30000 }).should('be.visible');
cy.injectAxe();
});

it('Has no detectable a11y violations on load for all variants', () => {
cy.checkA11y('#root-inner');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
describe('Palette', () => {
it('default', () => {
cy.visit('/iframe.html?id=snapshots--palette');
cy.get('.palette-default', { timeout: 30000 }).should('be.visible');
cy.percySnapshot('Palettes', { widths: [1440] });
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Canvas, Controls, Meta } from '@storybook/blocks';
import * as paletteStories from './palette.stories';

<Meta of={paletteStories} />

<div className="docs-title">
# Palettes
</div>

<div className="lead">
Easily apply colors to a section of your page using predefined color sets.
</div>

There are four different palettes:
- **Default** - The standard palette used when no other palette is specified.
- **Alternate** - Used to differentiate alternating sections from the body, without strong emphasis or highlighting.
- **Accent** - A complementary color used for highlights and emphasis.
- **Brand** - The primary color for the brand.

Palettes may also include a specific text color that is different from the body color.
You can apply this text color to any element by using the `.palette-text` class.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm missing documentation for people who'd like to implement palettes, without using an entry file. What files are necessary to just get palettes to work and where can they be found?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I created a separate ticket for that since it requires changes to the StylesPackageImport component: #4025

<Canvas sourceState="shown" of={paletteStories.Default} />

<div className="hide-col-default">
<Controls of={paletteStories.Default} />
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import meta from './palette.stories';

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

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

type Story = StoryObj;

export const Palette: Story = {
render: () => {
return html`${['light', 'dark'].map(
mainScheme => html`
<div class="palette-default p-24 d-flex flex-column gap-48" data-color-scheme=${mainScheme}>
${['', 'light', 'dark'].map(
paletteScheme => html`
<div>
<p class="px-24">Palette scheme: ${paletteScheme || 'none'}</p>
<div class="d-flex">
${meta.argTypes.palette.options.map(palette =>
meta.render({ palette, colorScheme: paletteScheme }),
)}
</div>
</div>
`,
)}
</div>
`,
)}`;
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Args, Meta, StoryObj } from '@storybook/web-components';
import { html, nothing } from 'lit';

const meta: Meta = {
id: '43481535-5b39-40b5-a273-478b07dc3b31',
title: 'Foundations/Palettes',
tags: ['package:HTML'],
render: renderPalette,
parameters: {
palettes: [],
design: {
type: 'figma',
url: 'https://www.figma.com/file/xZ0IW0MJO0vnFicmrHiKaY/Components-Post?type=design&node-id=18172-73431&mode=design&t=3lniLiZhl7q9Gqgn-4',
},
},
args: {
palette: 'default',
},
argTypes: {
palette: {
name: 'Palette',
description: 'The set of colors used for a section of the page.',
control: {
type: 'radio',
labels: {
default: 'Default',
alternate: 'Alternate',
brand: 'Brand',
accent: 'Accent',
},
},
options: ['default', 'alternate', 'accent', 'brand'],
table: {
category: 'General',
},
},
},
};

export default meta;

// RENDERER
function renderPalette(args: Args) {
return html`
<div class="palette-${args.palette} p-24" data-color-scheme=${args.colorScheme ?? nothing}>
<h2 class="palette-text">
I use a specific color from the palette (it might be the same as the body color).
</h2>
<p>I use the main body color.</p>
<button class="btn btn-primary">Primary button</button>
</div>
`;
}

// STORIES
type Story = StoryObj;

export const Default: Story = {};
2 changes: 1 addition & 1 deletion packages/styles/gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ gulp.task('copy', () => {
* See https://github.com/pnpm/pnpm/issues/8338 for more information and reproduction
*/
gulp.task('temporarily-copy-token-files', () => {
return gulp.src(['../tokens/dist/*.scss']).pipe(gulp.dest('./src/tokens/temp'));
return gulp.src(['../tokens/dist/**/*.scss']).pipe(gulp.dest('./src/tokens/temp'));
});

/**
Expand Down
1 change: 1 addition & 0 deletions packages/styles/src/cargo-external.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@use './tokens/device';
@use './tokens/external';
@use './tokens/cargo-theme';
@use './palettes/cargo-palettes';
@use './utilities';
@use './elements';
@use './components';
1 change: 1 addition & 0 deletions packages/styles/src/cargo-internal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@use './tokens/device';
@use './tokens/internal';
@use './tokens/cargo-theme';
@use './palettes/cargo-palettes';
@use './utilities';
@use './elements';
@use './components';
74 changes: 74 additions & 0 deletions packages/styles/src/palettes/_mixins.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
@use 'sass:map';
@use 'sass:meta';

@use '../functions/tokens';
@use '../placeholders/schemes';
@use '../tokens/elements';
@use '../tokens/palettes';

@use './variables' as *;

@forward './utilities';

@mixin palettes($theme) {
body {
background-color: var(--post-current-palette-bg) !important;

&:not([data-color-scheme='dark']) {
@include palette-tokens($default-palette, $theme, 'light');
}

&[data-color-scheme='dark'] {
@include palette-tokens($default-palette, $theme, 'dark');
}
}

@each $palette in $palettes {
.palette-#{$palette} {
// Redefining the body color is necessary to ensure that the new color scheme is applied correctly.
// Known limitation: body color may be incorrect with nested parent with different `data-color-scheme` values.
color: tokens.get('body-color', elements.$post-body);
background-color: var(--post-current-palette-bg) !important;

// Light scheme explicitly set on the palette:
&[data-color-scheme='light'],

// No scheme explicitly set on the palette, but parent has a light scheme:
&:where([data-color-scheme='light'] :not([data-color-scheme='dark'])),

// No scheme explicitly set on the palette, and no scheme on the parent either:
&:not([data-color-scheme='dark']):not([data-color-scheme='dark'] *) {
@include palette-tokens($palette, $theme, 'light', $override-scheme: true);
}

// Dark scheme explicitly set on the palette:
&[data-color-scheme='dark'],

// No scheme explicitly set on the palette, but parent has a dark scheme:
&:where([data-color-scheme='dark'] :not([data-color-scheme='dark'])) {
@include palette-tokens($palette, $theme, 'dark', $override-scheme: true);
}
}
}
}

@mixin palette-tokens($name, $theme, $scheme, $override-scheme: false) {
$palette: map.get(meta.module-variables(palettes), '#{$theme}-#{$scheme}');

@if (not $palette) {
@error 'Palette #{$theme}-#{$scheme} not found.';
}

--post-current-palette-fg: #{tokens.get('palettes-color-#{$name}-fg', $palette)};
--post-current-palette-bg: #{tokens.get('palettes-color-#{$name}-bg', $palette)};

@if ($override-scheme == true) {
$bg-scheme: tokens.get('palettes-color-#{$name}-bg-scheme', $palette);

@if ($bg-scheme == 'light') {
@extend %color-scheme-light;
} @else {
@extend %color-scheme-dark;
}
}
}
3 changes: 3 additions & 0 deletions packages/styles/src/palettes/_utilities.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.palette-text {
color: var(--post-current-palette-fg);
}
2 changes: 2 additions & 0 deletions packages/styles/src/palettes/_variables.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
$default-palette: 'default';
$palettes: $default-palette, 'alternate', 'brand', 'accent';
3 changes: 3 additions & 0 deletions packages/styles/src/palettes/cargo-palettes.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@use 'mixins' as *;

@include palettes('cargo');
3 changes: 3 additions & 0 deletions packages/styles/src/palettes/post-palettes.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@use 'mixins' as *;

@include palettes('post');
1 change: 1 addition & 0 deletions packages/styles/src/post-external.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@use './tokens/device';
@use './tokens/external';
@use './tokens/post-theme';
@use './palettes/post-palettes';
@use './utilities';
@use './elements';
@use './components';
1 change: 1 addition & 0 deletions packages/styles/src/post-internal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@use './tokens/device';
@use './tokens/internal';
@use './tokens/post-theme';
@use './palettes/post-palettes';
@use './utilities';
@use './elements';
@use './components';
9 changes: 9 additions & 0 deletions packages/styles/src/tokens/_palettes.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@use './temp/palettes/post-light' as post-light;
@use './temp/palettes/post-dark' as post-dark;
@use './temp/palettes/cargo-light' as cargo-light;
@use './temp/palettes/cargo-dark' as cargo-dark;

$post-light: post-light.$post-palettes;
$post-dark: post-dark.$post-palettes;
$cargo-light: cargo-light.$post-palettes;
$cargo-dark: cargo-dark.$post-palettes;
10 changes: 10 additions & 0 deletions packages/styles/tests/palettes/cargo-palettes.test.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@use 'src/palettes/cargo-palettes';

/* stylelint-disable scss/at-extend-no-missing-placeholder */
.palettes {
@extend .palette-text;
@extend .palette-default;
@extend .palette-alternate;
@extend .palette-brand;
@extend .palette-accent;
}
10 changes: 10 additions & 0 deletions packages/styles/tests/palettes/post-palettes.test.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@use 'src/palettes/post-palettes';

/* stylelint-disable scss/at-extend-no-missing-placeholder */
.palettes {
@extend .palette-text;
@extend .palette-default;
@extend .palette-alternate;
@extend .palette-brand;
@extend .palette-accent;
}