diff --git a/eslint.config.mjs b/eslint.config.mjs index 6e2de2681..8cc0500b2 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -132,13 +132,13 @@ const config = [ }, { files: [ - '**/*.test.ts', - '**/*.test.tsx', + '**/*.test.{ts,tsx}', '**/__tests__/**', '**/*.config.*', '*.config.*', '**/*.story.*', '.storybook/**', + '**/*.bench.{ts,tsx}', ], languageOptions: { globals: { diff --git a/package.json b/package.json index 0ccc58737..f8929b964 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@types/eslint__js": "^8.42.3", "@types/jest-image-snapshot": "^6.4.0", "@types/jest-specific-snapshot": "^0.5.9", - "@types/node": "^17.0.13", + "@types/node": "^18.19.59", "@types/prettier": "^2.4.3", "@types/styled-components": "^5.1.21", "@types/webpack": "^5.28.0", diff --git a/packages/theme/cli/token-object.ts b/packages/theme/cli/token-object.ts new file mode 100644 index 000000000..16fcf88c7 --- /dev/null +++ b/packages/theme/cli/token-object.ts @@ -0,0 +1,128 @@ +/* eslint-disable no-console */ +import { readFileSync, mkdirSync, writeFileSync } from 'node:fs' +import path from 'node:path' +import { createCSSTokenObject, createTokenObject } from '../src/token-object' +import type { TokenDictionary } from '../src/token-object/types' +import { camelCaseKeys } from '../src/token-object' + +type ValueStyle = 'cssVariable' +type KeyStyle = 'camelCase' + +type Config = { + tokenFile: string + baseFile: string + outputFile: string + keyStyle?: KeyStyle + valueStyle?: ValueStyle +} + +const configurations: Config[] = [ + { + tokenFile: './src/json/pixiv-light.json', + baseFile: './src/json/base.json', + outputFile: './dist/tokens/pixiv-light.json', + keyStyle: undefined, + valueStyle: undefined, + }, + { + tokenFile: './src/json/pixiv-dark.json', + baseFile: './src/json/base.json', + outputFile: './dist/tokens/pixiv-dark.json', + keyStyle: undefined, + valueStyle: undefined, + }, + + { + tokenFile: './src/json/pixiv-light.json', + baseFile: './src/json/base.json', + outputFile: './dist/tokens/camel/pixiv-light.json', + keyStyle: 'camelCase', + valueStyle: undefined, + }, + { + tokenFile: './src/json/pixiv-dark.json', + baseFile: './src/json/base.json', + outputFile: './dist/tokens/camel/pixiv-dark.json', + keyStyle: 'camelCase', + valueStyle: undefined, + }, + + { + tokenFile: './src/json/pixiv-light.json', + baseFile: './src/json/base.json', + outputFile: './dist/tokens/css-variables/pixiv-light.json', + keyStyle: undefined, + valueStyle: 'cssVariable', + }, + { + tokenFile: './src/json/pixiv-dark.json', + baseFile: './src/json/base.json', + outputFile: './dist/tokens/css-variables/pixiv-dark.json', + keyStyle: undefined, + valueStyle: 'cssVariable', + }, + + { + tokenFile: './src/json/pixiv-light.json', + baseFile: './src/json/base.json', + outputFile: './dist/tokens/css-variables/camel/pixiv-light.json', + keyStyle: 'camelCase', + valueStyle: 'cssVariable', + }, + { + tokenFile: './src/json/pixiv-dark.json', + baseFile: './src/json/base.json', + outputFile: './dist/tokens/css-variables/camel/pixiv-dark.json', + keyStyle: 'camelCase', + valueStyle: 'cssVariable', + }, +] + +for (const { + tokenFile, + baseFile, + outputFile, + keyStyle, + valueStyle, +} of configurations) { + const baseJson = JSON.parse( + readFileSync(path.resolve(baseFile), 'utf8') + ) as TokenDictionary + + const createToken = ( + value: T + ): Record => { + switch (valueStyle) { + case 'cssVariable': { + return createCSSTokenObject(value, (x) => `charcoal-${x}`) + } + default: { + return createTokenObject(value, baseJson) + } + } + } + const transformKey = >( + value: T + ): Record => { + switch (keyStyle) { + case 'camelCase': { + return camelCaseKeys(value) + } + default: { + return value + } + } + } + + const tokenJson = JSON.parse( + readFileSync(path.resolve(tokenFile), 'utf8') + ) as TokenDictionary + const tokenObject = transformKey(createToken(tokenJson)) + + mkdirSync(path.dirname(outputFile), { recursive: true }) + writeFileSync(path.resolve(outputFile), JSON.stringify(tokenObject, null, 2)) + + console.log( + `Generated ${outputFile} with keyStyle ${keyStyle} and valueStyle ${valueStyle}.` + ) +} diff --git a/packages/theme/package.json b/packages/theme/package.json index 6fbdb7c5d..bf255bcba 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -4,39 +4,69 @@ "license": "Apache-2.0", "main": "./dist/index.cjs.js", "module": "./dist/index.esm.js", + "types": "./dist/index.d.ts", "exports": { - "types": "./dist/index.d.ts", - "require": "./dist/index.cjs.js", - "import": "./dist/index.esm.js", - "default": "./dist/index.esm.js" + ".": { + "types": "./dist/index.d.ts", + "require": "./dist/index.cjs.js", + "import": "./dist/index.esm.js", + "default": "./dist/index.esm.js" + }, + "./token-object": { + "types": "./dist/token-object/index.d.ts", + "require": "./dist/token-object/index.cjs.js", + "import": "./dist/token-object/index.esm.js", + "default": "./dist/token-object/index.esm.js" + }, + "./css/*": "./dist/css/*", + "./tokens/*": "./dist/tokens/*" + }, + "typesVersions": { + "*": { + "token-object": [ + "./dist/token-object/index.d.ts" + ], + "tokens/*": [ + "./dist/tokens/*" + ], + "css/*": [ + "./dist/css/*" + ] + } }, - "types": "./dist/index.d.ts", "sideEffects": [ "*.css" ], "scripts": { - "build": "npm-run-all --print-label --parallel 'build:*' --sequential serialize", + "build": "npm-run-all --print-label -s 'build:*' --sequential serialize", "build:bundle": "FORCE_COLOR=1 tsup", "build:dts": "tsc --project tsconfig.build.json --pretty --emitDeclarationOnly", - "build:copy-css": "cpx 'src/css/**/*.css' dist/css && cpx 'src/json/**/*.json' dist/json", + "build:copy-css": "cpx --clean 'src/css/**/*.{css,d.ts}' dist/css", + "build:token-object": "tsx cli/token-object.ts", "serialize": "node cli/index.js", "typecheck": "run-p --print-label 'typecheck:*'", "typecheck:main": "tsc --project tsconfig.build.json --pretty --noEmit", "typecheck:cli": "tsc --project cli/tsconfig.build.json --noEmit", "clean": "rimraf dist .tsbuildinfo", - "test": "vitest run --passWithNoTests" + "test": "vitest run --passWithNoTests", + "bench": "vitest bench --passWithNoTests" }, "devDependencies": { + "@types/css": "^0.0.38", "cpx": "^1.5.0", + "css": "^3.0.0", "npm-run-all": "^4.1.5", "rimraf": "^3.0.2", "tsup": "^6.5.0", + "tsx": "^4.19.1", "typescript": "^4.9.5", "vitest": "^2.0.2" }, "dependencies": { "@charcoal-ui/foundation": "^4.0.0-beta.15", "@charcoal-ui/utils": "^4.0.0-beta.15", + "change-case-all": "^2.1.0", + "deepmerge": "^4.3.1", "polished": "^4.1.4" }, "files": [ diff --git a/packages/theme/src/css/_variables_dark.css.d.ts b/packages/theme/src/css/_variables_dark.css.d.ts new file mode 100644 index 000000000..22db8578f --- /dev/null +++ b/packages/theme/src/css/_variables_dark.css.d.ts @@ -0,0 +1 @@ +declare module "*.css" { } \ No newline at end of file diff --git a/packages/theme/src/css/_variables_light.css.d.ts b/packages/theme/src/css/_variables_light.css.d.ts new file mode 100644 index 000000000..22db8578f --- /dev/null +++ b/packages/theme/src/css/_variables_light.css.d.ts @@ -0,0 +1 @@ +declare module "*.css" { } \ No newline at end of file diff --git a/packages/theme/src/token-object/__snapshots__/token-object.test.ts.snap b/packages/theme/src/token-object/__snapshots__/token-object.test.ts.snap new file mode 100644 index 000000000..26cee6e93 --- /dev/null +++ b/packages/theme/src/token-object/__snapshots__/token-object.test.ts.snap @@ -0,0 +1,1361 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`createCSSTokenObject test: dark theme > should match snapshot 1`] = ` +{ + "border-width": { + "focus": { + "1": "var(--charcoal-border-width-focus-1)", + "2": "var(--charcoal-border-width-focus-2)", + }, + "l": "var(--charcoal-border-width-l)", + "m": "var(--charcoal-border-width-m)", + }, + "color": { + "background": { + "default": "var(--charcoal-color-background-default)", + "secondary": "var(--charcoal-color-background-secondary)", + "tertiary": "var(--charcoal-color-background-tertiary)", + }, + "border": { + "default": "var(--charcoal-color-border-default)", + "disable": "var(--charcoal-color-border-disable)", + "focus": { + "1": "var(--charcoal-color-border-focus-1)", + "2": "var(--charcoal-color-border-focus-2)", + "legacy": "var(--charcoal-color-border-focus-legacy)", + }, + "hover": "var(--charcoal-color-border-hover)", + "hud": "var(--charcoal-color-border-hud)", + "negative": "var(--charcoal-color-border-negative)", + "press": "var(--charcoal-color-border-press)", + "secondary": "var(--charcoal-color-border-secondary)", + "selected": "var(--charcoal-color-border-selected)", + }, + "container": { + "default": "var(--charcoal-color-container-default)", + "default-a": "var(--charcoal-color-container-default-a)", + "disable": "var(--charcoal-color-container-disable)", + "discovery": { + "default": "var(--charcoal-color-container-discovery-default)", + "hover": "var(--charcoal-color-container-discovery-hover)", + "press": "var(--charcoal-color-container-discovery-press)", + }, + "hover": "var(--charcoal-color-container-hover)", + "hover-a": "var(--charcoal-color-container-hover-a)", + "hud": { + "default": "var(--charcoal-color-container-hud-default)", + "hover": "var(--charcoal-color-container-hud-hover)", + "press": "var(--charcoal-color-container-hud-press)", + }, + "negative": { + "default": "var(--charcoal-color-container-negative-default)", + "hover": "var(--charcoal-color-container-negative-hover)", + "press": "var(--charcoal-color-container-negative-press)", + }, + "neutral": { + "default": "var(--charcoal-color-container-neutral-default)", + "hover": "var(--charcoal-color-container-neutral-hover)", + "press": "var(--charcoal-color-container-neutral-press)", + }, + "notice": { + "default": "var(--charcoal-color-container-notice-default)", + "hover": "var(--charcoal-color-container-notice-hover)", + "press": "var(--charcoal-color-container-notice-press)", + }, + "on-img": { + "default": "var(--charcoal-color-container-on-img-default)", + "hover": "var(--charcoal-color-container-on-img-hover)", + "press": "var(--charcoal-color-container-on-img-press)", + }, + "positive": { + "default": "var(--charcoal-color-container-positive-default)", + "hover": "var(--charcoal-color-container-positive-hover)", + "press": "var(--charcoal-color-container-positive-press)", + }, + "press": "var(--charcoal-color-container-press)", + "press-a": "var(--charcoal-color-container-press-a)", + "primary": { + "default": "var(--charcoal-color-container-primary-default)", + "hover": "var(--charcoal-color-container-primary-hover)", + "press": "var(--charcoal-color-container-primary-press)", + }, + "secondary": { + "default": "var(--charcoal-color-container-secondary-default)", + "default-a": "var(--charcoal-color-container-secondary-default-a)", + "hover": "var(--charcoal-color-container-secondary-hover)", + "hover-a": "var(--charcoal-color-container-secondary-hover-a)", + "press": "var(--charcoal-color-container-secondary-press)", + "press-a": "var(--charcoal-color-container-secondary-press-a)", + }, + "skeleton": "var(--charcoal-color-container-skeleton)", + "subtle": "var(--charcoal-color-container-subtle)", + "tertiary": { + "default": "var(--charcoal-color-container-tertiary-default)", + "default-a": "var(--charcoal-color-container-tertiary-default-a)", + "hover": "var(--charcoal-color-container-tertiary-hover)", + "hover-a": "var(--charcoal-color-container-tertiary-hover-a)", + "press": "var(--charcoal-color-container-tertiary-press)", + "pressA": "var(--charcoal-color-container-tertiary-press-a)", + }, + }, + "icon": { + "default": "var(--charcoal-color-icon-default)", + "disable": "var(--charcoal-color-icon-disable)", + "hover": "var(--charcoal-color-icon-hover)", + "negative": { + "default": "var(--charcoal-color-icon-negative-default)", + "hover": "var(--charcoal-color-icon-negative-hover)", + "press": "var(--charcoal-color-icon-negative-press)", + }, + "notice": { + "default": "var(--charcoal-color-icon-notice-default)", + "hover": "var(--charcoal-color-icon-notice-hover)", + "press": "var(--charcoal-color-icon-notice-press)", + }, + "on-negative": { + "default": "var(--charcoal-color-icon-on-negative-default)", + "hover": "var(--charcoal-color-icon-on-negative-hover)", + "press": "var(--charcoal-color-icon-on-negative-press)", + }, + "on-neutral": { + "default": "var(--charcoal-color-icon-on-neutral-default)", + "hover": "var(--charcoal-color-icon-on-neutral-hover)", + "press": "var(--charcoal-color-icon-on-neutral-press)", + }, + "on-notice": { + "default": "var(--charcoal-color-icon-on-notice-default)", + "hover": "var(--charcoal-color-icon-on-notice-hover)", + "press": "var(--charcoal-color-icon-on-notice-press)", + }, + "on-on-img": { + "default": "var(--charcoal-color-icon-on-on-img-default)", + "hover": "var(--charcoal-color-icon-on-on-img-hover)", + "press": "var(--charcoal-color-icon-on-on-img-press)", + }, + "on-positive": { + "default": "var(--charcoal-color-icon-on-positive-default)", + "hover": "var(--charcoal-color-icon-on-positive-hover)", + "press": "var(--charcoal-color-icon-on-positive-press)", + }, + "on-primary": { + "default": "var(--charcoal-color-icon-on-primary-default)", + "hover": "var(--charcoal-color-icon-on-primary-hover)", + "press": "var(--charcoal-color-icon-on-primary-press)", + }, + "positive": { + "default": "var(--charcoal-color-icon-positive-default)", + "hover": "var(--charcoal-color-icon-positive-hover)", + "press": "var(--charcoal-color-icon-positive-press)", + }, + "press": "var(--charcoal-color-icon-press)", + "secondary": { + "default": "var(--charcoal-color-icon-secondary-default)", + "hover": "var(--charcoal-color-icon-secondary-hover)", + "press": "var(--charcoal-color-icon-secondary-press)", + }, + "tertiary": { + "default": "var(--charcoal-color-icon-tertiary-default)", + "hover": "var(--charcoal-color-icon-tertiary-hover)", + "press": "var(--charcoal-color-icon-tertiary-press)", + }, + }, + "text": { + "brand-premium": { + "default": "var(--charcoal-color-text-brand-premium-default)", + "hover": "var(--charcoal-color-text-brand-premium-hover)", + "press": "var(--charcoal-color-text-brand-premium-press)", + }, + "default": "var(--charcoal-color-text-default)", + "disable": "var(--charcoal-color-text-disable)", + "hover": "var(--charcoal-color-text-hover)", + "info": { + "default": "var(--charcoal-color-text-info-default)", + "hover": "var(--charcoal-color-text-info-hover)", + "press": "var(--charcoal-color-text-info-press)", + }, + "negative": { + "default": "var(--charcoal-color-text-negative-default)", + "hover": "var(--charcoal-color-text-negative-hover)", + "press": "var(--charcoal-color-text-negative-press)", + }, + "notice": { + "default": "var(--charcoal-color-text-notice-default)", + "hover": "var(--charcoal-color-text-notice-hover)", + "press": "var(--charcoal-color-text-notice-press)", + }, + "on-discovery": { + "default": "var(--charcoal-color-text-on-discovery-default)", + "hover": "var(--charcoal-color-text-on-discovery-hover)", + "press": "var(--charcoal-color-text-on-discovery-press)", + }, + "on-hud": { + "default": "var(--charcoal-color-text-on-hud-default)", + "hover": "var(--charcoal-color-text-on-hud-hover)", + "press": "var(--charcoal-color-text-on-hud-press)", + }, + "on-negative": { + "default": "var(--charcoal-color-text-on-negative-default)", + "hover": "var(--charcoal-color-text-on-negative-hover)", + "press": "var(--charcoal-color-text-on-negative-press)", + }, + "on-notice": { + "default": "var(--charcoal-color-text-on-notice-default)", + "hover": "var(--charcoal-color-text-on-notice-hover)", + "press": "var(--charcoal-color-text-on-notice-press)", + }, + "on-on-img": { + "default": "var(--charcoal-color-text-on-on-img-default)", + "hover": "var(--charcoal-color-text-on-on-img-hover)", + "press": "var(--charcoal-color-text-on-on-img-press)", + }, + "on-positive": { + "default": "var(--charcoal-color-text-on-positive-default)", + "hover": "var(--charcoal-color-text-on-positive-hover)", + "press": "var(--charcoal-color-text-on-positive-press)", + }, + "on-primary": { + "default": "var(--charcoal-color-text-on-primary-default)", + "hover": "var(--charcoal-color-text-on-primary-hover)", + "press": "var(--charcoal-color-text-on-primary-press)", + }, + "placeholder": { + "default": "var(--charcoal-color-text-placeholder-default)", + "hover": "var(--charcoal-color-text-placeholder-hover)", + "press": "var(--charcoal-color-text-placeholder-press)", + }, + "positive": { + "default": "var(--charcoal-color-text-positive-default)", + "hover": "var(--charcoal-color-text-positive-hover)", + "press": "var(--charcoal-color-text-positive-press)", + }, + "press": "var(--charcoal-color-text-press)", + "secondary": { + "default": "var(--charcoal-color-text-secondary-default)", + "hover": "var(--charcoal-color-text-secondary-hover)", + "press": "var(--charcoal-color-text-secondary-press)", + }, + "tertiary": { + "default": "var(--charcoal-color-text-tertiary-default)", + "hover": "var(--charcoal-color-text-tertiary-hover)", + "press": "var(--charcoal-color-text-tertiary-press)", + }, + "visited": { + "default": "var(--charcoal-color-text-visited-default)", + "hover": "var(--charcoal-color-text-visited-hover)", + "press": "var(--charcoal-color-text-visited-press)", + }, + }, + }, + "paragraph-width": { + "l": "var(--charcoal-paragraph-width-l)", + "l-compact": "var(--charcoal-paragraph-width-l-compact)", + "l-cozy": "var(--charcoal-paragraph-width-l-cozy)", + "m": "var(--charcoal-paragraph-width-m)", + "m-compact": "var(--charcoal-paragraph-width-m-compact)", + "m-cozy": "var(--charcoal-paragraph-width-m-cozy)", + "s": "var(--charcoal-paragraph-width-s)", + "s-compact": "var(--charcoal-paragraph-width-s-compact)", + "s-cozy": "var(--charcoal-paragraph-width-s-cozy)", + }, + "radius": { + "0": "var(--charcoal-radius-0)", + "l": "var(--charcoal-radius-l)", + "m": "var(--charcoal-radius-m)", + "oval": "var(--charcoal-radius-oval)", + "s": "var(--charcoal-radius-s)", + "xl": "var(--charcoal-radius-xl)", + "xs": "var(--charcoal-radius-xs)", + "xxl": "var(--charcoal-radius-xxl)", + }, + "space": { + "between-checkboxes": { + "horizontal": "var(--charcoal-space-between-checkboxes-horizontal)", + "vertical": "var(--charcoal-space-between-checkboxes-vertical)", + }, + "layout": { + "0": "var(--charcoal-space-layout-0)", + "10": "var(--charcoal-space-layout-10)", + "100": "var(--charcoal-space-layout-100)", + "20": "var(--charcoal-space-layout-20)", + "25": "var(--charcoal-space-layout-25)", + "30": "var(--charcoal-space-layout-30)", + "40": "var(--charcoal-space-layout-40)", + "50": "var(--charcoal-space-layout-50)", + "60": "var(--charcoal-space-layout-60)", + "70": "var(--charcoal-space-layout-70)", + "80": "var(--charcoal-space-layout-80)", + "90": "var(--charcoal-space-layout-90)", + }, + "target": { + "l": "var(--charcoal-space-target-l)", + "m": "var(--charcoal-space-target-m)", + "s": "var(--charcoal-space-target-s)", + "xs": "var(--charcoal-space-target-xs)", + }, + }, + "text": { + "font-size": { + "body": "var(--charcoal-text-font-size-body)", + "caption": { + "m": "var(--charcoal-text-font-size-caption-m)", + "s": "var(--charcoal-text-font-size-caption-s)", + }, + "heading": { + "l": "var(--charcoal-text-font-size-heading-l)", + "m": "var(--charcoal-text-font-size-heading-m)", + "s": "var(--charcoal-text-font-size-heading-s)", + "xl": "var(--charcoal-text-font-size-heading-xl)", + "xs": "var(--charcoal-text-font-size-heading-xs)", + "xxl": "var(--charcoal-text-font-size-heading-xxl)", + "xxs": "var(--charcoal-text-font-size-heading-xxs)", + "xxxl": "var(--charcoal-text-font-size-heading-xxxl)", + "xxxs": "var(--charcoal-text-font-size-heading-xxxs)", + }, + "paragraph": "var(--charcoal-text-font-size-paragraph)", + }, + "font-weight": { + "bold": "var(--charcoal-text-font-weight-bold)", + "regular": "var(--charcoal-text-font-weight-regular)", + }, + "line-height": { + "body": "var(--charcoal-text-line-height-body)", + "caption": { + "m": "var(--charcoal-text-line-height-caption-m)", + "s": "var(--charcoal-text-line-height-caption-s)", + }, + "heading": { + "l": "var(--charcoal-text-line-height-heading-l)", + "m": "var(--charcoal-text-line-height-heading-m)", + "s": "var(--charcoal-text-line-height-heading-s)", + "xl": "var(--charcoal-text-line-height-heading-xl)", + "xs": "var(--charcoal-text-line-height-heading-xs)", + "xxl": "var(--charcoal-text-line-height-heading-xxl)", + "xxs": "var(--charcoal-text-line-height-heading-xxs)", + "xxxl": "var(--charcoal-text-line-height-heading-xxxl)", + "xxxs": "var(--charcoal-text-line-height-heading-xxxs)", + }, + "paragraph": "var(--charcoal-text-line-height-paragraph)", + }, + }, +} +`; + +exports[`createCSSTokenObject test: light theme > should match snapshot 1`] = ` +{ + "border-width": { + "focus": { + "1": "var(--charcoal-border-width-focus-1)", + "2": "var(--charcoal-border-width-focus-2)", + }, + "l": "var(--charcoal-border-width-l)", + "m": "var(--charcoal-border-width-m)", + }, + "color": { + "background": { + "default": "var(--charcoal-color-background-default)", + "secondary": "var(--charcoal-color-background-secondary)", + "tertiary": "var(--charcoal-color-background-tertiary)", + }, + "border": { + "default": "var(--charcoal-color-border-default)", + "disable": "var(--charcoal-color-border-disable)", + "focus": { + "1": "var(--charcoal-color-border-focus-1)", + "2": "var(--charcoal-color-border-focus-2)", + "legacy": "var(--charcoal-color-border-focus-legacy)", + }, + "hover": "var(--charcoal-color-border-hover)", + "hud": "var(--charcoal-color-border-hud)", + "negative": "var(--charcoal-color-border-negative)", + "press": "var(--charcoal-color-border-press)", + "secondary": "var(--charcoal-color-border-secondary)", + "selected": "var(--charcoal-color-border-selected)", + }, + "container": { + "default": "var(--charcoal-color-container-default)", + "default-a": "var(--charcoal-color-container-default-a)", + "disable": "var(--charcoal-color-container-disable)", + "discovery": { + "default": "var(--charcoal-color-container-discovery-default)", + "hover": "var(--charcoal-color-container-discovery-hover)", + "press": "var(--charcoal-color-container-discovery-press)", + }, + "hover": "var(--charcoal-color-container-hover)", + "hover-a": "var(--charcoal-color-container-hover-a)", + "hud": { + "default": "var(--charcoal-color-container-hud-default)", + "hover": "var(--charcoal-color-container-hud-hover)", + "press": "var(--charcoal-color-container-hud-press)", + }, + "negative": { + "default": "var(--charcoal-color-container-negative-default)", + "hover": "var(--charcoal-color-container-negative-hover)", + "press": "var(--charcoal-color-container-negative-press)", + }, + "neutral": { + "default": "var(--charcoal-color-container-neutral-default)", + "hover": "var(--charcoal-color-container-neutral-hover)", + "press": "var(--charcoal-color-container-neutral-press)", + }, + "notice": { + "default": "var(--charcoal-color-container-notice-default)", + "hover": "var(--charcoal-color-container-notice-hover)", + "press": "var(--charcoal-color-container-notice-press)", + }, + "on-img": { + "default": "var(--charcoal-color-container-on-img-default)", + "hover": "var(--charcoal-color-container-on-img-hover)", + "press": "var(--charcoal-color-container-on-img-press)", + }, + "positive": { + "default": "var(--charcoal-color-container-positive-default)", + "hover": "var(--charcoal-color-container-positive-hover)", + "press": "var(--charcoal-color-container-positive-press)", + }, + "press": "var(--charcoal-color-container-press)", + "press-a": "var(--charcoal-color-container-press-a)", + "primary": { + "default": "var(--charcoal-color-container-primary-default)", + "hover": "var(--charcoal-color-container-primary-hover)", + "press": "var(--charcoal-color-container-primary-press)", + }, + "secondary": { + "default": "var(--charcoal-color-container-secondary-default)", + "default-a": "var(--charcoal-color-container-secondary-default-a)", + "hover": "var(--charcoal-color-container-secondary-hover)", + "hover-a": "var(--charcoal-color-container-secondary-hover-a)", + "press": "var(--charcoal-color-container-secondary-press)", + "press-a": "var(--charcoal-color-container-secondary-press-a)", + }, + "skeleton": "var(--charcoal-color-container-skeleton)", + "subtle": "var(--charcoal-color-container-subtle)", + "tertiary": { + "default": "var(--charcoal-color-container-tertiary-default)", + "default-a": "var(--charcoal-color-container-tertiary-default-a)", + "hover": "var(--charcoal-color-container-tertiary-hover)", + "hover-a": "var(--charcoal-color-container-tertiary-hover-a)", + "press": "var(--charcoal-color-container-tertiary-press)", + "pressA": "var(--charcoal-color-container-tertiary-press-a)", + }, + }, + "icon": { + "default": "var(--charcoal-color-icon-default)", + "disable": "var(--charcoal-color-icon-disable)", + "hover": "var(--charcoal-color-icon-hover)", + "negative": { + "default": "var(--charcoal-color-icon-negative-default)", + "hover": "var(--charcoal-color-icon-negative-hover)", + "press": "var(--charcoal-color-icon-negative-press)", + }, + "notice": { + "default": "var(--charcoal-color-icon-notice-default)", + "hover": "var(--charcoal-color-icon-notice-hover)", + "press": "var(--charcoal-color-icon-notice-press)", + }, + "on-negative": { + "default": "var(--charcoal-color-icon-on-negative-default)", + "hover": "var(--charcoal-color-icon-on-negative-hover)", + "press": "var(--charcoal-color-icon-on-negative-press)", + }, + "on-neutral": { + "default": "var(--charcoal-color-icon-on-neutral-default)", + "hover": "var(--charcoal-color-icon-on-neutral-hover)", + "press": "var(--charcoal-color-icon-on-neutral-press)", + }, + "on-notice": { + "default": "var(--charcoal-color-icon-on-notice-default)", + "hover": "var(--charcoal-color-icon-on-notice-hover)", + "press": "var(--charcoal-color-icon-on-notice-press)", + }, + "on-on-img": { + "default": "var(--charcoal-color-icon-on-on-img-default)", + "hover": "var(--charcoal-color-icon-on-on-img-hover)", + "press": "var(--charcoal-color-icon-on-on-img-press)", + }, + "on-positive": { + "default": "var(--charcoal-color-icon-on-positive-default)", + "hover": "var(--charcoal-color-icon-on-positive-hover)", + "press": "var(--charcoal-color-icon-on-positive-press)", + }, + "on-primary": { + "default": "var(--charcoal-color-icon-on-primary-default)", + "hover": "var(--charcoal-color-icon-on-primary-hover)", + "press": "var(--charcoal-color-icon-on-primary-press)", + }, + "positive": { + "default": "var(--charcoal-color-icon-positive-default)", + "hover": "var(--charcoal-color-icon-positive-hover)", + "press": "var(--charcoal-color-icon-positive-press)", + }, + "press": "var(--charcoal-color-icon-press)", + "secondary": { + "default": "var(--charcoal-color-icon-secondary-default)", + "hover": "var(--charcoal-color-icon-secondary-hover)", + "press": "var(--charcoal-color-icon-secondary-press)", + }, + "tertiary": { + "default": "var(--charcoal-color-icon-tertiary-default)", + "hover": "var(--charcoal-color-icon-tertiary-hover)", + "press": "var(--charcoal-color-icon-tertiary-press)", + }, + }, + "text": { + "brand-premium": { + "default": "var(--charcoal-color-text-brand-premium-default)", + "hover": "var(--charcoal-color-text-brand-premium-hover)", + "press": "var(--charcoal-color-text-brand-premium-press)", + }, + "default": "var(--charcoal-color-text-default)", + "disable": "var(--charcoal-color-text-disable)", + "hover": "var(--charcoal-color-text-hover)", + "info": { + "default": "var(--charcoal-color-text-info-default)", + "hover": "var(--charcoal-color-text-info-hover)", + "press": "var(--charcoal-color-text-info-press)", + }, + "negative": { + "default": "var(--charcoal-color-text-negative-default)", + "hover": "var(--charcoal-color-text-negative-hover)", + "press": "var(--charcoal-color-text-negative-press)", + }, + "notice": { + "default": "var(--charcoal-color-text-notice-default)", + "hover": "var(--charcoal-color-text-notice-hover)", + "press": "var(--charcoal-color-text-notice-press)", + }, + "on-discovery": { + "default": "var(--charcoal-color-text-on-discovery-default)", + "hover": "var(--charcoal-color-text-on-discovery-hover)", + "press": "var(--charcoal-color-text-on-discovery-press)", + }, + "on-hud": { + "default": "var(--charcoal-color-text-on-hud-default)", + "hover": "var(--charcoal-color-text-on-hud-hover)", + "press": "var(--charcoal-color-text-on-hud-press)", + }, + "on-negative": { + "default": "var(--charcoal-color-text-on-negative-default)", + "hover": "var(--charcoal-color-text-on-negative-hover)", + "press": "var(--charcoal-color-text-on-negative-press)", + }, + "on-notice": { + "default": "var(--charcoal-color-text-on-notice-default)", + "hover": "var(--charcoal-color-text-on-notice-hover)", + "press": "var(--charcoal-color-text-on-notice-press)", + }, + "on-on-img": { + "default": "var(--charcoal-color-text-on-on-img-default)", + "hover": "var(--charcoal-color-text-on-on-img-hover)", + "press": "var(--charcoal-color-text-on-on-img-press)", + }, + "on-positive": { + "default": "var(--charcoal-color-text-on-positive-default)", + "hover": "var(--charcoal-color-text-on-positive-hover)", + "press": "var(--charcoal-color-text-on-positive-press)", + }, + "on-primary": { + "default": "var(--charcoal-color-text-on-primary-default)", + "hover": "var(--charcoal-color-text-on-primary-hover)", + "press": "var(--charcoal-color-text-on-primary-press)", + }, + "placeholder": { + "default": "var(--charcoal-color-text-placeholder-default)", + "hover": "var(--charcoal-color-text-placeholder-hover)", + "press": "var(--charcoal-color-text-placeholder-press)", + }, + "positive": { + "default": "var(--charcoal-color-text-positive-default)", + "hover": "var(--charcoal-color-text-positive-hover)", + "press": "var(--charcoal-color-text-positive-press)", + }, + "press": "var(--charcoal-color-text-press)", + "secondary": { + "default": "var(--charcoal-color-text-secondary-default)", + "hover": "var(--charcoal-color-text-secondary-hover)", + "press": "var(--charcoal-color-text-secondary-press)", + }, + "tertiary": { + "default": "var(--charcoal-color-text-tertiary-default)", + "hover": "var(--charcoal-color-text-tertiary-hover)", + "press": "var(--charcoal-color-text-tertiary-press)", + }, + "visited": { + "default": "var(--charcoal-color-text-visited-default)", + "hover": "var(--charcoal-color-text-visited-hover)", + "press": "var(--charcoal-color-text-visited-press)", + }, + }, + }, + "paragraph-width": { + "l": "var(--charcoal-paragraph-width-l)", + "l-compact": "var(--charcoal-paragraph-width-l-compact)", + "l-cozy": "var(--charcoal-paragraph-width-l-cozy)", + "m": "var(--charcoal-paragraph-width-m)", + "m-compact": "var(--charcoal-paragraph-width-m-compact)", + "m-cozy": "var(--charcoal-paragraph-width-m-cozy)", + "s": "var(--charcoal-paragraph-width-s)", + "s-compact": "var(--charcoal-paragraph-width-s-compact)", + "s-cozy": "var(--charcoal-paragraph-width-s-cozy)", + }, + "radius": { + "0": "var(--charcoal-radius-0)", + "l": "var(--charcoal-radius-l)", + "m": "var(--charcoal-radius-m)", + "oval": "var(--charcoal-radius-oval)", + "s": "var(--charcoal-radius-s)", + "xl": "var(--charcoal-radius-xl)", + "xs": "var(--charcoal-radius-xs)", + "xxl": "var(--charcoal-radius-xxl)", + }, + "space": { + "between-checkboxes": { + "horizontal": "var(--charcoal-space-between-checkboxes-horizontal)", + "vertical": "var(--charcoal-space-between-checkboxes-vertical)", + }, + "layout": { + "0": "var(--charcoal-space-layout-0)", + "10": "var(--charcoal-space-layout-10)", + "100": "var(--charcoal-space-layout-100)", + "20": "var(--charcoal-space-layout-20)", + "25": "var(--charcoal-space-layout-25)", + "30": "var(--charcoal-space-layout-30)", + "40": "var(--charcoal-space-layout-40)", + "50": "var(--charcoal-space-layout-50)", + "60": "var(--charcoal-space-layout-60)", + "70": "var(--charcoal-space-layout-70)", + "80": "var(--charcoal-space-layout-80)", + "90": "var(--charcoal-space-layout-90)", + }, + "target": { + "l": "var(--charcoal-space-target-l)", + "m": "var(--charcoal-space-target-m)", + "s": "var(--charcoal-space-target-s)", + "xs": "var(--charcoal-space-target-xs)", + }, + }, + "text": { + "font-size": { + "body": "var(--charcoal-text-font-size-body)", + "caption": { + "m": "var(--charcoal-text-font-size-caption-m)", + "s": "var(--charcoal-text-font-size-caption-s)", + }, + "heading": { + "l": "var(--charcoal-text-font-size-heading-l)", + "m": "var(--charcoal-text-font-size-heading-m)", + "s": "var(--charcoal-text-font-size-heading-s)", + "xl": "var(--charcoal-text-font-size-heading-xl)", + "xs": "var(--charcoal-text-font-size-heading-xs)", + "xxl": "var(--charcoal-text-font-size-heading-xxl)", + "xxs": "var(--charcoal-text-font-size-heading-xxs)", + "xxxl": "var(--charcoal-text-font-size-heading-xxxl)", + "xxxs": "var(--charcoal-text-font-size-heading-xxxs)", + }, + "paragraph": "var(--charcoal-text-font-size-paragraph)", + }, + "font-weight": { + "bold": "var(--charcoal-text-font-weight-bold)", + "regular": "var(--charcoal-text-font-weight-regular)", + }, + "line-height": { + "body": "var(--charcoal-text-line-height-body)", + "caption": { + "m": "var(--charcoal-text-line-height-caption-m)", + "s": "var(--charcoal-text-line-height-caption-s)", + }, + "heading": { + "l": "var(--charcoal-text-line-height-heading-l)", + "m": "var(--charcoal-text-line-height-heading-m)", + "s": "var(--charcoal-text-line-height-heading-s)", + "xl": "var(--charcoal-text-line-height-heading-xl)", + "xs": "var(--charcoal-text-line-height-heading-xs)", + "xxl": "var(--charcoal-text-line-height-heading-xxl)", + "xxs": "var(--charcoal-text-line-height-heading-xxs)", + "xxxl": "var(--charcoal-text-line-height-heading-xxxl)", + "xxxs": "var(--charcoal-text-line-height-heading-xxxs)", + }, + "paragraph": "var(--charcoal-text-line-height-paragraph)", + }, + }, +} +`; + +exports[`createTokenObject test: dark theme > should match snapshot 1`] = ` +{ + "border-width": { + "focus": { + "1": "1", + "2": "2", + }, + "l": "2", + "m": "1", + }, + "color": { + "background": { + "default": "rgba(31, 31, 31, 1)", + "secondary": "rgba(21, 21, 21, 1)", + "tertiary": "rgba(6, 6, 6, 1)", + }, + "border": { + "default": "rgba(228, 228, 228, 0.41)", + "disable": "rgba(228, 228, 228, 0.05)", + "focus": { + "1": "rgba(114, 181, 245, 1)", + "2": "rgba(39, 84, 126, 1)", + "legacy": "rgba(0, 150, 250, 0.32)", + }, + "hover": "rgba(228, 228, 228, 0.505)", + "hud": "rgba(31, 31, 31, 1)", + "negative": "rgba(136, 54, 46, 1)", + "press": "rgba(228, 228, 228, 0.61)", + "secondary": "rgba(228, 228, 228, 0.1)", + "selected": "rgba(8, 114, 190, 1)", + }, + "container": { + "default": "rgba(31, 31, 31, 1)", + "default-a": "rgba(228, 228, 228, 0)", + "disable": "rgba(51, 51, 51, 1)", + "discovery": { + "default": "rgba(197, 60, 51, 1)", + "hover": "rgba(217, 88, 76, 1)", + "press": "rgba(233, 114, 102, 1)", + }, + "hover": "rgba(41, 41, 41, 1)", + "hover-a": "rgba(228, 228, 228, 0.05)", + "hud": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(202, 202, 202, 1)", + "press": "rgba(188, 188, 188, 1)", + }, + "negative": { + "default": "rgba(197, 60, 51, 1)", + "hover": "rgba(217, 88, 76, 1)", + "press": "rgba(233, 114, 102, 1)", + }, + "neutral": { + "default": "rgba(112, 112, 112, 1)", + "hover": "rgba(130, 130, 130, 1)", + "press": "rgba(151, 151, 151, 1)", + }, + "notice": { + "default": "rgba(222, 185, 7, 1)", + "hover": "rgba(231, 199, 80, 1)", + "press": "rgba(252, 227, 145, 1)", + }, + "on-img": { + "default": "rgba(31, 31, 31, 0.37)", + "hover": "rgba(31, 31, 31, 0.475)", + "press": "rgba(31, 31, 31, 0.635)", + }, + "positive": { + "default": "rgba(13, 129, 5, 1)", + "hover": "rgba(58, 150, 52, 1)", + "press": "rgba(86, 169, 79, 1)", + }, + "press": "rgba(51, 51, 51, 1)", + "press-a": "rgba(228, 228, 228, 0.1)", + "primary": { + "default": "rgba(8, 114, 190, 1)", + "hover": "rgba(55, 136, 208, 1)", + "press": "rgba(83, 156, 224, 1)", + }, + "secondary": { + "default": "rgba(41, 41, 41, 1)", + "default-a": "rgba(228, 228, 228, 0.05)", + "hover": "rgba(51, 51, 51, 1)", + "hover-a": "rgba(228, 228, 228, 0.1)", + "press": "rgba(81, 81, 81, 1)", + "press-a": "rgba(228, 228, 228, 0.255)", + }, + "skeleton": "rgba(228, 228, 228, 0.05)", + "subtle": "rgba(228, 228, 228, 0.02)", + "tertiary": { + "default": "rgba(51, 51, 51, 1)", + "default-a": "rgba(228, 228, 228, 0.1)", + "hover": "rgba(81, 81, 81, 1)", + "hover-a": "rgba(228, 228, 228, 0.255)", + "press": "rgba(112, 112, 112, 1)", + "pressA": "rgba(228, 228, 228, 0.41)", + }, + }, + "icon": { + "default": "rgba(228, 228, 228, 1)", + "disable": "rgba(130, 130, 130, 1)", + "hover": "rgba(202, 202, 202, 1)", + "negative": { + "default": "rgba(252, 147, 134, 1)", + "hover": "rgba(249, 186, 177, 1)", + "press": "rgba(254, 219, 214, 1)", + }, + "notice": { + "default": "rgba(222, 167, 29, 1)", + "hover": "rgba(231, 199, 80, 1)", + "press": "rgba(252, 227, 145, 1)", + }, + "on-negative": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "on-neutral": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "on-notice": { + "default": "rgba(41, 41, 41, 1)", + "hover": "rgba(41, 41, 41, 1)", + "press": "rgba(41, 41, 41, 1)", + }, + "on-on-img": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "on-positive": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "on-primary": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "positive": { + "default": "rgba(120, 194, 113, 1)", + "hover": "rgba(161, 215, 155, 1)", + "press": "rgba(191, 241, 186, 1)", + }, + "press": "rgba(188, 188, 188, 1)", + "secondary": { + "default": "rgba(175, 175, 175, 1)", + "hover": "rgba(188, 188, 188, 1)", + "press": "rgba(202, 202, 202, 1)", + }, + "tertiary": { + "default": "rgba(130, 130, 130, 1)", + "hover": "rgba(175, 175, 175, 1)", + "press": "rgba(188, 188, 188, 1)", + }, + }, + "text": { + "brand-premium": { + "default": "rgba(253, 158, 22, 1)", + "hover": "rgba(243, 152, 21, 1)", + "press": "rgba(213, 133, 18, 1)", + }, + "default": "rgba(228, 228, 228, 1)", + "disable": "rgba(130, 130, 130, 1)", + "hover": "rgba(202, 202, 202, 1)", + "info": { + "default": "rgba(114, 181, 245, 1)", + "hover": "rgba(166, 205, 245, 1)", + "press": "rgba(207, 230, 253, 1)", + }, + "negative": { + "default": "rgba(252, 147, 134, 1)", + "hover": "rgba(249, 186, 177, 1)", + "press": "rgba(254, 219, 214, 1)", + }, + "notice": { + "default": "rgba(222, 167, 29, 1)", + "hover": "rgba(231, 199, 80, 1)", + "press": "rgba(252, 227, 145, 1)", + }, + "on-discovery": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "on-hud": { + "default": "rgba(31, 31, 31, 1)", + "hover": "rgba(31, 31, 31, 1)", + "press": "rgba(31, 31, 31, 1)", + }, + "on-negative": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "on-notice": { + "default": "rgba(41, 41, 41, 1)", + "hover": "rgba(41, 41, 41, 1)", + "press": "rgba(41, 41, 41, 1)", + }, + "on-on-img": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "on-positive": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "on-primary": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "placeholder": { + "default": "rgba(112, 112, 112, 1)", + "hover": "rgba(112, 112, 112, 1)", + "press": "rgba(112, 112, 112, 1)", + }, + "positive": { + "default": "rgba(120, 194, 113, 1)", + "hover": "rgba(161, 215, 155, 1)", + "press": "rgba(191, 241, 186, 1)", + }, + "press": "rgba(188, 188, 188, 1)", + "secondary": { + "default": "rgba(175, 175, 175, 1)", + "hover": "rgba(188, 188, 188, 1)", + "press": "rgba(202, 202, 202, 1)", + }, + "tertiary": { + "default": "rgba(130, 130, 130, 1)", + "hover": "rgba(175, 175, 175, 1)", + "press": "rgba(188, 188, 188, 1)", + }, + "visited": { + "default": "rgba(191, 160, 246, 1)", + "hover": "rgba(210, 192, 245, 1)", + "press": "rgba(233, 223, 255, 1)", + }, + }, + }, + "paragraph-width": { + "l": "672", + "l-compact": "588", + "l-cozy": "924", + "m": "448", + "m-compact": "392", + "m-cozy": "616", + "s": "320", + "s-compact": "280", + "s-cozy": "588", + }, + "radius": { + "0": "0", + "l": "12", + "m": "8", + "oval": "999999", + "s": "4", + "xl": "16", + "xs": "2", + "xxl": "24", + }, + "space": { + "between-checkboxes": { + "horizontal": "12", + "vertical": "0", + }, + "layout": { + "0": "0", + "10": "4", + "100": "440", + "20": "8", + "25": "12", + "30": "16", + "40": "24", + "50": "40", + "60": "64", + "70": "104", + "80": "168", + "90": "272", + }, + "target": { + "l": "48", + "m": "40", + "s": "32", + "xs": "24", + }, + }, + "text": { + "font-size": { + "body": "16", + "caption": { + "m": "14", + "s": "12", + }, + "heading": { + "l": "28", + "m": "25", + "s": "22", + "xl": "32", + "xs": "20", + "xxl": "36", + "xxs": "18", + "xxxl": "40", + "xxxs": "14", + }, + "paragraph": "16", + }, + "font-weight": { + "bold": "700", + "regular": "400", + }, + "line-height": { + "body": "24", + "caption": { + "m": "20", + "s": "18", + }, + "heading": { + "l": "36", + "m": "32", + "s": "28", + "xl": "40", + "xs": "28", + "xxl": "44", + "xxs": "24", + "xxxl": "52", + "xxxs": "20", + }, + "paragraph": "28", + }, + }, +} +`; + +exports[`createTokenObject test: light theme > should match snapshot 1`] = ` +{ + "border-width": { + "focus": { + "1": "1", + "2": "2", + }, + "l": "2", + "m": "1", + }, + "color": { + "background": { + "default": "rgba(255, 255, 255, 1)", + "secondary": "rgba(243, 243, 243, 1)", + "tertiary": "rgba(232, 232, 232, 1)", + }, + "border": { + "default": "rgba(31, 31, 31, 0.475)", + "disable": "rgba(31, 31, 31, 0.102)", + "focus": { + "1": "rgba(31, 117, 188, 1)", + "2": "rgba(188, 222, 252, 1)", + "legacy": "rgba(0, 150, 250, 0.32)", + }, + "hover": "rgba(31, 31, 31, 0.635)", + "hud": "rgba(255, 255, 255, 1)", + "negative": "rgba(253, 206, 199, 1)", + "press": "rgba(31, 31, 31, 0.775)", + "secondary": "rgba(31, 31, 31, 0.102)", + "selected": "rgba(0, 150, 250, 1)", + }, + "container": { + "default": "rgba(255, 255, 255, 1)", + "default-a": "rgba(31, 31, 31, 0)", + "disable": "rgba(232, 232, 232, 1)", + "discovery": { + "default": "rgba(253, 91, 78, 1)", + "hover": "rgba(206, 54, 46, 1)", + "press": "rgba(147, 33, 28, 1)", + }, + "hover": "rgba(243, 243, 243, 1)", + "hover-a": "rgba(31, 31, 31, 0.055)", + "hud": { + "default": "rgba(56, 56, 56, 1)", + "hover": "rgba(81, 81, 81, 1)", + "press": "rgba(113, 113, 113, 1)", + }, + "negative": { + "default": "rgba(253, 91, 78, 1)", + "hover": "rgba(206, 54, 46, 1)", + "press": "rgba(147, 33, 28, 1)", + }, + "neutral": { + "default": "rgba(148, 148, 148, 1)", + "hover": "rgba(113, 113, 113, 1)", + "press": "rgba(81, 81, 81, 1)", + }, + "notice": { + "default": "rgba(254, 214, 61, 1)", + "hover": "rgba(245, 183, 17, 1)", + "press": "rgba(231, 157, 20, 1)", + }, + "on-img": { + "default": "rgba(31, 31, 31, 0.37)", + "hover": "rgba(31, 31, 31, 0.475)", + "press": "rgba(31, 31, 31, 0.635)", + }, + "positive": { + "default": "rgba(37, 170, 28, 1)", + "hover": "rgba(17, 131, 8, 1)", + "press": "rgba(4, 93, 0, 1)", + }, + "press": "rgba(232, 232, 232, 1)", + "press-a": "rgba(31, 31, 31, 0.102)", + "primary": { + "default": "rgba(0, 150, 250, 1)", + "hover": "rgba(31, 117, 188, 1)", + "press": "rgba(24, 81, 130, 1)", + }, + "secondary": { + "default": "rgba(243, 243, 243, 1)", + "default-a": "rgba(31, 31, 31, 0.055)", + "hover": "rgba(232, 232, 232, 1)", + "hover-a": "rgba(31, 31, 31, 0.102)", + "press": "rgba(217, 217, 217, 1)", + "press-a": "rgba(31, 31, 31, 0.17)", + }, + "skeleton": "rgba(31, 31, 31, 0.055)", + "subtle": "rgba(31, 31, 31, 0.02)", + "tertiary": { + "default": "rgba(232, 232, 232, 1)", + "default-a": "rgba(31, 31, 31, 0.102)", + "hover": "rgba(217, 217, 217, 1)", + "hover-a": "rgba(31, 31, 31, 0.17)", + "press": "rgba(194, 194, 194, 1)", + "pressA": "rgba(31, 31, 31, 0.27)", + }, + }, + "icon": { + "default": "rgba(31, 31, 31, 1)", + "disable": "rgba(194, 194, 194, 1)", + "hover": "rgba(56, 56, 56, 1)", + "negative": { + "default": "rgba(206, 54, 46, 1)", + "hover": "rgba(147, 33, 28, 1)", + "press": "rgba(103, 22, 17, 1)", + }, + "notice": { + "default": "rgba(161, 99, 9, 1)", + "hover": "rgba(110, 72, 5, 1)", + "press": "rgba(74, 51, 7, 1)", + }, + "on-negative": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "on-neutral": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(243, 243, 243, 1)", + "press": "rgba(232, 232, 232, 1)", + }, + "on-notice": { + "default": "rgba(31, 31, 31, 1)", + "hover": "rgba(31, 31, 31, 1)", + "press": "rgba(31, 31, 31, 1)", + }, + "on-on-img": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "on-positive": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "on-primary": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "positive": { + "default": "rgba(17, 131, 8, 1)", + "hover": "rgba(4, 93, 0, 1)", + "press": "rgba(4, 93, 0, 1)", + }, + "press": "rgba(81, 81, 81, 1)", + "secondary": { + "default": "rgba(81, 81, 81, 1)", + "hover": "rgba(56, 56, 56, 1)", + "press": "rgba(31, 31, 31, 1)", + }, + "tertiary": { + "default": "rgba(113, 113, 113, 1)", + "hover": "rgba(81, 81, 81, 1)", + "press": "rgba(56, 56, 56, 1)", + }, + }, + "text": { + "brand-premium": { + "default": "rgba(253, 158, 22, 1)", + "hover": "rgba(243, 152, 21, 1)", + "press": "rgba(213, 133, 18, 1)", + }, + "default": "rgba(31, 31, 31, 1)", + "disable": "rgba(194, 194, 194, 1)", + "hover": "rgba(56, 56, 56, 1)", + "info": { + "default": "rgba(31, 117, 188, 1)", + "hover": "rgba(24, 81, 130, 1)", + "press": "rgba(19, 58, 93, 1)", + }, + "negative": { + "default": "rgba(206, 54, 46, 1)", + "hover": "rgba(147, 33, 28, 1)", + "press": "rgba(103, 22, 17, 1)", + }, + "notice": { + "default": "rgba(161, 99, 9, 1)", + "hover": "rgba(110, 72, 5, 1)", + "press": "rgba(74, 51, 7, 1)", + }, + "on-discovery": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "on-hud": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "on-negative": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "on-notice": { + "default": "rgba(31, 31, 31, 1)", + "hover": "rgba(31, 31, 31, 1)", + "press": "rgba(31, 31, 31, 1)", + }, + "on-on-img": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "on-positive": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "on-primary": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "placeholder": { + "default": "rgba(148, 148, 148, 1)", + "hover": "rgba(148, 148, 148, 1)", + "press": "rgba(148, 148, 148, 1)", + }, + "positive": { + "default": "rgba(17, 131, 8, 1)", + "hover": "rgba(4, 93, 0, 1)", + "press": "rgba(7, 64, 4, 1)", + }, + "press": "rgba(81, 81, 81, 1)", + "secondary": { + "default": "rgba(81, 81, 81, 1)", + "hover": "rgba(56, 56, 56, 1)", + "press": "rgba(31, 31, 31, 1)", + }, + "tertiary": { + "default": "rgba(113, 113, 113, 1)", + "hover": "rgba(81, 81, 81, 1)", + "press": "rgba(56, 56, 56, 1)", + }, + "visited": { + "default": "rgba(103, 39, 171, 1)", + "hover": "rgba(70, 32, 115, 1)", + "press": "rgba(40, 16, 70, 1)", + }, + }, + }, + "paragraph-width": { + "l": "672", + "l-compact": "588", + "l-cozy": "924", + "m": "448", + "m-compact": "392", + "m-cozy": "616", + "s": "320", + "s-compact": "280", + "s-cozy": "588", + }, + "radius": { + "0": "0", + "l": "12", + "m": "8", + "oval": "999999", + "s": "4", + "xl": "16", + "xs": "2", + "xxl": "24", + }, + "space": { + "between-checkboxes": { + "horizontal": "12", + "vertical": "0", + }, + "layout": { + "0": "0", + "10": "4", + "100": "440", + "20": "8", + "25": "12", + "30": "16", + "40": "24", + "50": "40", + "60": "64", + "70": "104", + "80": "168", + "90": "272", + }, + "target": { + "l": "48", + "m": "40", + "s": "32", + "xs": "24", + }, + }, + "text": { + "font-size": { + "body": "16", + "caption": { + "m": "14", + "s": "12", + }, + "heading": { + "l": "28", + "m": "25", + "s": "22", + "xl": "32", + "xs": "20", + "xxl": "36", + "xxs": "18", + "xxxl": "40", + "xxxs": "14", + }, + "paragraph": "16", + }, + "font-weight": { + "bold": "700", + "regular": "400", + }, + "line-height": { + "body": "24", + "caption": { + "m": "20", + "s": "18", + }, + "heading": { + "l": "36", + "m": "32", + "s": "28", + "xl": "40", + "xs": "28", + "xxl": "44", + "xxs": "24", + "xxxl": "52", + "xxxs": "20", + }, + "paragraph": "28", + }, + }, +} +`; diff --git a/packages/theme/src/token-object/helpers/__snapshots__/changecase-keys.test.ts.snap b/packages/theme/src/token-object/helpers/__snapshots__/changecase-keys.test.ts.snap new file mode 100644 index 000000000..0f9cf8453 --- /dev/null +++ b/packages/theme/src/token-object/helpers/__snapshots__/changecase-keys.test.ts.snap @@ -0,0 +1,681 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`changeCaseKeys snapshot test: dark theme > camelcaseKeys snapshot test 1`] = ` +{ + "borderWidth": { + "focus": { + "1": "1", + "2": "2", + }, + "l": "2", + "m": "1", + }, + "color": { + "background": { + "default": "rgba(31, 31, 31, 1)", + "secondary": "rgba(21, 21, 21, 1)", + "tertiary": "rgba(6, 6, 6, 1)", + }, + "border": { + "default": "rgba(228, 228, 228, 0.41)", + "disable": "rgba(228, 228, 228, 0.05)", + "focus": { + "1": "rgba(114, 181, 245, 1)", + "2": "rgba(39, 84, 126, 1)", + "legacy": "rgba(0, 150, 250, 0.32)", + }, + "hover": "rgba(228, 228, 228, 0.505)", + "hud": "rgba(31, 31, 31, 1)", + "negative": "rgba(136, 54, 46, 1)", + "press": "rgba(228, 228, 228, 0.61)", + "secondary": "rgba(228, 228, 228, 0.1)", + "selected": "rgba(8, 114, 190, 1)", + }, + "container": { + "default": "rgba(31, 31, 31, 1)", + "defaultA": "rgba(228, 228, 228, 0)", + "disable": "rgba(51, 51, 51, 1)", + "discovery": { + "default": "rgba(197, 60, 51, 1)", + "hover": "rgba(217, 88, 76, 1)", + "press": "rgba(233, 114, 102, 1)", + }, + "hover": "rgba(41, 41, 41, 1)", + "hoverA": "rgba(228, 228, 228, 0.05)", + "hud": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(202, 202, 202, 1)", + "press": "rgba(188, 188, 188, 1)", + }, + "negative": { + "default": "rgba(197, 60, 51, 1)", + "hover": "rgba(217, 88, 76, 1)", + "press": "rgba(233, 114, 102, 1)", + }, + "neutral": { + "default": "rgba(112, 112, 112, 1)", + "hover": "rgba(130, 130, 130, 1)", + "press": "rgba(151, 151, 151, 1)", + }, + "notice": { + "default": "rgba(222, 185, 7, 1)", + "hover": "rgba(231, 199, 80, 1)", + "press": "rgba(252, 227, 145, 1)", + }, + "onImg": { + "default": "rgba(31, 31, 31, 0.37)", + "hover": "rgba(31, 31, 31, 0.475)", + "press": "rgba(31, 31, 31, 0.635)", + }, + "positive": { + "default": "rgba(13, 129, 5, 1)", + "hover": "rgba(58, 150, 52, 1)", + "press": "rgba(86, 169, 79, 1)", + }, + "press": "rgba(51, 51, 51, 1)", + "pressA": "rgba(228, 228, 228, 0.1)", + "primary": { + "default": "rgba(8, 114, 190, 1)", + "hover": "rgba(55, 136, 208, 1)", + "press": "rgba(83, 156, 224, 1)", + }, + "secondary": { + "default": "rgba(41, 41, 41, 1)", + "defaultA": "rgba(228, 228, 228, 0.05)", + "hover": "rgba(51, 51, 51, 1)", + "hoverA": "rgba(228, 228, 228, 0.1)", + "press": "rgba(81, 81, 81, 1)", + "pressA": "rgba(228, 228, 228, 0.255)", + }, + "skeleton": "rgba(228, 228, 228, 0.05)", + "subtle": "rgba(228, 228, 228, 0.02)", + "tertiary": { + "default": "rgba(51, 51, 51, 1)", + "defaultA": "rgba(228, 228, 228, 0.1)", + "hover": "rgba(81, 81, 81, 1)", + "hoverA": "rgba(228, 228, 228, 0.255)", + "press": "rgba(112, 112, 112, 1)", + "pressA": "rgba(228, 228, 228, 0.41)", + }, + }, + "icon": { + "default": "rgba(228, 228, 228, 1)", + "disable": "rgba(130, 130, 130, 1)", + "hover": "rgba(202, 202, 202, 1)", + "negative": { + "default": "rgba(252, 147, 134, 1)", + "hover": "rgba(249, 186, 177, 1)", + "press": "rgba(254, 219, 214, 1)", + }, + "notice": { + "default": "rgba(222, 167, 29, 1)", + "hover": "rgba(231, 199, 80, 1)", + "press": "rgba(252, 227, 145, 1)", + }, + "onNegative": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "onNeutral": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "onNotice": { + "default": "rgba(41, 41, 41, 1)", + "hover": "rgba(41, 41, 41, 1)", + "press": "rgba(41, 41, 41, 1)", + }, + "onOnImg": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "onPositive": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "onPrimary": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "positive": { + "default": "rgba(120, 194, 113, 1)", + "hover": "rgba(161, 215, 155, 1)", + "press": "rgba(191, 241, 186, 1)", + }, + "press": "rgba(188, 188, 188, 1)", + "secondary": { + "default": "rgba(175, 175, 175, 1)", + "hover": "rgba(188, 188, 188, 1)", + "press": "rgba(202, 202, 202, 1)", + }, + "tertiary": { + "default": "rgba(130, 130, 130, 1)", + "hover": "rgba(175, 175, 175, 1)", + "press": "rgba(188, 188, 188, 1)", + }, + }, + "text": { + "brandPremium": { + "default": "rgba(253, 158, 22, 1)", + "hover": "rgba(243, 152, 21, 1)", + "press": "rgba(213, 133, 18, 1)", + }, + "default": "rgba(228, 228, 228, 1)", + "disable": "rgba(130, 130, 130, 1)", + "hover": "rgba(202, 202, 202, 1)", + "info": { + "default": "rgba(114, 181, 245, 1)", + "hover": "rgba(166, 205, 245, 1)", + "press": "rgba(207, 230, 253, 1)", + }, + "negative": { + "default": "rgba(252, 147, 134, 1)", + "hover": "rgba(249, 186, 177, 1)", + "press": "rgba(254, 219, 214, 1)", + }, + "notice": { + "default": "rgba(222, 167, 29, 1)", + "hover": "rgba(231, 199, 80, 1)", + "press": "rgba(252, 227, 145, 1)", + }, + "onDiscovery": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "onHud": { + "default": "rgba(31, 31, 31, 1)", + "hover": "rgba(31, 31, 31, 1)", + "press": "rgba(31, 31, 31, 1)", + }, + "onNegative": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "onNotice": { + "default": "rgba(41, 41, 41, 1)", + "hover": "rgba(41, 41, 41, 1)", + "press": "rgba(41, 41, 41, 1)", + }, + "onOnImg": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "onPositive": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "onPrimary": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "placeholder": { + "default": "rgba(112, 112, 112, 1)", + "hover": "rgba(112, 112, 112, 1)", + "press": "rgba(112, 112, 112, 1)", + }, + "positive": { + "default": "rgba(120, 194, 113, 1)", + "hover": "rgba(161, 215, 155, 1)", + "press": "rgba(191, 241, 186, 1)", + }, + "press": "rgba(188, 188, 188, 1)", + "secondary": { + "default": "rgba(175, 175, 175, 1)", + "hover": "rgba(188, 188, 188, 1)", + "press": "rgba(202, 202, 202, 1)", + }, + "tertiary": { + "default": "rgba(130, 130, 130, 1)", + "hover": "rgba(175, 175, 175, 1)", + "press": "rgba(188, 188, 188, 1)", + }, + "visited": { + "default": "rgba(191, 160, 246, 1)", + "hover": "rgba(210, 192, 245, 1)", + "press": "rgba(233, 223, 255, 1)", + }, + }, + }, + "paragraphWidth": { + "l": "672", + "lCompact": "588", + "lCozy": "924", + "m": "448", + "mCompact": "392", + "mCozy": "616", + "s": "320", + "sCompact": "280", + "sCozy": "588", + }, + "radius": { + "0": "0", + "l": "12", + "m": "8", + "oval": "999999", + "s": "4", + "xl": "16", + "xs": "2", + "xxl": "24", + }, + "space": { + "betweenCheckboxes": { + "horizontal": "12", + "vertical": "0", + }, + "layout": { + "0": "0", + "10": "4", + "100": "440", + "20": "8", + "25": "12", + "30": "16", + "40": "24", + "50": "40", + "60": "64", + "70": "104", + "80": "168", + "90": "272", + }, + "target": { + "l": "48", + "m": "40", + "s": "32", + "xs": "24", + }, + }, + "text": { + "fontSize": { + "body": "16", + "caption": { + "m": "14", + "s": "12", + }, + "heading": { + "l": "28", + "m": "25", + "s": "22", + "xl": "32", + "xs": "20", + "xxl": "36", + "xxs": "18", + "xxxl": "40", + "xxxs": "14", + }, + "paragraph": "16", + }, + "fontWeight": { + "bold": "700", + "regular": "400", + }, + "lineHeight": { + "body": "24", + "caption": { + "m": "20", + "s": "18", + }, + "heading": { + "l": "36", + "m": "32", + "s": "28", + "xl": "40", + "xs": "28", + "xxl": "44", + "xxs": "24", + "xxxl": "52", + "xxxs": "20", + }, + "paragraph": "28", + }, + }, +} +`; + +exports[`changeCaseKeys snapshot test: light theme > camelcaseKeys snapshot test 1`] = ` +{ + "borderWidth": { + "focus": { + "1": "1", + "2": "2", + }, + "l": "2", + "m": "1", + }, + "color": { + "background": { + "default": "rgba(255, 255, 255, 1)", + "secondary": "rgba(243, 243, 243, 1)", + "tertiary": "rgba(232, 232, 232, 1)", + }, + "border": { + "default": "rgba(31, 31, 31, 0.475)", + "disable": "rgba(31, 31, 31, 0.102)", + "focus": { + "1": "rgba(31, 117, 188, 1)", + "2": "rgba(188, 222, 252, 1)", + "legacy": "rgba(0, 150, 250, 0.32)", + }, + "hover": "rgba(31, 31, 31, 0.635)", + "hud": "rgba(255, 255, 255, 1)", + "negative": "rgba(253, 206, 199, 1)", + "press": "rgba(31, 31, 31, 0.775)", + "secondary": "rgba(31, 31, 31, 0.102)", + "selected": "rgba(0, 150, 250, 1)", + }, + "container": { + "default": "rgba(255, 255, 255, 1)", + "defaultA": "rgba(31, 31, 31, 0)", + "disable": "rgba(232, 232, 232, 1)", + "discovery": { + "default": "rgba(253, 91, 78, 1)", + "hover": "rgba(206, 54, 46, 1)", + "press": "rgba(147, 33, 28, 1)", + }, + "hover": "rgba(243, 243, 243, 1)", + "hoverA": "rgba(31, 31, 31, 0.055)", + "hud": { + "default": "rgba(56, 56, 56, 1)", + "hover": "rgba(81, 81, 81, 1)", + "press": "rgba(113, 113, 113, 1)", + }, + "negative": { + "default": "rgba(253, 91, 78, 1)", + "hover": "rgba(206, 54, 46, 1)", + "press": "rgba(147, 33, 28, 1)", + }, + "neutral": { + "default": "rgba(148, 148, 148, 1)", + "hover": "rgba(113, 113, 113, 1)", + "press": "rgba(81, 81, 81, 1)", + }, + "notice": { + "default": "rgba(254, 214, 61, 1)", + "hover": "rgba(245, 183, 17, 1)", + "press": "rgba(231, 157, 20, 1)", + }, + "onImg": { + "default": "rgba(31, 31, 31, 0.37)", + "hover": "rgba(31, 31, 31, 0.475)", + "press": "rgba(31, 31, 31, 0.635)", + }, + "positive": { + "default": "rgba(37, 170, 28, 1)", + "hover": "rgba(17, 131, 8, 1)", + "press": "rgba(4, 93, 0, 1)", + }, + "press": "rgba(232, 232, 232, 1)", + "pressA": "rgba(31, 31, 31, 0.102)", + "primary": { + "default": "rgba(0, 150, 250, 1)", + "hover": "rgba(31, 117, 188, 1)", + "press": "rgba(24, 81, 130, 1)", + }, + "secondary": { + "default": "rgba(243, 243, 243, 1)", + "defaultA": "rgba(31, 31, 31, 0.055)", + "hover": "rgba(232, 232, 232, 1)", + "hoverA": "rgba(31, 31, 31, 0.102)", + "press": "rgba(217, 217, 217, 1)", + "pressA": "rgba(31, 31, 31, 0.17)", + }, + "skeleton": "rgba(31, 31, 31, 0.055)", + "subtle": "rgba(31, 31, 31, 0.02)", + "tertiary": { + "default": "rgba(232, 232, 232, 1)", + "defaultA": "rgba(31, 31, 31, 0.102)", + "hover": "rgba(217, 217, 217, 1)", + "hoverA": "rgba(31, 31, 31, 0.17)", + "press": "rgba(194, 194, 194, 1)", + "pressA": "rgba(31, 31, 31, 0.27)", + }, + }, + "icon": { + "default": "rgba(31, 31, 31, 1)", + "disable": "rgba(194, 194, 194, 1)", + "hover": "rgba(56, 56, 56, 1)", + "negative": { + "default": "rgba(206, 54, 46, 1)", + "hover": "rgba(147, 33, 28, 1)", + "press": "rgba(103, 22, 17, 1)", + }, + "notice": { + "default": "rgba(161, 99, 9, 1)", + "hover": "rgba(110, 72, 5, 1)", + "press": "rgba(74, 51, 7, 1)", + }, + "onNegative": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "onNeutral": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(243, 243, 243, 1)", + "press": "rgba(232, 232, 232, 1)", + }, + "onNotice": { + "default": "rgba(31, 31, 31, 1)", + "hover": "rgba(31, 31, 31, 1)", + "press": "rgba(31, 31, 31, 1)", + }, + "onOnImg": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "onPositive": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "onPrimary": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "positive": { + "default": "rgba(17, 131, 8, 1)", + "hover": "rgba(4, 93, 0, 1)", + "press": "rgba(4, 93, 0, 1)", + }, + "press": "rgba(81, 81, 81, 1)", + "secondary": { + "default": "rgba(81, 81, 81, 1)", + "hover": "rgba(56, 56, 56, 1)", + "press": "rgba(31, 31, 31, 1)", + }, + "tertiary": { + "default": "rgba(113, 113, 113, 1)", + "hover": "rgba(81, 81, 81, 1)", + "press": "rgba(56, 56, 56, 1)", + }, + }, + "text": { + "brandPremium": { + "default": "rgba(253, 158, 22, 1)", + "hover": "rgba(243, 152, 21, 1)", + "press": "rgba(213, 133, 18, 1)", + }, + "default": "rgba(31, 31, 31, 1)", + "disable": "rgba(194, 194, 194, 1)", + "hover": "rgba(56, 56, 56, 1)", + "info": { + "default": "rgba(31, 117, 188, 1)", + "hover": "rgba(24, 81, 130, 1)", + "press": "rgba(19, 58, 93, 1)", + }, + "negative": { + "default": "rgba(206, 54, 46, 1)", + "hover": "rgba(147, 33, 28, 1)", + "press": "rgba(103, 22, 17, 1)", + }, + "notice": { + "default": "rgba(161, 99, 9, 1)", + "hover": "rgba(110, 72, 5, 1)", + "press": "rgba(74, 51, 7, 1)", + }, + "onDiscovery": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "onHud": { + "default": "rgba(228, 228, 228, 1)", + "hover": "rgba(228, 228, 228, 1)", + "press": "rgba(228, 228, 228, 1)", + }, + "onNegative": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "onNotice": { + "default": "rgba(31, 31, 31, 1)", + "hover": "rgba(31, 31, 31, 1)", + "press": "rgba(31, 31, 31, 1)", + }, + "onOnImg": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "onPositive": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "onPrimary": { + "default": "rgba(255, 255, 255, 1)", + "hover": "rgba(255, 255, 255, 1)", + "press": "rgba(255, 255, 255, 1)", + }, + "placeholder": { + "default": "rgba(148, 148, 148, 1)", + "hover": "rgba(148, 148, 148, 1)", + "press": "rgba(148, 148, 148, 1)", + }, + "positive": { + "default": "rgba(17, 131, 8, 1)", + "hover": "rgba(4, 93, 0, 1)", + "press": "rgba(7, 64, 4, 1)", + }, + "press": "rgba(81, 81, 81, 1)", + "secondary": { + "default": "rgba(81, 81, 81, 1)", + "hover": "rgba(56, 56, 56, 1)", + "press": "rgba(31, 31, 31, 1)", + }, + "tertiary": { + "default": "rgba(113, 113, 113, 1)", + "hover": "rgba(81, 81, 81, 1)", + "press": "rgba(56, 56, 56, 1)", + }, + "visited": { + "default": "rgba(103, 39, 171, 1)", + "hover": "rgba(70, 32, 115, 1)", + "press": "rgba(40, 16, 70, 1)", + }, + }, + }, + "paragraphWidth": { + "l": "672", + "lCompact": "588", + "lCozy": "924", + "m": "448", + "mCompact": "392", + "mCozy": "616", + "s": "320", + "sCompact": "280", + "sCozy": "588", + }, + "radius": { + "0": "0", + "l": "12", + "m": "8", + "oval": "999999", + "s": "4", + "xl": "16", + "xs": "2", + "xxl": "24", + }, + "space": { + "betweenCheckboxes": { + "horizontal": "12", + "vertical": "0", + }, + "layout": { + "0": "0", + "10": "4", + "100": "440", + "20": "8", + "25": "12", + "30": "16", + "40": "24", + "50": "40", + "60": "64", + "70": "104", + "80": "168", + "90": "272", + }, + "target": { + "l": "48", + "m": "40", + "s": "32", + "xs": "24", + }, + }, + "text": { + "fontSize": { + "body": "16", + "caption": { + "m": "14", + "s": "12", + }, + "heading": { + "l": "28", + "m": "25", + "s": "22", + "xl": "32", + "xs": "20", + "xxl": "36", + "xxs": "18", + "xxxl": "40", + "xxxs": "14", + }, + "paragraph": "16", + }, + "fontWeight": { + "bold": "700", + "regular": "400", + }, + "lineHeight": { + "body": "24", + "caption": { + "m": "20", + "s": "18", + }, + "heading": { + "l": "36", + "m": "32", + "s": "28", + "xl": "40", + "xs": "28", + "xxl": "44", + "xxs": "24", + "xxxl": "52", + "xxxs": "20", + }, + "paragraph": "28", + }, + }, +} +`; diff --git a/packages/theme/src/token-object/helpers/changecase-keys.test-d.ts b/packages/theme/src/token-object/helpers/changecase-keys.test-d.ts new file mode 100644 index 000000000..6ae1dc6ad --- /dev/null +++ b/packages/theme/src/token-object/helpers/changecase-keys.test-d.ts @@ -0,0 +1,32 @@ +import { camelCaseKeys } from './changecase-keys' + +describe('camelcaseKeys test', () => { + it('should convert snake_case keys to camelCase', () => { + const obj = { + snake_case: 'value', + nested: { + another_key: 'another_value', + }, + } + type Result = ReturnType> + expectTypeOf().toEqualTypeOf<{ + snakeCase: string + nested: { anotherKey: string } + }>() + }) + + it('should convert kebab-case keys to camelCase', () => { + const obj = { + 'kebab-case': 'value', + nested: { + 'another-key': 'another_value', + }, + } + type Result = ReturnType> + + expectTypeOf().toEqualTypeOf<{ + kebabCase: string + nested: { anotherKey: string } + }>() + }) +}) diff --git a/packages/theme/src/token-object/helpers/changecase-keys.test.ts b/packages/theme/src/token-object/helpers/changecase-keys.test.ts new file mode 100644 index 000000000..8d1e1f47f --- /dev/null +++ b/packages/theme/src/token-object/helpers/changecase-keys.test.ts @@ -0,0 +1,52 @@ +import { camelCaseKeys } from './changecase-keys' + +import { createTokenObject } from '..' +import lightToken from '../../json/pixiv-light.json' +import darkToken from '../../json/pixiv-dark.json' +import baseToken from '../../json/base.json' + +describe('camelcaseKeys test', () => { + it('should convert snake_case keys to camelCase', () => { + const obj = { + snake_case: 'value', + nested: { + another_key: 'another_value', + }, + } + const result = camelCaseKeys(obj) + expect(result).toEqual({ + snakeCase: 'value', + nested: { + anotherKey: 'another_value', + }, + }) + }) + + it('should convert kebab-case keys to camelCase', () => { + const obj = { + 'kebab-case': 'value', + nested: { + 'another-key': 'another_value', + }, + } + const result = camelCaseKeys(obj) + expect(result).toEqual({ + kebabCase: 'value', + nested: { + anotherKey: 'another_value', + }, + }) + }) +}) + +describe.each([ + ['light theme', lightToken], + ['dark theme', darkToken], +] as const)('changeCaseKeys snapshot test: %s', (description, token) => { + test('camelcaseKeys snapshot test', () => { + const theme = createTokenObject(token, baseToken) + const result = camelCaseKeys(theme) + + expect(result).toMatchSnapshot() + }) +}) diff --git a/packages/theme/src/token-object/helpers/changecase-keys.ts b/packages/theme/src/token-object/helpers/changecase-keys.ts new file mode 100644 index 000000000..9c6c1b4ca --- /dev/null +++ b/packages/theme/src/token-object/helpers/changecase-keys.ts @@ -0,0 +1,42 @@ +import { camelCase } from 'change-case-all' + +const isObject = (value: unknown): value is Record => { + if (value instanceof RegExp) return false + if (value instanceof Date) return false + if (value instanceof Error) return false + + return typeof value === 'object' && value !== null +} + +type CamelCase< + T extends string, + D extends string = '-' +> = T extends `${infer A}${D}${infer B}` + ? `${Lowercase}${Capitalize>}` + : T + +type CamelCaseKeys< + T extends Record, + D extends string = '-' +> = { + [K in keyof T as CamelCase]: T[K] extends Record< + string, + unknown + > + ? CamelCaseKeys + : T[K] +} + +export const camelCaseKeys = < + T extends Record, + Delimiter extends string = '-' +>( + obj: T +): CamelCaseKeys => { + return Object.fromEntries( + Object.entries(obj).map(([key, value]) => [ + camelCase(key), + isObject(value) ? camelCaseKeys(value) : value, + ]) + ) as CamelCaseKeys +} diff --git a/packages/theme/src/token-object/helpers/is-empty-array.ts b/packages/theme/src/token-object/helpers/is-empty-array.ts new file mode 100644 index 000000000..f86786ee2 --- /dev/null +++ b/packages/theme/src/token-object/helpers/is-empty-array.ts @@ -0,0 +1,2 @@ +export const isNonEmptyArray = (arr: T[]): arr is [T, ...T[]] => + arr.length > 0 diff --git a/packages/theme/src/token-object/helpers/nest-object.test.ts b/packages/theme/src/token-object/helpers/nest-object.test.ts new file mode 100644 index 000000000..e12febe0c --- /dev/null +++ b/packages/theme/src/token-object/helpers/nest-object.test.ts @@ -0,0 +1,39 @@ +import { nestObject } from './nest-object' + +describe('nestObject test', () => { + it('should create a nested object from a single key path', () => { + const path: ['a'] = ['a'] + const value = 'value' + const result = nestObject(path, value) + expect(result).toEqual({ a: value }) + }) + + it('should create a nested object from a multi-level key path', () => { + const path: ['a', 'b', 'c'] = ['a', 'b', 'c'] + const value = 'value' + const result = nestObject(path, value) + expect(result).toEqual({ a: { b: { c: value } } }) + }) + + it('should handle nested paths correctly', () => { + const path: ['theme', 'color', 'background', 'default'] = [ + 'theme', + 'color', + 'background', + 'default', + ] + const value = '#ffffff' + const result = nestObject(path, value) + expect(result).toEqual({ + theme: { color: { background: { default: value } } }, + }) + }) + + it('should throw an error if an empty path is provided', () => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + expect(() => nestObject([], 'value')).toThrowError( + 'Path must be a non-empty array' + ) + }) +}) diff --git a/packages/theme/src/token-object/helpers/nest-object.ts b/packages/theme/src/token-object/helpers/nest-object.ts new file mode 100644 index 000000000..d70718f95 --- /dev/null +++ b/packages/theme/src/token-object/helpers/nest-object.ts @@ -0,0 +1,28 @@ +import { isNonEmptyArray } from './is-empty-array' + +type MakeNestObject

= P extends [ + infer Head, + ...infer Tail +] + ? Head extends string + ? Tail extends string[] + ? { + [K in Head]: MakeNestObject + } + : { [K in Head]: T } + : T + : T + +export const nestObject =

( + path: P, + value: T +): MakeNestObject => { + if (!isNonEmptyArray(path)) throw new Error('Path must be a non-empty array') + + const [key, ...rest] = path + if (!isNonEmptyArray(rest)) return { [key]: value } as MakeNestObject + + return { + [key]: nestObject(rest, value), + } as MakeNestObject +} diff --git a/packages/theme/src/token-object/index.ts b/packages/theme/src/token-object/index.ts new file mode 100644 index 000000000..999300f4e --- /dev/null +++ b/packages/theme/src/token-object/index.ts @@ -0,0 +1,60 @@ +import { createReferenceTokenResolver } from './reference-token' +import { toTokenObject } from './to-token-object' +import type { TokenObject, TokenDictionary, TokenValue } from './types' + +import { kebabCase } from 'change-case-all' +export { camelCaseKeys } from './helpers/changecase-keys' + +export const createTokenObject = ( + tokenDictionary: T, + baseTokenDictionary: TokenDictionary +): { [K in keyof T]: TokenObject } => { + const result = {} as { [K in keyof T]: TokenObject } + const referenceTokenResolver = createReferenceTokenResolver( + tokenDictionary, + baseTokenDictionary + ) + + for (const category in tokenDictionary) { + const value = tokenDictionary[category] + + // category ごとに template を展開していく + const resolvedTokens = Object.fromEntries( + Object.entries(value).map(([key, value]) => [ + key, + { value: referenceTokenResolver(value.value) } satisfies TokenValue, + ]) + ) as typeof value + + result[category] = toTokenObject(resolvedTokens) + } + + return result +} + +export const createCSSTokenObject = ( + tokenDictionary: T, + format: (value: string) => string = (value) => value +): { [K in keyof T]: TokenObject } => { + const result = {} as { [K in keyof T]: TokenObject } + + for (const category in tokenDictionary) { + const value = tokenDictionary[category] + + // category ごとに template を展開していく + const resolvedTokens = Object.fromEntries( + Object.entries(value).map(([key]) => [ + key, + { + value: `var(--${format( + [category, ...key.split('/')].map((x) => kebabCase(x)).join('-') + )})`, + } satisfies TokenValue, + ]) + ) as typeof value + + result[category] = toTokenObject(resolvedTokens) + } + + return result +} diff --git a/packages/theme/src/token-object/reference-token.test.ts b/packages/theme/src/token-object/reference-token.test.ts new file mode 100644 index 000000000..020dc466b --- /dev/null +++ b/packages/theme/src/token-object/reference-token.test.ts @@ -0,0 +1,60 @@ +import { createReferenceTokenResolver } from './reference-token' + +describe('createReferenceTokenResolver', () => { + const target = { + colors: { + primary: { value: '{colors.accent}' }, + }, + fonts: { + header: { value: '{fonts.main}' }, + }, + } + + const origin = { + colors: { + accent: { value: '{colors.secondary}' }, + secondary: { value: '#00ff00' }, + }, + fonts: { + main: { value: 'Arial' }, + secondaryHeader: { value: '{fonts.main}' }, + }, + } + + const resolver = createReferenceTokenResolver(target, origin) + + it('should return the same value if not a reference token', () => { + const value = 'no-reference' + expect(resolver(value)).toBe(value) + }) + + it('should resolve a reference token using the reference', () => { + const value = '{colors.primary}' + expect(resolver(value)).toBe('#00ff00') + }) + + it('should resolve a reference token directly from reference', () => { + const value = '{colors.accent}' + expect(resolver(value)).toBe('#00ff00') + }) + + it('should resolve a nested reference token in source via reference', () => { + const value = '{fonts.header}' + expect(resolver(value)).toBe('Arial') + }) + + it('should resolve a reference directly from reference without template source', () => { + const value = '{colors.secondary}' + expect(resolver(value)).toBe('#00ff00') + }) + + it('should resolve a reference in valueReference that points to another valueReference', () => { + const value = '{fonts.secondaryHeader}' + expect(resolver(value)).toBe('Arial') + }) + + it('should throw error for unknown tokens', () => { + const value = '{unknown.category}' + expect(() => resolver(value)).toThrow() + }) +}) diff --git a/packages/theme/src/token-object/reference-token.ts b/packages/theme/src/token-object/reference-token.ts new file mode 100644 index 000000000..b2b12976a --- /dev/null +++ b/packages/theme/src/token-object/reference-token.ts @@ -0,0 +1,32 @@ +import { TokenDictionary, Tokens } from './types' + +export type ReferenceToken = `{${string}}` + +const isReferenceToken = (value: string): value is ReferenceToken => + value.startsWith('{') && value.endsWith('}') + +const parseReferenceToken = ( + value: ReferenceToken +): [category: string, key: string] => { + const [category, key] = value.slice(1, -1).split('.') + + return [category, key] +} + +export const createReferenceTokenResolver = ( + tokenDictionary: T, + baseTokenDictionary: TokenDictionary +) => { + const resolver = (value: string): string => { + if (!isReferenceToken(value)) return value + + const [category, tokenKey] = parseReferenceToken(value) + const baseTokens = baseTokenDictionary[category] as Tokens | undefined + + return resolver( + (baseTokens?.[tokenKey] ?? tokenDictionary[category][tokenKey]).value + ) + } + + return resolver +} diff --git a/packages/theme/src/token-object/to-token-object.ts b/packages/theme/src/token-object/to-token-object.ts new file mode 100644 index 000000000..622026298 --- /dev/null +++ b/packages/theme/src/token-object/to-token-object.ts @@ -0,0 +1,18 @@ +import deepmerge from 'deepmerge' +import { isNonEmptyArray } from './helpers/is-empty-array' +import { nestObject } from './helpers/nest-object' +import { Tokens, TokenObject } from './types' + +export const toTokenObject = (tokens: T): TokenObject => { + let result = {} + for (const key in tokens) { + const { value } = tokens[key] + const splitted = key.split('/') + if (!isNonEmptyArray(splitted)) continue + + const v = nestObject(splitted, value) + result = deepmerge(result, v) + } + + return result as TokenObject +} diff --git a/packages/theme/src/token-object/token-object.bench.ts b/packages/theme/src/token-object/token-object.bench.ts new file mode 100644 index 000000000..d3cd4904e --- /dev/null +++ b/packages/theme/src/token-object/token-object.bench.ts @@ -0,0 +1,23 @@ +import { camelCaseKeys, createCSSTokenObject, createTokenObject } from '.' +import lightToken from '../json/pixiv-light.json' +import darkToken from '../json/pixiv-dark.json' +import baseToken from '../json/base.json' + +import { bench } from 'vitest' + +describe.each([ + ['light theme', lightToken], + ['dark theme', darkToken], +] as const)('createTokenObject test: %s', (description, token) => { + bench('benchmarks token object creation for the theme', () => { + createTokenObject(token, baseToken) + }) + + bench('benchmarks token object creation with camelCase formatting', () => { + camelCaseKeys(createTokenObject(token, baseToken)) + }) + + bench('benchmarks css token object creation', () => { + createCSSTokenObject(token, (value) => `charcoal-${value}`) + }) +}) diff --git a/packages/theme/src/token-object/token-object.test.ts b/packages/theme/src/token-object/token-object.test.ts new file mode 100644 index 000000000..e70a7b61b --- /dev/null +++ b/packages/theme/src/token-object/token-object.test.ts @@ -0,0 +1,174 @@ +import { createCSSTokenObject, createTokenObject } from '.' +import { toTokenObject } from './to-token-object' +import { createReferenceTokenResolver } from './reference-token' +import lightToken from '../json/pixiv-light.json' +import darkToken from '../json/pixiv-dark.json' +import baseToken from '../json/base.json' +import deepmerge from 'deepmerge' +import { Tokens } from './types' +import { readFile } from 'fs/promises' +import { join } from 'node:path' +import { parse } from 'css' + +const isObject = (value: unknown): value is Record => { + if (value instanceof RegExp) return false + if (value instanceof Date) return false + if (value instanceof Error) return false + + return typeof value === 'object' && value !== null +} + +describe.each([ + ['light theme', lightToken], + ['dark theme', darkToken], +] as const)('createTokenObject test: %s', (description, token) => { + const theme = createTokenObject(token, baseToken) + const keys = Object.keys(token) + // 結局実装で使ってるコードで検証してるので意味ないかも + // とはいえほぼこの実装になると思うどうしよう + const templateResolver = createReferenceTokenResolver(token, baseToken) + + // スナップショット + it('should match snapshot', () => { + expect(theme).toMatchSnapshot() + }) + + describe.each(keys)(`[${description}] Category: %s`, (category) => { + const _category = category as keyof typeof token + const tokens = token[_category] + + it.each(Object.keys(tokens))( + `[${description}] ${category} should have %s`, + (key) => { + const splitted = key.split('/') + const tokenValue: { value: string } = tokens[key as keyof typeof tokens] + + expect(theme).toHaveProperty( + [_category, ...splitted], + templateResolver(tokenValue.value) + ) + } + ) + }) +}) + +describe.each([ + ['light theme', lightToken, '../css/_variables_light.css'], + ['dark theme', darkToken, '../css/_variables_dark.css'], +] as const)( + 'createCSSTokenObject test: %s', + async (description, token, cssFilePath) => { + const theme = createCSSTokenObject(token, (value) => `charcoal-${value}`) + const keys = Object.keys(token) + const css = await readFile(join(__dirname, cssFilePath), 'utf-8') + + // スナップショット + it('should match snapshot', () => { + expect(theme).toMatchSnapshot() + }) + + const cssVariables = new Map() + for (const rule of parse(css).stylesheet?.rules ?? []) { + if (rule.type !== 'rule') continue + + for (const declaration of rule.declarations ?? []) { + if ( + declaration.type !== 'declaration' || + declaration.property?.startsWith('--charcoal') !== true + ) + continue + cssVariables.set(declaration.property, declaration.value ?? '') + } + } + + describe.each(keys)(`[${description}] Category: %s`, (category) => { + const _category = category as keyof typeof token + const tokens = token[_category] + + it.each(Object.keys(tokens))( + `[${description}] ${category} should have %s`, + (key) => { + const splitted = key.split('/') + + expect(theme).toHaveProperty( + [_category, ...splitted], + expect.any(String) + ) + const variable = splitted.reduce((acc, key) => { + if (typeof acc === 'string') return acc + + const next = acc[key] + if (typeof next === 'string') return next + + return isObject(next) ? next : acc + }, theme[_category] as Record | string) + + expect( + Array.from(cssVariables.keys()).map((x) => `var(${x})`) + ).toContain(variable) + } + ) + }) + } +) + +describe('toTokenObject test', () => { + const tokens: Tokens = { + 'color/background/default': { value: '#ffffff' }, + 'color/background/secondary': { value: '#f2f2f2' }, + 'space/target/xs': { value: '4px' }, + 'space/target/md': { value: '8px' }, + } + + it('should create a nested object from token paths', () => { + const result = toTokenObject(tokens) + + expect(result).toEqual({ + color: { + background: { + default: tokens['color/background/default'].value, + secondary: tokens['color/background/secondary'].value, + }, + }, + space: { + target: { + xs: tokens['space/target/xs'].value, + md: tokens['space/target/md'].value, + }, + }, + }) + }) + + it('should handle merging of token paths with deepmerge', () => { + const additionalTokens: Tokens = { + 'color/background/default': { value: '#000000' }, + 'space/target/lg': { value: '16px' }, + } + + const mergedResult = deepmerge( + toTokenObject(tokens), + toTokenObject(additionalTokens) + ) + + expect(mergedResult).toEqual({ + color: { + background: { + default: additionalTokens['color/background/default'].value, + secondary: '#f2f2f2', + }, + }, + space: { + target: { + xs: '4px', + md: '8px', + lg: additionalTokens['space/target/lg'].value, + }, + }, + }) + }) + + it('should return an empty object for empty tokens', () => { + const result = toTokenObject({}) + expect(result).toEqual({}) + }) +}) diff --git a/packages/theme/src/token-object/types.ts b/packages/theme/src/token-object/types.ts new file mode 100644 index 000000000..f314b166b --- /dev/null +++ b/packages/theme/src/token-object/types.ts @@ -0,0 +1,21 @@ +type UnionToIntersection = + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (U extends any ? (k: U) => void : never) extends (k: infer I) => void + ? I + : never + +export type TokenValue = { value: string } +export type Tokens = { + [key: string]: TokenValue +} +export type TokenDictionary = { + [category: string]: Tokens +} + +type TokenToObject = S extends `${infer F}/${infer R}` + ? { [K in F]: TokenToObject } + : { [K in S]: V } + +export type TokenObject = UnionToIntersection< + { [K in keyof T]: TokenToObject }[keyof T] +> diff --git a/packages/theme/tsconfig.build.json b/packages/theme/tsconfig.build.json index 585b3f945..079dfe994 100644 --- a/packages/theme/tsconfig.build.json +++ b/packages/theme/tsconfig.build.json @@ -2,8 +2,10 @@ "extends": "../../tsconfig.build.json", "compilerOptions": { "incremental": true, + "resolveJsonModule": true, "outDir": "./dist", "tsBuildInfoFile": "./.tsbuildinfo" }, - "include": ["./src"] + "include": ["./src"], + "exclude": ["./src/docs/*"] } diff --git a/packages/theme/tsconfig.json b/packages/theme/tsconfig.json index ce897777d..5fc5adff9 100644 --- a/packages/theme/tsconfig.json +++ b/packages/theme/tsconfig.json @@ -1,4 +1,7 @@ { "extends": "../../tsconfig.base.json", + "compilerOptions": { + "resolveJsonModule": true + }, "include": ["./src"] } diff --git a/packages/theme/tsup.config.ts b/packages/theme/tsup.config.ts index 32353e14e..739eea7f8 100644 --- a/packages/theme/tsup.config.ts +++ b/packages/theme/tsup.config.ts @@ -1,7 +1,10 @@ import { defineConfig } from 'tsup' export default defineConfig({ - entry: ['src/index.ts'], + entry: { + index: 'src/index.ts', + 'token-object/index': 'src/token-object/index.ts', + }, format: ['esm', 'cjs'], outExtension({ format }) { return { @@ -10,4 +13,5 @@ export default defineConfig({ }, target: 'esnext', sourcemap: true, + clean: true, }) diff --git a/packages/theme/vitest.config.ts b/packages/theme/vitest.config.ts index dad7dcd32..5a1178071 100644 --- a/packages/theme/vitest.config.ts +++ b/packages/theme/vitest.config.ts @@ -5,7 +5,10 @@ import * as path from 'node:path' export default defineConfig({ test: { globals: true, - setupFiles: ['../../vitest.setup.ts'], + typecheck: { + enabled: true, + }, + benchmark: {}, alias: [ { find: /@charcoal-ui\/(.*)/, diff --git a/yarn.lock b/yarn.lock index 0c87fe61c..8c6f1163e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2224,11 +2224,16 @@ __metadata: dependencies: "@charcoal-ui/foundation": ^4.0.0-beta.15 "@charcoal-ui/utils": ^4.0.0-beta.15 + "@types/css": ^0.0.38 + change-case-all: ^2.1.0 cpx: ^1.5.0 + css: ^3.0.0 + deepmerge: ^4.3.1 npm-run-all: ^4.1.5 polished: ^4.1.4 rimraf: ^3.0.2 tsup: ^6.5.0 + tsx: ^4.19.1 typescript: ^4.9.5 vitest: ^2.0.2 languageName: unknown @@ -2662,6 +2667,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/aix-ppc64@npm:0.23.1" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm64@npm:0.18.20" @@ -2690,6 +2702,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm64@npm:0.23.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.15.18": version: 0.15.18 resolution: "@esbuild/android-arm@npm:0.15.18" @@ -2725,6 +2744,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm@npm:0.23.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-x64@npm:0.18.20" @@ -2753,6 +2779,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-x64@npm:0.23.1" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-arm64@npm:0.18.20" @@ -2781,6 +2814,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-arm64@npm:0.23.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-x64@npm:0.18.20" @@ -2809,6 +2849,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-x64@npm:0.23.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-arm64@npm:0.18.20" @@ -2837,6 +2884,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-arm64@npm:0.23.1" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-x64@npm:0.18.20" @@ -2865,6 +2919,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-x64@npm:0.23.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm64@npm:0.18.20" @@ -2893,6 +2954,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm64@npm:0.23.1" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm@npm:0.18.20" @@ -2921,6 +2989,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm@npm:0.23.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ia32@npm:0.18.20" @@ -2949,6 +3024,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ia32@npm:0.23.1" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.14.54": version: 0.14.54 resolution: "@esbuild/linux-loong64@npm:0.14.54" @@ -2991,6 +3073,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-loong64@npm:0.23.1" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-mips64el@npm:0.18.20" @@ -3019,6 +3108,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-mips64el@npm:0.23.1" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ppc64@npm:0.18.20" @@ -3047,6 +3143,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ppc64@npm:0.23.1" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-riscv64@npm:0.18.20" @@ -3075,6 +3178,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-riscv64@npm:0.23.1" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-s390x@npm:0.18.20" @@ -3103,6 +3213,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-s390x@npm:0.23.1" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-x64@npm:0.18.20" @@ -3131,6 +3248,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-x64@npm:0.23.1" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/netbsd-x64@npm:0.18.20" @@ -3159,6 +3283,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/netbsd-x64@npm:0.23.1" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-arm64@npm:0.23.1" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/openbsd-x64@npm:0.18.20" @@ -3187,6 +3325,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-x64@npm:0.23.1" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/sunos-x64@npm:0.18.20" @@ -3215,6 +3360,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/sunos-x64@npm:0.23.1" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-arm64@npm:0.18.20" @@ -3243,6 +3395,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-arm64@npm:0.23.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-ia32@npm:0.18.20" @@ -3271,6 +3430,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-ia32@npm:0.23.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-x64@npm:0.18.20" @@ -3299,6 +3465,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-x64@npm:0.23.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0": version: 4.2.0 resolution: "@eslint-community/eslint-utils@npm:4.2.0" @@ -8738,6 +8911,13 @@ __metadata: languageName: node linkType: hard +"@types/css@npm:^0.0.38": + version: 0.0.38 + resolution: "@types/css@npm:0.0.38" + checksum: c2275227be4af587485a0c1749601b0d96f13d8d430bff19c83242d39f17a764f9ea78c019b6e3b7372f43a35a3245518ad15fb57fdf3fada5f99eb40283c8d7 + languageName: node + linkType: hard + "@types/debug@npm:^4.0.0": version: 4.1.12 resolution: "@types/debug@npm:4.1.12" @@ -9190,7 +9370,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^17.0, @types/node@npm:^17.0.13": +"@types/node@npm:^17.0": version: 17.0.45 resolution: "@types/node@npm:17.0.45" checksum: aa04366b9103b7d6cfd6b2ef64182e0eaa7d4462c3f817618486ea0422984c51fc69fd0d436eae6c9e696ddfdbec9ccaa27a917f7c2e8c75c5d57827fe3d95e8 @@ -9206,6 +9386,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^18.19.59": + version: 18.19.59 + resolution: "@types/node@npm:18.19.59" + dependencies: + undici-types: ~5.26.4 + checksum: 8e45a05aa91437d3d11a346775ac16589353070c504f91a62cd91945a384231ccbbe92009a8e1ae653f954f9de5bf8ff106cc8e26721ecab98914dc019217aef + languageName: node + linkType: hard + "@types/normalize-package-data@npm:^2.4.0": version: 2.4.0 resolution: "@types/normalize-package-data@npm:2.4.0" @@ -12272,6 +12461,18 @@ __metadata: languageName: node linkType: hard +"change-case-all@npm:^2.1.0": + version: 2.1.0 + resolution: "change-case-all@npm:2.1.0" + dependencies: + change-case: ^5.2.0 + sponge-case: ^2.0.2 + swap-case: ^3.0.2 + title-case: ^3.0.3 + checksum: 0aadbdbde682976a9b34b05de930013404052a0eef75145405a99f7d59b06cbbad5a683d0c101b1823564e8d80b37da502884b9d9f6e7c36b8912fe5b2d3ac45 + languageName: node + linkType: hard + "change-case@npm:^4.1.2": version: 4.1.2 resolution: "change-case@npm:4.1.2" @@ -12292,6 +12493,13 @@ __metadata: languageName: node linkType: hard +"change-case@npm:^5.2.0": + version: 5.4.4 + resolution: "change-case@npm:5.4.4" + checksum: a22a25a763719658424ffbcd41e931d2d19cc22399cc765dca447fbe1eaf13e179d5e8ab1677af75f2e814dbddf74e42ffdecb526cd5bc906cc859f62aa154b2 + languageName: node + linkType: hard + "char-regex@npm:^1.0.2": version: 1.0.2 resolution: "char-regex@npm:1.0.2" @@ -12350,7 +12558,7 @@ __metadata: "@types/eslint__js": ^8.42.3 "@types/jest-image-snapshot": ^6.4.0 "@types/jest-specific-snapshot": ^0.5.9 - "@types/node": ^17.0.13 + "@types/node": ^18.19.59 "@types/prettier": ^2.4.3 "@types/styled-components": ^5.1.21 "@types/webpack": ^5.28.0 @@ -13859,6 +14067,13 @@ __metadata: languageName: node linkType: hard +"deepmerge@npm:^4.3.1": + version: 4.3.1 + resolution: "deepmerge@npm:4.3.1" + checksum: 2024c6a980a1b7128084170c4cf56b0fd58a63f2da1660dcfe977415f27b17dbe5888668b59d0b063753f3220719d5e400b7f113609489c90160bb9a5518d052 + languageName: node + linkType: hard + "default-browser-id@npm:3.0.0": version: 3.0.0 resolution: "default-browser-id@npm:3.0.0" @@ -15595,6 +15810,89 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:~0.23.0": + version: 0.23.1 + resolution: "esbuild@npm:0.23.1" + dependencies: + "@esbuild/aix-ppc64": 0.23.1 + "@esbuild/android-arm": 0.23.1 + "@esbuild/android-arm64": 0.23.1 + "@esbuild/android-x64": 0.23.1 + "@esbuild/darwin-arm64": 0.23.1 + "@esbuild/darwin-x64": 0.23.1 + "@esbuild/freebsd-arm64": 0.23.1 + "@esbuild/freebsd-x64": 0.23.1 + "@esbuild/linux-arm": 0.23.1 + "@esbuild/linux-arm64": 0.23.1 + "@esbuild/linux-ia32": 0.23.1 + "@esbuild/linux-loong64": 0.23.1 + "@esbuild/linux-mips64el": 0.23.1 + "@esbuild/linux-ppc64": 0.23.1 + "@esbuild/linux-riscv64": 0.23.1 + "@esbuild/linux-s390x": 0.23.1 + "@esbuild/linux-x64": 0.23.1 + "@esbuild/netbsd-x64": 0.23.1 + "@esbuild/openbsd-arm64": 0.23.1 + "@esbuild/openbsd-x64": 0.23.1 + "@esbuild/sunos-x64": 0.23.1 + "@esbuild/win32-arm64": 0.23.1 + "@esbuild/win32-ia32": 0.23.1 + "@esbuild/win32-x64": 0.23.1 + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 0413c3b9257327fb598427688b7186ea335bf1693746fe5713cc93c95854d6388b8ed4ad643fddf5b5ace093f7dcd9038dd58e087bf2da1f04dfb4c5571660af + languageName: node + linkType: hard + "escalade@npm:^3.1.1": version: 3.1.1 resolution: "escalade@npm:3.1.1" @@ -17266,6 +17564,15 @@ __metadata: languageName: node linkType: hard +"get-tsconfig@npm:^4.7.5": + version: 4.8.1 + resolution: "get-tsconfig@npm:4.8.1" + dependencies: + resolve-pkg-maps: ^1.0.0 + checksum: 12df01672e691d2ff6db8cf7fed1ddfef90ed94a5f3d822c63c147a26742026d582acd86afcd6f65db67d809625d17dd7f9d34f4d3f38f69bc2f48e19b2bdd5b + languageName: node + linkType: hard + "get-value@npm:^2.0.3, get-value@npm:^2.0.6": version: 2.0.6 resolution: "get-value@npm:2.0.6" @@ -26916,6 +27223,13 @@ __metadata: languageName: node linkType: hard +"sponge-case@npm:^2.0.2": + version: 2.0.3 + resolution: "sponge-case@npm:2.0.3" + checksum: e66fd121e05c9414780283f286d78d487319cc678835bd47a173144261610329435a2a4b7752cd1c4df1531fce08951f5241a6235b291c6679ce1030932f5bc1 + languageName: node + linkType: hard + "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -27577,6 +27891,13 @@ __metadata: languageName: node linkType: hard +"swap-case@npm:^3.0.2": + version: 3.0.3 + resolution: "swap-case@npm:3.0.3" + checksum: af210c61c9eecd8af539a214ba42c7f6ece7a9849dcd365bdd3e197200f909b134872b7ffa17f8227fed05215a1c46da343d08a8086f0b3400269ebd4676efe0 + languageName: node + linkType: hard + "swc-loader@npm:^0.2.3": version: 0.2.3 resolution: "swc-loader@npm:0.2.3" @@ -27974,6 +28295,15 @@ __metadata: languageName: node linkType: hard +"title-case@npm:^3.0.3": + version: 3.0.3 + resolution: "title-case@npm:3.0.3" + dependencies: + tslib: ^2.0.3 + checksum: e8b7ea006b53cf3208d278455d9f1e22c409459d7f9878da324fa3b18cc0aef8560924c19c744e870394a5d9cddfdbe029ebae9875909ee7f4fc562e7cbfc53e + languageName: node + linkType: hard + "tmp@npm:^0.0.33": version: 0.0.33 resolution: "tmp@npm:0.0.33" @@ -28366,6 +28696,22 @@ __metadata: languageName: node linkType: hard +"tsx@npm:^4.19.1": + version: 4.19.1 + resolution: "tsx@npm:4.19.1" + dependencies: + esbuild: ~0.23.0 + fsevents: ~2.3.3 + get-tsconfig: ^4.7.5 + dependenciesMeta: + fsevents: + optional: true + bin: + tsx: dist/cli.mjs + checksum: 31bfd2df62c1230f7c15f6e24d3790019ba7b2ad497221cb0cebcf5cf4f2c1ac971fac0d1283e3d80dc823652d2f9be946bd40ac65b640ff3f199b84a904a9c7 + languageName: node + linkType: hard + "tuf-js@npm:^1.1.7": version: 1.1.7 resolution: "tuf-js@npm:1.1.7"