From ce74927305e6fb10cbc29569df55f1e1434acc78 Mon Sep 17 00:00:00 2001 From: m7kvqbe1 <48086589+m7kvqbe1@users.noreply.github.com> Date: Wed, 24 Jun 2026 20:43:27 +0100 Subject: [PATCH 01/11] feat(DesignTokens): Add dark colour set and CSS variable engine --- .../src/__tests__/selectors.test.tsx | 21 ++- packages/design-tokens/src/getters.ts | 56 ++++++- packages/design-tokens/src/index.ts | 4 +- packages/design-tokens/src/selectors.ts | 2 + .../design-tokens/src/tokens/dark/colors.json | 145 +++++++++++------- 5 files changed, 165 insertions(+), 63 deletions(-) diff --git a/packages/design-tokens/src/__tests__/selectors.test.tsx b/packages/design-tokens/src/__tests__/selectors.test.tsx index a065ec5476..473910e07c 100644 --- a/packages/design-tokens/src/__tests__/selectors.test.tsx +++ b/packages/design-tokens/src/__tests__/selectors.test.tsx @@ -25,6 +25,7 @@ const { fontSize, shadow, zIndex, + colorValue, } = selectors let wrapper: RenderResult @@ -211,15 +212,31 @@ describe('color', () => { color: ${color('neutral', '100')}; ` - it('should set styles correctly', () => { + it('resolves to a themeable CSS variable with the light value as fallback', () => { wrapper = render() expect(wrapper.getByTestId('test-element')).toHaveStyleRule( 'color', - '#e2e9ee' + 'var(--color-neutral-100, #e2e9ee)' + ) + }) + }) +}) + +describe('colorValue', () => { + describe('when the group or shade is invalid', () => { + it('throws a friendly error', () => { + expect(() => colorValue('invalid' as ColorGroup, '400')).toThrow( + 'Invalid color token' ) }) }) + + describe('when the group and shade are valid', () => { + it('returns the concrete light value with no theme', () => { + expect(colorValue('neutral', '100')).toBe('#e2e9ee') + }) + }) }) describe('fontSize', () => { diff --git a/packages/design-tokens/src/getters.ts b/packages/design-tokens/src/getters.ts index 2765f37e13..91ed11b655 100644 --- a/packages/design-tokens/src/getters.ts +++ b/packages/design-tokens/src/getters.ts @@ -102,7 +102,19 @@ export function getAnimation(index: AnimationTiming, theme?: Theme): string { throw new Error(`Invalid animation token for index: '${index}'`) } -export function getColor( +export function colorVariableName( + group: ColorGroup, + weight: ColorShade +): string { + return `--color-${group}-${weight}` +} + +/** + * Resolve a colour token to its concrete hex value for the given theme + * (falling back to the default light theme). Use this where the value + * must be a parseable colour, e.g. when passed to `polished` helpers. + */ +export function getColorValue( group: ColorGroup, weight: ColorShade, theme?: Theme @@ -119,6 +131,48 @@ export function getColor( ) } +/** + * Resolve a colour token. When an explicit theme is provided the concrete + * hex value is returned (preserving threaded-theme behaviour). Otherwise a + * CSS custom property reference is returned so the colour reacts to the + * theme injected by `GlobalStyleProvider`, with the light value as a static + * fallback for unprovided/SSR contexts. + */ +export function getColor( + group: ColorGroup, + weight: ColorShade, + theme?: Theme +): string { + if (theme?.colorsTokens) { + return getColorValue(group, weight, theme) + } + + const fallback = getColorValue(group, weight) + + return `var(${colorVariableName(group, weight)}, ${fallback})` +} + +/** + * Build the `--color-*` custom property declarations for a theme, for + * injection by `GlobalStyleProvider`. + */ +export function getColorVariables(theme?: Theme): Record { + const { color } = getTheme(theme).colorsTokens as unknown as { + color: Record> + } + + const entries = Object.entries(color).flatMap(([group, shades]) => + Object.entries(shades) + .filter(([, token]) => isTokenValid(token?.value)) + .map( + ([weight, token]) => + [`--color-${group}-${weight}`, token.value as string] as const + ) + ) + + return Object.fromEntries(entries) +} + export function getTypography(size: TypographySize, theme?: Theme): string { const value = get( getTheme(theme).typographyTokens, diff --git a/packages/design-tokens/src/index.ts b/packages/design-tokens/src/index.ts index 97aaa5cf3e..22ba872e62 100644 --- a/packages/design-tokens/src/index.ts +++ b/packages/design-tokens/src/index.ts @@ -3,7 +3,7 @@ import selectors from './selectors' export * from './types' export * from './flat' -export { getTheme } from './getters' +export { getTheme, getColorVariables, colorVariableName } from './getters' export { selectors } @@ -14,6 +14,7 @@ const { animation, breakpoint, color, + colorValue, fontSize, mediaQuery, mq, @@ -26,6 +27,7 @@ export { animation, breakpoint, color, + colorValue, fontSize, mediaQuery, mq, diff --git a/packages/design-tokens/src/selectors.ts b/packages/design-tokens/src/selectors.ts index 9ce602a37b..9852758dfd 100644 --- a/packages/design-tokens/src/selectors.ts +++ b/packages/design-tokens/src/selectors.ts @@ -3,6 +3,7 @@ import { getBreakpoint, getMediaQuery, getColor, + getColorValue, getShadow, getSpacing, getTypography, @@ -15,6 +16,7 @@ export default { breakpoint: getBreakpoint, animation: getAnimation, color: getColor, + colorValue: getColorValue, fontSize: getTypography, shadow: getShadow, spacing: getSpacing, diff --git a/packages/design-tokens/src/tokens/dark/colors.json b/packages/design-tokens/src/tokens/dark/colors.json index 0bacd800a9..cd884fd879 100644 --- a/packages/design-tokens/src/tokens/dark/colors.json +++ b/packages/design-tokens/src/tokens/dark/colors.json @@ -2,51 +2,64 @@ "color": { "neutral": { "black": { - "value": "#0a141b" + "value": "#f8fafc", + "description": "Foreground (inverted in dark mode)" }, "white": { - "value": "#ffffff" + "value": "#1c2d39", + "description": "Raised surfaces, cards, panels (inverted in dark mode)" }, "000": { - "value": "#f8fafc" + "value": "#0a141b", + "description": "Page background, Disabled button" }, "100": { - "value": "#000000" + "value": "#16242f", + "description": "Borders and dividers, Inactive tab" }, "200": { - "value": "#b8c7d2" + "value": "#2a3f4d", + "description": "Input borders, Disabled button border, Toggle off disabled" }, "300": { - "value": "#748999" + "value": "#3e5667", + "description": "Breadcrumb divider, Toggle off" }, "400": { - "value": "#3e5667" + "value": "#8da0ad", + "description": "Body text, Input labels, Disabled button label" }, "500": { - "value": "#233745" + "value": "#a7b6c1", + "description": "Sidebar user menu background" }, "600": { - "value": "#1c2d39" + "value": "#cdd8e0", + "description": "Headings, Input text" }, "700": { - "value": "#12202b" + "value": "#dde5ea", + "description": "Sidebar" }, "800": { - "value": "#0c1720" + "value": "#eef2f5" }, "900": { - "value": "#0a141b" + "value": "#f8fafc" } }, "action": { "000": { - "value": "#ecf8ff" + "value": "#102536", + "description": "Checked/selected radio box background" }, "100": { - "value": "#ddf4ff" + "value": "#133048", + "description": "Secondary button, Hovered primary button border, Phase banner" }, "200": { - "value": "#b7dff7" + "value": "#b7dff7", + "description": "Hovered secondary and tertiary button, Toggle on disabled" }, "300": { "value": "#85c6f2" @@ -55,27 +68,32 @@ "value": "#58aae9" }, "500": { - "value": "#3a8fdd" + "value": "#3a8fdd", + "description": "Info alert elements, Focus state, Checked/selected radio, Toggle on" }, "600": { - "value": "#2a77c7" + "value": "#2a77c7", + "description": "Primary button, Secondary and tertiary button border" }, "700": { - "value": "#2661a7" + "value": "#2661a7", + "description": "Input interactions" }, "800": { - "value": "#274776" + "value": "#274776", + "description": "Primary button border, Hovered primary button" }, "900": { - "value": "#253b5b" + "value": "#b7dff7", + "description": "Secondary and tertiary button label" } }, "success": { "000": { - "value": "#f4ffef" + "value": "#102516" }, "100": { - "value": "#e5ffd9" + "value": "#15331f" }, "200": { "value": "#c6f3b5" @@ -87,7 +105,8 @@ "value": "#8fd57f" }, "500": { - "value": "#76c767" + "value": "#76c767", + "description": "Success icon" }, "600": { "value": "#60b255" @@ -99,15 +118,16 @@ "value": "#3b6f33" }, "900": { - "value": "#3b612c" + "value": "#abe39b", + "description": "Success text" } }, "warning": { "000": { - "value": "#ffffee" + "value": "#2a2208" }, "100": { - "value": "#fffddc" + "value": "#33290a" }, "200": { "value": "#fefbb8" @@ -119,7 +139,8 @@ "value": "#f5db54" }, "500": { - "value": "#e8c242" + "value": "#e8c242", + "description": "Warning icon" }, "600": { "value": "#cf9328" @@ -131,15 +152,17 @@ "value": "#8c4f17" }, "900": { - "value": "#693a12" + "value": "#faed7e", + "description": "Warning text" } }, "danger": { "000": { - "value": "#fff3f4" + "value": "#2a1011" }, "100": { - "value": "#feeaec" + "value": "#331417", + "description": "Hovered danger button border" }, "200": { "value": "#fed1d1" @@ -151,27 +174,31 @@ "value": "#fc7c75" }, "500": { - "value": "#f45249" + "value": "#f45249", + "description": "Danger icon" }, "600": { "value": "#ec4138" }, "700": { - "value": "#d53229" + "value": "#d53229", + "description": "Danger button" }, "800": { - "value": "#B22820" + "value": "#B22820", + "description": "Hovered danger button, Input error border" }, "900": { - "value": "#841c1b" + "value": "#fea9a9", + "description": "Danger text" } }, "supa": { "000": { - "value": "#e8f2ff" + "value": "#14182e" }, "100": { - "value": "#deebff" + "value": "#181d3a" }, "200": { "value": "#bbd5fe" @@ -195,15 +222,15 @@ "value": "#3b3985" }, "900": { - "value": "#343160" + "value": "#99b7f9" } }, "supb": { "000": { - "value": "#f9f3ff" + "value": "#1c142e" }, "100": { - "value": "#f2e9ff" + "value": "#22193a" }, "200": { "value": "#e5d3fd" @@ -227,15 +254,15 @@ "value": "#4b358f" }, "900": { - "value": "#3b2d6e" + "value": "#d0b5f9" } }, "supc": { "000": { - "value": "#fff3ff" + "value": "#2a142b" }, "100": { - "value": "#fee9ff" + "value": "#331937" }, "200": { "value": "#fcd3fd" @@ -259,47 +286,47 @@ "value": "#8c358f" }, "900": { - "value": "#6c2d6e" + "value": "#f7b5f9" } }, "supd": { "000": { - "value": "#fff3ff" + "value": "#2e141d" }, "100": { - "value": "#fee9ff" + "value": "#3a1926" }, "200": { - "value": "#fcd3fd" + "value": "#ffcce5" }, "300": { - "value": "#f7b5f9" + "value": "#ffa2b5" }, "400": { - "value": "#ee89f1" + "value": "#f77f97" }, "500": { - "value": "#e46fe8" + "value": "#f35d7b" }, "600": { - "value": "#cc4fd0" + "value": "#d84b67" }, "700": { - "value": "#b43fb8" + "value": "#c43854" }, "800": { - "value": "#8c358f" + "value": "#972b41" }, "900": { - "value": "#6c2d6e" + "value": "#ffa2b5" } }, "supe": { "000": { - "value": "#fff8f3" + "value": "#2e1c10" }, "100": { - "value": "#fef2ea" + "value": "#3a2415" }, "200": { "value": "#fee2d1" @@ -323,15 +350,15 @@ "value": "#9d4712" }, "900": { - "value": "#853a0c" + "value": "#fecaa9" } }, "supf": { "000": { - "value": "#eefff2" + "value": "#0e2016" }, "100": { - "value": "#dfffe9" + "value": "#13301f" }, "200": { "value": "#bff4cf" @@ -355,7 +382,7 @@ "value": "#245c40" }, "900": { - "value": "#1f4a35" + "value": "#8fe2ab" } } } From 80723b9895afa1d6192af5719be5ef5c3eb7ee6f Mon Sep 17 00:00:00 2001 From: m7kvqbe1 <48086589+m7kvqbe1@users.noreply.github.com> Date: Wed, 24 Jun 2026 20:43:38 +0100 Subject: [PATCH 02/11] feat(GlobalStyle): Inject theme CSS variables and add Storybook toggle --- .../.storybook/preview.js | 46 ++++++++++++++++++- .../src/styled-components/GlobalStyle.tsx | 32 ++++++++++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/packages/react-component-library/.storybook/preview.js b/packages/react-component-library/.storybook/preview.js index a2ab7c2d86..a2655515d6 100644 --- a/packages/react-component-library/.storybook/preview.js +++ b/packages/react-component-library/.storybook/preview.js @@ -1,12 +1,53 @@ import { DocsPage } from '@storybook/addon-docs/blocks' import isChromatic from 'chromatic' import React from 'react' +import { lightTheme, darkTheme, color } from '@royalnavy/design-tokens' import '@royalnavy/fonts' import 'iframe-resizer/js/iframeResizer.contentWindow' import 'url-search-params-polyfill' import { GlobalStyleProvider } from '../src/styled-components/GlobalStyle' +const THEMES = { + light: lightTheme, + dark: darkTheme, +} + +function getThemeFromContext(context) { + return THEMES[context.globals.theme] ?? lightTheme +} + +const ThemedCanvas = ({ theme, children }) => ( + +
+ {children} +
+
+) + +export const globalTypes = { + theme: { + name: 'Theme', + description: 'Design System token set', + defaultValue: 'light', + toolbar: { + icon: 'paintbrush', + items: [ + { value: 'light', title: 'Light' }, + { value: 'dark', title: 'Dark' }, + ], + dynamicTitle: true, + }, + }, +} + export const parameters = { jsx: { // Filter out callback props injected by the Actions addon @@ -54,14 +95,15 @@ export const parameters = { export const decorators = [ // https://github.com/storybookjs/storybook/issues/15223#issuecomment-1092837912 - (Story) => { + (Story, context) => { + const theme = getThemeFromContext(context) const queryParams = new URLSearchParams(window.location.search) if (queryParams.get('viewMode') === 'docs') { return Story() } - return {Story()} + return {Story()} }, ] diff --git a/packages/react-component-library/src/styled-components/GlobalStyle.tsx b/packages/react-component-library/src/styled-components/GlobalStyle.tsx index 53cfe14133..ce840ee70c 100644 --- a/packages/react-component-library/src/styled-components/GlobalStyle.tsx +++ b/packages/react-component-library/src/styled-components/GlobalStyle.tsx @@ -1,7 +1,13 @@ import React, { createContext, useMemo } from 'react' import { createGlobalStyle, ThemeProvider } from 'styled-components' import { Normalize } from 'styled-normalize' -import { lightTheme, color, fontSize } from '@royalnavy/design-tokens' +import { + lightTheme, + color, + fontSize, + getColorVariables, + Theme, +} from '@royalnavy/design-tokens' export interface GlobalStyleContextDefaults { theme?: Record @@ -12,6 +18,23 @@ export interface GlobalStyleProviderProps { theme?: Record } +/** + * Expose the active theme's colour tokens as CSS custom properties on the + * root, so every `color(...)` reference (which resolves to a `var(--color-*)`) + * reacts to the theme — including content rendered through portals that sits + * outside the provider's DOM subtree. + */ +const ThemeVariables = createGlobalStyle<{ + $variables: Record +}>` + :root { + ${({ $variables }) => + Object.entries($variables) + .map(([name, value]) => `${name}: ${value};`) + .join('\n')} + } +` + /** * Globally setting `border-box` */ @@ -50,6 +73,7 @@ const Fonts = createGlobalStyle` html { font-family: "lato", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: ${fontSize('m')}; + color: ${color('neutral', '600')}; } h1, @@ -113,10 +137,16 @@ export const GlobalStyleProvider = ({ [theme] ) + const colorVariables = useMemo( + () => getColorVariables(theme as Theme), + [theme] + ) + return ( + {children} From 7ff763cf0e9bd29edd5e06ee02f670ec1fc8249d Mon Sep 17 00:00:00 2001 From: m7kvqbe1 <48086589+m7kvqbe1@users.noreply.github.com> Date: Wed, 24 Jun 2026 20:43:58 +0100 Subject: [PATCH 03/11] fix(Components): Theme dark-mode stragglers and adapt colour tests --- .../Autocomplete/Autocomplete.test.tsx | 9 +++--- .../src/components/Checkbox/Checkbox.test.tsx | 6 ++-- .../partials/StyledLoadingOverlay.tsx | 13 +++++++- .../DatePicker/__tests__/DatePicker.test.tsx | 17 +++++----- .../DatePickerWhenTodayPropIsSet.test.tsx | 17 +++++----- .../DatePicker/partials/StyledDayPicker.tsx | 31 ++++++++++++++++--- .../components/Modal/partials/StyledModal.tsx | 5 ++- .../src/components/Radio/Radio.test.tsx | 14 +++------ .../src/components/RangeSlider/constants.ts | 16 +++++++--- .../RangeSlider/partials/StyledHandle.tsx | 4 +-- .../src/components/Select/Select.test.tsx | 6 ++-- .../Masthead/partials/StyledBanner.tsx | 4 +-- .../Masthead/partials/StyledOption.tsx | 5 +-- .../SearchBar/partials/StyledButton.tsx | 4 +-- 14 files changed, 95 insertions(+), 56 deletions(-) diff --git a/packages/react-component-library/src/components/Autocomplete/Autocomplete.test.tsx b/packages/react-component-library/src/components/Autocomplete/Autocomplete.test.tsx index 213def3acf..a18ba03656 100644 --- a/packages/react-component-library/src/components/Autocomplete/Autocomplete.test.tsx +++ b/packages/react-component-library/src/components/Autocomplete/Autocomplete.test.tsx @@ -1,4 +1,4 @@ -import { ColorDanger800, TypographyS } from '@royalnavy/design-tokens' +import { color, TypographyS } from '@royalnavy/design-tokens' import React from 'react' import { render, RenderResult, waitFor } from '@testing-library/react' @@ -8,9 +8,10 @@ import { COMPONENT_SIZE } from '../Forms' import { BORDER_WIDTH } from '../../styled-components' import { Autocomplete, AutocompleteOption } from '.' -const ERROR_BOX_SHADOW = `0 0 0 ${ - BORDER_WIDTH[COMPONENT_SIZE.FORMS] -} ${ColorDanger800.toUpperCase()}` +const ERROR_BOX_SHADOW = `0 0 0 ${BORDER_WIDTH[COMPONENT_SIZE.FORMS]} ${color( + 'danger', + '800' +)}` describe('Autocomplete', () => { let onBlurSpy: jest.Mock diff --git a/packages/react-component-library/src/components/Checkbox/Checkbox.test.tsx b/packages/react-component-library/src/components/Checkbox/Checkbox.test.tsx index c7d328f00a..35050fd1ec 100644 --- a/packages/react-component-library/src/components/Checkbox/Checkbox.test.tsx +++ b/packages/react-component-library/src/components/Checkbox/Checkbox.test.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react' import 'jest-styled-components' -import { ColorNeutral200 } from '@royalnavy/design-tokens' +import { color } from '@royalnavy/design-tokens' import { render, RenderResult } from '@testing-library/react' import userEvent from '@testing-library/user-event' @@ -106,7 +106,7 @@ describe('Checkbox', () => { it('should render a container', () => { expect(checkbox.getByTestId('checkbox')).toHaveStyleRule( 'border', - `1px solid ${ColorNeutral200}` + `1px solid ${color('neutral', '200')}` ) expect(checkbox.getByTestId('checkbox')).toHaveStyleRule( 'border-radius', @@ -292,7 +292,7 @@ describe('Checkbox', () => { it('should not render a container', () => { expect(checkbox.getByTestId('checkbox')).not.toHaveStyleRule( 'border', - `1px solid ${ColorNeutral200}` + `1px solid ${color('neutral', '200')}` ) expect(checkbox.getByTestId('checkbox')).not.toHaveStyleRule( 'border-radius', diff --git a/packages/react-component-library/src/components/DataGrid/partials/StyledLoadingOverlay.tsx b/packages/react-component-library/src/components/DataGrid/partials/StyledLoadingOverlay.tsx index cf9e560f7c..5cb132d7dd 100644 --- a/packages/react-component-library/src/components/DataGrid/partials/StyledLoadingOverlay.tsx +++ b/packages/react-component-library/src/components/DataGrid/partials/StyledLoadingOverlay.tsx @@ -1,4 +1,5 @@ import styled from 'styled-components' +import { color } from '@royalnavy/design-tokens' export const StyledLoadingOverlay = styled.div` position: absolute; @@ -6,7 +7,6 @@ export const StyledLoadingOverlay = styled.div` left: 0; right: 0; bottom: 0; - background-color: rgba(255, 255, 255, 0.5); display: flex; justify-content: center; align-items: center; @@ -14,6 +14,17 @@ export const StyledLoadingOverlay = styled.div` border-radius: 4px; overflow: hidden; + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: ${color('neutral', 'white')}; + opacity: 0.5; + } + > div { position: absolute; top: 50%; diff --git a/packages/react-component-library/src/components/DatePicker/__tests__/DatePicker.test.tsx b/packages/react-component-library/src/components/DatePicker/__tests__/DatePicker.test.tsx index bda8000930..e7520ebde1 100644 --- a/packages/react-component-library/src/components/DatePicker/__tests__/DatePicker.test.tsx +++ b/packages/react-component-library/src/components/DatePicker/__tests__/DatePicker.test.tsx @@ -1,6 +1,6 @@ import { format, isValid } from 'date-fns' import React, { useState } from 'react' -import { ColorDanger800, ColorWarning800 } from '@royalnavy/design-tokens' +import { color } from '@royalnavy/design-tokens' import { act, fireEvent, @@ -17,9 +17,10 @@ import { DATE_VALIDITY } from '../constants' const NOW = '2019-12-05T11:00:00.000Z' -const ERROR_BOX_SHADOW = `0 0 0 ${ - BORDER_WIDTH[COMPONENT_SIZE.FORMS] -} ${ColorDanger800.toUpperCase()}` +const ERROR_BOX_SHADOW = `0 0 0 ${BORDER_WIDTH[COMPONENT_SIZE.FORMS]} ${color( + 'danger', + '800' +)}` const PREVIOUS_MONTH_BUTTON_LABEL = 'Go to previous month' @@ -162,11 +163,11 @@ describe('DatePicker', () => { }) }) - it('colours the current date', () => { + it('marks the current date as today', () => { return waitFor(() => { - expect(wrapper.getByRole('gridcell', { name: '5' })).toHaveStyle({ - color: ColorWarning800, - }) + expect(wrapper.getByRole('gridcell', { name: '5' })).toHaveClass( + 'rdp-day_today' + ) }) }) diff --git a/packages/react-component-library/src/components/DatePicker/__tests__/DatePickerWhenTodayPropIsSet.test.tsx b/packages/react-component-library/src/components/DatePicker/__tests__/DatePickerWhenTodayPropIsSet.test.tsx index 6af7a2c303..3772b71ad7 100644 --- a/packages/react-component-library/src/components/DatePicker/__tests__/DatePickerWhenTodayPropIsSet.test.tsx +++ b/packages/react-component-library/src/components/DatePicker/__tests__/DatePickerWhenTodayPropIsSet.test.tsx @@ -1,5 +1,4 @@ import React from 'react' -import { ColorWarning800 } from '@royalnavy/design-tokens' import { act, render, RenderResult } from '@testing-library/react' import { DatePicker, DatePickerOnChangeData } from '../index' @@ -26,15 +25,15 @@ describe('when today prop is set', () => { onChange.mockReset() }) - it('colours the override date', () => { - expect(wrapper.getByRole('gridcell', { name: '15' })).toHaveStyle({ - color: ColorWarning800, - }) + it('marks the override date as today', () => { + expect(wrapper.getByRole('gridcell', { name: '15' })).toHaveClass( + 'rdp-day_today' + ) }) - it('does not colour the actual current date', () => { - expect(wrapper.getByRole('gridcell', { name: '5' })).not.toHaveStyle({ - color: ColorWarning800, - }) + it('does not mark the actual current date as today', () => { + expect(wrapper.getByRole('gridcell', { name: '5' })).not.toHaveClass( + 'rdp-day_today' + ) }) }) diff --git a/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx b/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx index e3970c4178..3342edd9f5 100644 --- a/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx +++ b/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx @@ -48,23 +48,44 @@ export const StyledDayPicker = styled(DayPicker)` position: absolute; top: ${spacing('6')}; width: 38px; - background-position: center; - background-size: 18px; - background-repeat: no-repeat; svg { display: none; } + + &::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: ${color('neutral', '500')}; + -webkit-mask-position: center; + mask-position: center; + -webkit-mask-size: 18px; + mask-size: 18px; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + } } .rdp-nav_button_previous { left: ${spacing('6')}; - background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='16px' height='16px' viewBox='0 0 16 16' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3EIcons/Navigation/chevron-left%3C/title%3E%3Cdefs%3E%3Cpolygon id='path-1' points='10.2755556 4.9422222 9.33333334 3.99999998 5.33333332 8 9.33333334 12 10.2755556 11.0577778 7.21777777 8'%3E%3C/polygon%3E%3C/defs%3E%3Cg id='Icons/Navigation/chevron-left' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cmask id='mask-2' fill='white'%3E%3Cuse xlink:href='%23path-1'%3E%3C/use%3E%3C/mask%3E%3Cuse id='Icons/Navigation/ic_chevron_left_18px' fill='%23233745' fill-rule='nonzero' xlink:href='%23path-1'%3E%3C/use%3E%3C/g%3E%3C/svg%3E"); + + &::after { + -webkit-mask-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='16px' height='16px' viewBox='0 0 16 16' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3EIcons/Navigation/chevron-left%3C/title%3E%3Cdefs%3E%3Cpolygon id='path-1' points='10.2755556 4.9422222 9.33333334 3.99999998 5.33333332 8 9.33333334 12 10.2755556 11.0577778 7.21777777 8'%3E%3C/polygon%3E%3C/defs%3E%3Cg id='Icons/Navigation/chevron-left' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cmask id='mask-2' fill='white'%3E%3Cuse xlink:href='%23path-1'%3E%3C/use%3E%3C/mask%3E%3Cuse id='Icons/Navigation/ic_chevron_left_18px' fill='%23233745' fill-rule='nonzero' xlink:href='%23path-1'%3E%3C/use%3E%3C/g%3E%3C/svg%3E"); + mask-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='16px' height='16px' viewBox='0 0 16 16' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3EIcons/Navigation/chevron-left%3C/title%3E%3Cdefs%3E%3Cpolygon id='path-1' points='10.2755556 4.9422222 9.33333334 3.99999998 5.33333332 8 9.33333334 12 10.2755556 11.0577778 7.21777777 8'%3E%3C/polygon%3E%3C/defs%3E%3Cg id='Icons/Navigation/chevron-left' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cmask id='mask-2' fill='white'%3E%3Cuse xlink:href='%23path-1'%3E%3C/use%3E%3C/mask%3E%3Cuse id='Icons/Navigation/ic_chevron_left_18px' fill='%23233745' fill-rule='nonzero' xlink:href='%23path-1'%3E%3C/use%3E%3C/g%3E%3C/svg%3E"); + } } .rdp-nav_button_next { right: ${spacing('6')}; - background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='16px' height='16px' viewBox='0 0 16 16' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3EIcons/Navigation/chevron-right%3C/title%3E%3Cdefs%3E%3Cpolygon id='path-1' points='6.66666666 3.99999998 5.72444443 4.9422222 8.78222223 8 5.72444443 11.0577778 6.66666666 12 10.6666667 8'%3E%3C/polygon%3E%3C/defs%3E%3Cg id='Icons/Navigation/chevron-right' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cmask id='mask-2' fill='white'%3E%3Cuse xlink:href='%23path-1'%3E%3C/use%3E%3C/mask%3E%3Cuse id='Icons/Navigation/ic_chevron_right_18px' fill='%23233745' fill-rule='nonzero' xlink:href='%23path-1'%3E%3C/use%3E%3C/g%3E%3C/svg%3E"); + + &::after { + -webkit-mask-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='16px' height='16px' viewBox='0 0 16 16' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3EIcons/Navigation/chevron-right%3C/title%3E%3Cdefs%3E%3Cpolygon id='path-1' points='6.66666666 3.99999998 5.72444443 4.9422222 8.78222223 8 5.72444443 11.0577778 6.66666666 12 10.6666667 8'%3E%3C/polygon%3E%3C/defs%3E%3Cg id='Icons/Navigation/chevron-right' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cmask id='mask-2' fill='white'%3E%3Cuse xlink:href='%23path-1'%3E%3C/use%3E%3C/mask%3E%3Cuse id='Icons/Navigation/ic_chevron_right_18px' fill='%23233745' fill-rule='nonzero' xlink:href='%23path-1'%3E%3C/use%3E%3C/g%3E%3C/svg%3E"); + mask-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='16px' height='16px' viewBox='0 0 16 16' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3EIcons/Navigation/chevron-right%3C/title%3E%3Cdefs%3E%3Cpolygon id='path-1' points='6.66666666 3.99999998 5.72444443 4.9422222 8.78222223 8 5.72444443 11.0577778 6.66666666 12 10.6666667 8'%3E%3C/polygon%3E%3C/defs%3E%3Cg id='Icons/Navigation/chevron-right' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cmask id='mask-2' fill='white'%3E%3Cuse xlink:href='%23path-1'%3E%3C/use%3E%3C/mask%3E%3Cuse id='Icons/Navigation/ic_chevron_right_18px' fill='%23233745' fill-rule='nonzero' xlink:href='%23path-1'%3E%3C/use%3E%3C/g%3E%3C/svg%3E"); + } } .rdp-caption_label { diff --git a/packages/react-component-library/src/components/Modal/partials/StyledModal.tsx b/packages/react-component-library/src/components/Modal/partials/StyledModal.tsx index 6e44b3071d..365e8f0d49 100644 --- a/packages/react-component-library/src/components/Modal/partials/StyledModal.tsx +++ b/packages/react-component-library/src/components/Modal/partials/StyledModal.tsx @@ -1,4 +1,4 @@ -import { zIndex } from '@royalnavy/design-tokens' +import { color, zIndex } from '@royalnavy/design-tokens' import styled from 'styled-components' export const StyledModal = styled.dialog` @@ -8,5 +8,8 @@ export const StyledModal = styled.dialog` bottom: 0; left: 0; background: rgba(0, 0, 0, 0.2); + /* Native defaults its text colour to CanvasText; set a themed + colour so content without an explicit colour stays legible in dark mode. */ + color: ${color('neutral', '600')}; z-index: ${zIndex('modal', 1)}; ` diff --git a/packages/react-component-library/src/components/Radio/Radio.test.tsx b/packages/react-component-library/src/components/Radio/Radio.test.tsx index 8630cefbb1..baba1e37b4 100644 --- a/packages/react-component-library/src/components/Radio/Radio.test.tsx +++ b/packages/react-component-library/src/components/Radio/Radio.test.tsx @@ -1,11 +1,7 @@ import React, { useState } from 'react' import 'jest-styled-components' -import { - ColorNeutral200, - ColorAction000, - ColorNeutralWhite, -} from '@royalnavy/design-tokens' +import { color } from '@royalnavy/design-tokens' import { render, RenderResult } from '@testing-library/react' import userEvent from '@testing-library/user-event' @@ -51,7 +47,7 @@ describe('Radio', () => { it('should render a container', () => { expect(radio.getByTestId('radio')).toHaveStyleRule( 'border', - `1px solid ${ColorNeutral200}` + `1px solid ${color('neutral', '200')}` ) expect(radio.getByTestId('radio')).toHaveStyleRule( 'border-radius', @@ -60,7 +56,7 @@ describe('Radio', () => { expect(radio.getByTestId('radio')).toHaveStyleRule( 'background', - ColorNeutralWhite + color('neutral', 'white') ) }) @@ -101,7 +97,7 @@ describe('Radio', () => { it('styles the container as active', () => { expect(radio.getByTestId('radio')).toHaveStyleRule( 'background', - ColorAction000 + color('action', '000') ) }) }) @@ -213,7 +209,7 @@ describe('Radio', () => { it('should not render a container', () => { expect(radio.getByTestId('radio')).not.toHaveStyleRule( 'border', - `1px solid ${ColorNeutral200}` + `1px solid ${color('neutral', '200')}` ) expect(radio.getByTestId('radio')).not.toHaveStyleRule( 'border-radius', diff --git a/packages/react-component-library/src/components/RangeSlider/constants.ts b/packages/react-component-library/src/components/RangeSlider/constants.ts index 96e33efa7c..802d130435 100644 --- a/packages/react-component-library/src/components/RangeSlider/constants.ts +++ b/packages/react-component-library/src/components/RangeSlider/constants.ts @@ -1,9 +1,17 @@ -import { color } from '@royalnavy/design-tokens' +import { color, colorValue } from '@royalnavy/design-tokens' export const RANGE_SLIDER_BG_COLOR = color('neutral', '200') export const RANGE_SLIDER_HANDLE_COLOR = color('action', '500') export const RANGE_SLIDER_TRACK_COLOR = color('action', '200') -export const RANGE_SLIDER_TRACK_BELOW_FIRST_THRESHOLD = color('action', '500') -export const RANGE_SLIDER_TRACK_BETWEEN_THRESHOLDS = color('warning', '500') -export const RANGE_SLIDER_TRACK_ABOVE_THRESHOLDS = color('danger', '500') +// Threshold colours are passed through polished's `setLightness`, which +// needs a concrete colour rather than a CSS custom property reference. +export const RANGE_SLIDER_TRACK_BELOW_FIRST_THRESHOLD = colorValue( + 'action', + '500' +) +export const RANGE_SLIDER_TRACK_BETWEEN_THRESHOLDS = colorValue( + 'warning', + '500' +) +export const RANGE_SLIDER_TRACK_ABOVE_THRESHOLDS = colorValue('danger', '500') diff --git a/packages/react-component-library/src/components/RangeSlider/partials/StyledHandle.tsx b/packages/react-component-library/src/components/RangeSlider/partials/StyledHandle.tsx index 9ad1f363c5..5abc35fbcc 100644 --- a/packages/react-component-library/src/components/RangeSlider/partials/StyledHandle.tsx +++ b/packages/react-component-library/src/components/RangeSlider/partials/StyledHandle.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color } from '@royalnavy/design-tokens' +import { colorValue } from '@royalnavy/design-tokens' import { transparentize } from 'polished' import { RANGE_SLIDER_HANDLE_COLOR } from '../constants' @@ -20,7 +20,7 @@ export const StyledHandle = styled.div` &:focus { box-shadow: 1px 1px 2px 0px rgba(000, 000, 000, 0.25), - 0px 0px 0px 5px ${transparentize(0.5, color('action', '200'))}; + 0px 0px 0px 5px ${transparentize(0.5, colorValue('action', '200'))}; outline: none; } ` diff --git a/packages/react-component-library/src/components/Select/Select.test.tsx b/packages/react-component-library/src/components/Select/Select.test.tsx index 8b8310d2e4..a523e2d763 100644 --- a/packages/react-component-library/src/components/Select/Select.test.tsx +++ b/packages/react-component-library/src/components/Select/Select.test.tsx @@ -2,7 +2,7 @@ import React from 'react' import { render, RenderResult, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { color, ColorDanger800 } from '@royalnavy/design-tokens' +import { color } from '@royalnavy/design-tokens' import { IconAgriculture, IconAnchor, @@ -470,9 +470,7 @@ describe('Select', () => { it('displays in an error state', () => { expect(wrapper.getByTestId('select-outer-wrapper')).toHaveStyleRule( 'box-shadow', - `0 0 0 ${ - BORDER_WIDTH[COMPONENT_SIZE.FORMS] - } ${ColorDanger800.toUpperCase()}` + `0 0 0 ${BORDER_WIDTH[COMPONENT_SIZE.FORMS]} ${color('danger', '800')}` ) }) }) diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledBanner.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledBanner.tsx index 8e6ca60359..981408394a 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledBanner.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledBanner.tsx @@ -1,5 +1,5 @@ import { rgba } from 'polished' -import { color, spacing } from '@royalnavy/design-tokens' +import { color, colorValue, spacing } from '@royalnavy/design-tokens' import styled from 'styled-components' import { MAIN_HEIGHT } from './constants' @@ -25,7 +25,7 @@ export const StyledBanner = styled.div<{ $withInlineNav?: boolean }>` } &:focus { - box-shadow: 0 0 0 0.2rem ${rgba(color('action', '700'), 0.5)}; + box-shadow: 0 0 0 0.2rem ${rgba(colorValue('action', '700'), 0.5)}; } } ` diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledOption.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledOption.tsx index bb8ee69379..11b806dd85 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledOption.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledOption.tsx @@ -1,4 +1,5 @@ -import { color } from '@royalnavy/design-tokens' +import { color, colorValue } from '@royalnavy/design-tokens' +import { rgba } from 'polished' import styled from 'styled-components' import { MAIN_HEIGHT } from './constants' @@ -22,7 +23,7 @@ export const StyledOption = styled.button` cursor: pointer; &:focus { - box-shadow: 0 0 0 0.2rem rgba(${color('action', '700')}, 0.5); + box-shadow: 0 0 0 0.2rem ${rgba(colorValue('action', '700'), 0.5)}; } > svg { diff --git a/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledButton.tsx b/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledButton.tsx index 2024962c0d..9499d775ac 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledButton.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledButton.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color, spacing } from '@royalnavy/design-tokens' +import { color, colorValue, spacing } from '@royalnavy/design-tokens' import { rgba } from 'polished' export const StyledButton = styled.button` @@ -20,7 +20,7 @@ export const StyledButton = styled.button` } &:focus { - box-shadow: 0 0 0 0.2rem ${rgba(color('action', '700'), 0.5)}; + box-shadow: 0 0 0 0.2rem ${rgba(colorValue('action', '700'), 0.5)}; outline: 0; } ` From 6f0ec0b6dc116cedc12db1b9c7352e97514e355c Mon Sep 17 00:00:00 2001 From: m7kvqbe1 <48086589+m7kvqbe1@users.noreply.github.com> Date: Wed, 24 Jun 2026 20:58:24 +0100 Subject: [PATCH 04/11] feat(Storybook): Theme docs pages with the active token set --- .../.storybook/preview.js | 49 ++++++++++++++++--- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/packages/react-component-library/.storybook/preview.js b/packages/react-component-library/.storybook/preview.js index a2655515d6..220b50e87a 100644 --- a/packages/react-component-library/.storybook/preview.js +++ b/packages/react-component-library/.storybook/preview.js @@ -1,4 +1,5 @@ -import { DocsPage } from '@storybook/addon-docs/blocks' +import { DocsContainer, DocsPage } from '@storybook/addon-docs/blocks' +import { themes } from 'storybook/theming' import isChromatic from 'chromatic' import React from 'react' import { lightTheme, darkTheme, color } from '@royalnavy/design-tokens' @@ -13,8 +14,31 @@ const THEMES = { dark: darkTheme, } +function getThemeMode(context) { + const globals = + context?.store?.userGlobals?.globals ?? + context?.store?.globals?.get?.() ?? + context?.globals ?? + {} + + return globals.theme === 'dark' ? 'dark' : 'light' +} + function getThemeFromContext(context) { - return THEMES[context.globals.theme] ?? lightTheme + return THEMES[getThemeMode(context)] ?? lightTheme +} + +const ThemedDocsContainer = ({ context, children }) => { + const mode = getThemeMode(context) + + return ( + + {children} + + ) } const ThemedCanvas = ({ theme, children }) => ( @@ -62,11 +86,8 @@ export const parameters = { // there type: typeof WeakSet === undefined ? 'code' : 'auto', }, - page: () => ( - - - - ), + container: ThemedDocsContainer, + page: () => , }, options: { storySort: { @@ -100,7 +121,19 @@ export const decorators = [ const queryParams = new URLSearchParams(window.location.search) if (queryParams.get('viewMode') === 'docs') { - return Story() + // In docs, the surrounding GlobalStyleProvider is supplied by the + // themed docs container; only give each embedded preview a themed + // background so it doesn't sit on Storybook's default light canvas. + return ( +
+ {Story()} +
+ ) } return {Story()} From c381bff78f00b0ba1613aa9bb7922fda9bf3cd85 Mon Sep 17 00:00:00 2001 From: m7kvqbe1 <48086589+m7kvqbe1@users.noreply.github.com> Date: Wed, 24 Jun 2026 21:32:35 +0100 Subject: [PATCH 05/11] fix(DarkTheme): Improve dark-mode contrast across components --- .../design-tokens/src/tokens/dark/colors.json | 38 +++++++-------- .../Avatar/partials/StyledAvatar.tsx | 8 ++-- .../components/Badge/partials/StyledBadge.tsx | 48 +++++++++++-------- .../src/components/Button/partials/styles.ts | 16 +++---- .../Checkbox/partials/StyledCheckmark.tsx | 6 +-- .../partials/StyledClassificationBar.tsx | 4 +- ...kerWhenNavigateMonthYearIsEnabled.test.tsx | 6 +-- .../partials/StyledCalendarNavigation.tsx | 6 +-- .../DatePicker/partials/StyledDayPicker.tsx | 4 +- .../Switch/partials/StyledSwitchOption.tsx | 6 +-- .../Tooltip/partials/StyledContent.tsx | 6 +-- .../partials/StyledUserItemWrapper.tsx | 4 +- .../SearchBar/partials/StyledButton.tsx | 2 +- .../SearchBar/partials/StyledForm.tsx | 8 ++-- .../Sidebar/partials/StyledHandle.tsx | 4 +- .../Sidebar/partials/StyledHead.tsx | 4 +- .../Sidebar/partials/StyledHeadIcon.tsx | 4 +- .../Sidebar/partials/StyledNav.tsx | 4 +- .../Sidebar/partials/StyledNavItem.tsx | 4 +- .../Sidebar/partials/StyledNavItemIcon.tsx | 6 +-- .../Sidebar/partials/StyledNavItemText.tsx | 6 +-- .../partials/StyledNotificationDot.tsx | 6 +-- .../partials/StyledNotificationsLabel.tsx | 4 +- .../StyledNotificationsSheetButton.tsx | 6 +-- .../Sidebar/partials/StyledSheetList.tsx | 4 +- .../Sidebar/partials/StyledSidebar.tsx | 6 +-- .../partials/StyledSubNavSheetButton.tsx | 8 ++-- .../Sidebar/partials/StyledUser.tsx | 4 +- .../Sidebar/partials/StyledUserText.tsx | 10 ++-- .../FloatingBox/partials/StyledContent.tsx | 10 ++-- 30 files changed, 129 insertions(+), 123 deletions(-) diff --git a/packages/design-tokens/src/tokens/dark/colors.json b/packages/design-tokens/src/tokens/dark/colors.json index cd884fd879..8d53aac529 100644 --- a/packages/design-tokens/src/tokens/dark/colors.json +++ b/packages/design-tokens/src/tokens/dark/colors.json @@ -2,11 +2,11 @@ "color": { "neutral": { "black": { - "value": "#f8fafc", + "value": "#f6f8fa", "description": "Foreground (inverted in dark mode)" }, "white": { - "value": "#1c2d39", + "value": "#1f3140", "description": "Raised surfaces, cards, panels (inverted in dark mode)" }, "000": { @@ -14,58 +14,58 @@ "description": "Page background, Disabled button" }, "100": { - "value": "#16242f", + "value": "#243542", "description": "Borders and dividers, Inactive tab" }, "200": { - "value": "#2a3f4d", + "value": "#3a4f5e", "description": "Input borders, Disabled button border, Toggle off disabled" }, "300": { - "value": "#3e5667", + "value": "#6a8093", "description": "Breadcrumb divider, Toggle off" }, "400": { - "value": "#8da0ad", + "value": "#b7c5d0", "description": "Body text, Input labels, Disabled button label" }, "500": { - "value": "#a7b6c1", + "value": "#cbd6dd", "description": "Sidebar user menu background" }, "600": { - "value": "#cdd8e0", + "value": "#e2e9ee", "description": "Headings, Input text" }, "700": { - "value": "#dde5ea", + "value": "#edf1f4", "description": "Sidebar" }, "800": { - "value": "#eef2f5" + "value": "#f4f7f8" }, "900": { - "value": "#f8fafc" + "value": "#f9fbfc" } }, "action": { "000": { - "value": "#102536", + "value": "#0e2233", "description": "Checked/selected radio box background" }, "100": { - "value": "#133048", + "value": "#16395a", "description": "Secondary button, Hovered primary button border, Phase banner" }, "200": { - "value": "#b7dff7", + "value": "#235d8c", "description": "Hovered secondary and tertiary button, Toggle on disabled" }, "300": { - "value": "#85c6f2" + "value": "#3f86c9" }, "400": { - "value": "#58aae9" + "value": "#6fb2ec" }, "500": { "value": "#3a8fdd", @@ -76,15 +76,15 @@ "description": "Primary button, Secondary and tertiary button border" }, "700": { - "value": "#2661a7", + "value": "#7cbcef", "description": "Input interactions" }, "800": { - "value": "#274776", + "value": "#9fcdf3", "description": "Primary button border, Hovered primary button" }, "900": { - "value": "#b7dff7", + "value": "#bfe0fa", "description": "Secondary and tertiary button label" } }, diff --git a/packages/react-component-library/src/components/Avatar/partials/StyledAvatar.tsx b/packages/react-component-library/src/components/Avatar/partials/StyledAvatar.tsx index 68a39989af..8b6fd4280d 100644 --- a/packages/react-component-library/src/components/Avatar/partials/StyledAvatar.tsx +++ b/packages/react-component-library/src/components/Avatar/partials/StyledAvatar.tsx @@ -1,5 +1,5 @@ import styled, { css } from 'styled-components' -import { color } from '@royalnavy/design-tokens' +import { color, colorValue } from '@royalnavy/design-tokens' interface StyledAvatarProps { $dark?: boolean @@ -20,14 +20,14 @@ export const StyledAvatar = styled.span` &:hover { background: ${color('action', '500')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; cursor: pointer; } ${({ $dark }) => $dark && css` - background: ${color('neutral', '400')}; - color: ${color('neutral', 'white')}; + background: ${colorValue('neutral', '400')}; + color: ${colorValue('neutral', 'white')}; `} ` diff --git a/packages/react-component-library/src/components/Badge/partials/StyledBadge.tsx b/packages/react-component-library/src/components/Badge/partials/StyledBadge.tsx index 0858507bcc..baa318b53d 100644 --- a/packages/react-component-library/src/components/Badge/partials/StyledBadge.tsx +++ b/packages/react-component-library/src/components/Badge/partials/StyledBadge.tsx @@ -1,4 +1,10 @@ -import { color, fontSize, shadow, spacing } from '@royalnavy/design-tokens' +import { + color, + fontSize, + shadow, + spacing, + colorValue, +} from '@royalnavy/design-tokens' import styled, { css } from 'styled-components' import { @@ -80,8 +86,8 @@ const StyledBadgeColorVariantMap = { text-shadow: ${shadow('0')}; `, [BADGE_COLOR_VARIANT.SOLID]: css` - background-color: ${color('neutral', '500')}; - color: ${color('neutral', 'white')}; + background-color: ${colorValue('neutral', '500')}; + color: ${colorValue('neutral', 'white')}; text-shadow: ${shadow('1')}; `, }, @@ -93,26 +99,26 @@ const StyledBadgeColorVariantMap = { `, [BADGE_COLOR_VARIANT.SOLID]: css` background-color: ${color('action', '600')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; text-shadow: ${shadow('1')}; `, }, [BADGE_COLOR.SUCCESS]: { [BADGE_COLOR_VARIANT.FADED]: css` background-color: ${color('success', '100')}; - color: ${color('success', '800')}; + color: ${color('success', '900')}; text-shadow: ${shadow('0')}; `, [BADGE_COLOR_VARIANT.SOLID]: css` background-color: ${color('success', '800')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; text-shadow: ${shadow('1')}; `, }, [BADGE_COLOR.WARNING]: { [BADGE_COLOR_VARIANT.FADED]: css` background-color: ${color('warning', '000')}; - color: ${color('warning', '800')}; + color: ${color('warning', '900')}; text-shadow: ${shadow('0')}; `, [BADGE_COLOR_VARIANT.SOLID]: css` @@ -124,84 +130,84 @@ const StyledBadgeColorVariantMap = { [BADGE_COLOR.DANGER]: { [BADGE_COLOR_VARIANT.FADED]: css` background-color: ${color('danger', '100')}; - color: ${color('danger', '800')}; + color: ${color('danger', '900')}; text-shadow: ${shadow('0')}; `, [BADGE_COLOR_VARIANT.SOLID]: css` background-color: ${color('danger', '700')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; text-shadow: ${shadow('1')}; `, }, [BADGE_COLOR.SUPA]: { [BADGE_COLOR_VARIANT.FADED]: css` background-color: ${color('supa', '000')}; - color: ${color('supa', '600')}; + color: ${color('supa', '900')}; text-shadow: ${shadow('0')}; `, [BADGE_COLOR_VARIANT.SOLID]: css` background-color: ${color('supa', '600')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; text-shadow: ${shadow('1')}; `, }, [BADGE_COLOR.SUPB]: { [BADGE_COLOR_VARIANT.FADED]: css` background-color: ${color('supb', '100')}; - color: ${color('supb', '600')}; + color: ${color('supb', '900')}; text-shadow: ${shadow('0')}; `, [BADGE_COLOR_VARIANT.SOLID]: css` background-color: ${color('supb', '600')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; text-shadow: ${shadow('1')}; `, }, [BADGE_COLOR.SUPC]: { [BADGE_COLOR_VARIANT.FADED]: css` background-color: ${color('supc', '100')}; - color: ${color('supc', '800')}; + color: ${color('supc', '900')}; text-shadow: ${shadow('0')}; `, [BADGE_COLOR_VARIANT.SOLID]: css` background-color: ${color('supc', '700')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; text-shadow: ${shadow('1')}; `, }, [BADGE_COLOR.SUPD]: { [BADGE_COLOR_VARIANT.FADED]: css` background-color: ${color('supd', '100')}; - color: ${color('supd', '800')}; + color: ${color('supd', '900')}; text-shadow: ${shadow('0')}; `, [BADGE_COLOR_VARIANT.SOLID]: css` background-color: ${color('supd', '700')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; text-shadow: ${shadow('1')}; `, }, [BADGE_COLOR.SUPE]: { [BADGE_COLOR_VARIANT.FADED]: css` background-color: ${color('supe', '200')}; - color: ${color('supe', '800')}; + color: ${color('supe', '900')}; text-shadow: ${shadow('0')}; `, [BADGE_COLOR_VARIANT.SOLID]: css` background-color: ${color('supe', '800')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; text-shadow: ${shadow('1')}; `, }, [BADGE_COLOR.SUPF]: { [BADGE_COLOR_VARIANT.FADED]: css` background-color: ${color('supf', '200')}; - color: ${color('supf', '800')}; + color: ${color('supf', '900')}; text-shadow: ${shadow('1')}; `, [BADGE_COLOR_VARIANT.SOLID]: css` background-color: ${color('supf', '700')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; text-shadow: ${shadow('1')}; `, }, diff --git a/packages/react-component-library/src/components/Button/partials/styles.ts b/packages/react-component-library/src/components/Button/partials/styles.ts index 44422a4b9f..ccdac484d9 100644 --- a/packages/react-component-library/src/components/Button/partials/styles.ts +++ b/packages/react-component-library/src/components/Button/partials/styles.ts @@ -1,4 +1,4 @@ -import { color, fontSize } from '@royalnavy/design-tokens' +import { color, fontSize, colorValue } from '@royalnavy/design-tokens' import { BUTTON_VARIANT } from '../constants' import { COMPONENT_SIZE } from '../../Forms' @@ -38,12 +38,12 @@ export const STYLES_MAP: { [key: string]: ButtonStyles } = { [BUTTON_VARIANT.PRIMARY]: { default: { backgroundColor: color('action', '600'), - color: color('neutral', 'white'), + color: colorValue('neutral', 'white'), boxShadow: `0 0 0 1px ${color('action', '600')}`, textDecoration: 'none', }, hover: { - backgroundColor: color('action', '700'), + backgroundColor: colorValue('action', '700'), boxShadow: `0 0 0 2px ${color('action', '900')}`, }, focus: { @@ -51,7 +51,7 @@ export const STYLES_MAP: { [key: string]: ButtonStyles } = { boxShadow: `0 0 0 3px ${color('action', '900')}`, }, active: { - backgroundColor: color('action', '900'), + backgroundColor: colorValue('action', '900'), boxShadow: `0 0 0 3px ${color('action', '900')}`, }, disabled: defaultDisabledStyle, @@ -80,7 +80,7 @@ export const STYLES_MAP: { [key: string]: ButtonStyles } = { [BUTTON_VARIANT.TERTIARY]: { default: { backgroundColor: color('neutral', 'white'), - color: color('action', '600'), + color: color('action', '700'), boxShadow: `0 0 0 1px ${color('action', '600')}`, textDecoration: 'none', }, @@ -102,7 +102,7 @@ export const STYLES_MAP: { [key: string]: ButtonStyles } = { }, [BUTTON_VARIANT.DANGER]: { default: { - color: color('neutral', 'white'), + color: colorValue('neutral', 'white'), backgroundColor: color('danger', '700'), textDecoration: 'none', boxShadow: `0 0 0 1px ${color('danger', '700')}`, @@ -116,7 +116,7 @@ export const STYLES_MAP: { [key: string]: ButtonStyles } = { boxShadow: `0 0 0 3px ${color('danger', '900')}`, }, active: { - backgroundColor: color('danger', '900'), + backgroundColor: colorValue('danger', '900'), boxShadow: `0 0 0 3px ${color('danger', '900')}`, }, @@ -125,7 +125,7 @@ export const STYLES_MAP: { [key: string]: ButtonStyles } = { [BUTTON_VARIANT.NO_CONTAINER]: { default: { backgroundColor: 'transparent', - color: color('action', '600'), + color: color('action', '700'), textDecoration: 'none', boxShadow: '0', }, diff --git a/packages/react-component-library/src/components/Checkbox/partials/StyledCheckmark.tsx b/packages/react-component-library/src/components/Checkbox/partials/StyledCheckmark.tsx index 3fffa24a31..6c12a04a35 100644 --- a/packages/react-component-library/src/components/Checkbox/partials/StyledCheckmark.tsx +++ b/packages/react-component-library/src/components/Checkbox/partials/StyledCheckmark.tsx @@ -1,6 +1,6 @@ import { position } from 'polished' import styled, { css } from 'styled-components' -import { color } from '@royalnavy/design-tokens' +import { color, colorValue } from '@royalnavy/design-tokens' import { StyledCheckbox } from './StyledCheckbox' import { CheckmarkProps } from '../../CheckboxRadioBase/CheckboxRadioBaseProps' @@ -32,7 +32,7 @@ export const StyledCheckmark = styled.span` content: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIiAvPgogICAgPHBhdGggdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMywgNCkiIGQ9Ik04LjgyMiAwYzEuMDUtLjAyNyAxLjU3NCAxLjMwNC44MjcgMi4wOEw0LjI5OCA3Ljc0YS44My44MyAwIDAgMS0xLjIwNyAwTC4zNzYgNC44NTVDLS43NTIgMy43MTguOTE0IDEuOTU2IDEuOTkgMy4xNDlsMS41MDggMS41OTVjLjEwNS4xMS4yODguMTEuNDA3IDBsNC4xMy00LjM3QTEuMSAxLjEgMCAwIDEgOC44MjMgMHoiCiAgICAgICAgICBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz4KPC9zdmc+Cg==); display: none; border-radius: 2px; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; position: absolute; top: 50%; left: 50%; @@ -67,7 +67,7 @@ export const StyledCheckmark = styled.span` top: 50%; left: 50%; transform: translate(-50%, -50%); - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; } } diff --git a/packages/react-component-library/src/components/ClassificationBar/partials/StyledClassificationBar.tsx b/packages/react-component-library/src/components/ClassificationBar/partials/StyledClassificationBar.tsx index 4e5ab16f6d..22a50bd288 100644 --- a/packages/react-component-library/src/components/ClassificationBar/partials/StyledClassificationBar.tsx +++ b/packages/react-component-library/src/components/ClassificationBar/partials/StyledClassificationBar.tsx @@ -1,4 +1,4 @@ -import { color, fontSize, spacing } from '@royalnavy/design-tokens' +import { color, fontSize, spacing, colorValue } from '@royalnavy/design-tokens' import styled, { css } from 'styled-components' const getColorStyles = (isSecret?: boolean, inSidebar?: boolean) => { @@ -11,7 +11,7 @@ const getColorStyles = (isSecret?: boolean, inSidebar?: boolean) => { if (inSidebar) { return css` - background-color: ${color('neutral', '400')}; + background-color: ${colorValue('neutral', '400')}; color: ${color('neutral', '000')}; ` } diff --git a/packages/react-component-library/src/components/DatePicker/__tests__/DatePickerWhenNavigateMonthYearIsEnabled.test.tsx b/packages/react-component-library/src/components/DatePicker/__tests__/DatePickerWhenNavigateMonthYearIsEnabled.test.tsx index c2dc46ab8a..3de16622df 100644 --- a/packages/react-component-library/src/components/DatePicker/__tests__/DatePickerWhenNavigateMonthYearIsEnabled.test.tsx +++ b/packages/react-component-library/src/components/DatePicker/__tests__/DatePickerWhenNavigateMonthYearIsEnabled.test.tsx @@ -1,4 +1,4 @@ -import { color } from '@royalnavy/design-tokens' +import { color, colorValue } from '@royalnavy/design-tokens' import { render, screen } from '@testing-library/react' import React from 'react' import userEvent from '@testing-library/user-event' @@ -115,7 +115,7 @@ it('applies correct styles to current and selected month', async () => { 'background-color', color('action', '700') ) - expect(selectedMonth).toHaveStyleRule('color', color('neutral', 'white')) + expect(selectedMonth).toHaveStyleRule('color', colorValue('neutral', 'white')) }) it('applies correct styles to current and selected year', async () => { @@ -144,7 +144,7 @@ it('applies correct styles to current and selected year', async () => { 'background-color', color('action', '700') ) - expect(selectedYear).toHaveStyleRule('color', color('neutral', 'white')) + expect(selectedYear).toHaveStyleRule('color', colorValue('neutral', 'white')) }) it('displays the initial month and allows navigation', async () => { diff --git a/packages/react-component-library/src/components/DatePicker/partials/StyledCalendarNavigation.tsx b/packages/react-component-library/src/components/DatePicker/partials/StyledCalendarNavigation.tsx index d88e95516f..3a5a08f6f6 100644 --- a/packages/react-component-library/src/components/DatePicker/partials/StyledCalendarNavigation.tsx +++ b/packages/react-component-library/src/components/DatePicker/partials/StyledCalendarNavigation.tsx @@ -1,5 +1,5 @@ import styled, { css } from 'styled-components' -import { color, fontSize, spacing } from '@royalnavy/design-tokens' +import { color, fontSize, spacing, colorValue } from '@royalnavy/design-tokens' import { Button } from '../../Button' @@ -105,11 +105,11 @@ export const StyledCalendarTiles = styled.button<{ $isSelected && css` background-color: ${color('action', '700')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; &:hover { background-color: ${color('action', '700')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; } `} ` diff --git a/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx b/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx index 3342edd9f5..723dabffec 100644 --- a/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx +++ b/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx @@ -1,5 +1,5 @@ import { DayPicker } from 'react-day-picker' -import { color, spacing, fontSize } from '@royalnavy/design-tokens' +import { color, spacing, fontSize, colorValue } from '@royalnavy/design-tokens' import styled from 'styled-components' import { BUTTON_VARIANT, getButtonStyles } from '../../Button' @@ -149,7 +149,7 @@ export const StyledDayPicker = styled(DayPicker)` &.rdp-day_start, &.rdp-day_end { - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; background-color: ${color('action', '700')}; } diff --git a/packages/react-component-library/src/components/Switch/partials/StyledSwitchOption.tsx b/packages/react-component-library/src/components/Switch/partials/StyledSwitchOption.tsx index 8cc599d70f..646a52164c 100644 --- a/packages/react-component-library/src/components/Switch/partials/StyledSwitchOption.tsx +++ b/packages/react-component-library/src/components/Switch/partials/StyledSwitchOption.tsx @@ -1,5 +1,5 @@ import styled, { css } from 'styled-components' -import { color, spacing } from '@royalnavy/design-tokens' +import { color, colorValue, spacing } from '@royalnavy/design-tokens' import { SWITCH_OPTION_VARIANT } from '../constants' import { SwitchOptionVariantType } from '../SwitchOption' @@ -21,7 +21,7 @@ type VariantActiveStyle = { const VARIANT_ACTIVE_STYLES: Record = { [SWITCH_OPTION_VARIANT.PRIMARY]: { backgroundColor: color('action', '600'), - color: color('neutral', 'white'), + color: colorValue('neutral', 'white'), borderColor: color('action', '600'), focusBorderColor: color('action', '500'), focusBoxShadow: `0 0 0 2px ${color('action', '500')}, 0 0 0 5px ${color( @@ -51,7 +51,7 @@ const VARIANT_ACTIVE_STYLES: Record = { }, [SWITCH_OPTION_VARIANT.DANGER]: { backgroundColor: color('danger', '700'), - color: color('neutral', 'white'), + color: colorValue('neutral', 'white'), borderColor: color('danger', '700'), focusBorderColor: color('danger', '700'), focusBoxShadow: `0 0 0 2px ${color('danger', '700')}, 0 0 0 5px ${color( diff --git a/packages/react-component-library/src/components/Tooltip/partials/StyledContent.tsx b/packages/react-component-library/src/components/Tooltip/partials/StyledContent.tsx index d6b0e8c0ad..8f23db22e8 100644 --- a/packages/react-component-library/src/components/Tooltip/partials/StyledContent.tsx +++ b/packages/react-component-library/src/components/Tooltip/partials/StyledContent.tsx @@ -1,5 +1,5 @@ import styled, { css, CSSProp } from 'styled-components' -import { color, spacing, zIndex } from '@royalnavy/design-tokens' +import { spacing, zIndex, colorValue } from '@royalnavy/design-tokens' import { TooltipPositionType } from '../Tooltip' @@ -7,7 +7,7 @@ const TOOLTIP_BORDER_THICK = 1 const TOOLTIP_INNER = 4 const TOOLTIP_OUTER = TOOLTIP_INNER - 4 const TOOLTIP_OFFSET = TOOLTIP_OUTER + TOOLTIP_BORDER_THICK -const TOOLTIP_DARK_BG = color('neutral', '700') +const TOOLTIP_DARK_BG = colorValue('neutral', '700') const TOOLTIP_DARK_BORDER = TOOLTIP_DARK_BG interface StyledContentProps { @@ -91,7 +91,7 @@ function getPositionStyles(position: TooltipPositionType): CSSProp { export const StyledContent = styled.div` z-index: ${zIndex('modal', 1)}; background: ${TOOLTIP_DARK_BG}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; border: ${TOOLTIP_DARK_BORDER} solid ${TOOLTIP_BORDER_THICK}px; border-radius: 5px; padding: ${spacing('6')} ${spacing('8')}; diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledUserItemWrapper.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledUserItemWrapper.tsx index ec39051de9..7337db826c 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledUserItemWrapper.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Masthead/partials/StyledUserItemWrapper.tsx @@ -1,4 +1,4 @@ -import { color } from '@royalnavy/design-tokens' +import { color, colorValue } from '@royalnavy/design-tokens' import styled from 'styled-components' import { StyledUserItemIcon } from './StyledUserItemIcon' @@ -8,7 +8,7 @@ export const StyledUserItemWrapper = styled.div` position: relative; a { - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; text-decoration: none; } diff --git a/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledButton.tsx b/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledButton.tsx index 9499d775ac..b0aa70bcea 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledButton.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledButton.tsx @@ -16,7 +16,7 @@ export const StyledButton = styled.button` cursor: pointer; > svg { - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; } &:focus { diff --git a/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledForm.tsx b/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledForm.tsx index 39297ec69b..97a2b211cb 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledForm.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/SearchBar/partials/StyledForm.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color, spacing, zIndex } from '@royalnavy/design-tokens' +import { spacing, zIndex, colorValue } from '@royalnavy/design-tokens' import { StyledInput } from '../../../TextInput/partials/StyledInput' import { StyledOuterWrapper } from '../../../TextInput/partials/StyledOuterWrapper' @@ -9,7 +9,7 @@ export const StyledForm = styled.form` z-index: ${zIndex('overlay', 1)}; display: flex; align-items: center; - background-color: ${color('neutral', '400')}; + background-color: ${colorValue('neutral', '400')}; height: 59px; ${StyledTextInput} { @@ -27,12 +27,12 @@ export const StyledForm = styled.form` ${StyledInput} { padding: ${spacing('8')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; background-color: transparent; border: 0; &::placeholder { - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; } } ` diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHandle.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHandle.tsx index 95fc21e5f0..b7b7ed92fa 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHandle.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHandle.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color, zIndex } from '@royalnavy/design-tokens' +import { color, zIndex, colorValue } from '@royalnavy/design-tokens' import { getTransitionOpacity, @@ -29,6 +29,6 @@ export const StyledHandle = styled.button` } > svg { - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; } ` diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHead.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHead.tsx index 27e4ffb7ea..d1d69f1a36 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHead.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHead.tsx @@ -1,10 +1,10 @@ import styled from 'styled-components' -import { color, spacing } from '@royalnavy/design-tokens' +import { spacing, colorValue } from '@royalnavy/design-tokens' export const StyledHead = styled.div` position: relative; display: flex; align-items: center; padding: ${spacing('8')} ${spacing('6')}; - background-color: ${color('neutral', '800')}; + background-color: ${colorValue('neutral', '800')}; ` diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHeadIcon.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHeadIcon.tsx index d540331c6e..284d627eaa 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHeadIcon.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledHeadIcon.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color, spacing } from '@royalnavy/design-tokens' +import { spacing, colorValue } from '@royalnavy/design-tokens' import { StyledHeadTitle } from './StyledHeadTitle' @@ -7,7 +7,7 @@ export const StyledHeadIcon = styled.div` display: inline-flex; align-items: center; border-radius: 4px; - background-color: ${color('neutral', '500')}; + background-color: ${colorValue('neutral', '500')}; padding: 0.55rem; min-width: 18px; diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNav.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNav.tsx index c40467b464..3864f47a52 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNav.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNav.tsx @@ -1,12 +1,12 @@ import styled from 'styled-components' -import { color, spacing } from '@royalnavy/design-tokens' +import { spacing, colorValue } from '@royalnavy/design-tokens' import { StyledContent } from '../../../../primitives/FloatingBox/partials/StyledContent' export const StyledNav = styled.nav` height: 100%; padding: ${spacing('1')} ${spacing('6')}; - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; ${StyledContent} { transform: translateX(0.5rem); diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItem.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItem.tsx index 6bacdd5e63..9588a29d25 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItem.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItem.tsx @@ -1,5 +1,5 @@ import styled, { css } from 'styled-components' -import { color, spacing } from '@royalnavy/design-tokens' +import { color, spacing, colorValue } from '@royalnavy/design-tokens' interface StyledNavItemProps { $isActive?: boolean @@ -28,7 +28,7 @@ export const StyledNavItem = styled.div` `} &:hover { - background-color: ${color('neutral', '400')}; + background-color: ${colorValue('neutral', '400')}; > * { text-decoration: none; diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItemIcon.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItemIcon.tsx index eafb4adde3..cd6e582c51 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItemIcon.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItemIcon.tsx @@ -1,5 +1,5 @@ import styled, { css } from 'styled-components' -import { color } from '@royalnavy/design-tokens' +import { colorValue } from '@royalnavy/design-tokens' import { StyledNavItem } from './StyledNavItem' @@ -17,10 +17,10 @@ export const StyledNavItemIcon = styled.div` svg { width: 18px; height: 18px; - color: ${color('neutral', '100')}; + color: ${colorValue('neutral', '100')}; ${StyledNavItem}:hover & { - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; } } diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItemText.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItemText.tsx index a87fcb6e6e..cb896da629 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItemText.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNavItemText.tsx @@ -1,5 +1,5 @@ import styled, { css } from 'styled-components' -import { color, fontSize } from '@royalnavy/design-tokens' +import { fontSize, colorValue } from '@royalnavy/design-tokens' import { getTransitionOpacity, @@ -13,7 +13,7 @@ interface StyledTextProps extends TransitionProps { export const StyledNavItemText = styled.div` display: inline-block; - color: ${color('neutral', '100')}; + color: ${colorValue('neutral', '100')}; font-size: ${fontSize('m')}; opacity: ${({ $transitionStatus }) => getTransitionOpacity($transitionStatus)}; @@ -21,7 +21,7 @@ export const StyledNavItemText = styled.div` padding: 0.25rem 0.5rem; ${StyledNavItem}:hover & { - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; } ${({ $isOpen }) => diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationDot.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationDot.tsx index a32cc25bc1..5e2f0a7363 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationDot.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationDot.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color, fontSize } from '@royalnavy/design-tokens' +import { color, fontSize, colorValue } from '@royalnavy/design-tokens' export const StyledNotificationDot = styled.span` position: absolute; @@ -12,8 +12,8 @@ export const StyledNotificationDot = styled.span` height: 24px; border-radius: 9999px; background-color: ${color('danger', '600')}; - border: 3px solid ${color('neutral', '700')}; - color: ${color('neutral', 'white')}; + border: 3px solid ${colorValue('neutral', '700')}; + color: ${colorValue('neutral', 'white')}; font-size: ${fontSize('s')}; font-weight: 600; ` diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationsLabel.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationsLabel.tsx index 27122a015a..dc853272a5 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationsLabel.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationsLabel.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color, fontSize, spacing } from '@royalnavy/design-tokens' +import { fontSize, spacing, colorValue } from '@royalnavy/design-tokens' import { getTransitionOpacity, @@ -9,7 +9,7 @@ import { export const StyledNotificationsLabel = styled.span` flex: 1; text-align: left; - color: ${color('neutral', '100')}; + color: ${colorValue('neutral', '100')}; font-size: ${fontSize('m')}; margin-left: ${spacing('4')}; white-space: nowrap; diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationsSheetButton.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationsSheetButton.tsx index 629eae6d5f..def4b7fc24 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationsSheetButton.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledNotificationsSheetButton.tsx @@ -1,6 +1,6 @@ import React from 'react' import styled, { css } from 'styled-components' -import { color, spacing } from '@royalnavy/design-tokens' +import { color, spacing, colorValue } from '@royalnavy/design-tokens' import { SheetButton, SheetButtonProps } from '../../Sheet/SheetButton' import { StyledNotificationDot } from './StyledNotificationDot' @@ -20,7 +20,7 @@ export const StyledNotificationsSheetButton = styled< white-space: nowrap; svg { - color: ${color('neutral', '100')}; + color: ${colorValue('neutral', '100')}; width: 20px; height: 20px; } @@ -46,7 +46,7 @@ export const StyledNotificationsSheetButton = styled< height: 12px; background-color: ${color('danger', '600')}; border-radius: 9999px; - border: 2px solid ${color('neutral', '700')}; + border: 2px solid ${colorValue('neutral', '700')}; } ${StyledNotificationDot} { diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSheetList.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSheetList.tsx index 3a19baf66c..ea9b0f9f0f 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSheetList.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSheetList.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color } from '@royalnavy/design-tokens' +import { colorValue } from '@royalnavy/design-tokens' export const StyledSheetList = styled.ol` list-style-type: none; @@ -8,7 +8,7 @@ export const StyledSheetList = styled.ol` a, a:hover { - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; text-decoration: none; } ` diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSidebar.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSidebar.tsx index 9b7e640936..9704a9a599 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSidebar.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSidebar.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color, zIndex } from '@royalnavy/design-tokens' +import { zIndex, colorValue } from '@royalnavy/design-tokens' import { StyledContent } from '../../../../primitives/FloatingBox/partials/StyledContent' @@ -31,8 +31,8 @@ export const StyledSidebar = styled.aside` height: 100%; left: 0; top: 0; - background-color: ${color('neutral', '700')}; - color: ${color('neutral', 'white')}; + background-color: ${colorValue('neutral', '700')}; + color: ${colorValue('neutral', 'white')}; transition: ${({ $isOpen }) => $isOpen diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSubNavSheetButton.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSubNavSheetButton.tsx index 05d0d126e1..c16eec796e 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSubNavSheetButton.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledSubNavSheetButton.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color, spacing } from '@royalnavy/design-tokens' +import { spacing, colorValue } from '@royalnavy/design-tokens' import { SheetButton } from '../../Sheet/SheetButton' @@ -17,15 +17,15 @@ export const StyledSubNavSheetButton = styled(SheetButton)` overflow: hidden; &:hover { - background-color: ${color('neutral', '400')}; + background-color: ${colorValue('neutral', '400')}; cursor: pointer; svg { - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; } } svg { - color: ${color('neutral', '100')}; + color: ${colorValue('neutral', '100')}; } ` diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledUser.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledUser.tsx index 854ceafce5..c4eb9249d6 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledUser.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledUser.tsx @@ -1,10 +1,10 @@ import styled from 'styled-components' -import { color, spacing } from '@royalnavy/design-tokens' +import { spacing, colorValue } from '@royalnavy/design-tokens' export const StyledUser = styled.div` display: flex; align-items: center; justify-content: center; padding: ${spacing('10')} ${spacing('8')}; - background-color: ${color('neutral', '500')}; + background-color: ${colorValue('neutral', '500')}; ` diff --git a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledUserText.tsx b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledUserText.tsx index 46ce69bc36..a6a0e2e5d5 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledUserText.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/Sidebar/partials/StyledUserText.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color, fontSize, spacing } from '@royalnavy/design-tokens' +import { fontSize, spacing, colorValue } from '@royalnavy/design-tokens' import { getTransitionOpacity, @@ -27,13 +27,13 @@ export const StyledUserText = styled.div` } > span { - color: ${color('neutral', 'white')}; + color: ${colorValue('neutral', 'white')}; font-size: ${fontSize('m')}; } a span { margin-top: ${spacing('1')}; - color: ${color('neutral', '300')}; + color: ${colorValue('neutral', '300')}; font-size: ${fontSize('s')}; } } @@ -41,8 +41,8 @@ export const StyledUserText = styled.div` svg { width: 1.65rem; height: 1.65rem; - color: ${color('neutral', 'white')}; - background-color: ${color('neutral', '400')}; + color: ${colorValue('neutral', 'white')}; + background-color: ${colorValue('neutral', '400')}; border-radius: 2px; padding: ${spacing('2')}; } diff --git a/packages/react-component-library/src/primitives/FloatingBox/partials/StyledContent.tsx b/packages/react-component-library/src/primitives/FloatingBox/partials/StyledContent.tsx index 828fcd083e..9b51bea880 100644 --- a/packages/react-component-library/src/primitives/FloatingBox/partials/StyledContent.tsx +++ b/packages/react-component-library/src/primitives/FloatingBox/partials/StyledContent.tsx @@ -1,5 +1,5 @@ import styled, { css } from 'styled-components' -import { color, mq, spacing } from '@royalnavy/design-tokens' +import { color, mq, spacing, colorValue } from '@royalnavy/design-tokens' import { FloatingBoxSchemeType } from '../types' import { FLOATING_BOX_SCHEME } from '../constants' @@ -26,9 +26,9 @@ const schemeStyleMap = { `, [FLOATING_BOX_SCHEME.DARK]: css` - background: ${color('neutral', '700')}; - border: ${color('neutral', '700')} solid ${spacing('px')}; - color: ${color('neutral', 'white')}; + background: ${colorValue('neutral', '700')}; + border: ${colorValue('neutral', '700')} solid ${spacing('px')}; + color: ${colorValue('neutral', 'white')}; ${StyledArrow} { &::before { @@ -36,7 +36,7 @@ const schemeStyleMap = { } &::after { - border-color: ${color('neutral', '700')} transparent; + border-color: ${colorValue('neutral', '700')} transparent; } } `, From ca76e34463b3f9a4765af739007be668c57aa13f Mon Sep 17 00:00:00 2001 From: m7kvqbe1 <48086589+m7kvqbe1@users.noreply.github.com> Date: Wed, 24 Jun 2026 22:12:23 +0100 Subject: [PATCH 06/11] fix(DarkTheme): Tune tabs, data grid header, tooltip and avatar --- .../components/Avatar/partials/StyledAvatar.tsx | 4 ++-- .../components/DataGrid/partials/StyledHead.tsx | 14 ++++++++------ .../src/components/TabBase/partials/StyledTabs.tsx | 2 ++ .../components/Tooltip/partials/StyledMessage.tsx | 6 ++++-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/react-component-library/src/components/Avatar/partials/StyledAvatar.tsx b/packages/react-component-library/src/components/Avatar/partials/StyledAvatar.tsx index 8b6fd4280d..560b7f57f0 100644 --- a/packages/react-component-library/src/components/Avatar/partials/StyledAvatar.tsx +++ b/packages/react-component-library/src/components/Avatar/partials/StyledAvatar.tsx @@ -27,7 +27,7 @@ export const StyledAvatar = styled.span` ${({ $dark }) => $dark && css` - background: ${colorValue('neutral', '400')}; - color: ${colorValue('neutral', 'white')}; + background: ${color('neutral', '400')}; + color: ${color('neutral', 'white')}; `} ` diff --git a/packages/react-component-library/src/components/DataGrid/partials/StyledHead.tsx b/packages/react-component-library/src/components/DataGrid/partials/StyledHead.tsx index 17805ed4b4..1fa43970b9 100644 --- a/packages/react-component-library/src/components/DataGrid/partials/StyledHead.tsx +++ b/packages/react-component-library/src/components/DataGrid/partials/StyledHead.tsx @@ -4,11 +4,13 @@ import { color, zIndex } from '@royalnavy/design-tokens' import { StyledLayoutProps } from './types' export const StyledHead = styled.thead` - background: ${color('neutral', '000')}; + background: ${color('neutral', '100')}; - ${({$hasScrolling}) => $hasScrolling && css` - position: sticky; - top: 0; - z-index: ${zIndex('header', 1)}; - `} + ${({ $hasScrolling }) => + $hasScrolling && + css` + position: sticky; + top: 0; + z-index: ${zIndex('header', 1)}; + `} ` diff --git a/packages/react-component-library/src/components/TabBase/partials/StyledTabs.tsx b/packages/react-component-library/src/components/TabBase/partials/StyledTabs.tsx index f4bb500fec..0bb2ce38a4 100644 --- a/packages/react-component-library/src/components/TabBase/partials/StyledTabs.tsx +++ b/packages/react-component-library/src/components/TabBase/partials/StyledTabs.tsx @@ -1,4 +1,5 @@ import styled from 'styled-components' +import { color } from '@royalnavy/design-tokens' export const StyledTabs = styled.ol` display: flex; @@ -6,4 +7,5 @@ export const StyledTabs = styled.ol` list-style-type: none; padding: 0; margin: 0; + background-color: ${color('neutral', '000')}; ` diff --git a/packages/react-component-library/src/components/Tooltip/partials/StyledMessage.tsx b/packages/react-component-library/src/components/Tooltip/partials/StyledMessage.tsx index e1a0902f1c..f6f678d4fe 100644 --- a/packages/react-component-library/src/components/Tooltip/partials/StyledMessage.tsx +++ b/packages/react-component-library/src/components/Tooltip/partials/StyledMessage.tsx @@ -1,7 +1,9 @@ import styled from 'styled-components' -import { color, fontSize } from '@royalnavy/design-tokens' +import { colorValue, fontSize } from '@royalnavy/design-tokens' export const StyledMessage = styled.div` font-size: ${fontSize('base')}; - color: ${color('neutral', '100')}; + // The tooltip bubble is always dark in both themes, so its message text + // stays a fixed light value rather than flipping with the theme. + color: ${colorValue('neutral', '100')}; ` From e0be44435582c4afd28356558e94411dbcafe74d Mon Sep 17 00:00:00 2001 From: m7kvqbe1 <48086589+m7kvqbe1@users.noreply.github.com> Date: Wed, 24 Jun 2026 23:34:26 +0100 Subject: [PATCH 07/11] fix(DarkTheme): Reset unstyled buttons and fix fixed-surface text --- .gitignore | 1 + packages/design-tokens/src/tokens/dark/colors.json | 4 ++-- .../partials/StyledClassificationBar.tsx | 4 ++-- .../components/DatePicker/partials/StyledDayPicker.tsx | 2 +- .../src/components/Field/partials/StyledError.tsx | 2 +- .../NotificationPanel/partials/StyledContent.tsx | 6 ++++-- .../src/styled-components/GlobalStyle.tsx | 9 +++++++++ 7 files changed, 20 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 85f5d23511..5751797391 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ npm-debug.log* package-lock.json +packages/react-component-library/*.tgz diff --git a/packages/design-tokens/src/tokens/dark/colors.json b/packages/design-tokens/src/tokens/dark/colors.json index 8d53aac529..74666995e7 100644 --- a/packages/design-tokens/src/tokens/dark/colors.json +++ b/packages/design-tokens/src/tokens/dark/colors.json @@ -329,7 +329,7 @@ "value": "#3a2415" }, "200": { - "value": "#fee2d1" + "value": "#3a2415" }, "300": { "value": "#fecaa9" @@ -361,7 +361,7 @@ "value": "#13301f" }, "200": { - "value": "#bff4cf" + "value": "#13301f" }, "300": { "value": "#8fe2ab" diff --git a/packages/react-component-library/src/components/ClassificationBar/partials/StyledClassificationBar.tsx b/packages/react-component-library/src/components/ClassificationBar/partials/StyledClassificationBar.tsx index 22a50bd288..65536baeb5 100644 --- a/packages/react-component-library/src/components/ClassificationBar/partials/StyledClassificationBar.tsx +++ b/packages/react-component-library/src/components/ClassificationBar/partials/StyledClassificationBar.tsx @@ -5,14 +5,14 @@ const getColorStyles = (isSecret?: boolean, inSidebar?: boolean) => { if (isSecret) { return css` background-color: ${color('danger', '600')}; - color: ${color('neutral', '000')}; + color: ${colorValue('neutral', '000')}; ` } if (inSidebar) { return css` background-color: ${colorValue('neutral', '400')}; - color: ${color('neutral', '000')}; + color: ${colorValue('neutral', '000')}; ` } diff --git a/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx b/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx index 723dabffec..d81128e5ba 100644 --- a/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx +++ b/packages/react-component-library/src/components/DatePicker/partials/StyledDayPicker.tsx @@ -140,7 +140,7 @@ export const StyledDayPicker = styled(DayPicker)` cursor: pointer; &.rdp-day_today { - color: ${color('warning', '800')}; + color: ${color('warning', '900')}; } &.rdp-day_selected { diff --git a/packages/react-component-library/src/components/Field/partials/StyledError.tsx b/packages/react-component-library/src/components/Field/partials/StyledError.tsx index 8fb18c641c..3c42a46459 100644 --- a/packages/react-component-library/src/components/Field/partials/StyledError.tsx +++ b/packages/react-component-library/src/components/Field/partials/StyledError.tsx @@ -4,6 +4,6 @@ import { color, fontSize } from '@royalnavy/design-tokens' export const StyledError = styled.span` display: inline-block; font-size: ${fontSize('s')}; - color: ${color('danger', '800')}; + color: ${color('danger', '900')}; margin: 0 0 6px 12px; ` diff --git a/packages/react-component-library/src/components/TopLevelNavigation/NotificationPanel/partials/StyledContent.tsx b/packages/react-component-library/src/components/TopLevelNavigation/NotificationPanel/partials/StyledContent.tsx index 459c9172b9..2c239fdeb0 100644 --- a/packages/react-component-library/src/components/TopLevelNavigation/NotificationPanel/partials/StyledContent.tsx +++ b/packages/react-component-library/src/components/TopLevelNavigation/NotificationPanel/partials/StyledContent.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { color, fontSize, spacing } from '@royalnavy/design-tokens' +import { colorValue, fontSize, spacing } from '@royalnavy/design-tokens' export const StyledContent = styled.span` display: block; @@ -7,7 +7,9 @@ export const StyledContent = styled.span` font-size: ${fontSize('s')}; line-height: 1.3; + // The notification panel is an always-dark surface, so emphasised text + // stays a fixed light value rather than flipping with the theme. strong { - color: ${color('neutral', '000')}; + color: ${colorValue('neutral', '000')}; } ` diff --git a/packages/react-component-library/src/styled-components/GlobalStyle.tsx b/packages/react-component-library/src/styled-components/GlobalStyle.tsx index ce840ee70c..35674228ec 100644 --- a/packages/react-component-library/src/styled-components/GlobalStyle.tsx +++ b/packages/react-component-library/src/styled-components/GlobalStyle.tsx @@ -76,6 +76,15 @@ const Fonts = createGlobalStyle` color: ${color('neutral', '600')}; } + /* Native