diff --git a/client/src/tokens/colors.js b/client/src/tokens/colors.js index a1d84ae621..3e30d2470e 100644 --- a/client/src/tokens/colors.js +++ b/client/src/tokens/colors.js @@ -1,13 +1,15 @@ /** @typedef {{ hex: string; + hsl: string; bgUtility: string; textUtility: string; + cssVariable: string; usage: string; contrastText: string; }} Shade */ /** @typedef {{ - [jsName: string]: Shade; + [jsName: string | number]: Shade; }} Hues */ /** @typedef {{ @@ -19,7 +21,7 @@ const colors = { black: { DEFAULT: { hex: '#000000', - hsl: 'hsl(0, 0%, 0%)', + hsl: 'hsl(0 0% 0%)', bgUtility: 'w-bg-black', textUtility: 'w-text-black', cssVariable: '--w-color-black', @@ -30,7 +32,7 @@ const colors = { grey: { 600: { hex: '#262626', - hsl: 'hsl(0, 0%, 15%)', + hsl: 'hsl(0 0% 15%)', bgUtility: 'w-bg-grey-600', textUtility: 'w-text-grey-600', cssVariable: '--w-color-grey-600', @@ -39,7 +41,7 @@ const colors = { }, 400: { hex: '#5C5C5C', - hsl: 'hsl(0, 0%, 36%)', + hsl: 'hsl(0 0% 36%)', bgUtility: 'w-bg-grey-400', textUtility: 'w-text-grey-400', cssVariable: '--w-color-grey-400', @@ -48,7 +50,7 @@ const colors = { }, 200: { hex: '#929292', - hsl: 'hsl(0, 0%, 57%)', + hsl: 'hsl(0 0% 57%)', bgUtility: 'w-bg-grey-200', textUtility: 'w-text-grey-200', cssVariable: '--w-color-grey-200', @@ -57,7 +59,7 @@ const colors = { }, 100: { hex: '#E0E0E0', - hsl: 'hsl(0, 0%, 88%)', + hsl: 'hsl(0 0% 88%)', bgUtility: 'w-bg-grey-100', textUtility: 'w-text-grey-100', cssVariable: '--w-color-grey-100', @@ -66,7 +68,7 @@ const colors = { }, 50: { hex: '#F6F6F8', - hsl: 'hsl(240, 12%, 97%)', + hsl: 'hsl(240 12% 97%)', bgUtility: 'w-bg-grey-50', textUtility: 'w-text-grey-50', cssVariable: '--w-color-grey-50', @@ -77,7 +79,7 @@ const colors = { white: { DEFAULT: { hex: '#FFFFFF', - hsl: 'hsl(0, 0%, 100%)', + hsl: 'hsl(0 0% 100%)', bgUtility: 'w-bg-white', textUtility: 'w-text-white', cssVariable: '--w-color-white', @@ -85,57 +87,10 @@ const colors = { contrastText: 'primary', }, }, - secondary: { - 600: { - hex: '#004345', - hsl: 'hsl(182, 100%, 14%)', - bgUtility: 'w-bg-secondary-600', - textUtility: 'w-text-secondary-600', - cssVariable: '--w-color-secondary-600', - usage: 'Hover states for two-tone buttons', - contrastText: 'white', - }, - 400: { - hex: '#005B5E', - hsl: 'hsl(182, 100%, 18%)', - bgUtility: 'w-bg-secondary-400', - textUtility: 'w-text-secondary-400', - cssVariable: '--w-color-secondary-400', - usage: 'Two-tone buttons, hover states', - contrastText: 'white', - }, - DEFAULT: { - hex: '#007D7E', - hsl: 'hsl(180, 100%, 25%)', - bgUtility: 'w-bg-secondary', - textUtility: 'w-text-secondary', - cssVariable: '--w-color-secondary', - usage: 'Primary buttons, action links', - contrastText: 'white', - }, - 100: { - hex: '#00B0B1', - hsl: 'hsl(180, 100%, 35%)', - bgUtility: 'w-bg-secondary-100', - textUtility: 'w-text-secondary-100', - cssVariable: '--w-color-secondary-100', - usage: 'UI element highlights', - contrastText: 'white', - }, - 50: { - hex: '#F2FCFC', - hsl: 'hsl(180, 63%, 97%)', - bgUtility: 'w-bg-secondary-50', - textUtility: 'w-text-secondary-50', - cssVariable: '--w-color-secondary-50', - usage: 'Button backgrounds, highlighted fields background', - contrastText: 'secondary', - }, - }, primary: { DEFAULT: { hex: '#2E1F5E', - hsl: 'hsl(254, 50%, 25%)', + hsl: 'hsl(254 50% 25%)', bgUtility: 'w-bg-primary', textUtility: 'w-text-primary', cssVariable: '--w-color-primary', @@ -144,7 +99,7 @@ const colors = { }, 200: { hex: '#261A4E', - hsl: 'hsl(254, 50%, 20%)', + hsl: 'hsl(254 50% 20%)', bgUtility: 'w-bg-primary-200', textUtility: 'w-text-primary-200', cssVariable: '--w-color-primary-200', @@ -153,10 +108,57 @@ const colors = { contrastText: 'white', }, }, + secondary: { + 600: { + hex: '#004345', + hsl: 'hsl(182 100% 14%)', + bgUtility: 'w-bg-secondary-600', + textUtility: 'w-text-secondary-600', + cssVariable: '--w-color-secondary-600', + usage: 'Hover states for two-tone buttons', + contrastText: 'white', + }, + 400: { + hex: '#005B5E', + hsl: 'hsl(182 100% 18%)', + bgUtility: 'w-bg-secondary-400', + textUtility: 'w-text-secondary-400', + cssVariable: '--w-color-secondary-400', + usage: 'Two-tone buttons, hover states', + contrastText: 'white', + }, + DEFAULT: { + hex: '#007D7E', + hsl: 'hsl(180 100% 25%)', + bgUtility: 'w-bg-secondary', + textUtility: 'w-text-secondary', + cssVariable: '--w-color-secondary', + usage: 'Primary buttons, action links', + contrastText: 'white', + }, + 100: { + hex: '#00B0B1', + hsl: 'hsl(180 100% 35%)', + bgUtility: 'w-bg-secondary-100', + textUtility: 'w-text-secondary-100', + cssVariable: '--w-color-secondary-100', + usage: 'UI element highlights', + contrastText: 'white', + }, + 50: { + hex: '#F2FCFC', + hsl: 'hsl(180 63% 97%)', + bgUtility: 'w-bg-secondary-50', + textUtility: 'w-text-secondary-50', + cssVariable: '--w-color-secondary-50', + usage: 'Button backgrounds, highlighted fields background', + contrastText: 'secondary', + }, + }, info: { 100: { hex: '#1F7E9A', - hsl: 'hsl(194, 66%, 36%)', + hsl: 'hsl(194 66% 36%)', bgUtility: 'w-bg-info-100', textUtility: 'w-text-info-100', cssVariable: '--w-color-info-100', @@ -165,7 +167,7 @@ const colors = { }, 50: { hex: '#E2F5FC', - hsl: 'hsl(196, 81%, 94%)', + hsl: 'hsl(196 81% 94%)', bgUtility: 'w-bg-info-50', textUtility: 'w-text-info-50', cssVariable: '--w-color-info-50', @@ -176,7 +178,7 @@ const colors = { positive: { 100: { hex: '#1B8666', - hsl: 'hsl(162, 66%, 32%)', + hsl: 'hsl(162 66% 32%)', bgUtility: 'w-bg-positive-100', textUtility: 'w-text-positive-100', cssVariable: '--w-color-positive-100', @@ -185,7 +187,7 @@ const colors = { }, 50: { hex: '#E0FBF4', - hsl: 'hsl(164, 77%, 93%)', + hsl: 'hsl(164 77% 93%)', bgUtility: 'w-bg-positive-50', textUtility: 'w-text-positive-50', cssVariable: '--w-color-positive-50', @@ -196,7 +198,7 @@ const colors = { warning: { 100: { hex: '#FAA500', - hsl: 'hsl(40, 100%, 49%)', + hsl: 'hsl(40 100% 49%)', bgUtility: 'w-bg-warning-100', textUtility: 'w-text-warning-100', cssVariable: '--w-color-warning-100', @@ -205,7 +207,7 @@ const colors = { }, 50: { hex: '#FAECD5', - hsl: 'hsl(37, 79%, 91%)', + hsl: 'hsl(37 79% 91%)', bgUtility: 'w-bg-warning-50', textUtility: 'w-text-warning-50', cssVariable: '--w-color-warning-50', @@ -216,7 +218,7 @@ const colors = { critical: { 200: { hex: '#CD4444', - hsl: 'hsl(0, 58%, 54%)', + hsl: 'hsl(0 58% 54%)', bgUtility: 'w-bg-critical-200', textUtility: 'w-text-critical-200', cssVariable: '--w-color-critical-200', @@ -225,7 +227,7 @@ const colors = { }, 100: { hex: '#FD5765', - hsl: 'hsl(355, 98%, 67%)', + hsl: 'hsl(355 98% 67%)', bgUtility: 'w-bg-critical-100', textUtility: 'w-text-critical-100', cssVariable: '--w-color-critical-100', @@ -234,7 +236,7 @@ const colors = { }, 50: { hex: '#FDE9E9', - hsl: 'hsl(0, 83%, 95%)', + hsl: 'hsl(0 83% 95%)', bgUtility: 'w-bg-critical-50', textUtility: 'w-text-critical-50', cssVariable: '--w-color-critical-50', diff --git a/client/src/tokens/colors.stories.tsx b/client/src/tokens/colors.stories.tsx index dc4462ac8c..21902cbbb5 100644 --- a/client/src/tokens/colors.stories.tsx +++ b/client/src/tokens/colors.stories.tsx @@ -1,5 +1,6 @@ import React from 'react'; import colors, { Hues, Shade } from './colors'; +import { generateColorVariables } from './colorVariables'; const description = ` Wagtail’s typographic styles are made available as separate design tokens, but in most scenarios it’s better to use one of the predefined text styles. @@ -17,8 +18,8 @@ const getContrastGridLink = () => { const url = 'https://contrast-grid.eightshapes.com/'; const parameters = '?version=1.1.0&es-color-form__tile-size=compact&es-color-form__show-contrast=aaa&es-color-form__show-contrast=aa&es-color-form__show-contrast=aa18'; - const bg = []; - const fg = []; + const bg: string[] = []; + const fg: string[] = []; Object.values(colors).forEach((hues: Hues) => { Object.values(hues).forEach((shade: Shade) => { const color = `${shade.hex}, ${shade.textUtility.replace('w-text-', '')}`; @@ -41,17 +42,19 @@ const Palette = ({ color, hues }: PaletteProps) => (

{`${color} ${name === 'DEFAULT' ? '' : name}`}

{shade.textUtility} {shade.bgUtility} + {shade.cssVariable} + {shade.hsl} {shade.hex}
-

{shade.usage}

+

{shade.usage}

))} @@ -81,3 +84,103 @@ export const ColorPalette = () => ( ))} ); + +const variablesMap = Object.entries(generateColorVariables(colors)) + .map(([cssVar, val]) => `${cssVar}: ${val};`) + .join(''); +const secondaryHSL = colors.secondary.DEFAULT.hsl.match(/\d+/g) as string[]; +// Make sure this contains no empty lines, otherwise Sphinx docs will treat this as paragraphs. +const liveEditorCustomisations = `:root { + --w-color-primary: ${colors.primary.DEFAULT.hex}; + /* Any valid CSS format is supported. */ + --w-color-primary-200: ${colors.primary[200].hsl}; + /* Set each HSL component separately to change all hues at once. */ + --w-color-secondary-hue: ${secondaryHSL[0]}; + --w-color-secondary-saturation: ${secondaryHSL[1]}%; + --w-color-secondary-lightness: ${secondaryHSL[2]}%; +}`; +// Story using inline styles only so it can be copy-pasted into the Wagtail documentation for color customisations. +const demoStyles = ` + :root {${variablesMap}} + .wagtail-color-swatch { + border-collapse: separate; + border-spacing: 4px; + } + + .wagtail-color-swatch td:first-child { + height: 1.5rem; + width: 1.5rem; + border: 1px solid #333; + forced-color-adjust: none; + } +`; + +const warningComment = + ''; + +const colorCustomisationsDemo = ( +
+
+

+ Make sure to test any customisations against our{' '} + Contrast Grid. Try out your own + customisations with this interactive style editor: +

+ {/* Required styles are in a separate tag so they can’t be overridden, compressed to a single line for ease of copy-pasting. */} + +
+      {/* contentEditable style element so it can be edited directly in the browser. */}
+      
+    
+ + + + + + + + + {Object.values(colors).map((hues) => + Object.entries(hues) + // Show DEFAULT shades first, then in numerical order. + .sort(([nameA], [nameB]) => + nameA === 'DEFAULT' ? -1 : Number(nameB) - Number(nameA), + ) + .map(([name, shade]) => ( + + + + + )), + )} + +
+ VariableUsage
+ + {shade.cssVariable} + {shade.usage}
+
+); + +export const ColorCustomisations = () => ( + <> +

+ Use this story to test customising colors. The section below is also + copied in the Wagtail docs so implementers know which colors are + customisable in a given release. +

+
+ {colorCustomisationsDemo} + +); diff --git a/docs/advanced_topics/customisation/admin_templates.md b/docs/advanced_topics/customisation/admin_templates.md index 350655e1f6..3eac06375e 100644 --- a/docs/advanced_topics/customisation/admin_templates.md +++ b/docs/advanced_topics/customisation/admin_templates.md @@ -104,42 +104,17 @@ To customise the font families used in the admin user interface, inject a CSS fi The default Wagtail colours conform to the WCAG2.1 AA level colour contrast requirements. When customising the admin colours you should test the contrast using tools like [Axe](https://www.deque.com/axe/browser-extensions/). ``` -To customise the primary colour used in the admin user interface, inject a CSS file using the hook [](insert_global_admin_css) and override the variables within the `:root` selector: - -```css -:root { - --w-color-primary-hue: 25; -} -``` - -`w-color-primary` is an [HSL colour](https://en.wikipedia.org/wiki/HSL_and_HSV) composed of 3 CSS variables - `--w-color-primary-hue` (0-360 with no unit), `--w-color-primary-saturation` (a percentage), and `--w-color-primary-lightness` (also a percentage). Separating the colour into 3 allows us to calculate variations on the colour to use alongside the primary colour. If needed, you can also control those variations manually by setting `hue`, `saturation`, and `lightness` variables: - -```css -:root { - --w-color-primary-hue: 25; - --w-color-primary-saturation: 100%; - --w-color-primary-lightness: 25%; - --w-color-primary-darker-hue: 24; - --w-color-primary-darker-saturation: 100%; - --w-color-primary-darker-lightness: 20%; - --w-color-primary-dark-hue: 23; - --w-color-primary-dark-saturation: 100%; - --w-color-primary-dark-lightness: 15%; -} -``` - -If instead you intend to set all available colours within a given hue, you can use any valid css colours: - -```css -:root { - --w-color-primary: mediumaquamarine; - --w-color-primary-200: rebeccapurple; -} -``` - -Color customisation is available for the following colors: - +To customise the colours used in the admin user interface, inject a CSS file using the hook [](insert_global_admin_css) and set the desired variables within the `:root` selector. There are two ways to customisation options: either set each colour separately (for example `--w-color-primary: #2E1F5E;`); or separately set [HSL](https://en.wikipedia.org/wiki/HSL_and_HSV) (`--w-color-primary-hue`, `--w-color-primary-saturation`, `--w-color-primary-lightness`) variables so all shades are customised at once. For example, setting `--w-color-secondary-hue: 180;` will customise all of the secondary shades at once. +

Make sure to test any customisations against our Contrast Grid. Try out your own customisations with this interactive style editor:

VariableUsage
--w-color-blackShadows only
--w-color-grey-600Body copy, user content
--w-color-grey-400Help text, placeholders, meta text, neutral state indicators
--w-color-grey-200Dividers, button borders
--w-color-grey-150Field borders
--w-color-grey-100Dividers, panel borders
--w-color-grey-50Background for panels, row highlights
--w-color-whitePage backgrounds, Panels, Button text
--w-color-primaryWagtail branding, Panels, Headings, Buttons, Labels
--w-color-primary-200Accent for elements used in conjunction with primary colour in sidebar
--w-color-secondaryPrimary buttons, action links
--w-color-secondary-600Hover states for two-tone buttons
--w-color-secondary-400Two-tone buttons, hover states
--w-color-secondary-100UI element highlights
--w-color-secondary-50Button backgrounds, highlighted fields background
--w-color-info-100Background and icons for information messages
--w-color-info-50Background only, for information messages
--w-color-positive-100Positive states
--w-color-positive-50Background only, for positive states
--w-color-warning-100Background and icons for potentially dangerous states
--w-color-warning-50Background only, for potentially dangerous states
--w-color-critical-200Dangerous actions or states (over light background), errors
--w-color-critical-100Dangerous actions or states (over dark background)
--w-color-critical-50Background only, for dangerous states
## Specifying a site or page in the branding