diff --git a/packages/govuk-frontend/src/govuk/components/service-navigation/_index.scss b/packages/govuk-frontend/src/govuk/components/service-navigation/_index.scss index 4a2c74a862..bd82cc0791 100644 --- a/packages/govuk-frontend/src/govuk/components/service-navigation/_index.scss +++ b/packages/govuk-frontend/src/govuk/components/service-navigation/_index.scss @@ -18,7 +18,7 @@ @include _govuk-rebrand( "background-color", $from: $govuk-service-navigation-background, - $to: $_govuk-rebrand-template-background-colour + $to: _govuk-brand-colour("blue", "tint-95") ); } diff --git a/packages/govuk-frontend/src/govuk/helpers/_colour.scss b/packages/govuk-frontend/src/govuk/helpers/_colour.scss index d5a2ceab69..f655bac2cb 100644 --- a/packages/govuk-frontend/src/govuk/helpers/_colour.scss +++ b/packages/govuk-frontend/src/govuk/helpers/_colour.scss @@ -27,9 +27,11 @@ "removed in the next major version."); } + // Sass parses unquoted colours as colours, so we need to turn them into + // strings before looking them up in the colour palette + // https://sass-lang.com/documentation/values/strings#unquoted @if type-of($colour) == "color" { - // stylelint-disable-next-line scss/function-quote-no-quoted-strings-inside - $colour: quote("#{$colour}"); + $colour: "#{$colour}"; } @if not map-has-key($govuk-colours, $colour) { @@ -39,6 +41,42 @@ @return map-get($govuk-colours, $colour); } +/// Get brand colour +/// +/// @param {String | Colour} $colour - Name of brand colour from the palette +/// (`$govuk-colour`) +/// @param {String } $variant - Name of the colour variant from the palette +/// @return {Colour} Representation of the variant of the brand colour +/// +/// @throw if `$variant` is not a variant from the colour +/// @access private +@function _govuk-brand-colour($colour, $variant: null) { + // Sass parses unquoted colours as colours, so we need to turn them into + // strings before looking them up in the colour palette + // https://sass-lang.com/documentation/values/strings#unquoted + @if type-of($colour) == "color" { + $colour: "#{$colour}"; + } + + @if $colour == "white" { + @return #fff; + } + + $colour-variants: map-get($govuk-brand-colours, $colour); + + @if not $colour-variants { + @error "Unknown colour `#{$colour}` (available colours: #{map-keys($govuk-brand-colours)}, white)"; + } + + $result: map-get($colour-variants, $variant); + + @if not $result { + @error "Unknown variant `#{$variant}` for colour `#{$colour}` (available variants: #{map-keys($colour-variants)})"; + } + + @return $result; +} + /// Get the colour for a government organisation /// /// @param {String} $organisation - Organisation name, lowercase, hyphenated diff --git a/packages/govuk-frontend/src/govuk/helpers/colour.unit.test.js b/packages/govuk-frontend/src/govuk/helpers/colour.unit.test.js index 11a13bdc2a..fbeca0e350 100644 --- a/packages/govuk-frontend/src/govuk/helpers/colour.unit.test.js +++ b/packages/govuk-frontend/src/govuk/helpers/colour.unit.test.js @@ -100,6 +100,111 @@ describe('@function govuk-colour', () => { }) }) +describe('@function _govuk-brand-colour', () => { + const sassBootstrap = ` + $govuk-brand-colours: ( + "blue": ( + "primary": #1d70b8, + "tint-25": #5694ca, + ), + "green": ( + "primary": #11875a, + "tint-25": #4da583, + ), + "red": ( + "primary": #ca3535, + "tint-25": #d76868, + ) + ); + + @import "helpers/colour"; + ` + + it('returns the variant of the colour if it exits', async () => { + const sass = ` + ${sassBootstrap} + + .foo { + color: _govuk-brand-colour('red', 'tint-25'); + } + ` + + await expect(compileSassString(sass, sassConfig)).resolves.toMatchObject({ + css: outdent` + .foo { + color: #d76868; + } + ` + }) + }) + + it('accepts unquoted strings', async () => { + const sass = ` + ${sassBootstrap} + + .foo { + color: _govuk-brand-colour(red, tint-25); + } + ` + + await expect(compileSassString(sass, sassConfig)).resolves.toMatchObject({ + css: outdent` + .foo { + color: #d76868; + } + ` + }) + }) + + it('returns #fff if the colour is white, regardless of the variant', async () => { + const sass = ` + ${sassBootstrap} + + .foo { + color: _govuk-brand-colour(white); + border-color: _govuk-brand-colour(white, any-variant); + } + ` + + await expect(compileSassString(sass, sassConfig)).resolves.toMatchObject({ + css: outdent` + .foo { + color: #fff; + border-color: #fff; + } + ` + }) + }) + + it('throws an error if the colour is not found', async () => { + const sass = ` + ${sassBootstrap} + + .foo { + color: _govuk-brand-colour('unknown-colour', 'tint-25'); + } + ` + + await expect(compileSassString(sass, sassConfig)).rejects.toThrow( + 'Unknown colour `unknown-colour` (available colours: blue, green, red, white)' + ) + }) + + it('throws an error if the variant is not found', async () => { + const sass = ` + ${sassBootstrap} + + .foo { + color: _govuk-brand-colour('red', 'unknown-variant'); + } + ` + + await expect(compileSassString(sass, sassConfig)).rejects.toThrow( + 'Unknown variant `unknown-variant` for colour `red` (available variants: primary, tint-25)' + ) + }) +}) + describe('@function govuk-organisation-colour', () => { const sassBootstrap = ` $govuk-new-organisation-colours: true; diff --git a/packages/govuk-frontend/src/govuk/settings/_colours-applied.scss b/packages/govuk-frontend/src/govuk/settings/_colours-applied.scss index 7b73024478..5e3940c327 100644 --- a/packages/govuk-frontend/src/govuk/settings/_colours-applied.scss +++ b/packages/govuk-frontend/src/govuk/settings/_colours-applied.scss @@ -184,10 +184,10 @@ $govuk-link-active-colour: govuk-colour("black") !default; /// /// @type Colour /// @access private -$_govuk-rebrand-template-background-colour: govuk-tint($govuk-brand-colour, 95%); +$_govuk-rebrand-template-background-colour: _govuk-brand-colour("blue", "tint-95"); /// Border colour for areas on a light-blue background /// /// @type Colour /// @access private -$_govuk-rebrand-border-colour-on-blue-tint-95: govuk-tint($govuk-brand-colour, 50%); +$_govuk-rebrand-border-colour-on-blue-tint-95: _govuk-brand-colour("blue", "tint-50"); diff --git a/packages/govuk-frontend/src/govuk/settings/_colours-palette.scss b/packages/govuk-frontend/src/govuk/settings/_colours-palette.scss index ea3833fd16..a183659ca5 100644 --- a/packages/govuk-frontend/src/govuk/settings/_colours-palette.scss +++ b/packages/govuk-frontend/src/govuk/settings/_colours-palette.scss @@ -33,3 +33,93 @@ $govuk-colours: ( "light-green": #85994b, "turquoise": #28a197 ) !default; + +/// Colour palette +/// +/// @type Map +/// +/// @prop $colour.$variant - Representation for the given $variant of $colour, where $colour is the +/// friendly name for the colour, and $variant the friendly name for the variant +/// (e.g. `"red": ("primary": #ff0000)`) +/// @access private + +$govuk-brand-colours: ( + "blue": ( + "primary": #1d70b8, + "tint-25": #5694ca, + "tint-50": #8eb8dc, + "tint-80": #d2e2f1, + "tint-95": #f4f8fb, + "shade-50": #0f385c + ), + "green": ( + "primary": #11875a, + "tint-25": #4da583, + "tint-50": #88c3ad, + "tint-80": #cfe7de, + "tint-95": #f3f9f7, + "shade-50": #09442d + ), + "teal": ( + "primary": #158187, + "tint-25": #50a1a5, + "tint-50": #8ac0c3, + "tint-80": #d0e6e7, + "tint-95": #f3f9f9, + "shade-50": #0b4144, + "accent": #00ffe0 + ), + "purple": ( + "primary": #54319f, + "tint-25": #7f65b7, + "tint-50": #aa98cf, + "tint-80": #ddd6ec, + "tint-95": #f6f5fa, + "shade-50": #2a1950 + ), + "magenta": ( + "primary": #ca357c, + "tint-25": #d7689d, + "tint-50": #e59abe, + "tint-80": #f4d7e5, + "tint-95": #fcf5f8, + "shade-50": #651b3e + ), + "red": ( + "primary": #ca3535, + "tint-25": #d76868, + "tint-50": #e59a9a, + "tint-80": #f4d7d7, + "tint-95": #fcf5f5, + "shade-50": #651b1b + ), + "orange": ( + "primary": #f47738, + "tint-25": #f7996a, + "tint-50": #fabb9c, + "tint-80": #fde4d7, + "tint-95": #fef8f5, + "shade-50": #7a3c1c + ), + "yellow": ( + "primary": #ffdd00, + "tint-25": #ffe640, + "tint-50": #ffee80, + "tint-80": #fff8cc, + "tint-95": #fffdf2, + "shade-50": #806f00 + ), + "brown": ( + "primary": #99704a, + "tint-25": #b39477, + "tint-50": #ccb8a5, + "tint-95": #faf8f6 + ), + "black": ( + "primary": #0b0c0c, + "tint-25": #484949, + "tint-50": #858686, + "tint-80": #cecece, + "tint-95": #f3f3f3 + ) +) !default;