Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Copy link
Member Author

Choose a reason for hiding this comment

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

note Now we can access the brand colours, we can avoid re-using the colour of the template background for the Service Navigation.

);
}

Expand Down
42 changes: 40 additions & 2 deletions packages/govuk-frontend/src/govuk/helpers/_colour.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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" {
Copy link
Member Author

Choose a reason for hiding this comment

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

note Maybe better as:

Suggested change
@if type-of($colour) == "color" {
@if type-of($colour) != "string" {

// stylelint-disable-next-line scss/function-quote-no-quoted-strings-inside
$colour: quote("#{$colour}");
$colour: "#{$colour}";
}

@if not map-has-key($govuk-colours, $colour) {
Expand All @@ -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;
}
Comment on lines +61 to +63
Copy link
Member Author

Choose a reason for hiding this comment

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

note Unless we have a long list of colours that don't fit the <name> -> <variant> structure, I think it's best to handle exceptions in the _govuk-brand-colour function.

If the list starts to grow, we could store them in $_govuk-brand-colours and test for @if type-of $colour-variants == "color" after accessing the value for the colour name.


$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
Expand Down
105 changes: 105 additions & 0 deletions packages/govuk-frontend/src/govuk/helpers/colour.unit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
90 changes: 90 additions & 0 deletions packages/govuk-frontend/src/govuk/settings/_colours-palette.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Member Author

Choose a reason for hiding this comment

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

note While the variable is private, this !default enable us to test the _govuk-brand-colour function easily. This is because of the @import "../settings/colours-palette"; at the top of helpers/_colours.scss.

Copy link
Member Author

Choose a reason for hiding this comment

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

An alternative could be to pass the map of colours to the _govuk-brand-colour function as a last argument: _govuk-brand-colour($colour, $variant, $colours), similarly to how breakpoint functions receive breakpoints.

If we rename the function govuk-colour-variant, we may use the concept for applied colours potentially, for example doing:

.govuk-link:hover {
	color: govuk-colour-variant(link, hover, $govuk-applied-colours)
}

:focus {
	govuk-colour-variant(focus, text, $govuk-applied-colours)
}

That looks like a separate piece of work though, and doesn't change the situation with testing: either through parameters or !default users need to pass a map of colours.