diff --git a/@navikt/core/react/src/layout/box/Box.darkside.tsx b/@navikt/core/react/src/layout/box/Box.darkside.tsx index 01b62b19a8..ffe6b48ad2 100644 --- a/@navikt/core/react/src/layout/box/Box.darkside.tsx +++ b/@navikt/core/react/src/layout/box/Box.darkside.tsx @@ -4,9 +4,9 @@ import type { BorderColorKeys, BorderColorWithRoleKeys, BorderRadiusKeys, - DefaultBgKeys, ShadowKeys, StaticBgKeys, + StaticDefaultBgKeys, } from "@navikt/ds-tokens/types"; import { Slot } from "../../slot/Slot"; import { omit } from "../../util"; @@ -25,7 +25,7 @@ export type BoxNewProps = React.HTMLAttributes & { * Accepts a [background/surface color token](https://aksel.nav.no/grunnleggende/styling/design-tokens#afff774dad80). * @see {@link DefaultBgKeys} and {@link StaticBgKeys} */ - background?: DefaultBgKeys | StaticBgKeys; + background?: StaticDefaultBgKeys | StaticBgKeys; /** * CSS `border-color` property. * Accepts a [border color token](https://aksel.nav.no/grunnleggende/styling/design-tokens#adb1767e2f87). diff --git a/@navikt/core/tokens/darkside/tokens.util.ts b/@navikt/core/tokens/darkside/tokens.util.ts index b4888d4d59..4f105f3475 100644 --- a/@navikt/core/tokens/darkside/tokens.util.ts +++ b/@navikt/core/tokens/darkside/tokens.util.ts @@ -1,9 +1,9 @@ -import { ColorRoles } from "../types"; +import type { GlobalColorRoles, SemanticColorRoles } from "../types"; export type GlobalColorEntry = { value: string; type: "global-color"; - group: ColorRoles; + group: GlobalColorRoles; }; export type TokenTypes = @@ -19,9 +19,9 @@ export type TokenTypes = export type SemanticTokenGroups = "background" | "border" | "text"; export type TokenGroup = - | ColorRoles + | GlobalColorRoles | SemanticTokenGroups - | `${SemanticTokenGroups}.${ColorRoles}`; + | `${SemanticTokenGroups}.${SemanticColorRoles}`; export type StyleDictionaryToken = { /** diff --git a/@navikt/core/tokens/darkside/tokens/global-dark.ts b/@navikt/core/tokens/darkside/tokens/global-dark.ts index 9ebf25188d..fdae5db836 100644 --- a/@navikt/core/tokens/darkside/tokens/global-dark.ts +++ b/@navikt/core/tokens/darkside/tokens/global-dark.ts @@ -1,8 +1,8 @@ -import { type ColorRoles, type GlobalColorScale } from "../../types"; +import { type GlobalColorRoles, type GlobalColorScale } from "../../types"; import { type GlobalColorEntry } from "../tokens.util"; export const globalColorDarkModeConfigWithoutAlpha: Record< - ColorRoles, + GlobalColorRoles, Record< Exclude, GlobalColorEntry diff --git a/@navikt/core/tokens/darkside/tokens/global-light.ts b/@navikt/core/tokens/darkside/tokens/global-light.ts index 83b2c444bb..deb95cf3c4 100644 --- a/@navikt/core/tokens/darkside/tokens/global-light.ts +++ b/@navikt/core/tokens/darkside/tokens/global-light.ts @@ -1,8 +1,8 @@ -import { type ColorRoles, type GlobalColorScale } from "../../types"; +import { type GlobalColorRoles, type GlobalColorScale } from "../../types"; import { type GlobalColorEntry } from "../tokens.util"; export const globalColorLightModeConfigWithoutAlpha: Record< - ColorRoles, + GlobalColorRoles, Record< Exclude, GlobalColorEntry diff --git a/@navikt/core/tokens/darkside/tokens/global.ts b/@navikt/core/tokens/darkside/tokens/global.ts index b9a06ad257..bf13692e7a 100644 --- a/@navikt/core/tokens/darkside/tokens/global.ts +++ b/@navikt/core/tokens/darkside/tokens/global.ts @@ -1,7 +1,7 @@ import Color from "colorjs.io"; import { - type ColorRoles, type ColorTheme, + type GlobalColorRoles, type GlobalColorScale, } from "../../types"; import { type GlobalColorEntry } from "../tokens.util"; @@ -20,11 +20,11 @@ export const globalColorLightModeConfig = globalColorConfigWithAlphaTokens( ); type GlobalConfigWithAlpha = Record< - Extract, + Extract, Record > & Record< - Exclude, + Exclude, Record, GlobalColorEntry> >; @@ -39,7 +39,7 @@ function globalColorConfigWithAlphaTokens( const localConfig = structuredClone(globalConfig) as GlobalConfigWithAlpha; Object.keys(globalConfig).forEach((key) => { - const _key = key as ColorRoles; + const _key = key as GlobalColorRoles; const scopedConfig = localConfig[_key]; scopedConfig["100A"] = { diff --git a/@navikt/core/tokens/darkside/tokens/semantic-roles.ts b/@navikt/core/tokens/darkside/tokens/semantic-roles.ts index 67678b9a69..c63dca920a 100644 --- a/@navikt/core/tokens/darkside/tokens/semantic-roles.ts +++ b/@navikt/core/tokens/darkside/tokens/semantic-roles.ts @@ -1,11 +1,15 @@ import _ from "lodash"; -import { type ColorRoles, ColorRolesList, type ColorTheme } from "../../types"; +import { + ColorRolesList, + type ColorTheme, + type SemanticColorRoles, +} from "../../types"; import { type StyleDictionaryTokenConfig } from "../tokens.util"; -const configForRole = (role: ColorRoles, theme: ColorTheme) => { +const configForRole = (role: SemanticColorRoles, theme: ColorTheme) => { return { bg: { - [role]: { + [`${role}-soft`]: { value: `{ax.${role}.100.value}`, type: "color", group: `background.${role}`, @@ -123,7 +127,7 @@ const configForRole = (role: ColorRoles, theme: ColorTheme) => { * We need to deep merge the token config for each role to get the complete token config for all roles. */ export const semanticTokensForAllRolesConfig = (theme: ColorTheme) => { - return ColorRolesList.reduce( + return ColorRolesList.filter((name) => name !== "neutral").reduce( (acc, role) => _.merge(acc, configForRole(role, theme)), {} as ReturnType, ); diff --git a/@navikt/core/tokens/darkside/tokens/semantic.ts b/@navikt/core/tokens/darkside/tokens/semantic.ts index c2c26b21e9..bc662ac99b 100644 --- a/@navikt/core/tokens/darkside/tokens/semantic.ts +++ b/@navikt/core/tokens/darkside/tokens/semantic.ts @@ -1,8 +1,9 @@ import { type BorderColorKeys, type ColorTheme, - type DefaultBgKeys, type DefaultTextColorKeys, + type StatefulDefaultBgKeys, + type StaticDefaultBgKeys, } from "../../types"; import { type StyleDictionaryToken } from "../tokens.util"; @@ -29,6 +30,11 @@ export function semanticTokenConfig(theme: ColorTheme) { type: "color", group: "text", }, + contrast: { + value: "{ax.neutral.000.value}", + type: "color", + group: "text", + }, }, bg: { default: { @@ -53,7 +59,7 @@ export function semanticTokenConfig(theme: ColorTheme) { value: theme === "light" ? "{ax.neutral.000.value}" - : "{ax.neutral.200.value}", + : "{ax.neutral.100.value}", type: "color", group: "background", }, @@ -67,6 +73,66 @@ export function semanticTokenConfig(theme: ColorTheme) { type: "color", group: "background", }, + soft: { + value: `{ax.neutral.100.value}`, + type: "color", + group: `background`, + }, + hover: { + value: `{ax.neutral.200.value}`, + type: "color", + group: `background`, + }, + hoverA: { + value: `{ax.neutral.200A.value}`, + type: "color", + group: `background`, + }, + moderate: { + value: `{ax.neutral.200.value}`, + type: "color", + group: `background`, + }, + moderateA: { + value: `{ax.neutral.200A.value}`, + type: "color", + group: `background`, + }, + "moderate-hover": { + value: `{ax.neutral.300.value}`, + type: "color", + group: `background`, + }, + "moderate-hoverA": { + value: `{ax.neutral.300A.value}`, + type: "color", + group: `background`, + }, + "moderate-pressed": { + value: `{ax.neutral.400.value}`, + type: "color", + group: `background`, + }, + "moderate-pressedA": { + value: `{ax.neutral.400A.value}`, + type: "color", + group: `background`, + }, + strong: { + value: `{ax.neutral.600.value}`, + type: "color", + group: `background`, + }, + "strong-hover": { + value: `{ax.neutral.700.value}`, + type: "color", + group: `background`, + }, + "strong-pressed": { + value: `{ax.neutral.800.value}`, + type: "color", + group: `background`, + }, }, border: { default: { @@ -104,7 +170,10 @@ export function semanticTokenConfig(theme: ColorTheme) { }, }, } satisfies { - bg: Record>; + bg: Record< + StaticDefaultBgKeys | StatefulDefaultBgKeys, + StyleDictionaryToken<"color"> + >; border: Record>; text: Record>; }; diff --git a/@navikt/core/tokens/darkside/tokens/text-contrast.ts b/@navikt/core/tokens/darkside/tokens/text-contrast.ts index b436a9ad77..a19a73ac3a 100644 --- a/@navikt/core/tokens/darkside/tokens/text-contrast.ts +++ b/@navikt/core/tokens/darkside/tokens/text-contrast.ts @@ -1,4 +1,4 @@ -import { type ColorRoles } from "../../types"; +import { type SemanticColorRoles } from "../../types"; import { type StyleDictionaryToken } from "../tokens.util"; export const textContrastTokenConfig = { @@ -9,11 +9,6 @@ export const textContrastTokenConfig = { type: "color", group: `text.accent`, }, - "neutral-contrast": { - value: "{ax.neutral.000.value}", - type: "color", - group: "text.neutral", - }, /* Status */ "danger-contrast": { value: "{ax.neutral.000.value}", @@ -64,5 +59,5 @@ export const textContrastTokenConfig = { }, }, } satisfies { - text: Record<`${ColorRoles}-contrast`, StyleDictionaryToken<"color">>; + text: Record<`${SemanticColorRoles}-contrast`, StyleDictionaryToken<"color">>; }; diff --git a/@navikt/core/tokens/types.ts b/@navikt/core/tokens/types.ts index ac9696c5a9..9764dfc8d0 100644 --- a/@navikt/core/tokens/types.ts +++ b/@navikt/core/tokens/types.ts @@ -14,7 +14,8 @@ export const ColorRolesList = [ "meta-lime", ] as const; -export type ColorRoles = (typeof ColorRolesList)[number]; +export type GlobalColorRoles = (typeof ColorRolesList)[number]; +export type SemanticColorRoles = Exclude; export type GlobalColorScale = | "100" @@ -34,43 +35,65 @@ export type GlobalColorScale = | "400A"; export type GlobalColorKeys = - | `${Extract}-${Extract}` - | `${ColorRoles}-${Exclude}`; + | `${Extract}-${Extract< + GlobalColorScale, + "000" + >}` + | `${GlobalColorRoles}-${Exclude}`; /* Semantic tokens */ -export type DefaultBgKeys = +export type StaticDefaultBgKeys = | "default" | "input" | "raised" | "sunken" - | "overlay"; + | "overlay" + | "soft" + | "moderate" + | "moderateA" + | "strong"; + +export type StatefulDefaultBgKeys = + | "hover" + | "hoverA" + | "moderate-hover" + | "moderate-hoverA" + | "moderate-pressed" + | "moderate-pressedA" + | "strong-hover" + | "strong-pressed"; export type StaticBgKeys = - | ColorRoles - | `${ColorRoles}-moderate` - | `${ColorRoles}-moderateA` - | `${ColorRoles}-strong` - | `${ColorRoles}-raised`; + | `${SemanticColorRoles}-soft` + | `${SemanticColorRoles}-moderate` + | `${SemanticColorRoles}-moderateA` + | `${SemanticColorRoles}-strong` + | `${SemanticColorRoles}-raised`; export type StatefulBgKeys = - | `${ColorRoles}-hover` - | `${ColorRoles}-hoverA` - | `${ColorRoles}-moderate-hover` - | `${ColorRoles}-moderate-hoverA` - | `${ColorRoles}-moderate-pressed` - | `${ColorRoles}-moderate-pressedA` - | `${ColorRoles}-strong-hover` - | `${ColorRoles}-strong-pressed` - | `${ColorRoles}-raised-hover`; - -export type DefaultTextColorKeys = "default" | "subtle" | "icon" | "logo"; + | `${SemanticColorRoles}-hover` + | `${SemanticColorRoles}-hoverA` + | `${SemanticColorRoles}-moderate-hover` + | `${SemanticColorRoles}-moderate-hoverA` + | `${SemanticColorRoles}-moderate-pressed` + | `${SemanticColorRoles}-moderate-pressedA` + | `${SemanticColorRoles}-strong-hover` + | `${SemanticColorRoles}-strong-pressed` + | `${SemanticColorRoles}-raised-hover`; + +export type DefaultTextColorKeys = + | "default" + | "subtle" + | "icon" + | "logo" + | "contrast"; export type TextColorKeys = - | ColorRoles - | `${ColorRoles}-strong` - | `${ColorRoles}-icon` - | `${ColorRoles}-contrast`; + | SemanticColorRoles + | `${SemanticColorRoles}-strong` + | `${SemanticColorRoles}-icon` + | `${SemanticColorRoles}-contrast`; export type BorderColorKeys = | "default" @@ -80,10 +103,10 @@ export type BorderColorKeys = | "focus"; export type BorderColorWithRoleKeys = - | ColorRoles - | `${ColorRoles}-subtle` - | `${ColorRoles}-subtleA` - | `${ColorRoles}-strong`; + | SemanticColorRoles + | `${SemanticColorRoles}-subtle` + | `${SemanticColorRoles}-subtleA` + | `${SemanticColorRoles}-strong`; export const spaceInPixels = [ 0, 1, 2, 4, 6, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 56, 64, 72, 80, 96,