ic-ui-kit icon indicating copy to clipboard operation
ic-ui-kit copied to clipboard

Expose action colour tokens as themeable token

Open DBD324 opened this issue 1 year ago โ€ข 0 comments

Summary

In same way as our theme colour tokens, we can expose the action colour tokens to allow greater theming functionality.

๐Ÿ’ฌ Description

To achieve a much greater theming capability, exposing the action token would allow a user to control larger parts of the interface including all buttons, input components and much more. Currently the only themable colour is the primary theme which only affects the navigation components.

Care must be taken in the approach as we would need to calculate many colours from the initial action colour token. Interaction state variants and interaction backgrounds would need to be automatically created from the specified action colour. This calculation may need to be conditionally specified based on the starting colour's initial HSL parameters.

For example, if our hover and pressed states are calculated by darkening the original colour, then if an already dark colour was specified as the initial action colour, then there would not be much contrast between default and hover states achieved through darkening.

๐Ÿ’ฐ User value

This will enhance our theming capability and allow interfaces to look and feel more customized from each other.

Implementation approach

The action colour will be used to create the hover, active, bg-hover and bg-active variants for use on interaction states. An additional token 'action contrast text' will be generated for use on bg variants to ensure good contrast.

Specifying action colour We need to either get the themed action colour specified as an HSL colour, or convert a specified Hex or RGB colour into HSL so that we can easily perform calculations on the individual values.

--ic-action-h
--ic-action-s
--ic-action-l

hsl(--ic-action-h, --ic-action-s, --ic-action-l)

Hover and active variants For the hover and active states, we need to perform the following operations to ensure that accessible pairings are achieved and the interaction states contrast with each other well enough without ever becoming full black or full white:

--ic-action
--ic-action-hover
--ic-action-active
If specified colour's luminosity is greater than 75%,
Then set the hover variant to be 10% darker and the active variant to be 15% darker, 
Else if luminosity is greater than 50%, 
Then set the hover variant to be 10% lighter and the active variant to be 15% lighter,
Else if luminosity is greater than 25%,
Then set the hover variant to be 10% darker and the active variant to be 15% darker,
Else,
Then set the hover variant to be 10% lighter and the active variant to be 15% lighter.

We should create a variable for the percentage change amounts so that they can be easily adjusted as part of a theme object at a later date.

--ic-hover-variant-adjustment: 10%
--ic-active-variant-adjustment: 15%

Action Backgrounds The action backgrounds are used for background fills on interactive components. For the background active and hover states, we simply set the luminosity value to a specified number, whilst retaining the specified colour's hue and saturation. They should be calculated as follows:

Background-hover variants should be set to L=95. background-active variants should be set to L=90.

--ic-action-bg-hover: hsl(--ic-action-h, --ic-action-s, 95%)
--ic-action-bg-active: hsl(--ic-action-h, --ic-action-s, 90%)

We may want to set a variable for the luminosity values so that these can be controlled easily via a theming library later on.

--ic-action-bg-hover-luminance: 95%
--ic-action-bg-active-luminance: 90%

Contrast text We can generate a new token for contrast text that is used when displaying coloured text on an action background, such as within secondary and tertiary buttons.

This can be calculated as follows: --ic-action-contrast-text: hsl(--ic-action-h, --ic-action-s, 20%)

Again, it might be good to specify the text luminance value as a variable for easy theming later down the line.

Light and dark variants The system uses light and dark action colour variants for when components are used on different coloured backgrounds. This avoids the action colour clashing with different backgrounds. They are calculated to be subtly tinted towards the specified action colour so that they follow the theme. The following colours should be calculated:

--ic-action-dark: hsl(--ic-action-h, 5%, 5%)
--ic-action-dark-hover: hsl(--ic-action-h, 5%, 20%)
--ic-action-dark-active: hsl(--ic-action-h, 5%, 30%)
--ic-action-bg-dark-hover: hsla(--ic-action-h, 5%, 20%, 0.1)
--ic-action-bg-dark-active: hsla(--ic-action-h, 5%, 30%, 0.2)

--ic-action-light: hsl(--ic-action-h, 5%, 100%)
--ic-action-light-hover: hsl(--ic-action-h, 5%, 80%)
--ic-action-light-active: hsl(--ic-action-h, 5%, 70%)
--ic-action-bg-light-hover: hsla(--ic-action-h, 5%, 80%, 0.1)
--ic-action-bg-light-active: hsla(--ic-action-h, 5%, 70%, 0.2)

Technical approach In order to calculate the colours, they are two suggested technical approaches:

  1. Pure CSS
  2. Use of CSS pre-processor such as SCSS/SASS.

In approach 1, using pure CSS we can use a sign function to create a multiplier that is either 1 or -1 in the required luminance intervals and therefore conditionally add or subtract the hover or active amount.

See the following PoC that achieves this by setting a switch threshold and calculating the sign of the difference in each interval.

https://jsfiddle.net/mpadyqte/3/

In approach 2, the calculation is much easier as we can rely on the SASS fucntions such as lighten and darken and the use of the conditional @if operator.

See the following PoC for that technical approach.

https://jsfiddle.net/6odt3k81/

๐Ÿ“ Acceptance Criteria

If relevant, describe in full detail the different interactions and edge cases that the component or patterns needs to fulfil.

Given that a custom action colour is specified as a theme When set Then the following other colour tokens should be automatically calculated:

  • --ic-action-default-hover: If action colour is light, darken by 10%, else if action colour is dark, lighten by 10%.

  • --ic-action-default-pressed: If action colour is light, darken by 15%, else if action colour is dark, lighten by 20%.

  • --ic-action-bg-default-hover: Set luminance value to 95%.

  • --ic-action-bg-default-pressed: Set luminance value to 90%.

  • --ic-action-contrast-text: Set luminance value to 20%.

  • --ic-action-dark: hsl(--ic-action-color-h, 5%, 5%)

  • --ic-action-dark-hover: hsl(--ic-action-color-h, 5%, 20%)

  • --ic-action-dark-pressed: hsl(--ic-action-color-h, 5%, 30%)

  • --ic-action-bg-dark-hover: hsla(--ic-action-color-h, 5%, 20%, 0.1)

  • --ic-action-bg-dark-pressed: hsla(--ic-action-color-h, 5%, 30%, 0.1)

  • --ic-action-light: hsl(--ic-action-color-h, 5%, 100%)

  • --ic-action-light-hover: hsl(--ic-action-color-h, 5%, 80%)

  • --ic-action-light-pressed: hsl(--ic-action-color-h, 5%, 70%)

  • --ic-action-bg-light-hover: hsla(--ic-action-color-h, 5%, 80%, 0.1)

  • --ic-action-bg-light-pressed: hsla(--ic-action-color-h, 5%, 70%, 0.1)

โœ Designs

If there's a Figma design file (or other mock-up), include it here.

##โ€ฏ๐Ÿงพ Guidance If there's written guidance or documentation, include a link to it here.

Additional info

Tell us anything else useful to help us understand your suggestion.

DBD324 avatar Feb 12 '24 14:02 DBD324