From 5beb5aa4b10bcbd1dad3d4740313482ae381a13c Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Thu, 30 Jul 2026 20:27:44 +0300 Subject: [PATCH 01/40] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=20=D0=B4=D0=B8=D0=B7=D0=B0=D0=B9=D0=BD-=D1=82?= =?UTF-8?q?=D0=BE=D0=BA=D0=B5=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eslint.config.ts | 4 + package.json | 8 +- scripts/token-generator/README.md | 102 +++++ .../__tests__/compiler.test.ts | 353 ++++++++++++++++++ scripts/token-generator/build.ts | 84 +++++ scripts/token-generator/core/compiler.ts | 206 ++++++++++ scripts/token-generator/core/normalization.ts | 151 ++++++++ scripts/token-generator/core/resolution.ts | 99 +++++ scripts/token-generator/core/tree.ts | 49 +++ scripts/token-generator/core/types.ts | 26 ++ scripts/token-generator/core/validation.ts | 81 ++++ scripts/token-generator/io.ts | 109 ++++++ scripts/token-generator/tsconfig.json | 11 + yarn.lock | 3 +- 14 files changed, 1284 insertions(+), 2 deletions(-) create mode 100644 scripts/token-generator/README.md create mode 100644 scripts/token-generator/__tests__/compiler.test.ts create mode 100644 scripts/token-generator/build.ts create mode 100644 scripts/token-generator/core/compiler.ts create mode 100644 scripts/token-generator/core/normalization.ts create mode 100644 scripts/token-generator/core/resolution.ts create mode 100644 scripts/token-generator/core/tree.ts create mode 100644 scripts/token-generator/core/types.ts create mode 100644 scripts/token-generator/core/validation.ts create mode 100644 scripts/token-generator/io.ts create mode 100644 scripts/token-generator/tsconfig.json diff --git a/eslint.config.ts b/eslint.config.ts index 8b9966fb..29583883 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -5,6 +5,10 @@ import { MobileConfig } from './configs/eslint' export default defineConfig([ ...MobileConfig, { files: ['configs/eslint/**/*'], rules: { 'max-lines': 'off' } }, + { + files: ['scripts/**/*.ts'], + rules: { 'import-x/no-nodejs-modules': 'off' }, + }, { ignores: [ 'node_modules/**/*', diff --git a/package.json b/package.json index 89b10451..16255f20 100644 --- a/package.json +++ b/package.json @@ -31,12 +31,17 @@ } }, "scripts": { - "build": "rm -rf dist && tsc -p tsconfig.build.json", + "build": "yarn tokens:validate && rm -rf dist && tsc -p tsconfig.build.json", "test": "jest", "start": "expo start --dev-client --clear", "android": "expo run:android", "ios": "expo run:ios --no-install", "storybook-generate": "sb-rn-get-stories --config-path .storybook && sed -i -e 's/export const view = global.view/export const view: ReturnType = global.view/' .storybook/storybook.requires.ts && prettier .storybook --write", + "tokens:generate": "ts-node --project scripts/token-generator/tsconfig.json scripts/token-generator/build.ts && yarn tokens:format", + "tokens:format": "prettier 'design-tokens/input/*.json' 'src/theme/tokens/**/*.json' --write", + "tokens:check": "ts-node --project scripts/token-generator/tsconfig.json scripts/token-generator/build.ts --check", + "tokens:typecheck": "tsc --noEmit -p scripts/token-generator/tsconfig.json", + "tokens:validate": "yarn tokens:typecheck && yarn tokens:check", "doctor": "expo-doctor", "check": "expo install --check", "lint:check": "eslint --cache .", @@ -75,6 +80,7 @@ "@testing-library/react-native": "13.3.3", "@types/jest": "29.5.14", "@types/lodash.map": "4.6.13", + "@types/node": "22.7.7", "@types/react": "19.2.14", "babel-loader": "8.2.3", "chalk": "4.1.2", diff --git a/scripts/token-generator/README.md b/scripts/token-generator/README.md new file mode 100644 index 00000000..bbe25f0b --- /dev/null +++ b/scripts/token-generator/README.md @@ -0,0 +1,102 @@ +# Генератор токенов + +Генератор преобразует входные токены из Figma в JSON для React Native. + +## Обновление токенов + +1. Обновить `design-tokens/input/tokens.json`. +2. Запустить `yarn tokens:generate`. +3. Проверить изменения в `src/theme/tokens`. +4. Запустить `yarn tokens:validate`. +5. Закоммитить входные и сгенерированные токены вместе. + +`tokens:generate` записывает и форматирует файлы. `tokens:validate` ничего не +меняет: проверяет TypeScript генератора и актуальность сгенерированных токенов. + +## Использование в компонентах + +Внутри UI Kit используются component-токены: + +```ts +StyleSheet.create(({ components }) => ({ + header: { + backgroundColor: components.accordion.colorScheme.header.background, + }, +})) +``` + +Semantic-токены доступны потребителям библиотеки в `semantic`. Unistyles +подставляет соответствующие light- или dark-токены при переключении темы. + +## Результат генерации + +Из `design-tokens/input/tokens.json` создаются четыре файла: + +```text +src/theme/tokens +├── semantic +│ ├── light.json +│ └── dark.json +└── components + ├── light.json + └── dark.json +``` + +Для каждого выходного файла выбирается соответствующая ветка `colorScheme.light` +или `colorScheme.dark`. Ключ `colorScheme` сохраняется, а уровень `light`/`dark` +удаляется: + +```text +semantic.colorScheme.light.color +→ semantic/light.json: colorScheme.color + +components.button.colorScheme.light.outlined +→ components/light.json: button.colorScheme.outlined +``` + +`primitive` нужен только для подстановки ссылок и не записывается в результат. +Light- и dark-файлы должны иметь одинаковую структуру и типы значений. + +## Преобразование значений + +Ссылки разрешаются до нормализации. Поддерживаются ссылки на всё значение и +вставки внутри строк: + +```text +"{dimension.space.400}" -> "0.875rem" -> 14 + +"inset 0 0 0 {dimension.focusRing.width} {colors.solid.green.200}" +-> "inset 0 0 0 4px #d4fedc" +``` + +```text +"1.5rem" -> 24 +"150ms" -> 150 +"0" -> 0 +``` + +CSS shorthand из 2–4 значений раскрывается в поля React Native: + +```text +padding: "8 14" +-> paddingTop: 8 +-> paddingRight: 14 +-> paddingBottom: 8 +-> paddingLeft: 14 +``` + +Генерация завершается с ошибкой при отсутствующей или циклической ссылке, +неподдерживаемом shorthand, оставшихся `rem`/`ms`, `NaN` или `Infinity`. + +## Автоматические проверки + +`yarn tokens:validate` запускается при сборке, в CI и перед push. Если +сгенерированные файлы устарели, нужно выполнить `yarn tokens:generate` и +проверить diff. + +## Устройство генератора + +Для изменения генератора: `core/compiler.ts` собирает темы, `core/resolution.ts` +разрешает ссылки, `core/normalization.ts` преобразует значения, +`core/validation.ts` проверяет результат. CLI и запись файлов находятся в +`build.ts` и `io.ts`. diff --git a/scripts/token-generator/__tests__/compiler.test.ts b/scripts/token-generator/__tests__/compiler.test.ts new file mode 100644 index 00000000..a0be0dc4 --- /dev/null +++ b/scripts/token-generator/__tests__/compiler.test.ts @@ -0,0 +1,353 @@ +import { readdirSync, mkdtempSync, writeFileSync, rmSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' + +import { + INPUT_DIRECTORY, + INPUT_FILE, + TOKENS_DIRECTORY, + parseArgs, +} from '../build' +import { compileTokens } from '../core/compiler' +import { convertUnit, parseBoxShorthand } from '../core/normalization' +import { resolveReferences } from '../core/resolution' +import { + isTokenTree, + type CompiledTokens, + type TokenTree, + type TokenValue, +} from '../core/types' +import { + OUTPUT_FILES, + findStaleGeneratedTokens, + loadTokenTree, + writeGeneratedTokens, +} from '../io' + +const listJsonFiles = (directory: string, prefix = ''): string[] => + readdirSync(directory, { withFileTypes: true }) + .flatMap((entry) => { + const relativePath = join(prefix, entry.name) + + return entry.isDirectory() + ? listJsonFiles(join(directory, entry.name), relativePath) + : entry.name.endsWith('.json') + ? [relativePath] + : [] + }) + .sort() + +const containsColorSchemeThemeBranch = (node: TokenValue): boolean => { + if (Array.isArray(node)) return node.some(containsColorSchemeThemeBranch) + + if (!isTokenTree(node)) return false + + return Object.entries(node).some(([key, value]) => { + if ( + key === 'colorScheme' && + isTokenTree(value) && + ('light' in value || 'dark' in value) + ) { + return true + } + + return containsColorSchemeThemeBranch(value) + }) +} + +describe('token compiler', () => { + describe('convertUnit', () => { + test.each([ + { name: 'положительный rem', value: '1.5rem', expected: 24 }, + { name: 'отрицательный rem', value: '-0.5rem', expected: -8 }, + { name: 'миллисекунды', value: '150ms', expected: 150 }, + { name: 'строковый ноль', value: '0', expected: 0 }, + { + name: 'rem внутри составной строки', + value: 'inset 0 0 0 0.25rem #fff', + expected: 'inset 0 0 0 4px #fff', + }, + { name: 'обычная строка', value: 'auto', expected: 'auto' }, + ])('$name преобразуется в ожидаемое значение', ({ value, expected }) => { + expect(convertUnit(value)).toBe(expected) + }) + }) + + describe('parseBoxShorthand', () => { + test.each([ + { + name: 'одно значение', + value: '8', + expected: { top: 8, right: 8, bottom: 8, left: 8 }, + }, + { + name: 'два значения', + value: '8 14', + expected: { top: 8, right: 14, bottom: 8, left: 14 }, + }, + { + name: 'три значения', + value: '8 14 10', + expected: { top: 8, right: 14, bottom: 10, left: 14 }, + }, + { + name: 'четыре значения с rem', + value: '0rem 1.5rem 0.875rem 1.5rem', + expected: { top: 0, right: 24, bottom: 14, left: 24 }, + }, + ])('$name раскрывается по правилам CSS', ({ value, expected }) => { + expect(parseBoxShorthand(value)).toStrictEqual(expected) + }) + + test.each([ + { name: 'пустая строка', value: '', message: 'Expected 1-4 box values' }, + { + name: 'пять значений', + value: '1 2 3 4 5', + message: 'Expected 1-4 box values', + }, + { + name: 'неподдерживаемая единица', + value: '1px 2px', + message: 'Invalid box value', + }, + { + name: 'нечисловое значение', + value: 'auto', + message: 'Invalid box value', + }, + ])('$name отклоняется', ({ value, message }) => { + expect(() => parseBoxShorthand(value)).toThrow(message) + }) + }) + + test('разделяет один источник на темы, разрешает ссылки и нормализует значения', () => { + const source: TokenTree = { + primitive: { + sizing: { small: '0.5rem', base: '1rem' }, + motion: { fast: '150ms' }, + }, + semantic: { + dimension: { + spacing: { small: '{sizing.small}', base: '{sizing.base}' }, + }, + effects: { duration: '{motion.fast}' }, + colorScheme: { + light: { color: { text: '#111111' } }, + dark: { color: { text: '#eeeeee' } }, + }, + }, + components: { + demo: { + extend: { + padding: '{dimension.spacing.small} {dimension.spacing.base}', + }, + root: { + margin: '{dimension.spacing.base}', + duration: '{effects.duration}', + borderWidth: '0rem 0rem {dimension.spacing.small} 0rem', + }, + icon: { size: '{dimension.spacing.base}' }, + colorScheme: { + light: { color: '{color.text}' }, + dark: { color: '{color.text}' }, + }, + }, + }, + } + + const compiled = compileTokens(source) + + expect(compiled).not.toHaveProperty('primitive') + expect(compiled.semantic).toStrictEqual({ + light: { + colorScheme: { color: { text: '#111111' } }, + dimension: { spacing: { small: 8, base: 16 } }, + effects: { duration: 150 }, + }, + dark: { + colorScheme: { color: { text: '#eeeeee' } }, + dimension: { spacing: { small: 8, base: 16 } }, + effects: { duration: 150 }, + }, + }) + expect(compiled.components.light).toStrictEqual({ + demo: { + extend: { + paddingTop: 8, + paddingRight: 16, + paddingBottom: 8, + paddingLeft: 16, + }, + root: { + margin: 16, + duration: 150, + borderTopWidth: 0, + borderRightWidth: 0, + borderBottomWidth: 8, + borderLeftWidth: 0, + }, + icon: { size: 16 }, + colorScheme: { color: '#111111' }, + }, + }) + expect(compiled.components.dark.demo).toHaveProperty( + 'colorScheme.color', + '#eeeeee' + ) + expect(compiled.components.light.demo).not.toHaveProperty( + 'colorScheme.light' + ) + expect(compiled.components.dark.demo).not.toHaveProperty('colorScheme.dark') + }) + + test('отклоняет источник без одной из цветовых схем semantic', () => { + const source: TokenTree = { + primitive: {}, + semantic: { colorScheme: { light: {} } }, + components: {}, + } + + expect(() => compileTokens(source)).toThrow( + 'Expected an object at "semantic.colorScheme.dark"' + ) + }) + + test('отклоняет циклические ссылки', () => { + const references: TokenTree = { first: '{second}', second: '{first}' } + + expect(() => resolveReferences('{first}', references)).toThrow( + 'Circular token reference' + ) + }) +}) + +describe('production input tokens', () => { + const source = loadTokenTree(INPUT_FILE) + const compiled: CompiledTokens = compileTokens(source) + + test('использует единственный входной tokens-файл', () => { + const tokenFiles = readdirSync(INPUT_DIRECTORY) + .filter((fileName) => /\.json$/.test(fileName)) + .sort() + + expect(tokenFiles).toStrictEqual(['tokens.json']) + }) + + test('не экспортирует primitive и убирает разделение тем из colorScheme', () => { + expect(Object.keys(compiled)).toStrictEqual(['semantic', 'components']) + expect(compiled).not.toHaveProperty('primitive') + + const inputComponents = source.components + const lightOutputComponents = compiled.components.light + const darkOutputComponents = compiled.components.dark + + if ( + !isTokenTree(inputComponents) || + !isTokenTree(inputComponents.button) || + !isTokenTree(lightOutputComponents.button) + ) { + throw new Error('Expected component namespaces') + } + + expect(Object.keys(lightOutputComponents).sort()).toStrictEqual( + Object.keys(inputComponents).sort() + ) + expect(Object.keys(darkOutputComponents).sort()).toStrictEqual( + Object.keys(inputComponents).sort() + ) + expect(lightOutputComponents.button).toHaveProperty('extend') + expect(lightOutputComponents.button).toHaveProperty('root') + expect(lightOutputComponents.button).toHaveProperty('colorScheme') + expect(darkOutputComponents.button).toHaveProperty('colorScheme') + expect(compiled.semantic.light).toHaveProperty('colorScheme.color') + expect(compiled.semantic.dark).toHaveProperty('colorScheme.color') + expect( + [ + compiled.semantic.light, + compiled.semantic.dark, + compiled.components.light, + compiled.components.dark, + ].filter(containsColorSchemeThemeBranch) + ).toHaveLength(0) + }) + + test('содержит только целевые файлы', () => { + const tokenFiles = listJsonFiles(TOKENS_DIRECTORY) + const expectedFiles = Object.values(OUTPUT_FILES) + .flatMap((group) => Object.values(group)) + .sort() + + expect(tokenFiles).toStrictEqual(expectedFiles) + }) + + test('не содержит неразрешённых ссылок и CSS-единиц', () => { + const serialized = JSON.stringify(compiled) + + expect(serialized).not.toMatch(/\{[a-z][^}]*\}/i) + expect(serialized).not.toMatch(/-?\d*\.?\d+(?:rem|ms)\b/) + }) + + test('совпадает с закоммиченными сгенерированными токенами', () => { + expect(findStaleGeneratedTokens(compiled, TOKENS_DIRECTORY)).toStrictEqual( + [] + ) + }) + + test('component-токены содержат выбранную схему на исходных путях', () => { + expect(compiled.components.light.accordion).toHaveProperty('root') + expect(compiled.components.light.accordion).toHaveProperty('extend') + expect(compiled.components.light.accordion).toHaveProperty( + 'colorScheme.header.background' + ) + expect(compiled.components.dark.accordion).toHaveProperty( + 'colorScheme.header.background' + ) + }) + + test('после записи повторная проверка не находит изменений', () => { + const temporaryDirectory = mkdtempSync(join(tmpdir(), 'token-generator-')) + + try { + writeGeneratedTokens(compiled, temporaryDirectory) + + expect(listJsonFiles(temporaryDirectory)).toStrictEqual( + Object.values(OUTPUT_FILES) + .flatMap((group) => Object.values(group)) + .sort() + ) + expect( + findStaleGeneratedTokens(compiled, temporaryDirectory) + ).toStrictEqual([]) + + writeFileSync(join(temporaryDirectory, 'common.json'), '{}\n') + + expect(findStaleGeneratedTokens(compiled, temporaryDirectory)).toContain( + 'common.json' + ) + + writeFileSync( + join(temporaryDirectory, OUTPUT_FILES.semantic.light), + '{}\n' + ) + + expect(findStaleGeneratedTokens(compiled, temporaryDirectory)).toContain( + OUTPUT_FILES.semantic.light + ) + } finally { + rmSync(temporaryDirectory, { recursive: true, force: true }) + } + }) +}) + +describe('token generator CLI', () => { + test('распознаёт check-режим', () => { + expect(parseArgs(['--check'])).toStrictEqual({ check: true, help: false }) + }) + + test('отклоняет неизвестный аргумент', () => { + expect(() => parseArgs(['--unknown'])).toThrow( + 'Неизвестный аргумент "--unknown"' + ) + }) +}) diff --git a/scripts/token-generator/build.ts b/scripts/token-generator/build.ts new file mode 100644 index 00000000..d4fb1510 --- /dev/null +++ b/scripts/token-generator/build.ts @@ -0,0 +1,84 @@ +import { resolve, join } from 'node:path' + +import { compileTokens } from './core/compiler' +import type { CompiledTokens } from './core/types' +import { + findStaleGeneratedTokens, + loadTokenTree, + writeGeneratedTokens, +} from './io' + +export const DESIGN_TOKENS_DIRECTORY = resolve(__dirname, '../../design-tokens') +export const INPUT_DIRECTORY = join(DESIGN_TOKENS_DIRECTORY, 'input') +export const TOKENS_DIRECTORY = resolve(__dirname, '../../src/theme/tokens') +export const INPUT_FILE = join(INPUT_DIRECTORY, 'tokens.json') + +interface CliOptions { + check: boolean + help: boolean +} + +const HELP = `Использование: + yarn tokens:generate + yarn tokens:check + +Опции: + --check проверить актуальность сгенерированных токенов без записи + --help показать эту справку` + +export const parseArgs = (arguments_: string[]): CliOptions => { + const options: CliOptions = { check: false, help: false } + + for (const argument of arguments_) { + if (argument === '--check') options.check = true + else if (argument === '--help') options.help = true + else { + throw new Error(`Неизвестный аргумент "${argument}"`) + } + } + + return options +} + +export const compileInputTokens = (): CompiledTokens => + compileTokens(loadTokenTree(INPUT_FILE)) + +export const run = (arguments_: string[]): void => { + const options = parseArgs(arguments_) + + if (options.help) { + console.log(HELP) + + return + } + + const compiled = compileInputTokens() + + if (options.check) { + const staleFiles = findStaleGeneratedTokens(compiled, TOKENS_DIRECTORY) + + if (staleFiles.length > 0) { + throw new Error( + `Сгенерированные токены устарели: ${staleFiles.join(', ')}. ` + + 'Запустите yarn tokens:generate.' + ) + } + + console.log('Сгенерированные токены актуальны.') + + return + } + + writeGeneratedTokens(compiled, TOKENS_DIRECTORY) + console.log(`Сгенерированные токены записаны в ${TOKENS_DIRECTORY}`) +} + +if (require.main === module) { + try { + run(process.argv.slice(2)) + } catch (error: unknown) { + const message = error instanceof Error ? error.message : String(error) + console.error(message) + process.exitCode = 1 + } +} diff --git a/scripts/token-generator/core/compiler.ts b/scripts/token-generator/core/compiler.ts new file mode 100644 index 00000000..1c57644a --- /dev/null +++ b/scripts/token-generator/core/compiler.ts @@ -0,0 +1,206 @@ +import { normalizeTree } from './normalization' +import { resolveReferences } from './resolution' +import { mergeTrees, resolvePath } from './tree' +import { + isTokenTree, + type CompiledTokens, + type ThemeTokens, + type TokenTree, + type TokenValue, +} from './types' +import { assertSameShape, assertValidOutput } from './validation' + +type ColorScheme = keyof ThemeTokens + +const compileGroup = ( + input: TokenValue, + group: 'semantic' | 'components', + scheme: 'light' | 'dark' +): TokenTree => { + const normalized = normalizeTree(input, group) + + if (!isTokenTree(normalized)) { + throw new Error( + `Expected an object at "${group}" in ${scheme} input tokens` + ) + } + + assertValidOutput(normalized, `${scheme}.${group}`) + + return normalized +} + +const getGroup = ( + source: TokenTree, + group: 'primitive' | 'semantic' | 'components' +): TokenTree => { + const value = resolvePath(source, group) + + if (!isTokenTree(value)) { + throw new Error(`Expected an object at "${group}" in input tokens`) + } + + return value +} + +const selectColorScheme = ( + group: TokenTree, + scheme: ColorScheme, + tokenPath: string +): TokenTree => { + const { colorScheme } = group + const selectedScheme = isTokenTree(colorScheme) + ? colorScheme[scheme] + : undefined + + if (!isTokenTree(selectedScheme)) { + throw new Error( + `Expected an object at "${tokenPath}.colorScheme.${scheme}"` + ) + } + + return Object.fromEntries( + Object.entries(group).map(([key, value]) => [ + key, + key === 'colorScheme' ? mergeTrees({}, selectedScheme) : value, + ]) + ) +} + +const selectComponentColorSchemes = ( + components: TokenTree, + scheme: ColorScheme +): TokenTree => + Object.fromEntries( + Object.entries(components).map(([componentName, component]) => { + if (!isTokenTree(component)) { + throw new Error(`Expected an object at "components.${componentName}"`) + } + + const { colorScheme, ...base } = component + + if (colorScheme === undefined) { + return [componentName, mergeTrees({}, base)] + } + + const selectedScheme = isTokenTree(colorScheme) + ? colorScheme[scheme] + : undefined + + if (!isTokenTree(selectedScheme)) { + throw new Error( + `Expected an object at "components.${componentName}.colorScheme.${scheme}"` + ) + } + + return [ + componentName, + Object.fromEntries( + Object.entries(component).map(([key, value]) => [ + key, + key === 'colorScheme' ? mergeTrees({}, selectedScheme) : value, + ]) + ), + ] + }) + ) + +const unwrapColorScheme = (group: TokenTree, tokenPath: string): TokenTree => { + const { colorScheme, ...base } = group + + if (!isTokenTree(colorScheme)) { + throw new Error(`Expected an object at "${tokenPath}.colorScheme"`) + } + + return mergeTrees(base, colorScheme) +} + +const createReferenceRoot = ( + primitive: TokenTree, + semantic: TokenTree +): TokenTree => { + const duplicateKeys = Object.keys(primitive).filter((key) => key in semantic) + + if (duplicateKeys.length > 0) { + throw new Error( + `Duplicate primitive and semantic namespaces: ${duplicateKeys.join(', ')}` + ) + } + + return { ...primitive, ...semantic } +} + +const compileScheme = ( + primitive: TokenTree, + semanticSource: TokenTree, + componentsSource: TokenTree, + scheme: ColorScheme +): { semantic: TokenTree; components: TokenTree } => { + const selectedSemantic = selectColorScheme(semanticSource, scheme, 'semantic') + const semanticForReferences = unwrapColorScheme(selectedSemantic, 'semantic') + const semanticReferences = createReferenceRoot( + primitive, + semanticForReferences + ) + const resolvedSemanticForReferences = resolveReferences( + semanticForReferences, + semanticReferences, + `${scheme}.semantic` + ) + const resolvedSemantic = resolveReferences( + selectedSemantic, + semanticReferences, + `${scheme}.semantic` + ) + + if ( + !isTokenTree(resolvedSemantic) || + !isTokenTree(resolvedSemanticForReferences) + ) { + throw new Error(`Expected resolved semantic tokens for "${scheme}"`) + } + + const componentReferences = createReferenceRoot( + primitive, + resolvedSemanticForReferences + ) + const selectedComponents = selectComponentColorSchemes( + componentsSource, + scheme + ) + const resolvedComponents = resolveReferences( + selectedComponents, + componentReferences, + `${scheme}.components` + ) + + return { + semantic: compileGroup(resolvedSemantic, 'semantic', scheme), + components: compileGroup(resolvedComponents, 'components', scheme), + } +} + +export const compileTokens = (source: TokenTree): CompiledTokens => { + const primitive = getGroup(source, 'primitive') + const semanticSource = getGroup(source, 'semantic') + const componentsSource = getGroup(source, 'components') + const light = compileScheme( + primitive, + semanticSource, + componentsSource, + 'light' + ) + const dark = compileScheme( + primitive, + semanticSource, + componentsSource, + 'dark' + ) + const semantic = { light: light.semantic, dark: dark.semantic } + const components = { light: light.components, dark: dark.components } + + assertSameShape(semantic.light, semantic.dark) + assertSameShape(components.light, components.dark) + + return { semantic, components } +} diff --git a/scripts/token-generator/core/normalization.ts b/scripts/token-generator/core/normalization.ts new file mode 100644 index 00000000..6856ba86 --- /dev/null +++ b/scripts/token-generator/core/normalization.ts @@ -0,0 +1,151 @@ +import { + isTokenTree, + type BoxEdges, + type TokenPrimitive, + type TokenTree, + type TokenValue, +} from './types' + +const REM_BASE = 16 +export const BOX_PROPERTIES = ['padding', 'margin', 'borderWidth'] as const + +export type BoxProperty = (typeof BOX_PROPERTIES)[number] + +export const convertUnit = (value: TokenPrimitive): TokenPrimitive => { + if (typeof value !== 'string') return value + + const isRem = /^-?\d*\.?\d+rem$/.test(value) + + if (isRem) return Number(value.slice(0, -3)) * REM_BASE + + const isMilliseconds = /^-?\d*\.?\d+ms$/.test(value) + + if (isMilliseconds) return Number(value.slice(0, -2)) + + if (value === '0') return 0 + + return value.replace(/-?\d*\.?\d+rem\b/g, (token) => { + const pixels = Number(token.slice(0, -3)) * REM_BASE + + return `${pixels}px` + }) +} + +const parseBoxPart = (part: string, tokenPath: string): number => { + if (!/^-?\d*\.?\d+(?:rem)?$/.test(part)) { + throw new Error(`Invalid box value "${part}" at "${tokenPath}"`) + } + + const isRem = part.endsWith('rem') + const value = Number(isRem ? part.slice(0, -3) : part) + const normalized = isRem ? value * REM_BASE : value + + if (!Number.isFinite(normalized)) { + throw new Error(`Non-finite box value "${part}" at "${tokenPath}"`) + } + + return normalized +} + +export const parseBoxShorthand = ( + value: string | number, + tokenPath = 'box' +): BoxEdges => { + const parts = + typeof value === 'number' + ? [value] + : value + .trim() + .split(/\s+/) + .filter(Boolean) + .map((part) => parseBoxPart(part, tokenPath)) + + if (parts.length === 0 || parts.length > 4) { + throw new Error(`Expected 1-4 box values at "${tokenPath}"`) + } + + const [top, right = top, bottom = top, left = right] = parts + + if ( + top === undefined || + right === undefined || + bottom === undefined || + left === undefined + ) { + throw new Error(`Unable to expand box value at "${tokenPath}"`) + } + + return { top, right, bottom, left } +} + +const edgePropertyName = ( + property: BoxProperty, + edge: keyof BoxEdges +): string => { + const capitalizedEdge = `${edge[0].toUpperCase()}${edge.slice(1)}` + + return property === 'borderWidth' + ? `border${capitalizedEdge}Width` + : `${property}${capitalizedEdge}` +} + +const assignBoxEdges = ( + target: TokenTree, + source: TokenTree, + property: BoxProperty, + edges: BoxEdges, + tokenPath: string +): void => { + for (const [edge, edgeValue] of Object.entries(edges) as Array< + [keyof BoxEdges, number] + >) { + const edgeKey = edgePropertyName(property, edge) + + if (edgeKey in source || edgeKey in target) { + throw new Error(`Duplicate generated token "${tokenPath}.${edgeKey}"`) + } + + target[edgeKey] = edgeValue + } +} + +export const normalizeTree = ( + node: TokenValue, + tokenPath = 'root' +): TokenValue => { + if (Array.isArray(node)) { + return node.map((item, index) => + normalizeTree(item, `${tokenPath}.${index}`) + ) + } + + if (!isTokenTree(node)) return convertUnit(node) + + const normalized: TokenTree = {} + + for (const [key, value] of Object.entries(node)) { + const currentPath = `${tokenPath}.${key}` + const boxProperty = BOX_PROPERTIES.find((property) => property === key) + + if ( + boxProperty && + (typeof value === 'string' || typeof value === 'number') + ) { + const edges = parseBoxShorthand(value, currentPath) + const partCount = + typeof value === 'number' + ? 1 + : value.trim().split(/\s+/).filter(Boolean).length + + if (partCount === 1) { + normalized[key] = edges.top + } else { + assignBoxEdges(normalized, node, boxProperty, edges, currentPath) + } + } else { + normalized[key] = normalizeTree(value, currentPath) + } + } + + return normalized +} diff --git a/scripts/token-generator/core/resolution.ts b/scripts/token-generator/core/resolution.ts new file mode 100644 index 00000000..42078ff6 --- /dev/null +++ b/scripts/token-generator/core/resolution.ts @@ -0,0 +1,99 @@ +import { resolvePath } from './tree' +import { isTokenTree, type TokenTree, type TokenValue } from './types' + +const EXACT_REFERENCE_PATTERN = /^\{[^{}]+\}$/ +const REFERENCE_PATTERN = /\{[^{}]+\}/g + +const stringifyReference = ( + value: TokenValue, + reference: string, + tokenPath: string +): string => { + if (value === null || Array.isArray(value) || isTokenTree(value)) { + throw new Error( + `Reference "${reference}" at "${tokenPath}" cannot be embedded in a string` + ) + } + + return String(value) +} + +export const resolveReferences = ( + node: TokenValue, + referenceRoot: TokenTree, + tokenPath = 'root' +): TokenValue => { + const cache = new Map() + + const resolveReference = ( + reference: string, + sourcePath: string, + stack: string[] + ): TokenValue => { + if (stack.includes(reference)) { + throw new Error( + `Circular token reference at "${sourcePath}": ${[ + ...stack, + reference, + ].join(' -> ')}` + ) + } + + const cached = cache.get(reference) + + if (cached !== undefined) return cached + + const referencedValue = resolvePath( + referenceRoot, + reference, + `references for "${sourcePath}"` + ) + const resolved = resolveNode(referencedValue, reference, [ + ...stack, + reference, + ]) + + cache.set(reference, resolved) + + return resolved + } + + const resolveNode = ( + value: TokenValue, + currentPath: string, + stack: string[] + ): TokenValue => { + if (Array.isArray(value)) { + return value.map((item, index) => + resolveNode(item, `${currentPath}.${index}`, stack) + ) + } + + if (isTokenTree(value)) { + return Object.fromEntries( + Object.entries(value).map(([key, nestedValue]) => [ + key, + resolveNode(nestedValue, `${currentPath}.${key}`, stack), + ]) + ) + } + + if (typeof value !== 'string') return value + + if (EXACT_REFERENCE_PATTERN.test(value)) { + return resolveReference(value.slice(1, -1), currentPath, stack) + } + + return value.replace(REFERENCE_PATTERN, (token) => { + const reference = token.slice(1, -1) + + return stringifyReference( + resolveReference(reference, currentPath, stack), + reference, + currentPath + ) + }) + } + + return resolveNode(node, tokenPath, []) +} diff --git a/scripts/token-generator/core/tree.ts b/scripts/token-generator/core/tree.ts new file mode 100644 index 00000000..e8141baa --- /dev/null +++ b/scripts/token-generator/core/tree.ts @@ -0,0 +1,49 @@ +import { isTokenTree, type TokenTree, type TokenValue } from './types' + +const cloneValue = (value: TokenValue): TokenValue => { + if (Array.isArray(value)) return value.map(cloneValue) + + if (isTokenTree(value)) { + return Object.fromEntries( + Object.entries(value).map(([key, nestedValue]) => [ + key, + cloneValue(nestedValue), + ]) + ) + } + + return value +} + +export const mergeTrees = (base: TokenTree, override: TokenTree): TokenTree => { + const result = cloneValue(base) as TokenTree + + for (const [key, value] of Object.entries(override)) { + const current = result[key] + + result[key] = + isTokenTree(current) && isTokenTree(value) + ? mergeTrees(current, value) + : cloneValue(value) + } + + return result +} + +export const resolvePath = ( + source: TokenTree, + tokenPath: string, + context = 'input tokens' +): TokenValue => { + let current: TokenValue = source + + for (const segment of tokenPath.split('.')) { + if (!isTokenTree(current) || !(segment in current)) { + throw new Error(`Missing "${tokenPath}" in ${context}`) + } + + current = current[segment] + } + + return current +} diff --git a/scripts/token-generator/core/types.ts b/scripts/token-generator/core/types.ts new file mode 100644 index 00000000..2c98a251 --- /dev/null +++ b/scripts/token-generator/core/types.ts @@ -0,0 +1,26 @@ +export type TokenPrimitive = string | number | boolean | null +export type TokenValue = TokenPrimitive | TokenTree | TokenValue[] + +export interface TokenTree { + [key: string]: TokenValue +} + +export interface BoxEdges { + top: number + right: number + bottom: number + left: number +} + +export interface CompiledTokens { + semantic: ThemeTokens + components: ThemeTokens +} + +export interface ThemeTokens { + light: TokenTree + dark: TokenTree +} + +export const isTokenTree = (value: unknown): value is TokenTree => + typeof value === 'object' && value !== null && !Array.isArray(value) diff --git a/scripts/token-generator/core/validation.ts b/scripts/token-generator/core/validation.ts new file mode 100644 index 00000000..3e02b946 --- /dev/null +++ b/scripts/token-generator/core/validation.ts @@ -0,0 +1,81 @@ +import { BOX_PROPERTIES, type BoxProperty } from './normalization' +import { isTokenTree, type TokenTree, type TokenValue } from './types' + +const REFERENCE_PATTERN = /\{[^}]+\}/ +const UNCONVERTED_UNIT_PATTERN = /-?\d*\.?\d+(?:rem|ms)\b/ + +export const assertValidOutput = ( + node: TokenValue, + tokenPath: string +): void => { + if (Array.isArray(node)) { + node.forEach((item, index) => + assertValidOutput(item, `${tokenPath}.${index}`) + ) + + return + } + + if (isTokenTree(node)) { + for (const [key, value] of Object.entries(node)) { + if ( + BOX_PROPERTIES.includes(key as BoxProperty) && + typeof value === 'string' + ) { + throw new Error(`Unconverted box shorthand at "${tokenPath}.${key}"`) + } + + assertValidOutput(value, `${tokenPath}.${key}`) + } + + return + } + + if (typeof node === 'number' && !Number.isFinite(node)) { + throw new Error(`Non-finite number at "${tokenPath}"`) + } + + if ( + typeof node === 'string' && + (REFERENCE_PATTERN.test(node) || UNCONVERTED_UNIT_PATTERN.test(node)) + ) { + throw new Error(`Unconverted token "${node}" at "${tokenPath}"`) + } +} + +const collectShape = ( + node: TokenValue, + tokenPath = 'root', + shape: string[] = [] +): string[] => { + if (Array.isArray(node)) { + shape.push(`${tokenPath}:array`) + node.forEach((item, index) => + collectShape(item, `${tokenPath}.${index}`, shape) + ) + + return shape + } + + if (isTokenTree(node)) { + shape.push(`${tokenPath}:object`) + Object.entries(node).forEach(([key, value]) => + collectShape(value, `${tokenPath}.${key}`, shape) + ) + + return shape + } + + shape.push(`${tokenPath}:${node === null ? 'null' : typeof node}`) + + return shape +} + +export const assertSameShape = (light: TokenTree, dark: TokenTree): void => { + const lightShape = collectShape(light).sort() + const darkShape = collectShape(dark).sort() + + if (JSON.stringify(lightShape) !== JSON.stringify(darkShape)) { + throw new Error('Light and dark runtime tokens have different shapes') + } +} diff --git a/scripts/token-generator/io.ts b/scripts/token-generator/io.ts new file mode 100644 index 00000000..d4c0e85f --- /dev/null +++ b/scripts/token-generator/io.ts @@ -0,0 +1,109 @@ +import { + readFileSync, + readdirSync, + mkdirSync, + writeFileSync, + renameSync, + existsSync, +} from 'node:fs' +import { dirname, join } from 'node:path' +import { isDeepStrictEqual } from 'node:util' + +import { isTokenTree, type CompiledTokens, type TokenTree } from './core/types' + +export const OUTPUT_FILES = { + semantic: { + light: join('semantic', 'light.json'), + dark: join('semantic', 'dark.json'), + }, + components: { + light: join('components', 'light.json'), + dark: join('components', 'dark.json'), + }, +} as const + +export const parseTokenTree = ( + contents: string, + filePath: string +): TokenTree => { + const parsed: unknown = JSON.parse(contents) + + if (!isTokenTree(parsed)) { + throw new Error(`Expected an object in "${filePath}"`) + } + + return parsed +} + +export const loadTokenTree = (filePath: string): TokenTree => + parseTokenTree(readFileSync(filePath, 'utf8'), filePath) + +export const renderJson = (value: TokenTree): string => + `${JSON.stringify(value, null, 2)}\n` + +const outputEntries = ( + compiled: CompiledTokens +): Array<[string, TokenTree]> => [ + [OUTPUT_FILES.semantic.light, compiled.semantic.light], + [OUTPUT_FILES.semantic.dark, compiled.semantic.dark], + [OUTPUT_FILES.components.light, compiled.components.light], + [OUTPUT_FILES.components.dark, compiled.components.dark], +] + +export const writeGeneratedTokens = ( + compiled: CompiledTokens, + outputDirectory: string +): void => { + mkdirSync(outputDirectory, { recursive: true }) + + for (const [fileName, value] of outputEntries(compiled)) { + const outputPath = join(outputDirectory, fileName) + const temporaryPath = `${outputPath}.tmp` + + mkdirSync(dirname(outputPath), { recursive: true }) + writeFileSync(temporaryPath, renderJson(value)) + renameSync(temporaryPath, outputPath) + } +} + +const findJsonFiles = (directory: string, prefix = ''): string[] => { + if (!existsSync(directory)) return [] + + return readdirSync(directory, { withFileTypes: true }) + .flatMap((entry) => { + const relativePath = join(prefix, entry.name) + + if (entry.isDirectory()) { + return findJsonFiles(join(directory, entry.name), relativePath) + } + + return entry.isFile() && entry.name.endsWith('.json') + ? [relativePath] + : [] + }) + .sort() +} + +export const findStaleGeneratedTokens = ( + compiled: CompiledTokens, + outputDirectory: string +): string[] => { + const entries = outputEntries(compiled) + const expectedFiles = new Set(entries.map(([fileName]) => fileName)) + const staleFiles = entries + .filter(([fileName, value]) => { + const outputPath = join(outputDirectory, fileName) + + return ( + !existsSync(outputPath) || + !isDeepStrictEqual(loadTokenTree(outputPath), value) + ) + }) + .map(([fileName]) => fileName) + + const unexpectedFiles = findJsonFiles(outputDirectory).filter( + (fileName) => !expectedFiles.has(fileName) + ) + + return [...staleFiles, ...unexpectedFiles] +} diff --git a/scripts/token-generator/tsconfig.json b/scripts/token-generator/tsconfig.json new file mode 100644 index 00000000..e2005382 --- /dev/null +++ b/scripts/token-generator/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext", + "moduleResolution": "NodeNext", + "noEmit": true, + "types": ["jest", "node"] + }, + "include": ["**/*.ts"], + "exclude": [] +} diff --git a/yarn.lock b/yarn.lock index 3ec08e23..d17ddfa0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2841,6 +2841,7 @@ __metadata: "@testing-library/react-native": "npm:13.3.3" "@types/jest": "npm:29.5.14" "@types/lodash.map": "npm:4.6.13" + "@types/node": "npm:22.7.7" "@types/react": "npm:19.2.14" babel-loader: "npm:8.2.3" chalk: "npm:4.1.2" @@ -6088,7 +6089,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*": +"@types/node@npm:*, @types/node@npm:22.7.7": version: 22.7.7 resolution: "@types/node@npm:22.7.7" dependencies: From 221ad2b07e60dce87b582b2ca19bb5b629d03752 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Thu, 30 Jul 2026 20:28:07 +0300 Subject: [PATCH 02/40] =?UTF-8?q?ci:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B4=D0=B8=D0=B7=D0=B0=D0=B9=D0=BD-=D1=82?= =?UTF-8?q?=D0=BE=D0=BA=D0=B5=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/actions/typecheck/action.yml | 8 ++++++-- lefthook.yml | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/actions/typecheck/action.yml b/.github/actions/typecheck/action.yml index be5114d9..9c14c2dd 100644 --- a/.github/actions/typecheck/action.yml +++ b/.github/actions/typecheck/action.yml @@ -1,5 +1,5 @@ -name: Run Typecheck -description: Run typecheck +name: Run Typechecks +description: Typecheck the project and validate generated tokens runs: using: composite @@ -9,3 +9,7 @@ runs: - name: Run Typecheck shell: bash run: yarn tsc --noEmit + + - name: Validate Design Tokens + shell: bash + run: yarn tokens:validate diff --git a/lefthook.yml b/lefthook.yml index c0ea5595..849f2579 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -73,3 +73,5 @@ pre-push: run: npx yarn eslint . type-check: run: npx yarn tsc --noEmit + tokens-validate: + run: npx yarn tokens:validate From f1ee7522e006d949cfe9d6e9726de838a8e525b3 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Thu, 30 Jul 2026 20:28:27 +0300 Subject: [PATCH 03/40] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=B8=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D0=B4=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D0=B9=D0=BD-=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design-tokens/README.md | 6 + design-tokens/input/tokens.json | 5220 +++++++++++++++++++++ src/theme/__tests__/ThemeContext.test.tsx | 15 + src/theme/darkTheme.ts | 4 + src/theme/lightTheme.ts | 4 + src/theme/tokens/README.md | 9 + src/theme/tokens/components/dark.json | 2920 ++++++++++++ src/theme/tokens/components/light.json | 2920 ++++++++++++ src/theme/tokens/semantic/dark.json | 352 ++ src/theme/tokens/semantic/light.json | 352 ++ src/theme/types.ts | 4 + 11 files changed, 11806 insertions(+) create mode 100644 design-tokens/README.md create mode 100644 design-tokens/input/tokens.json create mode 100644 src/theme/tokens/README.md create mode 100644 src/theme/tokens/components/dark.json create mode 100644 src/theme/tokens/components/light.json create mode 100644 src/theme/tokens/semantic/dark.json create mode 100644 src/theme/tokens/semantic/light.json diff --git a/design-tokens/README.md b/design-tokens/README.md new file mode 100644 index 00000000..73d1cf5c --- /dev/null +++ b/design-tokens/README.md @@ -0,0 +1,6 @@ +# Design tokens + +`input/tokens.json` содержит входные токены из Figma, из которых генерируются +light- и dark-токены проекта. + +Подробности: [генератор токенов](../scripts/token-generator/README.md). diff --git a/design-tokens/input/tokens.json b/design-tokens/input/tokens.json new file mode 100644 index 00000000..16993284 --- /dev/null +++ b/design-tokens/input/tokens.json @@ -0,0 +1,5220 @@ +{ + "primitive": { + "colors": { + "alpha": { + "white": { + "10": "rgba(255, 255, 255, 0.0100)", + "40": "rgba(255, 255, 255, 0.0400)", + "50": "rgba(255, 255, 255, 0.0500)", + "60": "rgba(255, 255, 255, 0.0600)", + "100": "rgba(255, 255, 255, 0.1000)", + "160": "rgba(255, 255, 255, 0.1600)", + "200": "rgba(255, 255, 255, 0.2000)", + "300": "rgba(255, 255, 255, 0.3000)", + "400": "rgba(255, 255, 255, 0.4000)", + "500": "rgba(255, 255, 255, 0.5000)", + "600": "rgba(255, 255, 255, 0.6000)", + "700": "rgba(255, 255, 255, 0.7000)", + "800": "rgba(255, 255, 255, 0.8000)", + "870": "rgba(255, 255, 255, 0.8700)", + "900": "rgba(255, 255, 255, 0.9000)", + "1000": "#ffffff" + }, + "black": { + "40": "rgba(0, 0, 0, 0.0400)", + "100": "rgba(0, 0, 0, 0.1000)", + "200": "rgba(0, 0, 0, 0.2000)", + "300": "rgba(0, 0, 0, 0.3000)", + "400": "rgba(0, 0, 0, 0.4000)", + "500": "rgba(0, 0, 0, 0.5000)", + "600": "rgba(0, 0, 0, 0.6000)", + "700": "rgba(0, 0, 0, 0.7000)", + "800": "rgba(0, 0, 0, 0.8000)", + "900": "rgba(0, 0, 0, 0.9000)", + "1000": "#000000" + }, + "green": { + "40": "rgba(68, 232, 88, 0.04)", + "100": "rgba(68, 232, 88, 0.1)", + "200": "rgba(68, 232, 88, 0.2)", + "400": "rgba(68, 232, 88, 0.4)", + "600": "rgba(68, 232, 88, 0.6)" + }, + "blue": { + "40": "rgba(68, 150, 232, 0.04)", + "100": "rgba(68, 150, 232, 0.1)", + "200": "rgba(68, 150, 232, 0.2)", + "400": "rgba(68, 150, 232, 0.4)", + "600": "rgba(68, 150, 232, 0.6)" + }, + "yellow": { + "40": "rgba(245, 184, 61, 0.04)", + "100": "rgba(245, 184, 61, 0.1)", + "200": "rgba(245, 184, 61, 0.2)", + "400": "rgba(245, 184, 61, 0.4)", + "600": "rgba(245, 184, 61, 0.6)" + }, + "red": { + "40": "rgba(232, 82, 68, 0.04)", + "100": "rgba(232, 82, 68, 0.1)", + "200": "rgba(232, 82, 68, 0.2)", + "400": "rgba(232, 82, 68, 0.4)", + "600": "rgba(232, 82, 68, 0.6)" + } + }, + "solid": { + "purple": { + "50": "#faf5ff", + "100": "#f3e8ff", + "200": "#e9d5ff", + "300": "#d8b4fe", + "400": "#c084fc", + "500": "#a855f7", + "600": "#9333ea", + "700": "#7e22ce", + "800": "#6b21a8", + "900": "#581c87", + "950": "#3b0764" + }, + "fuchsia": { + "50": "#fdf4ff", + "100": "#fae8ff", + "200": "#f5d0fe", + "300": "#f0abfc", + "400": "#e879f9", + "500": "#d946ef", + "600": "#c026d3", + "700": "#a21caf", + "800": "#86198f", + "900": "#701a75", + "950": "#4a044e" + }, + "pink": { + "50": "#fdf2f8", + "100": "#fce7f3", + "200": "#fbcfe8", + "300": "#f9a8d4", + "400": "#f472b6", + "500": "#ec4899", + "600": "#db2777", + "700": "#be185d", + "800": "#9d174d", + "900": "#831843", + "950": "#500724" + }, + "rose": { + "50": "#fff1f2", + "100": "#ffe4e6", + "200": "#fecdd3", + "300": "#fda4af", + "400": "#fb7185", + "500": "#f43f5e", + "600": "#e11d48", + "700": "#be123c", + "800": "#9f1239", + "900": "#881337", + "950": "#4c0519" + }, + "teal": { + "50": "#f0fdfa", + "100": "#ccfbf1", + "200": "#99f6e4", + "300": "#5eead4", + "400": "#2dd4bf", + "500": "#14b8a6", + "600": "#0d9488", + "700": "#0f766e", + "800": "#115e59", + "900": "#134e4a", + "950": "#042f2e" + }, + "cyan": { + "50": "#ecfeff", + "100": "#cffafe", + "200": "#a5f3fc", + "300": "#67e8f9", + "400": "#22d3ee", + "500": "#06b6d4", + "600": "#0891b2", + "700": "#0e7490", + "800": "#155e75", + "900": "#164e63", + "950": "#013138" + }, + "sky": { + "50": "#f0f9ff", + "100": "#e0f2fe", + "200": "#bae6fd", + "300": "#7dd3fc", + "400": "#38bdf8", + "500": "#0ea5e9", + "600": "#0284c7", + "700": "#0369a1", + "800": "#075985", + "900": "#0c4a6e", + "950": "#082f49" + }, + "blue": { + "50": "#fafdff", + "100": "#f0f9ff", + "200": "#d4ecfe", + "300": "#aad7fb", + "400": "#77baf4", + "500": "#4496e8", + "600": "#1e76cd", + "700": "#18538d", + "800": "#123a61", + "900": "#0e2a45", + "950": "#0c243b" + }, + "indigo": { + "50": "#eef2ff", + "100": "#e0e7ff", + "200": "#c7d2fe", + "300": "#a5b4fc", + "400": "#818cf8", + "500": "#6366f1", + "600": "#4f46e5", + "700": "#4338ca", + "800": "#3730a3", + "900": "#312e81", + "950": "#1e1b4b" + }, + "violet": { + "50": "#fcfaff", + "100": "#f6f0ff", + "200": "#e5d4fe", + "300": "#cbaafb", + "400": "#b284f5", + "500": "#a265ec", + "600": "#9457ea", + "700": "#48188d", + "800": "#321261", + "900": "#240e45", + "950": "#1f0c3b" + }, + "emerald": { + "50": "#ecfdf5", + "100": "#d1fae5", + "200": "#a7f3d0", + "300": "#6ee7b7", + "400": "#34d399", + "500": "#10b981", + "600": "#059669", + "700": "#047857", + "800": "#065f46", + "900": "#064e3b", + "950": "#022c22" + }, + "green": { + "50": "#fafffb", + "100": "#f0fff3", + "200": "#d4fedc", + "300": "#aafbb7", + "400": "#77f48a", + "500": "#44e858", + "600": "#1dc831", + "700": "#168322", + "800": "#12611b", + "900": "#0e4514", + "950": "#0c3b11" + }, + "lime": { + "50": "#f7fee7", + "100": "#ecfccb", + "200": "#d9f99d", + "300": "#bef264", + "400": "#a3e635", + "500": "#84cc16", + "600": "#65a30d", + "700": "#4d7c0f", + "800": "#3f6212", + "900": "#365314", + "950": "#1a2e05" + }, + "red": { + "50": "#fffafa", + "100": "#fff0f0", + "200": "#fed4d4", + "300": "#fbacaa", + "400": "#f47f77", + "500": "#e85244", + "600": "#db3424", + "700": "#8d2218", + "800": "#611912", + "900": "#45120e", + "950": "#3b100c" + }, + "orange": { + "50": "#fffbfa", + "100": "#fff3f0", + "200": "#ffddd5", + "300": "#ffbca9", + "400": "#ff9273", + "500": "#fe6434", + "600": "#d53f0b", + "700": "#a83107", + "800": "#752506", + "900": "#561c05", + "950": "#4b1905" + }, + "amber": { + "50": "#fffbeb", + "100": "#fef3c7", + "200": "#fde68a", + "300": "#fcd34d", + "400": "#fbbf24", + "500": "#f59e0b", + "600": "#d97706", + "700": "#b45309", + "800": "#92400e", + "900": "#78350f", + "950": "#451a03" + }, + "yellow": { + "50": "#fffdfa", + "100": "#fff9f0", + "200": "#ffeed4", + "300": "#fddeaa", + "400": "#facb75", + "500": "#f5b83d", + "600": "#dc9710", + "700": "#9d6d0e", + "800": "#6d4c0b", + "900": "#4f3709", + "950": "#453008" + }, + "slate": { + "50": "#f8fafc", + "100": "#f1f5f9", + "200": "#e2e8f0", + "300": "#cbd5e1", + "400": "#94a3b8", + "500": "#64748b", + "600": "#475569", + "700": "#334155", + "800": "#1e293b", + "900": "#0f172a", + "950": "#020617" + }, + "gray": { + "50": "#f9fafb", + "100": "#f3f4f6", + "200": "#e5e7eb", + "300": "#d1d5db", + "400": "#9ca3af", + "500": "#6b7280", + "600": "#4b5563", + "700": "#374151", + "800": "#1f2937", + "900": "#111827", + "950": "#030712" + }, + "zinc": { + "50": "#fafafa", + "100": "#f0f0f1", + "200": "#e2e2e4", + "300": "#cecfd2", + "400": "#a2a5a9", + "500": "#85888e", + "600": "#6d7076", + "700": "#56595f", + "800": "#404348", + "900": "#2b2e33", + "950": "#181a1f" + }, + "neutral": { + "50": "#fafafa", + "100": "#f5f5f5", + "200": "#e5e5e5", + "300": "#d4d4d4", + "400": "#a3a3a3", + "500": "#737373", + "600": "#525252", + "700": "#404040", + "800": "#262626", + "900": "#171717", + "950": "#0a0a0a" + }, + "stone": { + "50": "#fafaf9", + "100": "#f5f5f4", + "200": "#e7e5e4", + "300": "#d6d3d1", + "400": "#a8a29e", + "500": "#78716c", + "600": "#57534e", + "700": "#44403c", + "800": "#292524", + "900": "#1c1917", + "950": "#0c0a09" + } + } + }, + "sizing": { + "none": "0rem", + "05x": "0.0625rem", + "1x": "0.125rem", + "2x": "0.25rem", + "3x": "0.375rem", + "4x": "0.5rem", + "5x": "0.625rem", + "6x": "0.75rem", + "7x": "0.875rem", + "8x": "1rem", + "9x": "1.125rem", + "10x": "1.25rem", + "12x": "1.5rem", + "13x": "1.625rem", + "14x": "1.75rem", + "16x": "2rem", + "18x": "2.25rem", + "19x": "2.375rem", + "21x": "2.625rem", + "23x": "2.875rem", + "24x": "3rem", + "26x": "3.25rem", + "28x": "3.5rem", + "30x": "3.75rem", + "32x": "4rem", + "33x": "4.125rem", + "35x": "4.375rem", + "42x": "5.25rem", + "49x": "6.125rem", + "50x": "6.25rem", + "56x": "7rem", + "63x": "7.875rem", + "70x": "8.75rem", + "77x": "9.625rem", + "84x": "10.5rem", + "91x": "11.375rem", + "98x": "12.25rem", + "105x": "13.125rem", + "112x": "14rem", + "119x": "14.875rem", + "126x": "15.75rem", + "133x": "16.625rem", + "140x": "17.5rem", + "147x": "18.375rem", + "154x": "19.25rem", + "161x": "20.125rem", + "168x": "21rem", + "175x": "21.875rem", + "182x": "22.75rem", + "189x": "23.625rem", + "196x": "24.5rem", + "203x": "25.375rem", + "210x": "26.25rem", + "238x": "29.75rem", + "288x": "36rem", + "315x": "39.375rem", + "350x": "43.75rem", + "378x": "47.25rem", + "384x": "48rem", + "406x": "50.75rem", + "420x": "52.5rem", + "496x": "62rem", + "600x": "75rem", + "700x": "87.5rem", + "max": "100rem", + "20x": "2.5rem", + "40x": "5rem", + "120x": "15rem", + "136x": "17rem", + "152x": "19rem", + "200x": "25rem" + }, + "fonts": { + "fontFamily": { "base": "Noto Sans", "heading": "TT Fellows" }, + "fontWeight": { + "regular": "400", + "medium": "500", + "demibold": "600", + "bold": "700" + }, + "fontSize": { + "100": "0.75rem", + "200": "0.875rem", + "300": "1rem", + "400": "1.125rem", + "500": "1.25rem", + "600": "1.5rem", + "650": "1.875rem", + "700": "2.25rem", + "750": "3rem", + "800": "3.75rem", + "900": "4.5rem", + "1000": "6rem" + }, + "lineHeight": { + "100": "0.75rem", + "150": "0.875rem", + "200": "0.875rem", + "250": "1rem", + "300": "1.125rem", + "350": "1.125rem", + "400": "1.25rem", + "450": "1.375rem", + "500": "1.5rem", + "550": "1.625rem", + "600": "1.75rem", + "700": "1.875rem", + "800": "2.25rem", + "850": "2.375rem", + "900": "2.75rem", + "1000": "3.375rem", + "none": "1", + "auto": "auto" + }, + "letterSpacing": { + "200": "-0.02rem", + "400": "-0.03rem", + "500": "0rem", + "600": "0.02rem", + "700": "0.03rem" + } + } + }, + "semantic": { + "colorScheme": { + "light": { + "color": { + "fg": { + "default": "{colors.solid.zinc.900}", + "hover": "{colors.solid.zinc.700}", + "active": "{colors.solid.zinc.950}", + "focus": "{colors.solid.zinc.900}", + "muted": "{colors.solid.zinc.500}", + "subtle": "{colors.solid.zinc.600}", + "brand": { + "default": "{colors.solid.green.500}", + "hover": "{colors.solid.green.600}", + "active": "{colors.solid.green.700}", + "disabled": "{colors.solid.green.300}", + "visited": "{colors.solid.green.800}", + "muted": "{colors.solid.green.400}" + }, + "inverse": { + "default": "{colors.alpha.white.1000}", + "hover": "{colors.alpha.white.1000}", + "active": "{colors.alpha.white.1000}", + "focus": "{colors.alpha.white.1000}", + "muted": "{colors.alpha.white.700}" + }, + "status": { + "danger": { + "default": "{colors.solid.red.500}", + "hover": "{colors.solid.red.600}", + "active": "{colors.solid.red.700}", + "disabled": "{colors.solid.red.300}", + "visited": "{colors.solid.red.800}", + "muted": "{colors.solid.red.400}" + }, + "info": { + "default": "{colors.solid.blue.500}", + "hover": "{colors.solid.blue.600}", + "active": "{colors.solid.blue.700}", + "disabled": "{colors.solid.blue.300}", + "visited": "{colors.solid.blue.800}", + "muted": "{colors.solid.blue.400}" + }, + "warning": { + "default": "{colors.solid.yellow.500}", + "hover": "{colors.solid.yellow.600}", + "active": "{colors.solid.yellow.700}", + "disabled": "{colors.solid.yellow.300}", + "visited": "{colors.solid.yellow.800}", + "muted": "{colors.solid.yellow.400}" + }, + "success": { + "default": "{colors.solid.green.500}", + "hover": "{colors.solid.green.600}", + "active": "{colors.solid.green.700}", + "disabled": "{colors.solid.green.300}", + "visited": "{colors.solid.green.800}", + "muted": "{colors.solid.green.400}" + }, + "help": { + "default": "{colors.solid.purple.500}", + "hover": "{colors.solid.purple.600}", + "active": "{colors.solid.purple.700}", + "disabled": "{colors.solid.purple.300}", + "visited": "{colors.solid.purple.800}", + "muted": "{colors.solid.purple.400}" + } + }, + "on": { + "brand": { + "default": "{colors.solid.zinc.900}", + "hover": "{colors.solid.zinc.900}", + "active": "{colors.solid.zinc.900}" + }, + "fill": { + "default": "{colors.alpha.white.1000}", + "hover": "{colors.alpha.white.1000}", + "active": "{colors.alpha.white.1000}", + "muted": "{colors.solid.zinc.200}" + }, + "status": { + "danger": { + "default": "{colors.solid.red.900}", + "hover": "{colors.solid.red.950}" + }, + "info": { + "default": "{colors.solid.blue.900}", + "hover": "{colors.solid.blue.950}" + }, + "warning": { + "default": "{colors.solid.yellow.900}", + "hover": "{colors.solid.yellow.950}" + }, + "success": { + "default": "{colors.solid.green.900}", + "hover": "{colors.solid.green.950}" + }, + "help": { + "default": "{colors.solid.purple.900}", + "hover": "{colors.solid.purple.950}" + } + } + } + }, + "bg": { + "status": { + "danger": { + "weak": { + "default": "{colors.solid.red.50}", + "hover": "{colors.solid.red.100}", + "active": "{colors.solid.red.200}" + }, + "strong": { + "default": "{colors.solid.red.300}", + "hover": "{colors.solid.red.400}", + "active": "{colors.solid.red.500}" + } + }, + "info": { + "weak": { + "default": "{colors.solid.blue.50}", + "hover": "{colors.solid.blue.100}", + "active": "{colors.solid.blue.200}" + }, + "strong": { + "default": "{colors.solid.blue.300}", + "hover": "{colors.solid.blue.400}", + "active": "{colors.solid.blue.500}" + } + }, + "warning": { + "weak": { + "default": "{colors.solid.yellow.50}", + "hover": "{colors.solid.yellow.100}", + "active": "{colors.solid.yellow.200}" + }, + "strong": { + "default": "{colors.solid.yellow.300}", + "hover": "{colors.solid.yellow.400}", + "active": "{colors.solid.yellow.500}" + } + }, + "success": { + "weak": { + "default": "{colors.solid.green.50}", + "hover": "{colors.solid.green.100}", + "active": "{colors.solid.green.200}" + }, + "strong": { + "default": "{colors.solid.green.300}", + "hover": "{colors.solid.green.400}", + "active": "{colors.solid.green.500}" + } + }, + "help": { + "weak": { + "default": "{colors.solid.purple.50}", + "hover": "{colors.solid.purple.100}", + "active": "{colors.solid.purple.200}" + }, + "strong": { + "default": "{colors.solid.purple.300}", + "hover": "{colors.solid.purple.400}", + "active": "{colors.solid.purple.500}" + } + } + }, + "brand": { + "weak": { + "hover": "{colors.solid.green.50}", + "active": "{colors.solid.green.100}" + }, + "strong": { + "default": "{colors.solid.green.500}", + "hover": "{colors.solid.green.600}", + "active": "{colors.solid.green.700}" + } + }, + "surface": { + "canvas": { + "default": "{colors.solid.zinc.100}", + "hover": "{colors.solid.zinc.200}", + "active": "{colors.solid.zinc.300}", + "selected": "{colors.solid.zinc.200}" + }, + "default": { + "default": "{colors.alpha.white.1000}", + "hover": "{colors.solid.zinc.50}", + "active": "{colors.solid.zinc.100}", + "selected": "{colors.solid.zinc.50}" + }, + "raised": { + "default": "{colors.alpha.white.1000}", + "hover": "{colors.solid.zinc.50}", + "active": "{colors.solid.zinc.100}", + "selected": "{colors.solid.zinc.50}" + }, + "overlay": { + "default": "{colors.alpha.white.1000}", + "hover": "{colors.solid.zinc.50}" + }, + "backdrop": "{colors.alpha.black.400}" + }, + "neutral": { + "weak": { + "default": "{colors.solid.zinc.100}", + "hover": "{colors.solid.zinc.200}", + "active": "{colors.solid.zinc.300}", + "disabled": "{colors.solid.zinc.200}" + }, + "medium": { + "default": "{colors.solid.zinc.200}", + "hover": "{colors.solid.zinc.300}", + "active": "{colors.solid.zinc.400}", + "strong": "{colors.solid.zinc.500}" + }, + "strong": { + "default": "{colors.solid.zinc.900}", + "hover": "{colors.solid.zinc.800}", + "active": "{colors.solid.zinc.700}", + "selected": "{colors.solid.zinc.900}" + } + } + }, + "border": { + "focus": "{colors.solid.green.200}", + "neutral": { + "default": "{colors.solid.zinc.200}", + "strong": "{colors.solid.zinc.300}", + "bold": { + "default": "{colors.solid.zinc.900}", + "hover": "{colors.solid.zinc.800}" + }, + "inverse": "{colors.alpha.white.1000}" + }, + "brand": { + "subtle": "{colors.solid.green.200}", + "default": "{colors.solid.green.500}", + "strong": "{colors.solid.green.600}" + }, + "status": { + "danger": { + "subtle": "{colors.solid.red.400}", + "default": "{colors.solid.red.500}", + "strong": "{colors.solid.red.600}" + }, + "info": { + "default": "{colors.solid.blue.500}", + "strong": "{colors.solid.blue.600}" + }, + "warning": { + "default": "{colors.solid.yellow.500}", + "strong": "{colors.solid.yellow.600}" + }, + "success": { + "default": "{colors.solid.green.500}", + "strong": "{colors.solid.green.600}" + }, + "help": { "strong": "{colors.solid.purple.600}" } + } + } + } + }, + "dark": { + "color": { + "fg": { + "default": "{colors.alpha.white.1000}", + "hover": "{colors.solid.zinc.300}", + "active": "{colors.solid.zinc.100}", + "focus": "{colors.alpha.white.1000}", + "muted": "{colors.solid.zinc.400}", + "subtle": "{colors.solid.zinc.400}", + "brand": { + "default": "{colors.solid.green.400}", + "hover": "{colors.solid.green.300}", + "active": "{colors.solid.green.200}", + "disabled": "{colors.solid.green.700}", + "visited": "{colors.solid.green.300}", + "muted": "{colors.solid.green.500}" + }, + "inverse": { + "default": "{colors.solid.zinc.900}", + "hover": "{colors.solid.zinc.700}", + "active": "{colors.solid.zinc.950}", + "focus": "{colors.solid.zinc.900}", + "muted": "{colors.solid.zinc.500}" + }, + "status": { + "danger": { + "default": "{colors.solid.red.400}", + "hover": "{colors.solid.red.300}", + "active": "{colors.solid.red.200}", + "disabled": "{colors.solid.red.700}", + "visited": "{colors.solid.red.300}", + "muted": "{colors.solid.red.500}" + }, + "info": { + "default": "{colors.solid.blue.400}", + "hover": "{colors.solid.blue.300}", + "active": "{colors.solid.blue.200}", + "disabled": "{colors.solid.blue.700}", + "visited": "{colors.solid.blue.300}", + "muted": "{colors.solid.blue.500}" + }, + "warning": { + "default": "{colors.solid.yellow.400}", + "hover": "{colors.solid.yellow.300}", + "active": "{colors.solid.yellow.200}", + "disabled": "{colors.solid.yellow.700}", + "visited": "{colors.solid.yellow.300}", + "muted": "{colors.solid.yellow.500}" + }, + "success": { + "default": "{colors.solid.green.400}", + "hover": "{colors.solid.green.300}", + "active": "{colors.solid.green.200}", + "disabled": "{colors.solid.green.700}", + "visited": "{colors.solid.green.300}", + "muted": "{colors.solid.green.500}" + }, + "help": { + "default": "{colors.solid.purple.400}", + "hover": "{colors.solid.purple.300}", + "active": "{colors.solid.purple.200}", + "disabled": "{colors.solid.purple.700}", + "visited": "{colors.solid.purple.300}", + "muted": "{colors.solid.purple.500}" + } + }, + "on": { + "brand": { + "default": "{colors.solid.zinc.900}", + "hover": "{colors.solid.zinc.900}", + "active": "{colors.solid.zinc.900}" + }, + "fill": { + "default": "{colors.alpha.white.1000}", + "hover": "{colors.alpha.white.1000}", + "active": "{colors.alpha.white.1000}", + "muted": "{colors.solid.zinc.200}" + }, + "status": { + "danger": { + "default": "{colors.solid.red.100}", + "hover": "{colors.solid.red.50}" + }, + "info": { + "default": "{colors.solid.blue.100}", + "hover": "{colors.solid.blue.50}" + }, + "warning": { + "default": "{colors.solid.yellow.100}", + "hover": "{colors.solid.yellow.50}" + }, + "success": { + "default": "{colors.solid.green.100}", + "hover": "{colors.solid.green.50}" + }, + "help": { + "default": "{colors.solid.purple.100}", + "hover": "{colors.solid.purple.50}" + } + } + } + }, + "bg": { + "status": { + "danger": { + "weak": { + "default": "{colors.solid.red.950}", + "hover": "{colors.solid.red.900}", + "active": "{colors.solid.red.800}" + }, + "strong": { + "default": "{colors.solid.red.700}", + "hover": "{colors.solid.red.600}", + "active": "{colors.solid.red.500}" + } + }, + "info": { + "weak": { + "default": "{colors.solid.blue.950}", + "hover": "{colors.solid.blue.900}", + "active": "{colors.solid.blue.800}" + }, + "strong": { + "default": "{colors.solid.blue.700}", + "hover": "{colors.solid.blue.600}", + "active": "{colors.solid.blue.500}" + } + }, + "warning": { + "weak": { + "default": "{colors.solid.yellow.950}", + "hover": "{colors.solid.yellow.900}", + "active": "{colors.solid.yellow.800}" + }, + "strong": { + "default": "{colors.solid.yellow.700}", + "hover": "{colors.solid.yellow.600}", + "active": "{colors.solid.yellow.500}" + } + }, + "success": { + "weak": { + "default": "{colors.solid.green.950}", + "hover": "{colors.solid.green.900}", + "active": "{colors.solid.green.800}" + }, + "strong": { + "default": "{colors.solid.green.700}", + "hover": "{colors.solid.green.600}", + "active": "{colors.solid.green.500}" + } + }, + "help": { + "weak": { + "default": "{colors.solid.purple.950}", + "hover": "{colors.solid.purple.900}", + "active": "{colors.solid.purple.800}" + }, + "strong": { + "default": "{colors.solid.purple.700}", + "hover": "{colors.solid.purple.600}", + "active": "{colors.solid.purple.500}" + } + } + }, + "brand": { + "weak": { + "hover": "{colors.solid.green.950}", + "active": "{colors.solid.green.900}" + }, + "strong": { + "default": "{colors.solid.green.500}", + "hover": "{colors.solid.green.400}", + "active": "{colors.solid.green.300}" + } + }, + "surface": { + "canvas": { + "default": "{colors.solid.zinc.900}", + "hover": "{colors.solid.zinc.800}", + "active": "{colors.solid.zinc.700}", + "selected": "{colors.solid.zinc.800}" + }, + "default": { + "default": "{colors.solid.zinc.800}", + "hover": "{colors.solid.zinc.700}", + "active": "{colors.solid.zinc.600}", + "selected": "{colors.solid.zinc.700}" + }, + "raised": { + "default": "{colors.solid.zinc.700}", + "hover": "{colors.solid.zinc.600}", + "active": "{colors.solid.zinc.500}", + "selected": "{colors.solid.zinc.600}" + }, + "overlay": { + "default": "{colors.solid.zinc.800}", + "hover": "{colors.solid.zinc.700}" + }, + "backdrop": "{colors.alpha.black.600}" + }, + "neutral": { + "weak": { + "default": "{colors.solid.zinc.900}", + "hover": "{colors.solid.zinc.800}", + "active": "{colors.solid.zinc.700}", + "disabled": "{colors.solid.zinc.800}" + }, + "medium": { + "default": "{colors.solid.zinc.800}", + "hover": "{colors.solid.zinc.700}", + "active": "{colors.solid.zinc.600}", + "strong": "{colors.solid.zinc.500}" + }, + "strong": { + "default": "{colors.solid.zinc.100}", + "hover": "{colors.solid.zinc.200}", + "active": "{colors.solid.zinc.300}", + "selected": "{colors.solid.zinc.100}" + } + } + }, + "border": { + "focus": "{colors.solid.green.200}", + "neutral": { + "default": "{colors.solid.zinc.800}", + "strong": "{colors.solid.zinc.700}", + "bold": { + "default": "{colors.solid.zinc.100}", + "hover": "{colors.solid.zinc.200}" + }, + "inverse": "{colors.solid.zinc.900}" + }, + "brand": { + "subtle": "{colors.solid.green.800}", + "default": "{colors.solid.green.500}", + "strong": "{colors.solid.green.400}" + }, + "status": { + "danger": { + "subtle": "{colors.solid.red.600}", + "default": "{colors.solid.red.500}", + "strong": "{colors.solid.red.400}" + }, + "info": { + "default": "{colors.solid.blue.500}", + "strong": "{colors.solid.blue.400}" + }, + "warning": { + "default": "{colors.solid.yellow.500}", + "strong": "{colors.solid.yellow.400}" + }, + "success": { + "default": "{colors.solid.green.500}", + "strong": "{colors.solid.green.400}" + }, + "help": { "strong": "{colors.solid.purple.400}" } + } + } + } + } + }, + "dimension": { + "space": { + "none": "{sizing.none}", + "100": "{sizing.2x}", + "150": "{sizing.3x}", + "200": "{sizing.4x}", + "300": "{sizing.5x}", + "400": "{sizing.7x}", + "500": "{sizing.9x}", + "600": "{sizing.10x}", + "700": "{sizing.12x}", + "800": "{sizing.14x}", + "negative": { + "50": "-0.125rem", + "200": "-0.5rem", + "300": "-0.75rem", + "600": "-1.5rem" + } + }, + "size": { + "none": "{sizing.none}", + "50": "{sizing.1x}", + "100": "{sizing.2x}", + "150": "{sizing.3x}", + "200": "{sizing.4x}", + "300": "{sizing.5x}", + "350": "{sizing.6x}", + "400": "{sizing.7x}", + "450": "{sizing.8x}", + "500": "{sizing.9x}", + "600": "{sizing.10x}", + "700": "{sizing.12x}", + "750": "{sizing.13x}", + "800": "{sizing.14x}", + "900": "{sizing.16x}", + "1000": "{sizing.18x}", + "1100": "{sizing.20x}", + "1200": "{sizing.24x}", + "1300": "{sizing.28x}", + "1400": "{sizing.32x}", + "1500": "{sizing.40x}", + "1600": "{sizing.120x}", + "1700": "{sizing.136x}", + "1800": "{sizing.152x}", + "1900": "{sizing.168x}", + "2000": "{sizing.200x}", + "max": "{sizing.max}" + }, + "borderRadius": { + "none": "{sizing.none}", + "100": "{sizing.2x}", + "200": "{sizing.4x}", + "300": "{sizing.5x}", + "400": "{sizing.7x}", + "500": "{sizing.10x}", + "max": "{sizing.max}" + }, + "borderWidth": { + "none": "{sizing.none}", + "100": "{sizing.05x}", + "200": "{sizing.1x}", + "300": "{sizing.2x}" + }, + "focusRing": { "width": "{sizing.2x}", "offset": "{sizing.none}" }, + "depth": { + "100": "1000", + "200": "1100", + "300": "1200", + "400": "1300", + "500": "1400", + "600": "1500", + "700": "1600" + }, + "viewport": { + "100": "{sizing.288x}", + "200": "{sizing.384x}", + "300": "{sizing.496x}", + "400": "{sizing.600x}", + "500": "{sizing.700x}" + } + }, + "effects": { + "opacity": { + "0": "0", + "4": "0.04", + "8": "0.08", + "12": "0.12", + "16": "0.16", + "20": "0.2", + "30": "0.3", + "40": "0.4", + "50": "0.5", + "60": "0.6", + "70": "0.7", + "80": "0.8", + "90": "0.9", + "100": "1" + }, + "blur": { + "none": "0", + "100": "4px", + "200": "8px", + "300": "16px", + "400": "24px" + }, + "transition": { + "easing": { + "linear": "linear", + "in": "cubic-bezier(0.55, 0.06, 0.7, 0.2)", + "out": "cubic-bezier(0.2, 0.6, 0.4, 1)", + "inOut": "cubic-bezier(0.65, 0.05, 0.35, 1)", + "standard": "cubic-bezier(0.2, 0, 0, 1)", + "accelerate": "cubic-bezier(0.3, 0, 1, 1)", + "decelerate": "cubic-bezier(0, 0, 0, 1)", + "emphasizedAccelerate": "cubic-bezier(0.3, 0, 0.8, 0.15)", + "emphasizedDecelerate": "cubic-bezier(0.05, 0.7, 0.1, 1)", + "spring": "cubic-bezier(0.34, 1.56, 0.64, 1)" + }, + "duration": { + "100": "140ms", + "200": "180ms", + "300": "240ms", + "400": "320ms", + "500": "400ms" + } + }, + "elevation": { + "none": "none", + "100": "0 0 2px {colors.alpha.black.200}", + "200": "0 0 4px {colors.alpha.black.200}", + "300": "0 2px 4px {colors.alpha.black.200}", + "400": "0 4px 8px {colors.alpha.black.200}", + "500": "0 8px 16px 0 {colors.alpha.black.200}", + "status": { + "info": "0px 4px 8px 0px {colors.alpha.blue.40}", + "success": "0px 4px 8px 0px {colors.alpha.green.40}", + "warning": "0px 4px 8px 0px {colors.alpha.yellow.40}", + "danger": "0px 4px 8px 0px {colors.alpha.red.40}", + "secondary": "0px 4px 8px 0px {colors.alpha.black.40}", + "contrast": "0px 4px 8px 0px {colors.alpha.black.40}" + } + }, + "focusRing": { + "shadow": "inset 0 0 0 {dimension.focusRing.width} {colors.solid.green.200}" + } + } + }, + "components": { + "accordion": { + "extend": { + "extHeader": { + "iconSize": "{dimension.size.600}", + "gap": "{dimension.space.200}" + } + }, + "colorScheme": { + "light": { + "header": { + "background": "transparent", + "hoverBackground": "transparent", + "activeBackground": "transparent", + "activeHoverBackground": "transparent" + } + }, + "dark": { + "header": { + "activeBackground": "transparent", + "activeHoverBackground": "transparent", + "background": "transparent", + "hoverBackground": "transparent" + } + } + }, + "header": { + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "activeColor": "{color.fg.default}", + "activeHoverColor": "{color.fg.hover}", + "borderColor": "transparent", + "padding": "{dimension.space.400} {dimension.space.none} {dimension.space.400} {dimension.space.none}", + "fontWeight": "{fonts.fontWeight.bold}", + "borderRadius": "{dimension.borderRadius.none}", + "borderWidth": "{dimension.borderWidth.none}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.focusRing.shadow}" + }, + "toggleIcon": { + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "activeColor": "{color.fg.default}", + "activeHoverColor": "{color.fg.hover}" + }, + "last": { + "bottomBorderRadius": "{dimension.borderRadius.none}", + "activeBottomBorderRadius": "{dimension.borderRadius.none}" + }, + "first": { + "borderWidth": "{dimension.borderWidth.none}", + "topBorderRadius": "{dimension.borderRadius.none}" + } + }, + "root": { "transitionDuration": "{effects.transition.duration.200}" }, + "panel": { + "borderWidth": "{dimension.borderWidth.none} {dimension.borderWidth.none} {dimension.borderWidth.300} {dimension.borderWidth.none}", + "borderColor": "{color.border.neutral.strong}" + }, + "content": { + "borderWidth": "{dimension.borderWidth.100} {dimension.borderWidth.none} {dimension.borderWidth.none} {dimension.borderWidth.none}", + "borderColor": "transparent", + "background": "transparent", + "color": "{color.fg.default}", + "padding": "{dimension.space.none} {dimension.space.700} {dimension.space.400} {dimension.space.700}" + } + }, + "autocomplete": { + "extend": { + "extOption": { "gap": "{dimension.space.200}" }, + "extOptionGroup": { "gap": "{dimension.space.200}" } + }, + "colorScheme": { + "light": { + "chip": { + "focusBackground": "{color.bg.neutral.medium.default}", + "focusColor": "{color.fg.default}" + }, + "dropdown": { + "background": "{color.bg.surface.default.default}", + "hoverBackground": "{color.bg.surface.default.default}", + "activeBackground": "{color.bg.surface.default.default}", + "color": "{color.fg.active}", + "hoverColor": "{color.fg.active}", + "activeColor": "{color.fg.active}" + } + }, + "dark": { + "chip": { + "focusBackground": "{color.bg.neutral.strong.hover}", + "focusColor": "{color.fg.inverse.focus}" + }, + "dropdown": { + "activeBackground": "{color.bg.surface.default.default}", + "activeColor": "{color.fg.inverse.active}", + "background": "{color.bg.surface.default.default}", + "color": "{color.fg.inverse.active}", + "hoverBackground": "{color.bg.surface.default.default}", + "hoverColor": "{color.fg.inverse.active}" + } + } + }, + "root": { + "background": "{color.bg.surface.default.default}", + "disabledBackground": "{color.bg.surface.canvas.hover}", + "filledBackground": "{color.bg.surface.default.default}", + "filledHoverBackground": "{color.bg.surface.default.default}", + "filledFocusBackground": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.strong}", + "hoverBorderColor": "{color.border.brand.strong}", + "focusBorderColor": "{color.border.brand.strong}", + "invalidBorderColor": "{color.border.status.danger.subtle}", + "color": "{color.fg.active}", + "disabledColor": "{color.fg.muted}", + "placeholderColor": "{color.fg.muted}", + "invalidPlaceholderColor": "{color.fg.status.danger.hover}", + "shadow": "{effects.elevation.none}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}", + "borderRadius": "{dimension.borderRadius.400}", + "transitionDuration": "{effects.transition.duration.200}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}" + } + }, + "overlay": { + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "borderRadius": "{dimension.borderRadius.400}", + "color": "{color.fg.default}", + "shadow": "{effects.elevation.200}" + }, + "list": { + "padding": "{dimension.space.100}", + "gap": "{dimension.space.100}" + }, + "option": { + "focusBackground": "{color.bg.neutral.weak.default}", + "selectedBackground": "{color.bg.neutral.strong.selected}", + "selectedFocusBackground": "{color.bg.neutral.strong.active}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "selectedColor": "{color.fg.on.fill.default}", + "selectedFocusColor": "{color.fg.on.fill.active}", + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.200}" + }, + "optionGroup": { + "background": "{color.bg.surface.raised.default}", + "color": "{color.fg.muted}", + "fontWeight": "{fonts.fontWeight.demibold}", + "padding": "{dimension.space.200} {dimension.space.400}" + }, + "dropdown": { + "width": "{dimension.size.1700}", + "borderColor": "{color.border.neutral.strong}", + "hoverBorderColor": "{color.border.brand.strong}", + "activeBorderColor": "{color.border.brand.strong}", + "borderRadius": "{dimension.borderRadius.400}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}" + }, + "sm": { "width": "{dimension.size.1600}" }, + "lg": { "width": "{dimension.size.1800}" } + }, + "chip": { "borderRadius": "{dimension.borderRadius.200}" }, + "emptyMessage": { + "padding": "{dimension.space.200} {dimension.space.400}" + } + }, + "avatar": { + "extend": { + "borderColor": "{color.border.neutral.strong}", + "circle": { "borderRadius": "{dimension.borderRadius.max}" } + }, + "root": { + "width": "{dimension.size.900}", + "height": "{dimension.size.900}", + "fontSize": "{fonts.fontSize.300}", + "color": "{color.fg.default}", + "background": "{color.bg.brand.strong.default}", + "borderRadius": "{dimension.borderRadius.400}" + }, + "icon": { "size": "{dimension.size.450}" }, + "group": { + "borderColor": "{color.border.neutral.inverse}", + "offset": "{dimension.space.negative.300}" + }, + "lg": { + "width": "{dimension.size.1100}", + "height": "{dimension.size.1100}", + "fontSize": "{fonts.fontSize.300}", + "icon": { "size": "{dimension.size.450}" }, + "group": { "offset": "{dimension.space.negative.300}" } + }, + "xl": { + "width": "{dimension.size.1300}", + "height": "{dimension.size.1300}", + "icon": { "size": "{dimension.size.700}" }, + "group": { "offset": "{dimension.space.negative.600}" }, + "fontSize": "{fonts.fontSize.300}" + } + }, + "badge": { + "extend": { + "extDot": { + "success": { "background": "{color.bg.status.success.strong.hover}" }, + "info": { "background": "{color.bg.status.info.strong.hover}" }, + "warn": { "background": "{color.bg.status.warning.strong.hover}" }, + "danger": { "background": "{color.bg.status.danger.strong.hover}" }, + "lg": { "size": "{dimension.size.350}" }, + "xlg": { "size": "{dimension.size.450}" } + }, + "ext": { "padding": "{dimension.space.none}" } + }, + "colorScheme": { + "light": { + "primary": { + "color": "{color.fg.default}", + "background": "{color.bg.brand.strong.default}" + }, + "secondary": { + "color": "{color.fg.on.fill.default}", + "background": "{color.bg.neutral.strong.default}" + }, + "success": { + "color": "{color.fg.on.status.success.default}", + "background": "{color.bg.status.success.strong.default}" + }, + "info": { + "color": "{color.fg.on.status.info.default}", + "background": "{color.bg.status.info.strong.default}" + }, + "warn": { + "color": "{color.fg.on.status.warning.default}", + "background": "{color.bg.status.warning.strong.default}" + }, + "danger": { + "color": "{color.fg.on.status.danger.default}", + "background": "{color.bg.status.danger.strong.default}" + }, + "contrast": { + "background": "{color.bg.neutral.strong.default}", + "color": "{color.fg.on.fill.default}" + } + }, + "dark": { + "contrast": { + "background": "{color.bg.surface.canvas.default}", + "color": "{color.fg.default}" + }, + "danger": { + "background": "{color.bg.status.danger.strong.default}", + "color": "{color.fg.on.status.danger.default}" + }, + "info": { + "background": "{color.bg.status.info.strong.default}", + "color": "{color.fg.on.status.info.default}" + }, + "primary": { + "background": "{color.bg.brand.strong.default}", + "color": "{color.fg.inverse.default}" + }, + "secondary": { + "background": "{color.bg.surface.canvas.default}", + "color": "{color.fg.default}" + }, + "success": { + "background": "{color.bg.brand.strong.active}", + "color": "{color.fg.on.status.success.default}" + }, + "warn": { + "background": "{color.bg.status.warning.strong.default}", + "color": "{color.fg.on.status.warning.default}" + } + } + }, + "root": { + "borderRadius": "{dimension.borderRadius.200}", + "padding": "{dimension.space.200}", + "fontSize": "{fonts.fontSize.100}", + "fontWeight": "{fonts.fontWeight.regular}", + "minWidth": "{dimension.size.700}", + "height": "{dimension.size.700}" + }, + "dot": { "size": "{dimension.size.200}" }, + "sm": { + "fontSize": "{fonts.fontSize.100}", + "minWidth": "{dimension.size.none}", + "height": "{dimension.size.none}" + }, + "lg": { + "fontSize": "{fonts.fontSize.100}", + "minWidth": "{dimension.size.800}", + "height": "{dimension.size.800}" + }, + "xl": { + "fontSize": "{fonts.fontSize.100}", + "minWidth": "{dimension.size.900}", + "height": "{dimension.size.900}" + } + }, + "breadcrumb": { + "extend": { + "hoverBackground": "{color.bg.neutral.weak.default}", + "iconSize": "{dimension.size.600}", + "extItem": { "padding": "{dimension.space.100}" } + }, + "root": { + "padding": "{dimension.space.none}", + "background": "transparent", + "gap": "{dimension.space.none}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + }, + "item": { + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "borderRadius": "{dimension.borderRadius.100}", + "gap": "{dimension.space.200}", + "icon": { + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}" + }, + "focusRing": { + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}", + "style": "none", + "width": "{dimension.focusRing.width}" + } + }, + "separator": { "color": "{color.fg.default}" } + }, + "button": { + "extend": { + "disabledBackground": "{color.bg.neutral.weak.disabled}", + "extOutlined": { + "danger": { "focusBackground": "transparent" }, + "warn": { "focusBackground": "transparent" }, + "info": { "focusBackground": "transparent" }, + "help": { "focusBackground": "transparent" }, + "success": { "focusBackground": "transparent" } + }, + "disabledColor": "{color.fg.muted}", + "extText": { + "danger": { "focusBackground": "transparent" }, + "warn": { "focusBackground": "transparent" }, + "info": { "focusBackground": "transparent" }, + "help": { "focusBackground": "transparent" }, + "success": { "focusBackground": "transparent" } + }, + "extLink": { + "background": "transparent", + "colorHover": "{color.fg.hover}", + "paddingX": "{dimension.space.none}", + "paddingY": "{dimension.space.100}", + "sm": { "iconOnlyWidth": "{dimension.size.450}" }, + "base": { "iconOnlyWidth": "{dimension.size.700}" }, + "lg": { "iconOnlyWidth": "{dimension.size.800}" }, + "xlg": { "iconOnlyWidth": "{dimension.size.900}" } + }, + "extSm": { + "borderRadius": "{dimension.borderRadius.400}", + "gap": "{dimension.space.200}" + }, + "extLg": { + "borderRadius": "{dimension.borderRadius.400}", + "gap": "{dimension.space.400}", + "height": "{dimension.size.1300}" + }, + "extXlg": { + "borderRadius": "{dimension.borderRadius.400}", + "gap": "{dimension.space.400}", + "iconOnlyWidth": "{dimension.size.1400}", + "paddingX": "{dimension.space.700}", + "paddingY": "{dimension.space.600}", + "height": "{dimension.size.1400}" + }, + "borderWidth": "{dimension.borderWidth.100}", + "iconSize": { + "sm": "{dimension.size.450}", + "md": "{dimension.size.600}", + "lg": "{dimension.size.700}" + } + }, + "colorScheme": { + "light": { + "root": { + "primary": { + "background": "{color.bg.brand.strong.default}", + "hoverBackground": "{color.bg.brand.strong.hover}", + "activeBackground": "{color.bg.brand.strong.active}", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.default}", + "activeColor": "{color.fg.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + }, + "secondary": { + "background": "{color.bg.neutral.strong.default}", + "hoverBackground": "{color.bg.neutral.strong.hover}", + "activeBackground": "{color.bg.neutral.strong.active}", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "{color.fg.on.fill.default}", + "hoverColor": "{color.fg.on.fill.hover}", + "activeColor": "{color.fg.on.fill.active}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + }, + "contrast": { + "background": "{color.bg.surface.canvas.hover}", + "hoverBackground": "{color.bg.surface.canvas.active}", + "activeBackground": "{color.bg.neutral.medium.active}", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.default}", + "activeColor": "{color.fg.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + }, + "info": { + "background": "{color.bg.status.info.strong.default}", + "hoverBackground": "{color.bg.status.info.strong.hover}", + "activeBackground": "{color.bg.status.info.strong.active}", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "{color.fg.on.status.info.default}", + "hoverColor": "{color.fg.on.status.info.hover}", + "activeColor": "{color.fg.on.status.info.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + } + }, + "success": { + "background": "{color.bg.status.success.strong.default}", + "hoverBackground": "{color.bg.status.success.strong.hover}", + "activeBackground": "{color.bg.status.success.strong.active}", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "{color.fg.on.status.success.default}", + "hoverColor": "{color.fg.on.status.success.hover}", + "activeColor": "{color.fg.on.status.success.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + } + }, + "warn": { + "background": "{color.bg.status.warning.strong.default}", + "hoverBackground": "{color.bg.status.warning.strong.hover}", + "activeBackground": "{color.bg.status.warning.strong.active}", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "{color.fg.on.status.warning.default}", + "hoverColor": "{color.fg.on.status.warning.hover}", + "activeColor": "{color.fg.on.status.warning.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + } + }, + "help": { + "background": "{color.bg.status.help.strong.default}", + "hoverBackground": "{color.bg.status.help.strong.hover}", + "activeBackground": "{color.bg.status.help.strong.active}", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "{color.fg.on.status.help.default}", + "hoverColor": "{color.fg.on.status.help.hover}", + "activeColor": "{color.fg.on.status.help.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + } + }, + "danger": { + "background": "{color.bg.status.danger.strong.default}", + "hoverBackground": "{color.bg.status.danger.strong.hover}", + "activeBackground": "{color.bg.status.danger.strong.active}", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "{color.fg.on.status.danger.default}", + "hoverColor": "{color.fg.on.status.danger.hover}", + "activeColor": "{color.fg.on.status.danger.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + } + } + }, + "outlined": { + "primary": { + "hoverBackground": "{color.bg.brand.weak.hover}", + "activeBackground": "{color.bg.brand.weak.active}", + "borderColor": "{color.border.focus}", + "color": "{color.fg.brand.default}" + }, + "success": { + "hoverBackground": "{color.bg.status.success.weak.hover}", + "activeBackground": "{color.bg.status.success.weak.active}", + "borderColor": "{color.border.brand.strong}", + "color": "{color.fg.status.success.hover}" + }, + "info": { + "hoverBackground": "{color.bg.status.info.weak.hover}", + "activeBackground": "{color.bg.status.info.weak.active}", + "borderColor": "{color.border.status.info.strong}", + "color": "{color.fg.status.info.hover}" + }, + "warn": { + "hoverBackground": "{color.bg.status.warning.weak.hover}", + "activeBackground": "{color.bg.status.warning.weak.active}", + "borderColor": "{color.border.status.warning.strong}", + "color": "{color.fg.status.warning.hover}" + }, + "help": { + "hoverBackground": "{color.bg.status.help.weak.hover}", + "activeBackground": "{color.bg.status.help.weak.active}", + "borderColor": "{color.border.status.help.strong}", + "color": "{color.fg.status.help.hover}" + }, + "danger": { + "hoverBackground": "{color.bg.status.danger.weak.hover}", + "activeBackground": "{color.bg.status.danger.weak.active}", + "borderColor": "{color.border.status.danger.strong}", + "color": "{color.fg.status.danger.hover}" + }, + "contrast": { + "activeBackground": "{color.bg.neutral.strong.active}", + "borderColor": "{color.border.neutral.bold.default}", + "color": "{color.fg.on.fill.default}", + "hoverBackground": "{color.bg.neutral.strong.hover}" + }, + "plain": { + "activeBackground": "{color.bg.neutral.medium.default}", + "borderColor": "{color.border.neutral.strong}", + "color": "{color.fg.default}", + "hoverBackground": "{color.bg.neutral.weak.default}" + }, + "secondary": { + "activeBackground": "{color.bg.neutral.medium.default}", + "borderColor": "{color.border.neutral.strong}", + "color": "{color.fg.default}", + "hoverBackground": "{color.bg.neutral.weak.default}" + } + }, + "text": { + "primary": { + "hoverBackground": "{color.bg.neutral.weak.default}", + "activeBackground": "{color.bg.neutral.medium.default}", + "color": "{color.fg.default}" + }, + "success": { + "hoverBackground": "{color.bg.status.success.weak.hover}", + "activeBackground": "{color.bg.status.success.weak.active}", + "color": "{color.fg.status.success.hover}" + }, + "info": { + "hoverBackground": "{color.bg.status.info.weak.hover}", + "activeBackground": "{color.bg.status.info.weak.active}", + "color": "{color.fg.status.info.hover}" + }, + "warn": { + "hoverBackground": "{color.bg.status.warning.weak.hover}", + "activeBackground": "{color.bg.status.warning.weak.active}", + "color": "{color.fg.status.warning.hover}" + }, + "help": { + "hoverBackground": "{color.bg.status.help.weak.hover}", + "activeBackground": "{color.bg.status.help.weak.active}", + "color": "{color.fg.status.help.hover}" + }, + "danger": { + "hoverBackground": "{color.bg.status.danger.weak.hover}", + "activeBackground": "{color.bg.status.danger.weak.active}", + "color": "{color.fg.status.danger.hover}" + }, + "contrast": { + "activeBackground": "{color.bg.neutral.strong.active}", + "color": "{color.fg.on.fill.default}", + "hoverBackground": "{color.bg.neutral.strong.hover}" + }, + "plain": { + "activeBackground": "{color.bg.neutral.medium.default}", + "color": "{color.fg.default}", + "hoverBackground": "{color.bg.neutral.weak.default}" + }, + "secondary": { + "activeBackground": "{color.bg.neutral.medium.default}", + "color": "{color.fg.default}", + "hoverBackground": "{color.bg.neutral.weak.default}" + } + }, + "link": { + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "activeColor": "{color.fg.muted}" + } + }, + "dark": { + "link": { + "activeColor": "{color.fg.inverse.muted}", + "color": "{color.fg.inverse.default}", + "hoverColor": "{color.fg.inverse.hover}" + }, + "outlined": { + "contrast": { + "activeBackground": "{color.bg.surface.canvas.active}", + "borderColor": "{color.border.neutral.inverse}", + "color": "{color.fg.default}", + "hoverBackground": "{color.bg.surface.canvas.hover}" + }, + "danger": { + "activeBackground": "{color.bg.status.danger.weak.active}", + "borderColor": "{color.border.status.danger.subtle}", + "color": "{color.fg.status.danger.hover}", + "hoverBackground": "{color.bg.status.danger.weak.hover}" + }, + "help": { + "activeBackground": "{color.bg.status.help.weak.active}", + "borderColor": "{color.border.status.help.strong}", + "color": "{color.fg.status.help.hover}", + "hoverBackground": "{color.bg.status.help.weak.hover}" + }, + "info": { + "activeBackground": "{color.bg.status.info.weak.active}", + "borderColor": "{color.border.status.info.strong}", + "color": "{color.fg.status.info.hover}", + "hoverBackground": "{color.bg.status.info.weak.hover}" + }, + "plain": { + "activeBackground": "{color.bg.neutral.strong.hover}", + "borderColor": "{color.border.neutral.strong}", + "color": "{color.fg.inverse.default}", + "hoverBackground": "{color.bg.neutral.strong.selected}" + }, + "primary": { + "activeBackground": "{color.bg.brand.weak.active}", + "borderColor": "{color.border.focus}", + "color": "{color.fg.brand.muted}", + "hoverBackground": "{color.bg.brand.weak.hover}" + }, + "secondary": { + "activeBackground": "{color.bg.neutral.strong.hover}", + "borderColor": "{color.border.neutral.strong}", + "color": "{color.fg.inverse.default}", + "hoverBackground": "{color.bg.neutral.strong.selected}" + }, + "success": { + "activeBackground": "{color.bg.status.success.weak.active}", + "borderColor": "{color.border.brand.strong}", + "color": "{color.fg.status.success.hover}", + "hoverBackground": "{color.bg.status.success.weak.hover}" + }, + "warn": { + "activeBackground": "{color.bg.status.warning.weak.active}", + "borderColor": "{color.border.status.warning.strong}", + "color": "{color.fg.status.warning.hover}", + "hoverBackground": "{color.bg.status.warning.weak.hover}" + } + }, + "root": { + "contrast": { + "activeBackground": "{color.bg.neutral.medium.active}", + "activeBorderColor": "transparent", + "activeColor": "{color.fg.on.brand.active}", + "background": "{color.bg.neutral.strong.hover}", + "borderColor": "transparent", + "color": "{color.fg.inverse.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "{color.bg.neutral.strong.active}", + "hoverBorderColor": "transparent", + "hoverColor": "{color.fg.on.brand.hover}" + }, + "danger": { + "activeBackground": "{color.bg.status.danger.strong.active}", + "activeBorderColor": "transparent", + "activeColor": "{color.fg.on.status.danger.default}", + "background": "{color.bg.status.danger.strong.default}", + "borderColor": "transparent", + "color": "{color.fg.on.status.danger.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + }, + "hoverBackground": "{color.bg.status.danger.strong.hover}", + "hoverBorderColor": "transparent", + "hoverColor": "{color.fg.on.status.danger.hover}" + }, + "help": { + "activeBackground": "{color.bg.status.help.strong.active}", + "activeBorderColor": "transparent", + "activeColor": "{color.fg.on.status.help.default}", + "background": "{color.bg.status.help.strong.default}", + "borderColor": "transparent", + "color": "{color.fg.on.status.help.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + }, + "hoverBackground": "{color.bg.status.help.strong.hover}", + "hoverBorderColor": "transparent", + "hoverColor": "{color.fg.on.status.help.hover}" + }, + "info": { + "activeBackground": "{color.bg.status.info.strong.active}", + "activeBorderColor": "transparent", + "activeColor": "{color.fg.on.status.info.default}", + "background": "{color.bg.status.info.strong.default}", + "borderColor": "transparent", + "color": "{color.fg.on.status.info.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + }, + "hoverBackground": "{color.bg.status.info.strong.hover}", + "hoverBorderColor": "transparent", + "hoverColor": "{color.fg.on.status.info.hover}" + }, + "primary": { + "activeBackground": "{color.bg.status.success.strong.default}", + "activeBorderColor": "transparent", + "activeColor": "{color.fg.on.brand.active}", + "background": "{color.bg.brand.strong.default}", + "borderColor": "transparent", + "color": "{color.fg.inverse.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "{color.bg.status.success.strong.hover}", + "hoverBorderColor": "transparent", + "hoverColor": "{color.fg.on.brand.hover}" + }, + "secondary": { + "activeBackground": "{color.bg.surface.canvas.active}", + "activeBorderColor": "transparent", + "activeColor": "{color.fg.on.fill.active}", + "background": "{color.bg.surface.canvas.default}", + "borderColor": "transparent", + "color": "{color.fg.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "{color.bg.surface.canvas.hover}", + "hoverBorderColor": "transparent", + "hoverColor": "{color.fg.on.fill.hover}" + }, + "success": { + "activeBackground": "{color.bg.status.success.strong.active}", + "activeBorderColor": "transparent", + "activeColor": "{color.fg.on.status.success.default}", + "background": "{color.bg.brand.strong.active}", + "borderColor": "transparent", + "color": "{color.fg.on.status.success.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + }, + "hoverBackground": "{color.bg.brand.strong.hover}", + "hoverBorderColor": "transparent", + "hoverColor": "{color.fg.on.status.success.hover}" + }, + "warn": { + "activeBackground": "{color.bg.status.warning.strong.active}", + "activeBorderColor": "transparent", + "activeColor": "{color.fg.on.status.warning.default}", + "background": "{color.bg.status.warning.strong.default}", + "borderColor": "transparent", + "color": "{color.fg.on.status.warning.default}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + }, + "hoverBackground": "{color.bg.status.warning.strong.hover}", + "hoverBorderColor": "transparent", + "hoverColor": "{color.fg.on.status.warning.hover}" + } + }, + "text": { + "contrast": { + "activeBackground": "{color.bg.surface.canvas.active}", + "color": "{color.fg.default}", + "hoverBackground": "{color.bg.surface.canvas.hover}" + }, + "danger": { + "activeBackground": "{color.bg.status.danger.weak.active}", + "color": "{color.fg.status.danger.hover}", + "hoverBackground": "{color.bg.status.danger.weak.hover}" + }, + "help": { + "activeBackground": "{color.bg.status.help.weak.active}", + "color": "{color.fg.status.help.hover}", + "hoverBackground": "{color.bg.status.help.weak.hover}" + }, + "info": { + "activeBackground": "{color.bg.status.info.weak.active}", + "color": "{color.fg.status.info.hover}", + "hoverBackground": "{color.bg.status.info.weak.hover}" + }, + "plain": { + "activeBackground": "{color.bg.neutral.strong.hover}", + "color": "{color.fg.inverse.default}", + "hoverBackground": "{color.bg.neutral.strong.selected}" + }, + "primary": { + "activeBackground": "{color.bg.neutral.strong.hover}", + "color": "{color.fg.inverse.default}", + "hoverBackground": "{color.bg.neutral.strong.selected}" + }, + "secondary": { + "activeBackground": "{color.bg.neutral.strong.hover}", + "color": "{color.fg.inverse.default}", + "hoverBackground": "{color.bg.neutral.strong.selected}" + }, + "success": { + "activeBackground": "{color.bg.status.success.weak.active}", + "color": "{color.fg.status.success.hover}", + "hoverBackground": "{color.bg.status.success.weak.hover}" + }, + "warn": { + "activeBackground": "{color.bg.status.warning.weak.active}", + "color": "{color.fg.status.warning.hover}", + "hoverBackground": "{color.bg.status.warning.weak.hover}" + } + } + } + }, + "root": { + "borderRadius": "{dimension.borderRadius.400}", + "roundedBorderRadius": "{dimension.borderRadius.max}", + "gap": "{dimension.space.200}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.200}", + "iconOnlyWidth": "{dimension.size.1100}", + "raisedShadow": "none", + "badgeSize": "{dimension.size.450}", + "transitionDuration": "{effects.transition.duration.200}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "offset": "{dimension.focusRing.offset}" + }, + "sm": { + "fontSize": "{fonts.fontSize.200}", + "iconOnlyWidth": "{dimension.size.900}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.200}" + }, + "lg": { + "fontSize": "{fonts.fontSize.500}", + "iconOnlyWidth": "{dimension.size.1300}", + "paddingX": "{dimension.space.700}", + "paddingY": "{dimension.space.400}" + }, + "label": { "fontWeight": "{fonts.fontWeight.demibold}" } + } + }, + "card": { + "extend": { + "borderColor": "{color.border.neutral.default}", + "borderWidth": "{dimension.borderWidth.100}" + }, + "root": { + "background": "{color.bg.surface.default.default}", + "borderRadius": "{dimension.borderRadius.400}", + "color": "{color.fg.default}", + "shadow": "{effects.elevation.none}" + }, + "body": { + "padding": "{dimension.space.400}", + "gap": "{dimension.space.400}" + }, + "caption": { "gap": "{dimension.space.100}" }, + "title": { + "fontSize": "{fonts.fontSize.400}", + "fontWeight": "{fonts.fontWeight.demibold}" + }, + "subtitle": { "color": "{color.fg.muted}" } + }, + "carousel": { + "colorScheme": { + "light": { + "indicator": { + "background": "{color.bg.neutral.weak.active}", + "hoverBackground": "{color.bg.neutral.medium.active}", + "activeBackground": "{color.bg.neutral.strong.default}" + } + }, + "dark": { + "indicator": { + "activeBackground": "{color.bg.surface.canvas.default}", + "background": "{color.bg.neutral.strong.active}", + "hoverBackground": "{color.bg.neutral.medium.active}" + } + } + }, + "root": { "transitionDuration": "{effects.transition.duration.200}" }, + "content": { "gap": "{dimension.space.200}" }, + "indicatorList": { + "padding": "{dimension.space.400}", + "gap": "{dimension.space.200}" + }, + "indicator": { + "width": "{dimension.size.200}", + "height": "{dimension.size.200}", + "borderRadius": "{dimension.borderRadius.max}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + } + }, + "checkbox": { + "root": { + "borderRadius": "{dimension.borderRadius.200}", + "extend": { "borderWidth": "{dimension.borderWidth.100}" }, + "width": "{dimension.size.700}", + "height": "{dimension.size.700}", + "background": "{color.bg.surface.default.default}", + "checkedBackground": "{color.bg.neutral.strong.default}", + "checkedHoverBackground": "{color.bg.neutral.strong.hover}", + "disabledBackground": "{color.bg.surface.canvas.hover}", + "filledBackground": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.strong}", + "hoverBorderColor": "{color.border.neutral.bold.default}", + "focusBorderColor": "{color.border.neutral.bold.default}", + "checkedBorderColor": "{color.border.neutral.bold.default}", + "checkedHoverBorderColor": "{color.border.neutral.bold.hover}", + "checkedFocusBorderColor": "{color.border.brand.default}", + "checkedDisabledBorderColor": "{color.border.neutral.strong}", + "invalidBorderColor": "{color.border.status.danger.subtle}", + "shadow": "{effects.elevation.none}", + "focusRing": { + "focusRing": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}", + "width": "{dimension.focusRing.width}" + }, + "sm": { + "width": "{dimension.size.200}", + "height": "{dimension.size.200}" + }, + "lg": { + "width": "{dimension.size.600}", + "height": "{dimension.size.600}" + }, + "transitionDuration": "{effects.transition.duration.200}" + }, + "icon": { + "size": "{dimension.size.450}", + "color": "{color.fg.active}", + "checkedColor": "{color.fg.on.fill.default}", + "checkedHoverColor": "{color.fg.on.fill.hover}", + "disabledColor": "{color.fg.muted}", + "sm": { "size": "{dimension.size.350}" }, + "lg": { "size": "{dimension.size.600}" } + } + }, + "chip": { + "extend": { + "borderColor": "transparent", + "borderWidth": "{dimension.borderWidth.100}" + }, + "root": { + "borderRadius": "{dimension.borderRadius.200}", + "paddingX": "{dimension.space.200}", + "paddingY": "{dimension.space.100}", + "gap": "{dimension.space.200}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "colorScheme": { + "light": { + "root": { + "background": "{color.bg.surface.canvas.hover}", + "color": "{color.fg.default}" + }, + "icon": { "color": "{color.fg.default}" }, + "removeIcon": { "color": "{color.fg.default}" } + }, + "dark": { + "icon": { "color": "{color.fg.inverse.default}" }, + "removeIcon": { "color": "{color.fg.inverse.default}" }, + "root": { + "background": "{color.bg.neutral.strong.hover}", + "color": "{color.fg.inverse.default}" + } + } + }, + "image": { + "width": "{dimension.size.none}", + "height": "{dimension.size.none}" + }, + "icon": { "size": "{dimension.size.450}" }, + "removeIcon": { + "size": "{dimension.size.450}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + } + }, + "confirmdialog": { + "extend": { + "extIcon": { + "success": "{color.fg.status.success.default}", + "info": "{color.fg.status.info.default}", + "help": "{color.fg.status.help.default}", + "warn": "{color.fg.status.warning.default}", + "danger": "{color.fg.status.danger.default}" + } + }, + "icon": { "size": "{dimension.size.700}", "color": "{color.fg.default}" }, + "content": { "gap": "{dimension.space.none}" } + }, + "confirmpopup": { + "root": { + "background": "{color.bg.surface.default.default}", + "color": "{color.fg.default}", + "shadow": "{effects.elevation.400}", + "gutter": "{dimension.space.400}", + "arrowOffset": "{dimension.space.600}", + "borderColor": "{color.border.neutral.default}", + "borderRadius": "{dimension.borderRadius.400}" + }, + "content": { + "padding": "{dimension.space.400}", + "gap": "{dimension.space.400}" + }, + "icon": { "size": "{dimension.size.700}", "color": "{color.fg.default}" }, + "footer": { + "gap": "{dimension.space.200}", + "padding": "{dimension.space.none} {dimension.space.700} {dimension.space.700} {dimension.space.700}" + } + }, + "contextmenu": { + "root": { + "background": "{color.bg.surface.default.default}", + "color": "{color.fg.default}", + "shadow": "{effects.elevation.400}", + "borderColor": "{color.border.neutral.default}", + "borderRadius": "{dimension.borderRadius.400}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "list": { + "padding": "{dimension.space.200} {dimension.space.none}", + "gap": "{dimension.space.100}" + }, + "item": { + "padding": "{dimension.space.200} {dimension.space.400}", + "gap": "{dimension.space.200}", + "activeBackground": "{color.bg.neutral.medium.default}", + "activeColor": "{color.fg.hover}", + "borderRadius": "{dimension.borderRadius.400}", + "color": "{color.fg.default}", + "focusBackground": "{color.bg.neutral.weak.default}", + "focusColor": "{color.fg.hover}", + "icon": { + "activeColor": "{color.fg.hover}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.hover}" + } + }, + "submenu": { "mobileIndent": "{dimension.space.600}" }, + "separator": { "borderColor": "{color.border.neutral.default}" }, + "submenuIcon": { + "activeColor": "{color.fg.hover}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.hover}", + "size": "{dimension.size.400}" + } + }, + "datatable": { + "colorScheme": { + "light": { + "root": { + "color": "{color.fg.default}", + "borderColor": "{color.border.neutral.default}" + }, + "header": { + "background": "{color.bg.surface.default.hover}", + "color": "{color.fg.default}" + }, + "headerCell": { + "background": "{color.bg.surface.raised.selected}", + "hoverBackground": "{color.bg.neutral.weak.default}", + "color": "{color.fg.default}" + }, + "footer": { + "background": "{color.bg.surface.canvas.default}", + "color": "{color.fg.default}" + }, + "footerCell": { + "background": "{color.bg.neutral.weak.default}", + "color": "{color.fg.default}" + }, + "row": { "stripedBackground": "{color.bg.neutral.weak.default}" }, + "bodyCell": { + "selectedBorderColor": "{color.border.neutral.default}" + } + }, + "dark": { + "bodyCell": { + "selectedBorderColor": "{color.border.neutral.bold.hover}" + }, + "footer": { + "background": "{color.bg.neutral.strong.default}", + "color": "{color.fg.inverse.default}" + }, + "footerCell": { + "background": "{color.bg.neutral.strong.default}", + "color": "{color.fg.inverse.default}" + }, + "header": { + "background": "{color.bg.surface.default.hover}", + "color": "{color.fg.inverse.default}" + }, + "headerCell": { + "background": "{color.bg.surface.raised.selected}", + "color": "{color.fg.inverse.default}", + "hoverBackground": "{color.bg.neutral.strong.selected}" + }, + "root": { + "borderColor": "{color.border.neutral.bold.hover}", + "color": "{color.fg.inverse.default}" + }, + "row": { "stripedBackground": "{color.bg.neutral.strong.default}" } + } + }, + "extended": { + "extHeaderCell": { + "selectedHoverBackground": "{color.bg.neutral.strong.hover}" + }, + "extRow": { + "selectedHoverBackground": "{color.bg.neutral.strong.hover}", + "stripedHoverBackground": "{color.bg.neutral.weak.default}", + "iconSize": "{dimension.size.600}" + } + }, + "root": { "transitionDuration": "{effects.transition.duration.200}" }, + "header": { + "borderColor": "{color.border.neutral.default}", + "borderWidth": "{dimension.borderWidth.100} {dimension.borderWidth.none} {dimension.borderWidth.100} {dimension.borderWidth.none}", + "padding": "{dimension.space.400}", + "sm": { "padding": "{dimension.space.200}" }, + "lg": { "padding": "{dimension.space.600}" } + }, + "headerCell": { + "selectedBackground": "{color.bg.neutral.strong.selected}", + "borderColor": "{color.border.neutral.default}", + "hoverColor": "{color.fg.hover}", + "selectedColor": "{color.fg.on.fill.default}", + "gap": "{dimension.space.200}", + "padding": "{dimension.space.400}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.focusRing.shadow}" + }, + "sm": { "padding": "{dimension.space.200}" }, + "lg": { "padding": "{dimension.space.600}" } + }, + "columnTitle": { "fontWeight": "{fonts.fontWeight.bold}" }, + "row": { + "background": "{color.bg.surface.raised.default}", + "hoverBackground": "{color.bg.neutral.weak.default}", + "selectedBackground": "{color.bg.neutral.strong.selected}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "selectedColor": "{color.fg.on.fill.default}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.focusRing.shadow}" + } + }, + "bodyCell": { + "borderColor": "{color.border.neutral.default}", + "padding": "{dimension.space.400}", + "sm": { "padding": "{dimension.space.200}" }, + "lg": { "padding": "{dimension.space.600}" } + }, + "footerCell": { + "borderColor": "{color.border.neutral.default}", + "padding": "{dimension.space.400}", + "sm": { "padding": "{dimension.space.200}" }, + "lg": { "padding": "{dimension.space.600}" } + }, + "columnFooter": { "fontWeight": "{fonts.fontWeight.bold}" }, + "dropPoint": { "color": "{color.fg.default}" }, + "footer": { + "borderColor": "{color.border.neutral.default}", + "borderWidth": "{dimension.borderWidth.none} {dimension.borderWidth.none} {dimension.borderWidth.100} {dimension.borderWidth.none}", + "padding": "{dimension.space.400}", + "sm": { "padding": "{dimension.space.200}" }, + "lg": { "padding": "{dimension.space.600}" } + }, + "columnResizer": { "width": "{dimension.size.200}" }, + "resizeIndicator": { + "width": "{dimension.borderWidth.100}", + "color": "{color.fg.default}" + }, + "sortIcon": { + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "size": "{dimension.size.450}" + }, + "loadingIcon": { "size": "{dimension.size.900}" }, + "rowToggleButton": { + "hoverBackground": "{color.bg.neutral.weak.default}", + "selectedHoverBackground": "{color.bg.neutral.weak.default}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.default}", + "selectedHoverColor": "{color.fg.default}", + "size": "{dimension.size.900}", + "borderRadius": "{dimension.borderRadius.400}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + }, + "filter": { + "inlineGap": "{dimension.space.200}", + "rule": { "borderColor": "{color.border.neutral.default}" }, + "constraintList": { + "padding": "{dimension.space.100}", + "gap": "{dimension.space.100}" + }, + "constraint": { + "focusBackground": "{color.bg.neutral.weak.default}", + "selectedBackground": "{color.bg.neutral.strong.selected}", + "selectedFocusBackground": "{color.bg.neutral.strong.active}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "selectedColor": "{color.fg.on.fill.default}", + "selectedFocusColor": "{color.fg.on.fill.active}", + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.200}", + "separator": { "borderColor": "{color.border.neutral.default}" } + }, + "overlaySelect": { + "background": "{color.bg.surface.raised.default}", + "color": "{color.fg.default}", + "borderColor": "{color.border.neutral.default}", + "borderRadius": "{dimension.borderRadius.400}", + "shadow": "{effects.elevation.400}" + }, + "overlayPopover": { + "background": "{color.bg.surface.raised.default}", + "color": "{color.fg.default}", + "borderColor": "{color.border.neutral.default}", + "borderRadius": "{dimension.borderRadius.400}", + "shadow": "{effects.elevation.400}", + "padding": "{dimension.space.400}", + "gap": "{dimension.space.100}" + } + }, + "paginatorTop": { + "borderColor": "{color.border.neutral.strong}", + "borderWidth": "{dimension.borderWidth.none} {dimension.borderWidth.none} {dimension.borderWidth.100} {dimension.borderWidth.none}" + }, + "paginatorBottom": { + "borderWidth": "{dimension.borderWidth.none} {dimension.borderWidth.none} {dimension.borderWidth.100} {dimension.borderWidth.none}", + "borderColor": "{color.border.neutral.default}" + } + }, + "dataview": { + "root": { + "borderWidth": "{dimension.borderWidth.100}", + "borderRadius": "{dimension.borderRadius.100}", + "padding": "{dimension.space.none}", + "borderColor": "{color.border.neutral.default}" + }, + "header": { + "borderWidth": "{dimension.borderWidth.none} {dimension.borderWidth.none} {dimension.borderWidth.100} {dimension.borderWidth.none}", + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.none} {dimension.borderRadius.none} {dimension.borderRadius.none} {dimension.borderRadius.none}", + "color": "{color.fg.default}", + "borderColor": "{color.border.neutral.default}" + }, + "content": { + "background": "{color.bg.surface.default.default}", + "color": "{color.fg.default}", + "borderColor": "{color.border.neutral.default}", + "borderWidth": "{dimension.borderWidth.none}", + "padding": "{dimension.space.none}", + "borderRadius": "{dimension.borderRadius.none}" + }, + "footer": { + "background": "{color.bg.surface.canvas.default}", + "color": "{color.fg.default}", + "borderWidth": "{dimension.borderWidth.100} {dimension.borderWidth.none} {dimension.borderWidth.none} {dimension.borderWidth.none}", + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.none} {dimension.borderRadius.none} {dimension.borderRadius.none} {dimension.borderRadius.none}", + "borderColor": "{color.border.neutral.default}" + }, + "paginatorTop": { + "borderWidth": "{dimension.borderWidth.none} {dimension.borderWidth.none} {dimension.borderWidth.100} {dimension.borderWidth.none}", + "borderColor": "{color.border.neutral.default}" + }, + "paginatorBottom": { + "borderWidth": "{dimension.borderWidth.100} {dimension.borderWidth.none} {dimension.borderWidth.none} {dimension.borderWidth.none}", + "borderColor": "{color.border.neutral.default}" + }, + "colorScheme": { + "dark": { + "header": { + "background": "{color.bg.surface.default.default}", + "color": "{color.fg.inverse.default}" + } + }, + "light": { + "header": { + "background": "{color.bg.surface.default.default}", + "color": "{color.fg.default}" + } + } + } + }, + "datepicker": { + "extend": { + "extDate": { + "selectedHoverBackground": "{color.bg.neutral.strong.hover}" + }, + "extToday": { + "hoverBackground": "{color.bg.neutral.weak.default}", + "borderColor": "{color.border.neutral.bold.hover}" + }, + "extTitle": { "width": "{dimension.size.1900}" }, + "extTimePicker": { + "minWidth": "{dimension.size.1800}", + "color": "{color.fg.default}" + } + }, + "colorScheme": { + "light": { + "dropdown": { + "background": "{color.bg.surface.default.default}", + "hoverBackground": "{color.bg.surface.canvas.default}", + "activeBackground": "{color.bg.neutral.strong.default}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.default}", + "activeColor": "{color.fg.inverse.active}" + }, + "today": { + "background": "transparent", + "color": "{color.fg.default}" + } + }, + "dark": { + "dropdown": { + "activeBackground": "{color.bg.surface.canvas.default}", + "activeColor": "{color.fg.on.fill.active}", + "background": "{color.bg.surface.default.default}", + "color": "{color.fg.inverse.default}", + "hoverBackground": "{color.bg.neutral.strong.selected}", + "hoverColor": "{color.fg.on.brand.hover}" + }, + "today": { + "background": "transparent", + "color": "{color.fg.inverse.default}" + } + } + }, + "panel": { + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "color": "{color.fg.default}", + "borderRadius": "{dimension.borderRadius.400}", + "shadow": "{effects.elevation.400}", + "padding": "{dimension.space.none}" + }, + "header": { + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "color": "{color.fg.default}", + "padding": "{dimension.space.400}" + }, + "title": { + "gap": "{dimension.space.200}", + "fontWeight": "{fonts.fontWeight.bold}" + }, + "selectMonth": { + "hoverBackground": "{color.bg.neutral.weak.default}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "borderRadius": "{dimension.borderRadius.400}", + "padding": "{dimension.space.200}" + }, + "inputIcon": { "color": "{color.fg.muted}" }, + "dropdown": { + "width": "{dimension.size.1700}", + "borderColor": "{color.border.neutral.strong}", + "hoverBorderColor": "{color.border.neutral.strong}", + "activeBorderColor": "{color.border.neutral.strong}", + "borderRadius": "{dimension.borderRadius.400}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + }, + "sm": { "width": "{dimension.size.none}" }, + "lg": { "width": "{dimension.size.none}" } + }, + "group": { + "borderColor": "{color.border.neutral.default}", + "gap": "{dimension.space.400}" + }, + "selectYear": { + "hoverBackground": "{color.bg.neutral.weak.default}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "borderRadius": "{dimension.borderRadius.400}", + "padding": "{dimension.space.100}" + }, + "dayView": { "margin": "{dimension.space.400}" }, + "weekDay": { + "padding": "{dimension.space.100}", + "fontWeight": "{fonts.fontWeight.bold}", + "color": "{color.fg.default}" + }, + "date": { + "hoverBackground": "{color.bg.neutral.weak.default}", + "selectedBackground": "{color.bg.neutral.strong.selected}", + "rangeSelectedBackground": "{color.bg.neutral.weak.default}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.default}", + "selectedColor": "{color.fg.on.fill.default}", + "rangeSelectedColor": "{color.fg.default}", + "width": "{dimension.size.900}", + "height": "{dimension.size.900}", + "borderRadius": "{dimension.borderRadius.200}", + "padding": "{dimension.space.100}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + }, + "monthView": { + "margin": "{dimension.space.none} {dimension.space.none} {dimension.space.none} {dimension.space.none}" + }, + "month": { + "padding": "{dimension.space.none}", + "borderRadius": "{dimension.borderRadius.none}" + }, + "yearView": { + "margin": "{dimension.space.none} {dimension.space.none} {dimension.space.none} {dimension.space.none}" + }, + "year": { + "padding": "{dimension.space.none}", + "borderRadius": "{dimension.borderRadius.none}" + }, + "buttonbar": { + "padding": "{dimension.space.400}", + "borderColor": "{color.border.neutral.default}" + }, + "timePicker": { + "padding": "{dimension.space.400}", + "borderColor": "{color.border.neutral.default}", + "gap": "{dimension.space.200}", + "buttonGap": "{dimension.space.100}" + }, + "root": { "transitionDuration": "{effects.transition.duration.200}" } + }, + "dialog": { + "extend": { + "borderWidth": "{dimension.borderWidth.100}", + "backdrop": "{color.bg.surface.backdrop}" + }, + "root": { + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "color": "{color.fg.default}", + "borderRadius": "{dimension.borderRadius.max}", + "shadow": "{effects.elevation.400}" + }, + "header": { + "padding": "{dimension.space.700} {dimension.space.700} {dimension.space.400} {dimension.space.700}", + "gap": "{dimension.space.200}" + }, + "title": { + "fontSize": "{fonts.fontSize.500}", + "fontWeight": "{fonts.fontWeight.demibold}" + }, + "content": { "padding": "{dimension.space.700}" }, + "footer": { + "padding": "{dimension.space.none} {dimension.space.700} {dimension.space.700} {dimension.space.700}", + "gap": "{dimension.space.200}" + } + }, + "divider": { + "extend": { + "content": { "gap": "{dimension.space.200}" }, + "iconSize": "{dimension.size.450}" + }, + "horizontal": { + "margin": "{dimension.space.400} {dimension.space.none}", + "padding": "{dimension.space.none} {dimension.space.400}", + "content": { "padding": "{dimension.space.none} {dimension.space.200}" } + }, + "vertical": { + "margin": "{dimension.space.none} {dimension.space.400}", + "padding": "{dimension.space.400} {dimension.space.none}", + "content": { "padding": "{dimension.space.200} {dimension.space.none}" } + }, + "content": { + "background": "{color.bg.surface.default.default}", + "color": "{color.fg.default}" + }, + "root": { "borderColor": "{color.border.neutral.default}" } + }, + "drawer": { + "extend": { + "borderRadius": "{dimension.borderRadius.200}", + "borderWidth": "{dimension.borderWidth.100}", + "width": "{dimension.size.2000}", + "extHeader": { + "gap": "{dimension.space.200}", + "borderColor": "{color.border.neutral.default}" + }, + "margin": "{dimension.space.200}", + "scale": "{dimension.size.50}", + "backdrop": "{color.bg.surface.backdrop}" + }, + "root": { + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "color": "{color.fg.default}", + "shadow": "{effects.elevation.200}" + }, + "header": { + "padding": "{dimension.space.700} {dimension.space.700} {dimension.space.400} {dimension.space.700}" + }, + "title": { + "fontSize": "{fonts.fontSize.500}", + "fontWeight": "{fonts.fontWeight.demibold}" + }, + "content": { "padding": "{dimension.space.700}" }, + "footer": { + "padding": "{dimension.space.none} {dimension.space.700} {dimension.space.700} {dimension.space.700}" + } + }, + "fileupload": { + "extend": { + "extDragNdrop": { + "background": "{color.bg.surface.raised.default}", + "borderRadius": "{dimension.borderRadius.400}", + "iconSize": "{dimension.size.900}", + "padding": "{dimension.space.400}", + "info": { "gap": "{dimension.space.100}" } + }, + "extFile": { "iconSize": "{dimension.size.600}" }, + "extContent": { + "borderRadius": "{dimension.borderRadius.400}", + "highlightBorderDefault": "{color.border.neutral.strong}" + } + }, + "colorScheme": { + "light": { + "header": { + "background": "{color.bg.surface.default.default}", + "color": "{color.fg.default}" + } + }, + "dark": { + "header": { + "background": "{color.bg.surface.default.default}", + "color": "{color.fg.inverse.default}" + } + } + }, + "root": { + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "color": "{color.fg.default}", + "borderRadius": "{dimension.borderRadius.400}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "header": { + "borderColor": "{color.border.neutral.default}", + "borderWidth": "{dimension.borderWidth.none}", + "padding": "{dimension.space.none}", + "borderRadius": "{dimension.borderRadius.none}", + "gap": "{dimension.space.200}" + }, + "content": { + "highlightBorderColor": "{color.border.neutral.bold.default}", + "padding": "{dimension.space.none}", + "gap": "{dimension.space.200}" + }, + "file": { + "padding": "{dimension.space.200}", + "gap": "{dimension.space.200}", + "borderColor": "{color.border.neutral.strong}", + "info": { "gap": "{dimension.space.100}" } + }, + "fileList": { "gap": "{dimension.space.200}" }, + "progressbar": { "height": "{dimension.size.200}" }, + "basic": { "gap": "{dimension.space.200}" } + }, + "floatlabel": { + "extend": { + "height": "{dimension.size.1400}", + "iconSize": "{dimension.size.600}" + }, + "root": { + "color": "{color.fg.muted}", + "focusColor": "{color.fg.muted}", + "activeColor": "{color.fg.muted}", + "invalidColor": "{color.fg.status.danger.hover}", + "transitionDuration": "{effects.transition.duration.200}", + "positionX": "{dimension.space.400}", + "positionY": "{dimension.space.400}", + "fontWeight": "{fonts.fontWeight.regular}", + "active": { + "fontSize": "{fonts.fontSize.100}", + "fontWeight": "{fonts.fontWeight.regular}" + } + }, + "over": { "active": { "top": "{dimension.space.400}" } }, + "inside": { + "input": { + "paddingTop": "{dimension.space.800}", + "paddingBottom": "{dimension.space.400}" + }, + "active": { "top": "{dimension.space.400}" } + }, + "on": { + "borderRadius": "{dimension.borderRadius.none}", + "active": { + "padding": "{dimension.space.none} {dimension.space.100}", + "background": "{color.bg.surface.raised.default}" + } + } + }, + "galleria": { + "extend": { "backdrop": "{color.bg.surface.backdrop}" }, + "colorScheme": { + "light": { + "thumbnailContent": { + "background": "{color.bg.neutral.weak.default}" + }, + "thumbnailNavButton": { + "hoverBackground": "{color.bg.neutral.medium.default}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}" + }, + "indicatorButton": { + "background": "{color.bg.neutral.weak.active}", + "hoverBackground": "{color.bg.neutral.medium.active}" + }, + "thumbnailsContent": { + "background": "{color.bg.neutral.medium.default}" + } + }, + "dark": { + "indicatorButton": { + "background": "{color.bg.neutral.strong.active}", + "hoverBackground": "{color.bg.neutral.medium.active}" + }, + "thumbnailNavButton": { + "color": "{color.fg.inverse.default}", + "hoverBackground": "{color.bg.neutral.medium.default}", + "hoverColor": "{color.fg.inverse.hover}" + }, + "thumbnailsContent": { + "background": "{color.bg.neutral.medium.default}" + }, + "thumbnailContent": { + "background": "{color.bg.neutral.strong.default}" + } + } + }, + "root": { + "borderWidth": "{dimension.borderWidth.100}", + "borderColor": "{color.border.neutral.default}", + "borderRadius": "{dimension.borderRadius.400}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "navButton": { + "background": "transparent", + "hoverBackground": "{color.bg.neutral.medium.default}", + "color": "{color.fg.inverse.default}", + "hoverColor": "{color.fg.inverse.hover}", + "size": "{dimension.size.1400}", + "gutter": "{dimension.space.200}", + "prev": { "borderRadius": "{dimension.borderRadius.200}" }, + "next": { "borderRadius": "{dimension.borderRadius.200}" }, + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + }, + "navIcon": { "size": "{dimension.size.900}" }, + "thumbnailsContent": { "padding": "{dimension.space.100}" }, + "thumbnailNavButton": { + "size": "{dimension.size.900}", + "borderRadius": "{dimension.borderRadius.400}", + "gutter": "{dimension.space.200}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + }, + "thumbnailNavButtonIcon": { "size": "{dimension.size.450}" }, + "caption": { + "background": "{color.bg.neutral.medium.default}", + "color": "{color.fg.default}", + "padding": "{dimension.space.200}" + }, + "indicatorList": { + "gap": "{dimension.space.200}", + "padding": "{dimension.space.400}" + }, + "indicatorButton": { + "width": "{dimension.size.200}", + "height": "{dimension.size.200}", + "activeBackground": "{color.bg.neutral.strong.default}", + "borderRadius": "{dimension.borderRadius.400}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + }, + "insetIndicatorList": { "background": "{color.bg.surface.backdrop}" }, + "insetIndicatorButton": { + "background": "{color.bg.neutral.medium.default}", + "hoverBackground": "{color.bg.neutral.medium.default}", + "activeBackground": "{color.bg.neutral.medium.default}" + }, + "closeButton": { + "size": "{dimension.size.1400}", + "gutter": "{dimension.space.200}", + "background": "{color.bg.neutral.medium.default}", + "hoverBackground": "{color.bg.neutral.medium.default}", + "color": "{color.fg.inverse.default}", + "hoverColor": "{color.fg.inverse.hover}", + "borderRadius": "{dimension.borderRadius.400}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + }, + "closeButtonIcon": { "size": "{dimension.size.900}" } + }, + "inputgroup": { + "extend": { + "borderWidth": "{dimension.borderWidth.100}", + "iconSize": "{dimension.size.450}" + }, + "colorScheme": { + "light": { + "addon": { + "background": "{color.bg.surface.raised.default}", + "borderColor": "{color.border.neutral.strong}", + "color": "{color.fg.muted}" + } + }, + "dark": { + "addon": { + "background": "{color.bg.surface.raised.default}", + "borderColor": "{color.border.neutral.strong}", + "color": "{color.fg.inverse.muted}" + } + } + }, + "addon": { + "borderRadius": "{dimension.borderRadius.400}", + "padding": "{dimension.space.400}", + "minWidth": "{dimension.size.1700}" + } + }, + "inputnumber": { + "extend": { + "borderWidth": "{dimension.borderWidth.100}", + "extButton": { + "height": "{dimension.size.1100}", + "iconSize": "{dimension.size.450}" + } + }, + "colorScheme": { + "light": { + "button": { + "background": "{color.bg.surface.raised.default}", + "hoverBackground": "{color.bg.neutral.weak.default}", + "activeBackground": "transparent", + "borderColor": "{color.border.neutral.strong}", + "hoverBorderColor": "{color.border.neutral.strong}", + "activeBorderColor": "{color.border.neutral.strong}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "activeColor": "{color.fg.default}" + } + }, + "dark": { + "button": { + "activeBackground": "transparent", + "activeBorderColor": "{color.border.neutral.strong}", + "activeColor": "{color.fg.on.brand.active}", + "background": "{color.bg.surface.raised.default}", + "borderColor": "{color.border.neutral.strong}", + "color": "{color.fg.inverse.default}", + "hoverBackground": "{color.bg.neutral.strong.selected}", + "hoverBorderColor": "{color.border.neutral.strong}", + "hoverColor": "{color.fg.inverse.hover}" + } + } + }, + "transitionDuration": { + "transitionDuration": "{effects.transition.duration.200}" + }, + "button": { + "width": "{dimension.size.1700}", + "borderRadius": "{dimension.borderRadius.400}", + "verticalPadding": "{dimension.space.400}" + }, + "root": { "transitionDuration": "{effects.transition.duration.200}" } + }, + "inputotp": { + "extend": { + "height": "{dimension.size.1100}", + "borderWidth": "{dimension.borderWidth.100}" + }, + "root": { "gap": "{dimension.space.200}" }, + "input": { + "width": "{dimension.size.1800}", + "lg": { "width": "{dimension.size.1900}" }, + "sm": { "width": "{dimension.size.1700}" } + }, + "sm": { "width": "{dimension.size.none}" }, + "lg": { "width": "{dimension.size.none}" } + }, + "inputtext": { + "extend": { + "readonlyBackground": "{color.bg.neutral.weak.default}", + "iconSize": "{dimension.size.450}", + "borderWidth": "{dimension.borderWidth.100}", + "extXlg": { + "fontSize": "{fonts.fontSize.300}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}" + } + }, + "root": { + "background": "{color.bg.surface.default.default}", + "disabledBackground": "{color.bg.surface.canvas.hover}", + "filledBackground": "{color.bg.surface.default.default}", + "filledHoverBackground": "{color.bg.surface.default.default}", + "filledFocusBackground": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.strong}", + "hoverBorderColor": "{color.border.brand.strong}", + "focusBorderColor": "{color.border.brand.strong}", + "invalidBorderColor": "{color.border.status.danger.subtle}", + "color": "{color.fg.default}", + "disabledColor": "{color.fg.muted}", + "placeholderColor": "{color.fg.muted}", + "invalidPlaceholderColor": "{color.fg.status.danger.hover}", + "shadow": "{effects.elevation.none}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}", + "borderRadius": "{dimension.borderRadius.400}", + "transitionDuration": "{effects.transition.duration.200}", + "sm": { + "fontSize": "{fonts.fontSize.300}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}" + }, + "lg": { + "fontSize": "{fonts.fontSize.300}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}" + }, + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}" + } + } + }, + "listbox": { + "extend": { + "extOption": { + "label": { "gap": "{dimension.space.100}" }, + "caption": { + "color": "{color.fg.muted}", + "stripedColor": "{color.fg.muted}" + }, + "gap": "{dimension.space.200}" + } + }, + "colorScheme": { + "light": { + "option": { + "stripedBackground": "{color.bg.surface.raised.selected}" + } + }, + "dark": { + "option": { + "stripedBackground": "{color.bg.surface.raised.selected}" + } + } + }, + "root": { + "background": "{color.bg.surface.default.default}", + "disabledBackground": "{color.bg.surface.canvas.hover}", + "borderColor": "{color.border.neutral.strong}", + "invalidBorderColor": "{color.border.status.danger.subtle}", + "color": "{color.fg.active}", + "disabledColor": "{color.fg.muted}", + "shadow": "{effects.elevation.none}", + "borderRadius": "{dimension.borderRadius.400}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "list": { + "padding": "{dimension.space.100}", + "gap": "{dimension.space.100}", + "header": { + "padding": "{dimension.space.400} {dimension.space.400} {dimension.space.none} {dimension.space.400}" + } + }, + "option": { + "focusBackground": "{color.bg.neutral.weak.default}", + "selectedBackground": "{color.bg.neutral.strong.selected}", + "selectedFocusBackground": "{color.bg.neutral.strong.active}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "selectedColor": "{color.fg.on.fill.default}", + "selectedFocusColor": "{color.fg.on.fill.active}", + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.200}" + }, + "optionGroup": { + "background": "{color.bg.surface.raised.default}", + "color": "{color.fg.muted}", + "fontWeight": "{fonts.fontWeight.demibold}", + "padding": "{dimension.space.200} {dimension.space.400}" + }, + "checkmark": { + "color": "{color.fg.default}", + "gutterStart": "{dimension.space.negative.200}", + "gutterEnd": "{dimension.space.200}" + }, + "emptyMessage": { + "padding": "{dimension.space.200} {dimension.space.400}" + } + }, + "megamenu": { + "extend": { + "extItem": { + "caption": { + "color": "{color.fg.muted}", + "gap": "{dimension.space.100}" + } + }, + "iconSize": "{dimension.size.600}" + }, + "colorScheme": { + "light": { "root": { "background": "transparent" } }, + "dark": { "root": { "background": "transparent" } } + }, + "root": { + "borderColor": "transparent", + "borderRadius": "{dimension.borderRadius.400}", + "color": "{color.fg.default}", + "gap": "{dimension.space.100}", + "transitionDuration": "{effects.transition.duration.200}", + "verticalOrientation": { + "padding": "{dimension.space.100}", + "gap": "{dimension.space.100}" + }, + "horizontalOrientation": { + "padding": "{dimension.space.100}", + "gap": "{dimension.space.100}" + } + }, + "baseItem": { + "borderRadius": "{dimension.borderRadius.400}", + "padding": "{dimension.space.200} {dimension.space.400}" + }, + "item": { + "focusBackground": "{color.bg.neutral.weak.default}", + "activeBackground": "{color.bg.neutral.strong.default}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "activeColor": "{color.fg.inverse.active}", + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.200}", + "gap": "{dimension.space.200}", + "icon": { + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "activeColor": "{color.fg.inverse.active}" + } + }, + "overlay": { + "padding": "{dimension.space.100}", + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "borderRadius": "{dimension.borderRadius.400}", + "color": "{color.fg.default}", + "shadow": "{effects.elevation.400}", + "gap": "{dimension.space.none}" + }, + "submenu": { + "padding": "{dimension.space.100}", + "gap": "{dimension.space.100}" + }, + "submenuLabel": { + "padding": "{dimension.space.200} {dimension.space.400}", + "background": "transparent", + "color": "{color.fg.muted}", + "fontWeight": "{fonts.fontWeight.demibold}" + }, + "submenuIcon": { + "size": "{dimension.size.600}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "activeColor": "{color.fg.inverse.active}" + }, + "separator": { "borderColor": "{color.border.neutral.default}" }, + "mobileButton": { + "borderRadius": "{dimension.borderRadius.200}", + "size": "{dimension.size.900}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "hoverBackground": "{color.bg.neutral.weak.default}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + } + }, + "menu": { + "extend": { + "paddingX": "{dimension.space.100}", + "iconSize": "{dimension.size.600}", + "paddingY": "{dimension.space.100}", + "extItem": { + "caption": { + "gap": "{dimension.space.100}", + "color": "{color.fg.muted}" + }, + "activeBackground": "{color.bg.neutral.strong.default}", + "activeColor": "{color.fg.inverse.active}", + "icon": { "activeColor": "{color.fg.inverse.active}" } + } + }, + "root": { + "borderRadius": "{dimension.borderRadius.400}", + "shadow": "{effects.elevation.400}", + "transitionDuration": "{effects.transition.duration.200}", + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "color": "{color.fg.default}" + }, + "list": { + "padding": "{dimension.space.100}", + "gap": "{dimension.space.100}" + }, + "submenuLabel": { + "padding": "{dimension.space.200} {dimension.space.400}", + "fontWeight": "{fonts.fontWeight.demibold}", + "background": "transparent", + "color": "{color.fg.muted}" + }, + "separator": { "borderColor": "{color.border.neutral.default}" }, + "item": { + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.200}", + "gap": "{dimension.space.200}", + "color": "{color.fg.default}", + "focusBackground": "{color.bg.surface.canvas.default}", + "focusColor": "{color.fg.hover}", + "icon": { + "color": "{color.fg.default}", + "focusColor": "{color.fg.hover}" + } + } + }, + "menubar": { + "extend": { + "iconSize": "{dimension.size.600}", + "extItem": { + "caption": { + "color": "{color.fg.muted}", + "gap": "{dimension.space.100}" + } + }, + "extSubmenuLabel": { + "padding": "{dimension.space.200} {dimension.space.400}", + "fontWeight": "{fonts.fontWeight.demibold}", + "background": "transparent", + "color": "{color.fg.muted}" + } + }, + "colorScheme": { + "light": { "root": { "background": "transparent" } }, + "dark": { "root": { "background": "transparent" } } + }, + "root": { + "borderColor": "transparent", + "borderRadius": "{dimension.borderRadius.200}", + "color": "{color.fg.default}", + "gap": "{dimension.space.100}", + "padding": "{dimension.space.100}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "baseItem": { + "borderRadius": "{dimension.borderRadius.200}", + "padding": "{dimension.space.200} {dimension.space.400}" + }, + "item": { + "focusBackground": "{color.bg.neutral.weak.default}", + "activeBackground": "{color.bg.neutral.strong.default}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "activeColor": "{color.fg.inverse.active}", + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.200}", + "gap": "{dimension.space.200}", + "icon": { + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "activeColor": "{color.fg.inverse.active}" + } + }, + "submenu": { + "padding": "{dimension.space.100}", + "gap": "{dimension.space.100}", + "background": "{color.bg.surface.raised.default}", + "borderColor": "{color.border.neutral.default}", + "borderRadius": "{dimension.borderRadius.400}", + "shadow": "{effects.elevation.400}", + "mobileIndent": "{dimension.space.400}", + "icon": { + "size": "{dimension.size.600}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "activeColor": "{color.fg.inverse.active}" + } + }, + "separator": { "borderColor": "{color.border.neutral.default}" }, + "mobileButton": { + "borderRadius": "{dimension.borderRadius.200}", + "size": "{dimension.size.900}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "hoverBackground": "{color.bg.neutral.weak.default}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + } + }, + "message": { + "extend": { + "width": "{dimension.size.2000}", + "extText": { "gap": "{dimension.space.100}" }, + "extInfo": { + "color": "{color.fg.status.info.default}", + "closeButton": { + "color": "{color.fg.status.info.default}", + "borderColor": "{color.border.status.info.default}" + }, + "caption": { "color": "{color.fg.default}" } + }, + "extAccentLine": { "width": "{dimension.size.100}" }, + "extCloseButton": { "width": "{dimension.borderWidth.100}" }, + "extSuccess": { + "color": "{color.fg.status.success.default}", + "closeButton": { + "color": "{color.fg.status.success.default}", + "borderColor": "{color.border.brand.default}" + }, + "caption": { "color": "{color.fg.default}" } + }, + "extWarn": { + "color": "{color.fg.status.warning.default}", + "closeButton": { + "color": "{color.fg.status.warning.default}", + "borderColor": "{color.border.status.warning.default}" + }, + "caption": { "color": "{color.fg.default}" } + }, + "extError": { + "color": "{color.fg.status.danger.default}", + "closeButton": { + "color": "{color.fg.status.danger.default}", + "borderColor": "{color.border.status.danger.default}" + }, + "caption": { "color": "{color.fg.default}" } + } + }, + "colorScheme": { + "light": { + "success": { + "background": "{color.bg.status.success.weak.default}", + "borderColor": "{color.border.brand.default}", + "color": "{color.fg.default}", + "shadow": "none", + "outlined": { + "color": "{color.fg.default}", + "borderColor": "{color.border.brand.default}" + }, + "closeButton": { + "hoverBackground": "{color.bg.status.success.weak.active}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + }, + "simple": { "color": "{color.fg.default}" } + }, + "outlined": { + "root": { "borderWidth": "{dimension.borderWidth.none}" }, + "closeButton": { + "hoverBackground": "transparent", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + }, + "outlined": { + "color": "transparent", + "borderColor": "transparent" + }, + "simple": { "color": "transparent" } + }, + "simple": { "content": { "padding": "{dimension.space.none}" } }, + "warn": { + "background": "{color.bg.status.warning.weak.default}", + "borderColor": "{color.border.status.warning.default}", + "color": "{color.fg.default}", + "shadow": "none", + "outlined": { + "color": "{color.fg.default}", + "borderColor": "{color.border.status.warning.default}" + }, + "closeButton": { + "hoverBackground": "{color.bg.status.warning.weak.active}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + }, + "simple": { "color": "{color.fg.default}" } + }, + "error": { + "background": "{color.bg.status.danger.weak.default}", + "borderColor": "{color.border.status.danger.default}", + "color": "{color.fg.default}", + "shadow": "none", + "outlined": { + "color": "{color.fg.default}", + "borderColor": "{color.border.status.danger.default}" + }, + "closeButton": { + "hoverBackground": "{color.bg.status.danger.weak.active}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + }, + "simple": { "color": "{color.fg.default}" } + }, + "secondary": { + "borderColor": "transparent", + "shadow": "none", + "closeButton": { + "hoverBackground": "transparent", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + }, + "simple": { "color": "transparent" }, + "outlined": { + "color": "transparent", + "borderColor": "transparent" + }, + "background": "{color.bg.neutral.weak.default}", + "color": "{color.fg.default}" + }, + "contrast": { + "borderColor": "transparent", + "shadow": "none", + "closeButton": { + "hoverBackground": "transparent", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + }, + "simple": { "color": "transparent" }, + "outlined": { + "color": "transparent", + "borderColor": "transparent" + }, + "background": "{color.bg.neutral.strong.default}", + "color": "{color.fg.on.fill.default}" + }, + "info": { + "background": "{color.bg.status.info.weak.default}", + "borderColor": "{color.border.status.info.default}", + "color": "{color.fg.default}", + "shadow": "none", + "closeButton": { + "hoverBackground": "{color.bg.status.info.weak.active}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + }, + "outlined": { + "color": "{color.fg.default}", + "borderColor": "{color.border.status.info.default}" + }, + "simple": { "color": "{color.fg.default}" } + } + }, + "dark": { + "contrast": { + "background": "{color.bg.surface.canvas.default}", + "borderColor": "transparent", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "transparent" + }, + "color": "{color.fg.default}", + "outlined": { + "borderColor": "transparent", + "color": "transparent" + }, + "shadow": "none", + "simple": { "color": "transparent" } + }, + "error": { + "background": "{color.bg.status.danger.weak.default}", + "borderColor": "{color.border.status.danger.default}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "{color.bg.status.danger.weak.active}" + }, + "color": "{color.fg.inverse.default}", + "outlined": { + "borderColor": "{color.border.status.danger.default}", + "color": "{color.fg.inverse.default}" + }, + "shadow": "none", + "simple": { "color": "{color.fg.inverse.default}" } + }, + "info": { + "background": "{color.bg.status.info.weak.default}", + "borderColor": "{color.border.status.info.default}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "{color.bg.status.info.weak.active}" + }, + "color": "{color.fg.inverse.default}", + "outlined": { + "borderColor": "{color.border.status.info.default}", + "color": "{color.fg.inverse.default}" + }, + "shadow": "none", + "simple": { "color": "{color.fg.inverse.default}" } + }, + "secondary": { + "background": "{color.bg.neutral.strong.default}", + "borderColor": "transparent", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "transparent" + }, + "color": "{color.fg.inverse.default}", + "outlined": { + "borderColor": "transparent", + "color": "transparent" + }, + "shadow": "none", + "simple": { "color": "transparent" } + }, + "success": { + "background": "{color.bg.status.success.weak.default}", + "borderColor": "{color.border.brand.default}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "{color.bg.status.success.weak.active}" + }, + "color": "{color.fg.inverse.default}", + "outlined": { + "borderColor": "{color.border.brand.default}", + "color": "{color.fg.inverse.default}" + }, + "shadow": "none", + "simple": { "color": "{color.fg.inverse.default}" } + }, + "warn": { + "background": "{color.bg.status.warning.weak.default}", + "borderColor": "{color.border.status.warning.default}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "{color.bg.status.warning.weak.active}" + }, + "color": "{color.fg.inverse.default}", + "outlined": { + "borderColor": "{color.border.status.warning.default}", + "color": "{color.fg.inverse.default}" + }, + "shadow": "none", + "simple": { "color": "{color.fg.inverse.default}" } + }, + "outlined": { + "root": { "borderWidth": "{dimension.borderWidth.none}" }, + "closeButton": { + "hoverBackground": "transparent", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + }, + "outlined": { + "color": "transparent", + "borderColor": "transparent" + }, + "simple": { "color": "transparent" } + }, + "simple": { "content": { "padding": "{dimension.space.none}" } } + } + }, + "root": { + "borderRadius": "{dimension.borderRadius.400}", + "borderWidth": "{dimension.borderWidth.100}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "content": { + "padding": "{dimension.space.400}", + "gap": "{dimension.space.400}", + "sm": { "padding": "{dimension.space.400}" }, + "lg": { "padding": "{dimension.space.400}" } + }, + "text": { + "fontSize": "{fonts.fontSize.300}", + "fontWeight": "{fonts.fontWeight.bold}", + "sm": { "fontSize": "{fonts.fontSize.300}" }, + "lg": { "fontSize": "{fonts.fontSize.300}" } + }, + "icon": { + "size": "{dimension.size.1000}", + "sm": { "size": "{dimension.size.1000}" }, + "lg": { "size": "{dimension.size.1000}" } + }, + "closeButton": { + "width": "{dimension.size.900}", + "height": "{dimension.size.900}", + "borderRadius": "{dimension.borderRadius.400}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "offset": "{dimension.focusRing.offset}" + } + }, + "closeIcon": { + "size": "{dimension.size.450}", + "sm": { "size": "{dimension.size.450}" }, + "lg": { "size": "{dimension.size.450}" } + }, + "outlined": { "root": { "borderWidth": "{dimension.borderWidth.100}" } }, + "simple": { "content": { "padding": "{dimension.space.none}" } } + }, + "metergroup": { + "extend": { "extLabel": { "color": "{color.fg.muted}" } }, + "root": { + "borderRadius": "{dimension.borderRadius.400}", + "gap": "{dimension.space.400}" + }, + "meters": { + "size": "{dimension.size.200}", + "background": "{color.bg.neutral.medium.default}" + }, + "label": { "gap": "{dimension.space.100}" }, + "labelMarker": { "size": "{dimension.size.200}" }, + "labelIcon": { "size": "{dimension.size.450}" }, + "labelList": { + "verticalGap": "{dimension.space.200}", + "horizontalGap": "{dimension.space.400}" + } + }, + "multiselect": { + "extend": { + "paddingX": "{dimension.space.150}", + "paddingY": "{dimension.space.150}", + "borderWidth": "{dimension.borderWidth.100}", + "iconSize": "{dimension.size.450}", + "width": "{dimension.size.1700}", + "readonlyBackground": "{color.bg.neutral.weak.default}" + }, + "root": { + "shadow": "{effects.elevation.none}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}", + "borderRadius": "{dimension.borderRadius.400}", + "transitionDuration": "{effects.transition.duration.200}", + "sm": { + "fontSize": "{fonts.fontSize.300}", + "paddingX": "{dimension.space.200}", + "paddingY": "{dimension.space.200}" + }, + "lg": { + "fontSize": "{fonts.fontSize.300}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}" + }, + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}", + "color": "{color.border.focus}" + }, + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.strong}", + "color": "{color.fg.default}", + "disabledBackground": "{color.bg.surface.canvas.hover}", + "disabledColor": "{color.fg.muted}", + "filledBackground": "{color.bg.surface.default.default}", + "filledFocusBackground": "{color.bg.surface.default.default}", + "filledHoverBackground": "{color.bg.surface.default.default}", + "focusBorderColor": "{color.border.brand.strong}", + "hoverBorderColor": "{color.border.brand.strong}", + "invalidBorderColor": "{color.border.status.danger.subtle}", + "invalidPlaceholderColor": "{color.fg.status.danger.hover}", + "placeholderColor": "{color.fg.muted}" + }, + "dropdown": { + "width": "{dimension.size.1700}", + "color": "{color.fg.active}" + }, + "overlay": { + "borderRadius": "{dimension.borderRadius.400}", + "shadow": "{effects.elevation.400}", + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "color": "{color.fg.default}" + }, + "list": { + "padding": "{dimension.space.100}", + "header": { + "padding": "{dimension.space.400} {dimension.space.400} {dimension.space.none} {dimension.space.400}" + }, + "gap": "{dimension.space.100}" + }, + "chip": { "borderRadius": "{dimension.borderRadius.200}" }, + "option": { + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.200}", + "gap": "{dimension.space.200}", + "color": "{color.fg.default}", + "focusBackground": "{color.bg.neutral.weak.default}", + "focusColor": "{color.fg.default}", + "selectedBackground": "{color.bg.neutral.strong.selected}", + "selectedColor": "{color.fg.on.fill.default}", + "selectedFocusBackground": "{color.bg.neutral.strong.active}", + "selectedFocusColor": "{color.fg.on.fill.active}" + }, + "optionGroup": { + "fontWeight": "{fonts.fontWeight.demibold}", + "padding": "{dimension.space.200} {dimension.space.400}", + "background": "{color.bg.surface.raised.default}", + "color": "{color.fg.muted}" + }, + "emptyMessage": { + "padding": "{dimension.space.200} {dimension.space.400}" + }, + "clearIcon": { "color": "{color.fg.active}" } + }, + "paginator": { + "root": { + "padding": "{dimension.space.none} {dimension.space.200}", + "gap": "{dimension.space.200}", + "borderRadius": "{dimension.borderRadius.400}", + "background": "transparent", + "color": "{color.fg.default}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "currentPageReport": { "color": "{color.fg.muted}" }, + "navButton": { + "background": "transparent", + "hoverBackground": "{color.bg.neutral.weak.default}", + "selectedBackground": "{color.bg.neutral.strong.selected}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "selectedColor": "{color.fg.on.fill.default}", + "width": "{dimension.size.1100}", + "height": "{dimension.size.1100}", + "borderRadius": "{dimension.borderRadius.400}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "focus": "{effects.elevation.200}", + "shadow": "{effects.elevation.none}" + } + }, + "jumpToPageInput": { "maxWidth": "{dimension.size.1500}" } + }, + "panelmenu": { + "extend": { + "iconSize": "{dimension.size.600}", + "extPanel": { "gap": "{dimension.space.100}" }, + "extItem": { + "activeBackground": "{color.bg.neutral.strong.default}", + "activeColor": "{color.fg.inverse.active}", + "caption": { + "color": "{color.fg.muted}", + "gap": "{dimension.space.100}" + } + } + }, + "root": { + "gap": "{dimension.space.100}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "panel": { + "background": "transparent", + "borderColor": "transparent", + "borderWidth": "{dimension.borderWidth.100}", + "color": "{color.fg.default}", + "padding": "{dimension.space.100}", + "borderRadius": "{dimension.borderRadius.400}", + "first": { + "borderWidth": "{dimension.borderWidth.100} {dimension.borderWidth.100} {dimension.borderWidth.none} {dimension.borderWidth.100}", + "topBorderRadius": "{dimension.borderRadius.400}" + }, + "last": { + "borderWidth": "{dimension.borderWidth.none} {dimension.borderWidth.100} {dimension.borderWidth.100} {dimension.borderWidth.100}", + "topBorderRadius": "{dimension.borderRadius.400}", + "bottomBorderRadius": "{dimension.borderRadius.400}" + } + }, + "item": { + "focusBackground": "{color.bg.neutral.weak.default}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "gap": "{dimension.space.200}", + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.200}", + "icon": { + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}" + } + }, + "submenu": { "indent": "{dimension.space.700}" }, + "separator": { "borderColor": "{color.border.neutral.default}" }, + "submenuIcon": { + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}" + } + }, + "password": { + "extend": { "borderWidth": "{dimension.borderWidth.100}" }, + "colorScheme": { + "light": { + "strength": { + "weakBackground": "{color.bg.status.danger.strong.active}", + "mediumBackground": "{color.bg.status.warning.strong.active}", + "strongBackground": "{color.bg.brand.strong.hover}" + }, + "icon": { "color": "{color.fg.muted}" } + }, + "dark": { + "strength": { + "mediumBackground": "{color.bg.status.warning.strong.active}", + "strongBackground": "{color.bg.status.success.strong.hover}", + "weakBackground": "{color.bg.status.danger.strong.active}" + }, + "icon": { "color": "{color.fg.inverse.muted}" } + } + }, + "meter": { + "background": "{color.bg.neutral.medium.default}", + "borderRadius": "{dimension.borderRadius.400}", + "height": "{dimension.size.200}" + }, + "overlay": { + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.strong}", + "borderRadius": "{dimension.borderRadius.200}", + "color": "{color.fg.default}", + "padding": "{dimension.space.400}", + "shadow": "{effects.elevation.400}" + }, + "content": { "gap": "{dimension.space.200}" }, + "icon": { "color": "{color.fg.default}" } + }, + "popover": { + "extend": { + "borderWidth": "{dimension.borderWidth.100}", + "arrow": { + "width": "{dimension.size.350}", + "height": "{dimension.size.200}" + } + }, + "root": { + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.strong}", + "color": "{color.fg.default}", + "borderRadius": "{dimension.borderRadius.200}", + "shadow": "{effects.elevation.400}", + "gutter": "{dimension.space.100}", + "arrowOffset": "{dimension.space.600}" + }, + "content": { "padding": "{dimension.space.400}" } + }, + "progressbar": { + "label": { + "color": "{color.fg.default}", + "fontSize": "{fonts.fontSize.100}", + "fontWeight": "{fonts.fontWeight.regular}" + }, + "root": { + "background": "{color.bg.surface.canvas.hover}", + "borderRadius": "{dimension.borderRadius.400}", + "height": "{dimension.size.450}" + }, + "value": { "background": "{color.bg.brand.strong.default}" } + }, + "progressspinner": { + "extend": { + "small": "{dimension.size.450}", + "medium": "{dimension.size.900}", + "large": "{dimension.size.1200}", + "xlarge": "{dimension.size.1300}" + }, + "colorScheme": { + "light": { + "root": { + "colorOne": "{color.fg.brand.default}", + "colorTwo": "{color.fg.status.info.default}", + "colorThree": "{color.fg.status.danger.default}", + "colorFour": "{color.fg.status.warning.default}" + } + }, + "dark": { + "root": { + "colorFour": "{color.fg.status.warning.muted}", + "colorOne": "{color.fg.brand.muted}", + "colorThree": "{color.fg.status.danger.muted}", + "colorTwo": "{color.fg.status.info.muted}" + } + } + }, + "root": { "borderWidth": "{dimension.borderWidth.300}" } + }, + "radiobutton": { + "root": { + "width": "{dimension.size.700}", + "height": "{dimension.size.700}", + "background": "{color.bg.surface.default.default}", + "checkedBackground": "{color.bg.neutral.strong.default}", + "checkedHoverBackground": "{color.bg.neutral.strong.hover}", + "disabledBackground": "{color.bg.surface.canvas.hover}", + "filledBackground": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.strong}", + "hoverBorderColor": "{color.border.neutral.bold.default}", + "focusBorderColor": "{color.border.neutral.strong}", + "checkedBorderColor": "{color.border.neutral.bold.default}", + "checkedHoverBorderColor": "{color.border.neutral.bold.default}", + "checkedFocusBorderColor": "{color.border.neutral.bold.default}", + "checkedDisabledBorderColor": "{color.border.neutral.strong}", + "invalidBorderColor": "{color.border.status.danger.subtle}", + "shadow": "{effects.elevation.none}", + "transitionDuration": "{effects.transition.duration.200}", + "focusRing": { + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}", + "style": "none", + "width": "{dimension.focusRing.width}" + }, + "lg": { + "height": "{dimension.size.600}", + "width": "{dimension.size.600}" + }, + "sm": { + "height": "{dimension.size.200}", + "width": "{dimension.size.200}" + } + }, + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + }, + "sm": { + "width": "{dimension.size.450}", + "height": "{dimension.size.450}" + }, + "lg": { + "width": "{dimension.size.600}", + "height": "{dimension.size.600}" + }, + "icon": { + "size": "{dimension.size.350}", + "checkedColor": "{color.fg.on.fill.default}", + "checkedHoverColor": "{color.fg.on.fill.hover}", + "disabledColor": "{color.fg.muted}", + "sm": { "size": "{dimension.size.200}" }, + "lg": { "size": "{dimension.size.450}" } + } + }, + "rating": { + "root": { + "gap": "{dimension.space.200}", + "transitionDuration": "{effects.transition.duration.200}", + "focusRing": { + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}", + "style": "none", + "width": "{dimension.focusRing.width}" + } + }, + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + }, + "icon": { + "size": "{dimension.size.700}", + "color": "{color.fg.muted}", + "hoverColor": "{color.fg.status.warning.default}", + "activeColor": "{color.fg.status.warning.default}" + } + }, + "ripple": { + "colorScheme": { + "light": { + "root": { "background": "{color.bg.neutral.medium.default}" } + }, + "dark": { + "root": { "background": "{color.bg.neutral.medium.default}" } + } + } + }, + "scrollpanel": { + "colorScheme": { + "light": { "bar": { "background": "{color.bg.neutral.weak.active}" } }, + "dark": { "bar": { "background": "{color.bg.neutral.strong.active}" } } + }, + "root": { "transitionDuration": "{effects.transition.duration.200}" }, + "bar": { + "size": "{dimension.size.200}", + "borderRadius": "{dimension.borderRadius.200}", + "focusRing": { + "width": "{dimension.size.none}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + } + }, + "select": { + "extend": { + "extOption": { + "background": "{color.bg.surface.raised.default}", + "gap": "{dimension.space.200}" + }, + "extOptionGroup": { "gap": "{dimension.space.200}" }, + "readonlyBackground": "{color.bg.neutral.weak.default}", + "borderWidth": "{dimension.borderWidth.100}", + "iconSize": "{dimension.size.450}" + }, + "root": { + "background": "{color.bg.surface.default.default}", + "disabledBackground": "{color.bg.surface.canvas.hover}", + "filledBackground": "{color.bg.surface.default.default}", + "filledHoverBackground": "{color.bg.surface.default.default}", + "filledFocusBackground": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.strong}", + "hoverBorderColor": "{color.border.brand.strong}", + "focusBorderColor": "{color.border.brand.strong}", + "invalidBorderColor": "{color.border.status.danger.subtle}", + "color": "{color.fg.default}", + "disabledColor": "{color.fg.muted}", + "placeholderColor": "{color.fg.muted}", + "invalidPlaceholderColor": "{color.fg.status.danger.hover}", + "shadow": "{effects.elevation.none}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}", + "borderRadius": "{dimension.borderRadius.400}", + "transitionDuration": "{effects.transition.duration.200}", + "sm": { + "fontSize": "{fonts.fontSize.300}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}" + }, + "lg": { + "fontSize": "{fonts.fontSize.300}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}" + }, + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}" + } + }, + "dropdown": { + "width": "{dimension.size.1700}", + "color": "{color.fg.active}" + }, + "overlay": { + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "borderRadius": "{dimension.borderRadius.400}", + "color": "{color.fg.default}", + "shadow": "{effects.elevation.400}" + }, + "list": { + "padding": "{dimension.space.100}", + "gap": "{dimension.space.100}", + "header": { + "padding": "{dimension.space.400} {dimension.space.400} {dimension.space.none} {dimension.space.400}" + } + }, + "option": { + "focusBackground": "{color.bg.neutral.weak.default}", + "selectedBackground": "{color.bg.neutral.strong.selected}", + "selectedFocusBackground": "{color.bg.neutral.strong.active}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "selectedColor": "{color.fg.on.fill.default}", + "selectedFocusColor": "{color.fg.on.fill.active}", + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.200}" + }, + "optionGroup": { + "background": "{color.bg.surface.raised.default}", + "color": "{color.fg.muted}", + "fontWeight": "{fonts.fontWeight.demibold}", + "padding": "{dimension.space.200} {dimension.space.400}" + }, + "clearIcon": { "color": "{color.fg.active}" }, + "checkmark": { + "color": "{color.fg.default}", + "gutterStart": "{dimension.space.negative.200}", + "gutterEnd": "{dimension.space.200}" + }, + "emptyMessage": { + "padding": "{dimension.space.200} {dimension.space.400}" + } + }, + "selectbutton": { + "extend": { + "gap": "{dimension.space.100}", + "paddingX": "{dimension.space.100}", + "paddingY": "{dimension.space.100}", + "iconSize": { + "sm": "{dimension.size.450}", + "md": "{dimension.size.600}", + "lg": "{dimension.size.700}", + "xlg": "{dimension.size.800}" + }, + "checkedBackground": "{color.bg.surface.raised.default}", + "checkedBorderColor": "{color.border.neutral.inverse}", + "checkedColor": "{color.fg.active}", + "ext": { "borderRadius": "{dimension.borderRadius.200}" } + }, + "colorScheme": { + "light": { + "root": { + "invalidBorderColor": "{color.border.status.danger.subtle}" + }, + "extend": { "background": "{color.bg.neutral.medium.default}" } + }, + "dark": { + "root": { + "invalidBorderColor": "{color.border.status.danger.strong}" + }, + "extend": { "background": "{color.bg.neutral.strong.hover}" } + } + }, + "root": { "borderRadius": "{dimension.borderRadius.400}" } + }, + "skeleton": { + "extend": { + "minWidth": "{dimension.size.900}", + "height": "{dimension.size.900}" + }, + "colorScheme": { + "light": { + "root": { + "background": "{color.bg.surface.canvas.hover}", + "animationBackground": "{color.bg.surface.canvas.default}" + } + }, + "dark": { + "root": { + "background": "{color.bg.surface.raised.default}", + "animationBackground": "{color.bg.surface.raised.selected}" + } + } + }, + "root": { "borderRadius": "{dimension.borderRadius.400}" } + }, + "slider": { + "colorScheme": { + "light": { + "handle": { + "content": { "background": "{color.bg.surface.default.default}" } + } + }, + "dark": { + "handle": { + "content": { "background": "{color.bg.surface.canvas.default}" } + } + } + }, + "root": { "transitionDuration": "{effects.transition.duration.200}" }, + "track": { + "background": "{color.bg.neutral.medium.default}", + "borderRadius": "{dimension.borderRadius.400}", + "size": "{dimension.size.100}" + }, + "range": { "background": "{color.bg.neutral.strong.default}" }, + "handle": { + "width": "{dimension.size.600}", + "height": "{dimension.size.600}", + "borderRadius": "{dimension.borderRadius.max}", + "background": "{color.bg.neutral.strong.default}", + "hoverBackground": "{color.bg.neutral.strong.default}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + }, + "content": { + "borderRadius": "{dimension.borderRadius.max}", + "hoverBackground": "{color.bg.neutral.strong.default}", + "width": "{dimension.size.350}", + "height": "{dimension.size.350}", + "shadow": "none" + } + } + }, + "splitter": { + "colorScheme": { + "light": { + "handle": { "background": "{color.bg.neutral.strong.default}" } + }, + "dark": { + "handle": { "background": "{color.bg.surface.canvas.default}" } + } + }, + "gutter": { "background": "{color.bg.neutral.weak.default}" }, + "root": { + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "color": "{color.fg.default}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "handle": { + "size": "{dimension.size.100}", + "borderRadius": "{dimension.borderRadius.400}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + } + }, + "stepper": { + "extend": { + "extCaption": { "gap": "{dimension.space.100}" }, + "extStepNumber": { + "invalidBackground": "{color.bg.status.danger.strong.hover}", + "invalidColor": "{color.fg.on.status.danger.default}", + "invalidBorderColor": "{color.border.status.danger.subtle}", + "borderWidth": "{dimension.borderWidth.100}", + "iconSize": "{dimension.size.700}" + } + }, + "root": { "transitionDuration": "{effects.transition.duration.200}" }, + "separator": { + "background": "{color.bg.neutral.medium.default}", + "activeBackground": "{color.bg.neutral.strong.default}", + "margin": "{dimension.space.none} {dimension.space.none} {dimension.space.none} {dimension.space.700}", + "size": "{dimension.borderWidth.100}" + }, + "step": { + "padding": "{dimension.space.200}", + "gap": "{dimension.space.200}" + }, + "stepHeader": { + "padding": "{dimension.space.none}", + "borderRadius": "{dimension.borderRadius.none}", + "gap": "{dimension.space.200}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + }, + "stepTitle": { + "color": "{color.fg.default}", + "activeColor": "{color.fg.default}", + "fontWeight": "{fonts.fontWeight.regular}" + }, + "stepNumber": { + "background": "{color.bg.surface.raised.default}", + "activeBackground": "{color.bg.brand.strong.default}", + "borderColor": "{color.border.neutral.default}", + "activeBorderColor": "{color.border.brand.default}", + "color": "{color.fg.default}", + "activeColor": "{color.fg.default}", + "size": "{dimension.size.700}", + "fontSize": "{fonts.fontSize.300}", + "fontWeight": "{fonts.fontWeight.bold}", + "borderRadius": "{dimension.borderRadius.max}", + "shadow": "none" + }, + "steppanels": { "padding": "{dimension.space.400}" }, + "steppanel": { + "background": "{color.bg.surface.raised.default}", + "color": "{color.fg.default}", + "padding": "{dimension.space.none}", + "indent": "{dimension.space.none}" + } + }, + "steps": { + "itemLink": { + "gap": "{dimension.space.200}", + "borderRadius": "{dimension.borderRadius.400}", + "focusRing": { + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}", + "style": "none", + "width": "{dimension.focusRing.width}" + } + }, + "itemLabel": { + "fontWeight": "{fonts.fontWeight.regular}", + "activeColor": "{color.fg.hover}", + "color": "{color.fg.default}" + }, + "itemNumber": { + "background": "{color.bg.surface.raised.default}", + "size": "{dimension.size.900}", + "fontSize": "{fonts.fontSize.300}", + "fontWeight": "{fonts.fontWeight.bold}", + "borderRadius": "{dimension.borderRadius.max}", + "shadow": "none", + "activeBackground": "{color.bg.surface.raised.default}", + "activeBorderColor": "{color.border.neutral.default}", + "activeColor": "{color.fg.hover}", + "borderColor": "{color.border.neutral.default}", + "color": "{color.fg.default}" + }, + "root": { "transitionDuration": "{effects.transition.duration.200}" }, + "separator": { "background": "{color.bg.neutral.medium.default}" } + }, + "tabs": { + "colorScheme": { + "light": { + "navButton": { "shadow": "none" }, + "tab": { + "background": "transparent", + "hoverBackground": "transparent", + "activeBackground": "transparent" + } + }, + "dark": { + "navButton": { "shadow": "none" }, + "tab": { + "activeBackground": "transparent", + "background": "transparent", + "hoverBackground": "transparent" + } + } + }, + "root": { "transitionDuration": "{effects.transition.duration.200}" }, + "tablist": { + "borderWidth": "{dimension.borderWidth.none} {dimension.borderWidth.none} {dimension.borderWidth.100} {dimension.borderWidth.none}", + "background": "transparent", + "borderColor": "{color.border.neutral.default}" + }, + "tab": { + "borderWidth": "{dimension.borderWidth.none}", + "borderColor": "{color.border.neutral.default}", + "hoverBorderColor": "{color.border.neutral.default}", + "activeBorderColor": "{color.border.neutral.bold.hover}", + "color": "{color.fg.muted}", + "hoverColor": "{color.fg.default}", + "activeColor": "{color.fg.default}", + "padding": "{dimension.space.400}", + "fontWeight": "{fonts.fontWeight.demibold}", + "margin": "{dimension.space.none}", + "gap": "{dimension.space.200}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + }, + "tabpanel": { + "background": "transparent", + "color": "{color.fg.default}", + "padding": "{dimension.space.400}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + }, + "navButton": { + "background": "{color.bg.surface.raised.default}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}", + "width": "{dimension.size.700}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + } + }, + "activeBar": { + "height": "{dimension.size.50}", + "bottom": "{dimension.space.negative.50}", + "background": "{color.bg.neutral.strong.default}" + } + }, + "toast": { + "extend": { + "extInfo": { + "color": "{color.fg.status.info.default}", + "closeButton": { + "color": "{color.fg.status.info.default}", + "borderColor": "{color.border.status.info.default}" + }, + "caption": { "color": "{color.fg.default}" } + }, + "extAccentLine": { "width": "{dimension.size.100}" }, + "extCloseButton": { "width": "{dimension.borderWidth.100}" }, + "extSuccess": { + "color": "{color.fg.status.success.default}", + "closeButton": { + "color": "{color.fg.status.success.default}", + "borderColor": "{color.border.brand.default}" + }, + "caption": { "color": "{color.fg.default}" } + }, + "extWarn": { + "color": "{color.fg.status.warning.default}", + "closeButton": { + "color": "{color.fg.status.warning.default}", + "borderColor": "{color.border.status.warning.default}" + }, + "caption": { "color": "{color.fg.default}" } + }, + "extError": { + "color": "{color.fg.status.danger.default}", + "closeButton": { + "color": "{color.fg.status.danger.default}", + "borderColor": "{color.border.status.danger.default}" + }, + "caption": { "color": "{color.fg.default}" } + } + }, + "colorScheme": { + "light": { + "info": { + "background": "{color.bg.status.info.weak.default}", + "borderColor": "{color.border.status.info.default}", + "color": "{color.fg.default}", + "detailColor": "{color.fg.default}", + "shadow": "{effects.elevation.400}", + "closeButton": { + "hoverBackground": "{color.bg.status.info.weak.active}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + } + }, + "success": { + "background": "{color.bg.status.success.weak.default}", + "borderColor": "{color.border.brand.default}", + "color": "{color.fg.default}", + "detailColor": "{color.fg.default}", + "shadow": "{effects.elevation.400}", + "closeButton": { + "hoverBackground": "{color.bg.status.success.weak.active}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + } + }, + "warn": { + "background": "{color.bg.status.warning.weak.default}", + "borderColor": "{color.border.status.warning.default}", + "color": "{color.fg.default}", + "detailColor": "{color.fg.default}", + "shadow": "{effects.elevation.400}", + "closeButton": { + "hoverBackground": "{color.bg.status.warning.weak.active}", + "focusRing": { "color": "{color.border.focus}", "shadow": "none" } + } + }, + "error": { + "background": "{color.bg.status.danger.weak.default}", + "borderColor": "{color.border.status.danger.default}", + "color": "{color.fg.default}", + "detailColor": "{color.fg.default}", + "shadow": "{effects.elevation.400}", + "closeButton": { + "hoverBackground": "{color.bg.status.danger.weak.active}", + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + } + } + }, + "secondary": { + "shadow": "{effects.elevation.400}", + "background": "{color.bg.neutral.weak.default}", + "borderColor": "{color.border.neutral.strong}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + }, + "hoverBackground": "{color.bg.neutral.weak.default}" + }, + "color": "{color.fg.default}", + "detailColor": "{color.fg.subtle}" + }, + "contrast": { + "shadow": "{effects.elevation.400}", + "background": "{color.bg.neutral.strong.default}", + "borderColor": "{color.border.neutral.bold.default}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + }, + "hoverBackground": "{color.bg.neutral.strong.hover}" + }, + "color": "{color.fg.on.fill.default}", + "detailColor": "{color.fg.on.fill.muted}" + }, + "root": { "blur": "{effects.blur.none}" } + }, + "dark": { + "contrast": { + "background": "{color.bg.surface.canvas.default}", + "borderColor": "{color.border.neutral.inverse}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + }, + "hoverBackground": "{color.bg.surface.canvas.hover}" + }, + "color": "{color.fg.default}", + "detailColor": "{color.fg.on.fill.muted}", + "shadow": "{effects.elevation.400}" + }, + "error": { + "background": "{color.bg.status.danger.weak.default}", + "borderColor": "{color.border.status.danger.default}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "{color.bg.status.danger.weak.active}" + }, + "color": "{color.fg.inverse.default}", + "detailColor": "{color.fg.inverse.default}", + "shadow": "{effects.elevation.400}" + }, + "info": { + "background": "{color.bg.status.info.weak.default}", + "borderColor": "{color.border.status.info.default}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "{color.bg.status.info.weak.active}" + }, + "color": "{color.fg.inverse.default}", + "detailColor": "{color.fg.inverse.default}", + "shadow": "{effects.elevation.400}" + }, + "root": { "blur": "{effects.blur.none}" }, + "secondary": { + "background": "{color.bg.neutral.strong.default}", + "borderColor": "{color.border.neutral.strong}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.none}" + }, + "hoverBackground": "{color.bg.neutral.strong.selected}" + }, + "color": "{color.fg.inverse.default}", + "detailColor": "{color.fg.subtle}", + "shadow": "{effects.elevation.400}" + }, + "success": { + "background": "{color.bg.status.success.weak.default}", + "borderColor": "{color.border.brand.default}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "{effects.elevation.200}" + }, + "hoverBackground": "{color.bg.status.success.weak.active}" + }, + "color": "{color.fg.inverse.default}", + "detailColor": "{color.fg.inverse.default}", + "shadow": "{effects.elevation.400}" + }, + "warn": { + "background": "{color.bg.status.warning.weak.default}", + "borderColor": "{color.border.status.warning.default}", + "closeButton": { + "focusRing": { + "color": "{color.border.focus}", + "shadow": "none" + }, + "hoverBackground": "{color.bg.status.warning.weak.active}" + }, + "color": "{color.fg.inverse.default}", + "detailColor": "{color.fg.inverse.default}", + "shadow": "{effects.elevation.400}" + } + } + }, + "root": { + "width": "{dimension.size.2000}", + "borderWidth": "{dimension.borderWidth.100}", + "borderRadius": "{dimension.borderRadius.400}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "icon": { "size": "{dimension.size.1000}" }, + "content": { + "padding": "{dimension.space.400}", + "gap": "{dimension.space.400}" + }, + "text": { "gap": "{dimension.space.100}" }, + "summary": { + "fontWeight": "{fonts.fontWeight.bold}", + "fontSize": "{fonts.fontSize.300}" + }, + "detail": { + "fontWeight": "{fonts.fontWeight.regular}", + "fontSize": "{fonts.fontSize.200}" + }, + "closeButton": { + "width": "{dimension.size.900}", + "height": "{dimension.size.900}", + "borderRadius": "{dimension.borderRadius.400}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "offset": "{dimension.focusRing.offset}" + } + }, + "closeIcon": { "size": "{dimension.size.450}" } + }, + "tag": { + "colorScheme": { + "light": { + "primary": { + "background": "{color.bg.brand.strong.default}", + "color": "{color.fg.default}" + }, + "secondary": { + "background": "{color.bg.neutral.medium.default}", + "color": "{color.fg.default}" + }, + "success": { + "background": "{color.bg.status.success.strong.hover}", + "color": "{color.fg.on.status.success.default}" + }, + "info": { + "background": "{color.bg.status.info.strong.default}", + "color": "{color.fg.on.status.info.default}" + }, + "warn": { + "background": "{color.bg.status.warning.strong.default}", + "color": "{color.fg.on.status.warning.default}" + }, + "danger": { + "background": "{color.bg.status.danger.strong.default}", + "color": "{color.fg.on.status.danger.default}" + }, + "contrast": { + "background": "{color.bg.neutral.strong.default}", + "color": "{color.fg.on.fill.default}" + } + }, + "dark": { + "contrast": { + "background": "{color.bg.surface.canvas.default}", + "color": "{color.fg.default}" + }, + "danger": { + "background": "{color.bg.status.danger.strong.default}", + "color": "{color.fg.on.status.danger.default}" + }, + "info": { + "background": "{color.bg.status.info.strong.default}", + "color": "{color.fg.on.status.info.default}" + }, + "primary": { + "background": "{color.bg.brand.strong.default}", + "color": "{color.fg.inverse.default}" + }, + "secondary": { + "background": "{color.bg.neutral.strong.hover}", + "color": "{color.fg.inverse.default}" + }, + "success": { + "background": "{color.bg.brand.strong.hover}", + "color": "{color.fg.on.status.success.default}" + }, + "warn": { + "background": "{color.bg.status.warning.strong.default}", + "color": "{color.fg.on.status.warning.default}" + } + } + }, + "root": { + "fontSize": "{fonts.fontSize.100}", + "fontWeight": "{fonts.fontWeight.regular}", + "padding": "{dimension.space.100} {dimension.space.200}", + "gap": "{dimension.space.100}", + "borderRadius": "{dimension.borderRadius.200}", + "roundedBorderRadius": "{dimension.borderRadius.max}" + }, + "icon": { "size": "{dimension.size.450}" } + }, + "textarea": { + "extend": { + "readonlyBackground": "{color.bg.neutral.weak.default}", + "borderWidth": "{dimension.borderWidth.100}", + "iconSize": "{dimension.size.450}", + "minHeight": "{dimension.size.1500}" + }, + "root": { + "background": "{color.bg.surface.default.default}", + "disabledBackground": "{color.bg.surface.canvas.hover}", + "filledBackground": "{color.bg.surface.default.default}", + "filledHoverBackground": "{color.bg.surface.default.default}", + "filledFocusBackground": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.strong}", + "hoverBorderColor": "{color.border.brand.strong}", + "focusBorderColor": "{color.border.brand.strong}", + "invalidBorderColor": "{color.border.status.danger.subtle}", + "color": "{color.fg.active}", + "disabledColor": "{color.fg.muted}", + "placeholderColor": "{color.fg.muted}", + "invalidPlaceholderColor": "{color.fg.status.danger.hover}", + "shadow": "{effects.elevation.none}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}", + "borderRadius": "{dimension.borderRadius.400}", + "transitionDuration": "{effects.transition.duration.200}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}" + }, + "lg": { + "fontSize": "{fonts.fontSize.300}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}" + }, + "sm": { + "fontSize": "{fonts.fontSize.300}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}" + } + }, + "sm": { + "fontSize": "{fonts.fontSize.300}", + "paddingX": "{dimension.space.200}", + "paddingY": "{dimension.space.200}" + }, + "lg": { + "fontSize": "{fonts.fontSize.300}", + "paddingX": "{dimension.space.400}", + "paddingY": "{dimension.space.400}" + } + }, + "tieredmenu": { + "extend": { + "iconSize": "{dimension.size.600}", + "extSubmenu": { + "borderColor": "{color.border.neutral.default}", + "background": "{color.bg.surface.raised.default}" + }, + "extItem": { + "caption": { + "gap": "{dimension.space.100}", + "color": "{color.fg.muted}" + } + } + }, + "root": { + "background": "{color.bg.surface.default.default}", + "borderColor": "transparent", + "color": "{color.fg.default}", + "borderRadius": "{dimension.borderRadius.400}", + "shadow": "{effects.elevation.400}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "list": { + "padding": "{dimension.space.100}", + "gap": "{dimension.space.100}" + }, + "item": { + "focusBackground": "{color.bg.neutral.weak.default}", + "activeBackground": "{color.bg.neutral.strong.default}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "activeColor": "{color.fg.inverse.active}", + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.200}", + "gap": "{dimension.space.200}", + "icon": { + "color": "{color.fg.default}", + "focusColor": "{color.fg.default}", + "activeColor": "{color.fg.inverse.active}" + } + }, + "submenu": { "mobileIndent": "{dimension.space.400}" }, + "separator": { "borderColor": "{color.border.neutral.default}" }, + "submenuIcon": { + "activeColor": "{color.fg.hover}", + "color": "{color.fg.default}", + "focusColor": "{color.fg.hover}", + "size": "{dimension.size.400}" + } + }, + "timeline": { + "extend": { "extEvent": { "gap": "{dimension.space.100}" } }, + "event": { "minHeight": "{dimension.size.1400}" }, + "vertical": { + "eventContent": { + "padding": "{dimension.space.none} {dimension.space.600}" + } + }, + "horizontal": { + "eventContent": { + "padding": "{dimension.space.600} {dimension.space.none}" + } + }, + "eventMarker": { + "size": "{dimension.size.450}", + "borderRadius": "{dimension.borderRadius.400}", + "borderWidth": "{dimension.borderWidth.300}", + "background": "{color.bg.surface.raised.default}", + "borderColor": "{color.border.brand.default}", + "content": { + "borderRadius": "{dimension.borderRadius.400}", + "size": "{dimension.size.350}", + "background": "transparent", + "insetShadow": "none" + } + }, + "eventConnector": { + "color": "{color.border.neutral.default}", + "size": "{dimension.borderWidth.100}" + } + }, + "togglebutton": { + "extend": { + "ext": { "gap": "{dimension.space.400}" }, + "iconSize": { + "sm": "{dimension.size.450}", + "md": "{dimension.size.600}", + "lg": "{dimension.size.700}" + }, + "iconOnlyWidth": "{dimension.size.1100}", + "hoverBorderColor": "{color.border.neutral.strong}", + "checkedHoverColor": "{color.fg.on.fill.hover}", + "checkedHoverBackground": "{color.bg.neutral.strong.hover}", + "checkedHoverBorderColor": "{color.border.neutral.bold.hover}", + "extXlg": { + "padding": "{dimension.space.600} {dimension.space.600}", + "iconOnlyWidth": "{dimension.size.1400}" + }, + "extSm": { "iconOnlyWidth": "{dimension.size.900}" }, + "extLg": { "iconOnlyWidth": "{dimension.size.1300}" } + }, + "colorScheme": { + "light": { + "root": { + "background": "{color.bg.surface.canvas.hover}", + "hoverBackground": "{color.bg.surface.canvas.active}", + "borderColor": "{color.border.neutral.default}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.default}", + "checkedBackground": "{color.bg.neutral.strong.default}", + "checkedColor": "{color.fg.on.fill.default}", + "checkedBorderColor": "{color.border.neutral.bold.default}", + "disabledBackground": "{color.bg.surface.canvas.hover}", + "disabledBorderColor": "{color.border.neutral.default}", + "disabledColor": "{color.fg.muted}", + "invalidBorderColor": "{color.border.status.danger.subtle}" + }, + "icon": { + "color": "{color.fg.default}", + "hoverColor": "{color.fg.default}", + "checkedColor": "{color.fg.on.fill.default}", + "disabledColor": "{color.fg.muted}" + }, + "content": { "checkedBackground": "transparent" } + }, + "dark": { + "root": { + "hoverBackground": "{color.bg.neutral.strong.active}", + "background": "{color.bg.neutral.strong.hover}", + "borderColor": "{color.border.neutral.bold.hover}", + "color": "{color.fg.inverse.default}", + "hoverColor": "{color.fg.on.brand.hover}", + "checkedBackground": "{color.bg.surface.canvas.default}", + "checkedColor": "{color.fg.focus}", + "checkedBorderColor": "{color.border.neutral.inverse}", + "disabledBackground": "{color.bg.neutral.strong.hover}", + "disabledBorderColor": "{color.border.neutral.bold.hover}", + "disabledColor": "{color.fg.inverse.muted}", + "invalidBorderColor": "{color.border.status.danger.strong}" + }, + "icon": { + "color": "{color.fg.inverse.default}", + "hoverColor": "{color.fg.on.brand.hover}", + "checkedColor": "{color.fg.focus}", + "disabledColor": "{color.fg.inverse.muted}" + }, + "content": { "checkedBackground": "transparent" } + } + }, + "root": { + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.max}", + "gap": "{dimension.space.200}", + "fontWeight": "{fonts.fontWeight.demibold}", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.200}" + }, + "sm": { + "fontSize": "{fonts.fontSize.200}", + "padding": "{dimension.space.100} {dimension.space.400}" + }, + "lg": { + "fontSize": "{fonts.fontSize.500}", + "padding": "{dimension.space.400} {dimension.space.700}" + }, + "transitionDuration": "{effects.transition.duration.200}", + "background": "{color.bg.surface.default.default}", + "borderColor": "{color.border.neutral.default}", + "checkedBackground": "{color.bg.surface.default.default}", + "checkedBorderColor": "{color.border.neutral.default}", + "checkedColor": "{color.fg.default}", + "color": "{color.fg.default}", + "disabledBackground": "{color.bg.surface.canvas.hover}", + "disabledBorderColor": "{color.border.neutral.default}", + "disabledColor": "{color.fg.muted}", + "hoverColor": "{color.fg.hover}", + "invalidBorderColor": "{color.border.status.danger.subtle}" + }, + "content": { + "checkedShadow": "none", + "padding": "{dimension.space.none}", + "borderRadius": "{dimension.borderRadius.none}", + "sm": { "padding": "{dimension.space.none}" }, + "lg": { "padding": "{dimension.space.none}" }, + "checkedBackground": "{color.bg.surface.default.default}" + }, + "icon": { + "checkedColor": "{color.fg.default}", + "color": "{color.fg.default}", + "disabledColor": "{color.fg.muted}", + "hoverColor": "{color.fg.hover}" + } + }, + "toggleswitch": { + "colorScheme": { + "light": { + "root": { + "background": "{color.bg.neutral.medium.active}", + "hoverBackground": "{color.bg.neutral.medium.strong}", + "disabledBackground": "{color.bg.surface.canvas.hover}", + "checkedBackground": "{color.bg.neutral.strong.default}", + "checkedHoverBackground": "{color.bg.neutral.strong.hover}" + }, + "handle": { + "background": "{color.bg.surface.raised.default}", + "hoverBackground": "{color.bg.surface.raised.default}", + "disabledBackground": "{color.bg.neutral.medium.strong}", + "checkedBackground": "{color.bg.surface.raised.default}", + "checkedHoverBackground": "{color.bg.surface.raised.default}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.default}", + "checkedColor": "{color.fg.default}", + "checkedHoverColor": "{color.fg.default}" + } + }, + "dark": { + "handle": { + "background": "{color.bg.surface.raised.default}", + "checkedBackground": "{color.bg.surface.raised.default}", + "checkedColor": "{color.fg.inverse.focus}", + "checkedHoverBackground": "{color.bg.surface.raised.default}", + "checkedHoverColor": "{color.fg.on.brand.hover}", + "color": "{color.fg.inverse.default}", + "disabledBackground": "{color.bg.surface.raised.active}", + "hoverBackground": "{color.bg.surface.raised.default}", + "hoverColor": "{color.fg.on.brand.hover}" + }, + "root": { + "background": "{color.bg.neutral.medium.active}", + "checkedBackground": "{color.bg.surface.canvas.default}", + "checkedHoverBackground": "{color.bg.surface.canvas.hover}", + "disabledBackground": "{color.bg.neutral.strong.hover}", + "hoverBackground": "{color.bg.surface.raised.active}" + } + } + }, + "root": { + "width": "{dimension.size.1100}", + "height": "{dimension.size.700}", + "borderRadius": "{dimension.borderRadius.max}", + "gap": "{dimension.space.100}", + "borderWidth": "{dimension.borderWidth.100}", + "shadow": "none", + "focusRing": { + "width": "{dimension.focusRing.width}", + "style": "none", + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}" + }, + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "checkedBorderColor": "transparent", + "checkedHoverBorderColor": "transparent", + "invalidBorderColor": "{color.border.status.danger.subtle}", + "transitionDuration": "{effects.transition.duration.200}", + "slideDuration": "{effects.transition.duration.200}" + }, + "handle": { + "borderRadius": "{dimension.borderRadius.max}", + "size": "{dimension.size.450}" + } + }, + "tooltip": { + "colorScheme": { + "light": { + "root": { + "background": "{color.bg.neutral.strong.default}", + "color": "{color.fg.inverse.default}" + } + }, + "dark": { + "root": { + "background": "{color.bg.surface.canvas.default}", + "color": "{color.fg.default}" + } + } + }, + "root": { + "maxWidth": "{dimension.size.2000}", + "gutter": "{dimension.space.100}", + "shadow": "{effects.elevation.400}", + "padding": "{dimension.space.200} {dimension.space.400}", + "borderRadius": "{dimension.borderRadius.200}" + } + }, + "tree": { + "root": { + "background": "{color.bg.surface.default.default}", + "color": "{color.fg.default}", + "padding": "{dimension.space.400}", + "gap": "{dimension.space.100}", + "indent": "{dimension.space.400}", + "transitionDuration": "{effects.transition.duration.200}" + }, + "node": { + "padding": "{dimension.space.200} {dimension.space.400}", + "color": "{color.fg.default}", + "selectedColor": "{color.fg.on.fill.default}", + "gap": "{dimension.space.100}", + "borderRadius": "{dimension.borderRadius.400}", + "focusRing": { + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}", + "style": "none", + "width": "{dimension.focusRing.width}" + }, + "hoverBackground": "{color.bg.neutral.weak.default}", + "hoverColor": "{color.fg.default}", + "selectedBackground": "{color.bg.neutral.strong.selected}" + }, + "nodeIcon": { + "selectedColor": "{color.fg.on.fill.default}", + "color": "{color.fg.default}", + "hoverColor": "{color.fg.hover}" + }, + "nodeToggleButton": { + "borderRadius": "{dimension.borderRadius.100}", + "size": "{dimension.size.800}", + "selectedHoverBackground": "{color.bg.neutral.strong.default}", + "color": "{color.fg.default}", + "focusRing": { + "color": "{color.border.focus}", + "offset": "{dimension.focusRing.offset}", + "shadow": "{effects.elevation.none}", + "style": "none", + "width": "{dimension.focusRing.width}" + }, + "hoverBackground": "{color.bg.neutral.weak.default}", + "hoverColor": "{color.fg.hover}", + "selectedHoverColor": "{color.fg.hover}" + }, + "loadingIcon": { "size": "{dimension.size.450}" }, + "filter": { + "margin": "{dimension.space.none} {dimension.space.none} {dimension.space.200} {dimension.space.none}" + } + }, + "overlaybadge": { + "root": { + "outline": { "width": "{dimension.size.none}", "color": "transparent" } + } + } + } +} diff --git a/src/theme/__tests__/ThemeContext.test.tsx b/src/theme/__tests__/ThemeContext.test.tsx index ed58df0e..0106d5ff 100644 --- a/src/theme/__tests__/ThemeContext.test.tsx +++ b/src/theme/__tests__/ThemeContext.test.tsx @@ -4,7 +4,12 @@ import { Text } from 'react-native' import { UnistylesRuntime } from 'react-native-unistyles' import { ThemeContextProvider } from '../ThemeContext' +import { darkTheme } from '../darkTheme' import { lightTheme } from '../lightTheme' +import darkComponentTokens from '../tokens/components/dark.json' +import lightComponentTokens from '../tokens/components/light.json' +import darkSemanticTokens from '../tokens/semantic/dark.json' +import lightSemanticTokens from '../tokens/semantic/light.json' import { ThemeVariant } from '../types' describe('ThemeContextProvider', () => { @@ -66,4 +71,14 @@ describe('ThemeContextProvider', () => { expect(UnistylesRuntime.updateTheme).not.toHaveBeenCalled() }) + + test('каждая тема содержит соответствующие semantic-токены', () => { + expect(lightTheme.semantic).toBe(lightSemanticTokens) + expect(darkTheme.semantic).toBe(darkSemanticTokens) + }) + + test('каждая тема содержит соответствующие component-токены', () => { + expect(lightTheme.components).toBe(lightComponentTokens) + expect(darkTheme.components).toBe(darkComponentTokens) + }) }) diff --git a/src/theme/darkTheme.ts b/src/theme/darkTheme.ts index 1f52f8ed..aa8bf3f0 100644 --- a/src/theme/darkTheme.ts +++ b/src/theme/darkTheme.ts @@ -3,9 +3,13 @@ import { ModalSize } from './assets/ModalSize' import { customDark } from './assets/customDark' import darkThemeAssets from './assets/themeDark.json' import { commonTheme } from './commonTheme' +import darkComponentTokens from './tokens/components/dark.json' +import darkSemanticTokens from './tokens/semantic/dark.json' import type { ThemeType } from './types' export const darkTheme: ThemeType = { + semantic: darkSemanticTokens, + components: darkComponentTokens, theme: { ...darkThemeAssets, InputSize, ModalSize, custom: customDark }, ...commonTheme, fonts: { primary: 'TT Fellows', secondary: 'Noto Sans' }, diff --git a/src/theme/lightTheme.ts b/src/theme/lightTheme.ts index cc47c3be..b91a6008 100644 --- a/src/theme/lightTheme.ts +++ b/src/theme/lightTheme.ts @@ -3,9 +3,13 @@ import { ModalSize } from './assets/ModalSize' import { customLight } from './assets/customLight' import lightThemeAssets from './assets/themeLight.json' import { commonTheme } from './commonTheme' +import lightComponentTokens from './tokens/components/light.json' +import lightSemanticTokens from './tokens/semantic/light.json' import type { ThemeType } from './types' export const lightTheme: ThemeType = { + semantic: lightSemanticTokens, + components: lightComponentTokens, theme: { ...lightThemeAssets, InputSize, ModalSize, custom: customLight }, ...commonTheme, fonts: { primary: 'TT Fellows', secondary: 'Noto Sans' }, diff --git a/src/theme/tokens/README.md b/src/theme/tokens/README.md new file mode 100644 index 00000000..3badaaae --- /dev/null +++ b/src/theme/tokens/README.md @@ -0,0 +1,9 @@ +# Сгенерированные токены + +`semantic` подключается к темам как `ThemeType.semantic`. `components` хранит +внутренние токены компонентов для `ThemeType.components`. В сгенерированных +файлах нет `primitive`; `colorScheme` содержит только выбранную ветку без +вложенных `light` и `dark`. Всё генерируется из +`design-tokens/input/tokens.json` и не редактируется вручную. + +Подробности: [генератор токенов](../../../scripts/token-generator/README.md). diff --git a/src/theme/tokens/components/dark.json b/src/theme/tokens/components/dark.json new file mode 100644 index 00000000..111be1c4 --- /dev/null +++ b/src/theme/tokens/components/dark.json @@ -0,0 +1,2920 @@ +{ + "accordion": { + "extend": { "extHeader": { "iconSize": 20, "gap": 8 } }, + "colorScheme": { + "header": { + "activeBackground": "transparent", + "activeHoverBackground": "transparent", + "background": "transparent", + "hoverBackground": "transparent" + } + }, + "header": { + "color": "#ffffff", + "hoverColor": "#cecfd2", + "activeColor": "#ffffff", + "activeHoverColor": "#cecfd2", + "borderColor": "transparent", + "paddingTop": 14, + "paddingRight": 0, + "paddingBottom": 14, + "paddingLeft": 0, + "fontWeight": "700", + "borderRadius": 0, + "borderWidth": 0, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "inset 0 0 0 4px #d4fedc" + }, + "toggleIcon": { + "color": "#ffffff", + "hoverColor": "#cecfd2", + "activeColor": "#ffffff", + "activeHoverColor": "#cecfd2" + }, + "last": { "bottomBorderRadius": 0, "activeBottomBorderRadius": 0 }, + "first": { "borderWidth": 0, "topBorderRadius": 0 } + }, + "root": { "transitionDuration": 180 }, + "panel": { + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 4, + "borderLeftWidth": 0, + "borderColor": "#56595f" + }, + "content": { + "borderTopWidth": 1, + "borderRightWidth": 0, + "borderBottomWidth": 0, + "borderLeftWidth": 0, + "borderColor": "transparent", + "background": "transparent", + "color": "#ffffff", + "paddingTop": 0, + "paddingRight": 24, + "paddingBottom": 14, + "paddingLeft": 24 + } + }, + "autocomplete": { + "extend": { "extOption": { "gap": 8 }, "extOptionGroup": { "gap": 8 } }, + "colorScheme": { + "chip": { "focusBackground": "#e2e2e4", "focusColor": "#2b2e33" }, + "dropdown": { + "activeBackground": "#404348", + "activeColor": "#181a1f", + "background": "#404348", + "color": "#181a1f", + "hoverBackground": "#404348", + "hoverColor": "#181a1f" + } + }, + "root": { + "background": "#404348", + "disabledBackground": "#404348", + "filledBackground": "#404348", + "filledHoverBackground": "#404348", + "filledFocusBackground": "#404348", + "borderColor": "#56595f", + "hoverBorderColor": "#77f48a", + "focusBorderColor": "#77f48a", + "invalidBorderColor": "#db3424", + "color": "#f0f0f1", + "disabledColor": "#a2a5a9", + "placeholderColor": "#a2a5a9", + "invalidPlaceholderColor": "#fbacaa", + "shadow": "none", + "paddingX": 14, + "paddingY": 14, + "borderRadius": 14, + "transitionDuration": 180, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + } + }, + "overlay": { + "background": "#404348", + "borderColor": "#404348", + "borderRadius": 14, + "color": "#ffffff", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "list": { "padding": 4, "gap": 4 }, + "option": { + "focusBackground": "#2b2e33", + "selectedBackground": "#f0f0f1", + "selectedFocusBackground": "#cecfd2", + "color": "#ffffff", + "focusColor": "#ffffff", + "selectedColor": "#ffffff", + "selectedFocusColor": "#ffffff", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8 + }, + "optionGroup": { + "background": "#56595f", + "color": "#a2a5a9", + "fontWeight": "600", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "dropdown": { + "width": 272, + "borderColor": "#56595f", + "hoverBorderColor": "#77f48a", + "activeBorderColor": "#77f48a", + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + }, + "sm": { "width": 240 }, + "lg": { "width": 304 } + }, + "chip": { "borderRadius": 8 }, + "emptyMessage": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + } + }, + "avatar": { + "extend": { "borderColor": "#56595f", "circle": { "borderRadius": 1600 } }, + "root": { + "width": 32, + "height": 32, + "fontSize": 16, + "color": "#ffffff", + "background": "#44e858", + "borderRadius": 14 + }, + "icon": { "size": 16 }, + "group": { "borderColor": "#2b2e33", "offset": -12 }, + "lg": { + "width": 40, + "height": 40, + "fontSize": 16, + "icon": { "size": 16 }, + "group": { "offset": -12 } + }, + "xl": { + "width": 56, + "height": 56, + "icon": { "size": 24 }, + "group": { "offset": -24 }, + "fontSize": 16 + } + }, + "badge": { + "extend": { + "extDot": { + "success": { "background": "#1dc831" }, + "info": { "background": "#1e76cd" }, + "warn": { "background": "#dc9710" }, + "danger": { "background": "#db3424" }, + "lg": { "size": 12 }, + "xlg": { "size": 16 } + }, + "ext": { "padding": 0 } + }, + "colorScheme": { + "contrast": { "background": "#2b2e33", "color": "#ffffff" }, + "danger": { "background": "#8d2218", "color": "#fff0f0" }, + "info": { "background": "#18538d", "color": "#f0f9ff" }, + "primary": { "background": "#44e858", "color": "#2b2e33" }, + "secondary": { "background": "#2b2e33", "color": "#ffffff" }, + "success": { "background": "#aafbb7", "color": "#f0fff3" }, + "warn": { "background": "#9d6d0e", "color": "#fff9f0" } + }, + "root": { + "borderRadius": 8, + "padding": 8, + "fontSize": 12, + "fontWeight": "400", + "minWidth": 24, + "height": 24 + }, + "dot": { "size": 8 }, + "sm": { "fontSize": 12, "minWidth": 0, "height": 0 }, + "lg": { "fontSize": 12, "minWidth": 28, "height": 28 }, + "xl": { "fontSize": 12, "minWidth": 32, "height": 32 } + }, + "breadcrumb": { + "extend": { + "hoverBackground": "#2b2e33", + "iconSize": 20, + "extItem": { "padding": 4 } + }, + "root": { + "padding": 0, + "background": "transparent", + "gap": 0, + "transitionDuration": 180 + }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "item": { + "color": "#ffffff", + "hoverColor": "#cecfd2", + "borderRadius": 4, + "gap": 8, + "icon": { "color": "#ffffff", "hoverColor": "#cecfd2" }, + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + } + }, + "separator": { "color": "#ffffff" } + }, + "button": { + "extend": { + "disabledBackground": "#404348", + "extOutlined": { + "danger": { "focusBackground": "transparent" }, + "warn": { "focusBackground": "transparent" }, + "info": { "focusBackground": "transparent" }, + "help": { "focusBackground": "transparent" }, + "success": { "focusBackground": "transparent" } + }, + "disabledColor": "#a2a5a9", + "extText": { + "danger": { "focusBackground": "transparent" }, + "warn": { "focusBackground": "transparent" }, + "info": { "focusBackground": "transparent" }, + "help": { "focusBackground": "transparent" }, + "success": { "focusBackground": "transparent" } + }, + "extLink": { + "background": "transparent", + "colorHover": "#cecfd2", + "paddingX": 0, + "paddingY": 4, + "sm": { "iconOnlyWidth": 16 }, + "base": { "iconOnlyWidth": 24 }, + "lg": { "iconOnlyWidth": 28 }, + "xlg": { "iconOnlyWidth": 32 } + }, + "extSm": { "borderRadius": 14, "gap": 8 }, + "extLg": { "borderRadius": 14, "gap": 14, "height": 56 }, + "extXlg": { + "borderRadius": 14, + "gap": 14, + "iconOnlyWidth": 64, + "paddingX": 24, + "paddingY": 20, + "height": 64 + }, + "borderWidth": 1, + "iconSize": { "sm": 16, "md": 20, "lg": 24 } + }, + "colorScheme": { + "link": { + "activeColor": "#85888e", + "color": "#2b2e33", + "hoverColor": "#56595f" + }, + "outlined": { + "contrast": { + "activeBackground": "#56595f", + "borderColor": "#2b2e33", + "color": "#ffffff", + "hoverBackground": "#404348" + }, + "danger": { + "activeBackground": "#611912", + "borderColor": "#db3424", + "color": "#fbacaa", + "hoverBackground": "#45120e" + }, + "help": { + "activeBackground": "#6b21a8", + "borderColor": "#c084fc", + "color": "#d8b4fe", + "hoverBackground": "#581c87" + }, + "info": { + "activeBackground": "#123a61", + "borderColor": "#77baf4", + "color": "#aad7fb", + "hoverBackground": "#0e2a45" + }, + "plain": { + "activeBackground": "#e2e2e4", + "borderColor": "#56595f", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1" + }, + "primary": { + "activeBackground": "#0e4514", + "borderColor": "#d4fedc", + "color": "#44e858", + "hoverBackground": "#0c3b11" + }, + "secondary": { + "activeBackground": "#e2e2e4", + "borderColor": "#56595f", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1" + }, + "success": { + "activeBackground": "#12611b", + "borderColor": "#77f48a", + "color": "#aafbb7", + "hoverBackground": "#0e4514" + }, + "warn": { + "activeBackground": "#6d4c0b", + "borderColor": "#facb75", + "color": "#fddeaa", + "hoverBackground": "#4f3709" + } + }, + "root": { + "contrast": { + "activeBackground": "#6d7076", + "activeBorderColor": "transparent", + "activeColor": "#2b2e33", + "background": "#e2e2e4", + "borderColor": "transparent", + "color": "#2b2e33", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "#cecfd2", + "hoverBorderColor": "transparent", + "hoverColor": "#2b2e33" + }, + "danger": { + "activeBackground": "#e85244", + "activeBorderColor": "transparent", + "activeColor": "#fff0f0", + "background": "#8d2218", + "borderColor": "transparent", + "color": "#fff0f0", + "focusRing": { "color": "#d4fedc", "shadow": "none" }, + "hoverBackground": "#db3424", + "hoverBorderColor": "transparent", + "hoverColor": "#fffafa" + }, + "help": { + "activeBackground": "#a855f7", + "activeBorderColor": "transparent", + "activeColor": "#f3e8ff", + "background": "#7e22ce", + "borderColor": "transparent", + "color": "#f3e8ff", + "focusRing": { "color": "#d4fedc", "shadow": "none" }, + "hoverBackground": "#9333ea", + "hoverBorderColor": "transparent", + "hoverColor": "#faf5ff" + }, + "info": { + "activeBackground": "#4496e8", + "activeBorderColor": "transparent", + "activeColor": "#f0f9ff", + "background": "#18538d", + "borderColor": "transparent", + "color": "#f0f9ff", + "focusRing": { "color": "#d4fedc", "shadow": "none" }, + "hoverBackground": "#1e76cd", + "hoverBorderColor": "transparent", + "hoverColor": "#fafdff" + }, + "primary": { + "activeBackground": "#168322", + "activeBorderColor": "transparent", + "activeColor": "#2b2e33", + "background": "#44e858", + "borderColor": "transparent", + "color": "#2b2e33", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "#1dc831", + "hoverBorderColor": "transparent", + "hoverColor": "#2b2e33" + }, + "secondary": { + "activeBackground": "#56595f", + "activeBorderColor": "transparent", + "activeColor": "#ffffff", + "background": "#2b2e33", + "borderColor": "transparent", + "color": "#ffffff", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "#404348", + "hoverBorderColor": "transparent", + "hoverColor": "#ffffff" + }, + "success": { + "activeBackground": "#44e858", + "activeBorderColor": "transparent", + "activeColor": "#f0fff3", + "background": "#aafbb7", + "borderColor": "transparent", + "color": "#f0fff3", + "focusRing": { "color": "#d4fedc", "shadow": "none" }, + "hoverBackground": "#77f48a", + "hoverBorderColor": "transparent", + "hoverColor": "#fafffb" + }, + "warn": { + "activeBackground": "#f5b83d", + "activeBorderColor": "transparent", + "activeColor": "#fff9f0", + "background": "#9d6d0e", + "borderColor": "transparent", + "color": "#fff9f0", + "focusRing": { "color": "#d4fedc", "shadow": "none" }, + "hoverBackground": "#dc9710", + "hoverBorderColor": "transparent", + "hoverColor": "#fffdfa" + } + }, + "text": { + "contrast": { + "activeBackground": "#56595f", + "color": "#ffffff", + "hoverBackground": "#404348" + }, + "danger": { + "activeBackground": "#611912", + "color": "#fbacaa", + "hoverBackground": "#45120e" + }, + "help": { + "activeBackground": "#6b21a8", + "color": "#d8b4fe", + "hoverBackground": "#581c87" + }, + "info": { + "activeBackground": "#123a61", + "color": "#aad7fb", + "hoverBackground": "#0e2a45" + }, + "plain": { + "activeBackground": "#e2e2e4", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1" + }, + "primary": { + "activeBackground": "#e2e2e4", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1" + }, + "secondary": { + "activeBackground": "#e2e2e4", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1" + }, + "success": { + "activeBackground": "#12611b", + "color": "#aafbb7", + "hoverBackground": "#0e4514" + }, + "warn": { + "activeBackground": "#6d4c0b", + "color": "#fddeaa", + "hoverBackground": "#4f3709" + } + } + }, + "root": { + "borderRadius": 14, + "roundedBorderRadius": 1600, + "gap": 8, + "paddingX": 14, + "paddingY": 8, + "iconOnlyWidth": 40, + "raisedShadow": "none", + "badgeSize": 16, + "transitionDuration": 180, + "focusRing": { "width": 4, "style": "none", "offset": 0 }, + "sm": { + "fontSize": 14, + "iconOnlyWidth": 32, + "paddingX": 14, + "paddingY": 8 + }, + "lg": { + "fontSize": 20, + "iconOnlyWidth": 56, + "paddingX": 24, + "paddingY": 14 + }, + "label": { "fontWeight": "600" } + } + }, + "card": { + "extend": { "borderColor": "#404348", "borderWidth": 1 }, + "root": { + "background": "#404348", + "borderRadius": 14, + "color": "#ffffff", + "shadow": "none" + }, + "body": { "padding": 14, "gap": 14 }, + "caption": { "gap": 4 }, + "title": { "fontSize": 18, "fontWeight": "600" }, + "subtitle": { "color": "#a2a5a9" } + }, + "carousel": { + "colorScheme": { + "indicator": { + "activeBackground": "#2b2e33", + "background": "#cecfd2", + "hoverBackground": "#6d7076" + } + }, + "root": { "transitionDuration": 180 }, + "content": { "gap": 8 }, + "indicatorList": { "padding": 14, "gap": 8 }, + "indicator": { + "width": 8, + "height": 8, + "borderRadius": 1600, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "checkbox": { + "root": { + "borderRadius": 8, + "extend": { "borderWidth": 1 }, + "width": 24, + "height": 24, + "background": "#404348", + "checkedBackground": "#f0f0f1", + "checkedHoverBackground": "#e2e2e4", + "disabledBackground": "#404348", + "filledBackground": "#404348", + "borderColor": "#56595f", + "hoverBorderColor": "#f0f0f1", + "focusBorderColor": "#f0f0f1", + "checkedBorderColor": "#f0f0f1", + "checkedHoverBorderColor": "#e2e2e4", + "checkedFocusBorderColor": "#44e858", + "checkedDisabledBorderColor": "#56595f", + "invalidBorderColor": "#db3424", + "shadow": "none", + "focusRing": { + "focusRing": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)", + "width": 4 + }, + "sm": { "width": 8, "height": 8 }, + "lg": { "width": 20, "height": 20 }, + "transitionDuration": 180 + }, + "icon": { + "size": 16, + "color": "#f0f0f1", + "checkedColor": "#ffffff", + "checkedHoverColor": "#ffffff", + "disabledColor": "#a2a5a9", + "sm": { "size": 12 }, + "lg": { "size": 20 } + } + }, + "chip": { + "extend": { "borderColor": "transparent", "borderWidth": 1 }, + "root": { + "borderRadius": 8, + "paddingX": 8, + "paddingY": 4, + "gap": 8, + "transitionDuration": 180 + }, + "colorScheme": { + "icon": { "color": "#2b2e33" }, + "removeIcon": { "color": "#2b2e33" }, + "root": { "background": "#e2e2e4", "color": "#2b2e33" } + }, + "image": { "width": 0, "height": 0 }, + "icon": { "size": 16 }, + "removeIcon": { + "size": 16, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "confirmdialog": { + "extend": { + "extIcon": { + "success": "#77f48a", + "info": "#77baf4", + "help": "#c084fc", + "warn": "#facb75", + "danger": "#f47f77" + } + }, + "icon": { "size": 24, "color": "#ffffff" }, + "content": { "gap": 0 } + }, + "confirmpopup": { + "root": { + "background": "#404348", + "color": "#ffffff", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "gutter": 14, + "arrowOffset": 20, + "borderColor": "#404348", + "borderRadius": 14 + }, + "content": { "padding": 14, "gap": 14 }, + "icon": { "size": 24, "color": "#ffffff" }, + "footer": { + "gap": 8, + "paddingTop": 0, + "paddingRight": 24, + "paddingBottom": 24, + "paddingLeft": 24 + } + }, + "contextmenu": { + "root": { + "background": "#404348", + "color": "#ffffff", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "borderColor": "#404348", + "borderRadius": 14, + "transitionDuration": 180 + }, + "list": { + "paddingTop": 8, + "paddingRight": 0, + "paddingBottom": 8, + "paddingLeft": 0, + "gap": 4 + }, + "item": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "gap": 8, + "activeBackground": "#404348", + "activeColor": "#cecfd2", + "borderRadius": 14, + "color": "#ffffff", + "focusBackground": "#2b2e33", + "focusColor": "#cecfd2", + "icon": { + "activeColor": "#cecfd2", + "color": "#ffffff", + "focusColor": "#cecfd2" + } + }, + "submenu": { "mobileIndent": 20 }, + "separator": { "borderColor": "#404348" }, + "submenuIcon": { + "activeColor": "#cecfd2", + "color": "#ffffff", + "focusColor": "#cecfd2", + "size": 14 + } + }, + "datatable": { + "colorScheme": { + "bodyCell": { "selectedBorderColor": "#e2e2e4" }, + "footer": { "background": "#f0f0f1", "color": "#2b2e33" }, + "footerCell": { "background": "#f0f0f1", "color": "#2b2e33" }, + "header": { "background": "#56595f", "color": "#2b2e33" }, + "headerCell": { + "background": "#6d7076", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1" + }, + "root": { "borderColor": "#e2e2e4", "color": "#2b2e33" }, + "row": { "stripedBackground": "#f0f0f1" } + }, + "extended": { + "extHeaderCell": { "selectedHoverBackground": "#e2e2e4" }, + "extRow": { + "selectedHoverBackground": "#e2e2e4", + "stripedHoverBackground": "#2b2e33", + "iconSize": 20 + } + }, + "root": { "transitionDuration": 180 }, + "header": { + "borderColor": "#404348", + "borderTopWidth": 1, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "padding": 14, + "sm": { "padding": 8 }, + "lg": { "padding": 20 } + }, + "headerCell": { + "selectedBackground": "#f0f0f1", + "borderColor": "#404348", + "hoverColor": "#cecfd2", + "selectedColor": "#ffffff", + "gap": 8, + "padding": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "inset 0 0 0 4px #d4fedc" + }, + "sm": { "padding": 8 }, + "lg": { "padding": 20 } + }, + "columnTitle": { "fontWeight": "700" }, + "row": { + "background": "#56595f", + "hoverBackground": "#2b2e33", + "selectedBackground": "#f0f0f1", + "color": "#ffffff", + "hoverColor": "#cecfd2", + "selectedColor": "#ffffff", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "inset 0 0 0 4px #d4fedc" + } + }, + "bodyCell": { + "borderColor": "#404348", + "padding": 14, + "sm": { "padding": 8 }, + "lg": { "padding": 20 } + }, + "footerCell": { + "borderColor": "#404348", + "padding": 14, + "sm": { "padding": 8 }, + "lg": { "padding": 20 } + }, + "columnFooter": { "fontWeight": "700" }, + "dropPoint": { "color": "#ffffff" }, + "footer": { + "borderColor": "#404348", + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "padding": 14, + "sm": { "padding": 8 }, + "lg": { "padding": 20 } + }, + "columnResizer": { "width": 8 }, + "resizeIndicator": { "width": 1, "color": "#ffffff" }, + "sortIcon": { "color": "#ffffff", "hoverColor": "#cecfd2", "size": 16 }, + "loadingIcon": { "size": 32 }, + "rowToggleButton": { + "hoverBackground": "#2b2e33", + "selectedHoverBackground": "#2b2e33", + "color": "#ffffff", + "hoverColor": "#ffffff", + "selectedHoverColor": "#ffffff", + "size": 32, + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "filter": { + "inlineGap": 8, + "rule": { "borderColor": "#404348" }, + "constraintList": { "padding": 4, "gap": 4 }, + "constraint": { + "focusBackground": "#2b2e33", + "selectedBackground": "#f0f0f1", + "selectedFocusBackground": "#cecfd2", + "color": "#ffffff", + "focusColor": "#ffffff", + "selectedColor": "#ffffff", + "selectedFocusColor": "#ffffff", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "separator": { "borderColor": "#404348" } + }, + "overlaySelect": { + "background": "#56595f", + "color": "#ffffff", + "borderColor": "#404348", + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "overlayPopover": { + "background": "#56595f", + "color": "#ffffff", + "borderColor": "#404348", + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "padding": 14, + "gap": 4 + } + }, + "paginatorTop": { + "borderColor": "#56595f", + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0 + }, + "paginatorBottom": { + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "borderColor": "#404348" + } + }, + "dataview": { + "root": { + "borderWidth": 1, + "borderRadius": 4, + "padding": 0, + "borderColor": "#404348" + }, + "header": { + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": "0px 0px 0px 0px", + "color": "#ffffff", + "borderColor": "#404348" + }, + "content": { + "background": "#404348", + "color": "#ffffff", + "borderColor": "#404348", + "borderWidth": 0, + "padding": 0, + "borderRadius": 0 + }, + "footer": { + "background": "#2b2e33", + "color": "#ffffff", + "borderTopWidth": 1, + "borderRightWidth": 0, + "borderBottomWidth": 0, + "borderLeftWidth": 0, + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": "0px 0px 0px 0px", + "borderColor": "#404348" + }, + "paginatorTop": { + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "borderColor": "#404348" + }, + "paginatorBottom": { + "borderTopWidth": 1, + "borderRightWidth": 0, + "borderBottomWidth": 0, + "borderLeftWidth": 0, + "borderColor": "#404348" + }, + "colorScheme": { "header": { "background": "#404348", "color": "#2b2e33" } } + }, + "datepicker": { + "extend": { + "extDate": { "selectedHoverBackground": "#e2e2e4" }, + "extToday": { "hoverBackground": "#2b2e33", "borderColor": "#e2e2e4" }, + "extTitle": { "width": 336 }, + "extTimePicker": { "minWidth": 304, "color": "#ffffff" } + }, + "colorScheme": { + "dropdown": { + "activeBackground": "#2b2e33", + "activeColor": "#ffffff", + "background": "#404348", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1", + "hoverColor": "#2b2e33" + }, + "today": { "background": "transparent", "color": "#2b2e33" } + }, + "panel": { + "background": "#404348", + "borderColor": "#404348", + "color": "#ffffff", + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "padding": 0 + }, + "header": { + "background": "#404348", + "borderColor": "#404348", + "color": "#ffffff", + "padding": 14 + }, + "title": { "gap": 8, "fontWeight": "700" }, + "selectMonth": { + "hoverBackground": "#2b2e33", + "color": "#ffffff", + "hoverColor": "#cecfd2", + "borderRadius": 14, + "padding": 8 + }, + "inputIcon": { "color": "#a2a5a9" }, + "dropdown": { + "width": 272, + "borderColor": "#56595f", + "hoverBorderColor": "#56595f", + "activeBorderColor": "#56595f", + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "sm": { "width": 0 }, + "lg": { "width": 0 } + }, + "group": { "borderColor": "#404348", "gap": 14 }, + "selectYear": { + "hoverBackground": "#2b2e33", + "color": "#ffffff", + "hoverColor": "#cecfd2", + "borderRadius": 14, + "padding": 4 + }, + "dayView": { "margin": 14 }, + "weekDay": { "padding": 4, "fontWeight": "700", "color": "#ffffff" }, + "date": { + "hoverBackground": "#2b2e33", + "selectedBackground": "#f0f0f1", + "rangeSelectedBackground": "#2b2e33", + "color": "#ffffff", + "hoverColor": "#ffffff", + "selectedColor": "#ffffff", + "rangeSelectedColor": "#ffffff", + "width": 32, + "height": 32, + "borderRadius": 8, + "padding": 4, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "monthView": { + "marginTop": 0, + "marginRight": 0, + "marginBottom": 0, + "marginLeft": 0 + }, + "month": { "padding": 0, "borderRadius": 0 }, + "yearView": { + "marginTop": 0, + "marginRight": 0, + "marginBottom": 0, + "marginLeft": 0 + }, + "year": { "padding": 0, "borderRadius": 0 }, + "buttonbar": { "padding": 14, "borderColor": "#404348" }, + "timePicker": { + "padding": 14, + "borderColor": "#404348", + "gap": 8, + "buttonGap": 4 + }, + "root": { "transitionDuration": 180 } + }, + "dialog": { + "extend": { "borderWidth": 1, "backdrop": "rgba(0, 0, 0, 0.6000)" }, + "root": { + "background": "#404348", + "borderColor": "#404348", + "color": "#ffffff", + "borderRadius": 1600, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "header": { + "paddingTop": 24, + "paddingRight": 24, + "paddingBottom": 14, + "paddingLeft": 24, + "gap": 8 + }, + "title": { "fontSize": 20, "fontWeight": "600" }, + "content": { "padding": 24 }, + "footer": { + "paddingTop": 0, + "paddingRight": 24, + "paddingBottom": 24, + "paddingLeft": 24, + "gap": 8 + } + }, + "divider": { + "extend": { "content": { "gap": 8 }, "iconSize": 16 }, + "horizontal": { + "marginTop": 14, + "marginRight": 0, + "marginBottom": 14, + "marginLeft": 0, + "paddingTop": 0, + "paddingRight": 14, + "paddingBottom": 0, + "paddingLeft": 14, + "content": { + "paddingTop": 0, + "paddingRight": 8, + "paddingBottom": 0, + "paddingLeft": 8 + } + }, + "vertical": { + "marginTop": 0, + "marginRight": 14, + "marginBottom": 0, + "marginLeft": 14, + "paddingTop": 14, + "paddingRight": 0, + "paddingBottom": 14, + "paddingLeft": 0, + "content": { + "paddingTop": 8, + "paddingRight": 0, + "paddingBottom": 8, + "paddingLeft": 0 + } + }, + "content": { "background": "#404348", "color": "#ffffff" }, + "root": { "borderColor": "#404348" } + }, + "drawer": { + "extend": { + "borderRadius": 8, + "borderWidth": 1, + "width": 400, + "extHeader": { "gap": 8, "borderColor": "#404348" }, + "margin": 8, + "scale": 2, + "backdrop": "rgba(0, 0, 0, 0.6000)" + }, + "root": { + "background": "#404348", + "borderColor": "#404348", + "color": "#ffffff", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "header": { + "paddingTop": 24, + "paddingRight": 24, + "paddingBottom": 14, + "paddingLeft": 24 + }, + "title": { "fontSize": 20, "fontWeight": "600" }, + "content": { "padding": 24 }, + "footer": { + "paddingTop": 0, + "paddingRight": 24, + "paddingBottom": 24, + "paddingLeft": 24 + } + }, + "fileupload": { + "extend": { + "extDragNdrop": { + "background": "#56595f", + "borderRadius": 14, + "iconSize": 32, + "padding": 14, + "info": { "gap": 4 } + }, + "extFile": { "iconSize": 20 }, + "extContent": { "borderRadius": 14, "highlightBorderDefault": "#56595f" } + }, + "colorScheme": { + "header": { "background": "#404348", "color": "#2b2e33" } + }, + "root": { + "background": "#404348", + "borderColor": "#404348", + "color": "#ffffff", + "borderRadius": 14, + "transitionDuration": 180 + }, + "header": { + "borderColor": "#404348", + "borderWidth": 0, + "padding": 0, + "borderRadius": 0, + "gap": 8 + }, + "content": { "highlightBorderColor": "#f0f0f1", "padding": 0, "gap": 8 }, + "file": { + "padding": 8, + "gap": 8, + "borderColor": "#56595f", + "info": { "gap": 4 } + }, + "fileList": { "gap": 8 }, + "progressbar": { "height": 8 }, + "basic": { "gap": 8 } + }, + "floatlabel": { + "extend": { "height": 64, "iconSize": 20 }, + "root": { + "color": "#a2a5a9", + "focusColor": "#a2a5a9", + "activeColor": "#a2a5a9", + "invalidColor": "#fbacaa", + "transitionDuration": 180, + "positionX": 14, + "positionY": 14, + "fontWeight": "400", + "active": { "fontSize": 12, "fontWeight": "400" } + }, + "over": { "active": { "top": 14 } }, + "inside": { + "input": { "paddingTop": 28, "paddingBottom": 14 }, + "active": { "top": 14 } + }, + "on": { + "borderRadius": 0, + "active": { + "paddingTop": 0, + "paddingRight": 4, + "paddingBottom": 0, + "paddingLeft": 4, + "background": "#56595f" + } + } + }, + "galleria": { + "extend": { "backdrop": "rgba(0, 0, 0, 0.6000)" }, + "colorScheme": { + "indicatorButton": { + "background": "#cecfd2", + "hoverBackground": "#6d7076" + }, + "thumbnailNavButton": { + "color": "#2b2e33", + "hoverBackground": "#404348", + "hoverColor": "#56595f" + }, + "thumbnailsContent": { "background": "#404348" }, + "thumbnailContent": { "background": "#f0f0f1" } + }, + "root": { + "borderWidth": 1, + "borderColor": "#404348", + "borderRadius": 14, + "transitionDuration": 180 + }, + "navButton": { + "background": "transparent", + "hoverBackground": "#404348", + "color": "#2b2e33", + "hoverColor": "#56595f", + "size": 64, + "gutter": 8, + "prev": { "borderRadius": 8 }, + "next": { "borderRadius": 8 }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "navIcon": { "size": 32 }, + "thumbnailsContent": { "padding": 4 }, + "thumbnailNavButton": { + "size": 32, + "borderRadius": 14, + "gutter": 8, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "thumbnailNavButtonIcon": { "size": 16 }, + "caption": { "background": "#404348", "color": "#ffffff", "padding": 8 }, + "indicatorList": { "gap": 8, "padding": 14 }, + "indicatorButton": { + "width": 8, + "height": 8, + "activeBackground": "#f0f0f1", + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "insetIndicatorList": { "background": "rgba(0, 0, 0, 0.6000)" }, + "insetIndicatorButton": { + "background": "#404348", + "hoverBackground": "#404348", + "activeBackground": "#404348" + }, + "closeButton": { + "size": 64, + "gutter": 8, + "background": "#404348", + "hoverBackground": "#404348", + "color": "#2b2e33", + "hoverColor": "#56595f", + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "closeButtonIcon": { "size": 32 } + }, + "inputgroup": { + "extend": { "borderWidth": 1, "iconSize": 16 }, + "colorScheme": { + "addon": { + "background": "#56595f", + "borderColor": "#56595f", + "color": "#85888e" + } + }, + "addon": { "borderRadius": 14, "padding": 14, "minWidth": 272 } + }, + "inputnumber": { + "extend": { + "borderWidth": 1, + "extButton": { "height": 40, "iconSize": 16 } + }, + "colorScheme": { + "button": { + "activeBackground": "transparent", + "activeBorderColor": "#56595f", + "activeColor": "#2b2e33", + "background": "#56595f", + "borderColor": "#56595f", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1", + "hoverBorderColor": "#56595f", + "hoverColor": "#56595f" + } + }, + "transitionDuration": { "transitionDuration": 180 }, + "button": { "width": 272, "borderRadius": 14, "verticalPadding": 14 }, + "root": { "transitionDuration": 180 } + }, + "inputotp": { + "extend": { "height": 40, "borderWidth": 1 }, + "root": { "gap": 8 }, + "input": { "width": 304, "lg": { "width": 336 }, "sm": { "width": 272 } }, + "sm": { "width": 0 }, + "lg": { "width": 0 } + }, + "inputtext": { + "extend": { + "readonlyBackground": "#2b2e33", + "iconSize": 16, + "borderWidth": 1, + "extXlg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 } + }, + "root": { + "background": "#404348", + "disabledBackground": "#404348", + "filledBackground": "#404348", + "filledHoverBackground": "#404348", + "filledFocusBackground": "#404348", + "borderColor": "#56595f", + "hoverBorderColor": "#77f48a", + "focusBorderColor": "#77f48a", + "invalidBorderColor": "#db3424", + "color": "#ffffff", + "disabledColor": "#a2a5a9", + "placeholderColor": "#a2a5a9", + "invalidPlaceholderColor": "#fbacaa", + "shadow": "none", + "paddingX": 14, + "paddingY": 14, + "borderRadius": 14, + "transitionDuration": 180, + "sm": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "lg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + } + } + }, + "listbox": { + "extend": { + "extOption": { + "label": { "gap": 4 }, + "caption": { "color": "#a2a5a9", "stripedColor": "#a2a5a9" }, + "gap": 8 + } + }, + "colorScheme": { "option": { "stripedBackground": "#6d7076" } }, + "root": { + "background": "#404348", + "disabledBackground": "#404348", + "borderColor": "#56595f", + "invalidBorderColor": "#db3424", + "color": "#f0f0f1", + "disabledColor": "#a2a5a9", + "shadow": "none", + "borderRadius": 14, + "transitionDuration": 180 + }, + "list": { + "padding": 4, + "gap": 4, + "header": { + "paddingTop": 14, + "paddingRight": 14, + "paddingBottom": 0, + "paddingLeft": 14 + } + }, + "option": { + "focusBackground": "#2b2e33", + "selectedBackground": "#f0f0f1", + "selectedFocusBackground": "#cecfd2", + "color": "#ffffff", + "focusColor": "#ffffff", + "selectedColor": "#ffffff", + "selectedFocusColor": "#ffffff", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8 + }, + "optionGroup": { + "background": "#56595f", + "color": "#a2a5a9", + "fontWeight": "600", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "checkmark": { "color": "#ffffff", "gutterStart": -8, "gutterEnd": 8 }, + "emptyMessage": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + } + }, + "megamenu": { + "extend": { + "extItem": { "caption": { "color": "#a2a5a9", "gap": 4 } }, + "iconSize": 20 + }, + "colorScheme": { "root": { "background": "transparent" } }, + "root": { + "borderColor": "transparent", + "borderRadius": 14, + "color": "#ffffff", + "gap": 4, + "transitionDuration": 180, + "verticalOrientation": { "padding": 4, "gap": 4 }, + "horizontalOrientation": { "padding": 4, "gap": 4 } + }, + "baseItem": { + "borderRadius": 14, + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "item": { + "focusBackground": "#2b2e33", + "activeBackground": "#f0f0f1", + "color": "#ffffff", + "focusColor": "#ffffff", + "activeColor": "#181a1f", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "gap": 8, + "icon": { + "color": "#ffffff", + "focusColor": "#ffffff", + "activeColor": "#181a1f" + } + }, + "overlay": { + "padding": 4, + "background": "#404348", + "borderColor": "#404348", + "borderRadius": 14, + "color": "#ffffff", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "gap": 0 + }, + "submenu": { "padding": 4, "gap": 4 }, + "submenuLabel": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "background": "transparent", + "color": "#a2a5a9", + "fontWeight": "600" + }, + "submenuIcon": { + "size": 20, + "color": "#ffffff", + "focusColor": "#ffffff", + "activeColor": "#181a1f" + }, + "separator": { "borderColor": "#404348" }, + "mobileButton": { + "borderRadius": 8, + "size": 32, + "color": "#ffffff", + "hoverColor": "#cecfd2", + "hoverBackground": "#2b2e33", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "menu": { + "extend": { + "paddingX": 4, + "iconSize": 20, + "paddingY": 4, + "extItem": { + "caption": { "gap": 4, "color": "#a2a5a9" }, + "activeBackground": "#f0f0f1", + "activeColor": "#181a1f", + "icon": { "activeColor": "#181a1f" } + } + }, + "root": { + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "transitionDuration": 180, + "background": "#404348", + "borderColor": "#404348", + "color": "#ffffff" + }, + "list": { "padding": 4, "gap": 4 }, + "submenuLabel": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "fontWeight": "600", + "background": "transparent", + "color": "#a2a5a9" + }, + "separator": { "borderColor": "#404348" }, + "item": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "gap": 8, + "color": "#ffffff", + "focusBackground": "#2b2e33", + "focusColor": "#cecfd2", + "icon": { "color": "#ffffff", "focusColor": "#cecfd2" } + } + }, + "menubar": { + "extend": { + "iconSize": 20, + "extItem": { "caption": { "color": "#a2a5a9", "gap": 4 } }, + "extSubmenuLabel": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "fontWeight": "600", + "background": "transparent", + "color": "#a2a5a9" + } + }, + "colorScheme": { "root": { "background": "transparent" } }, + "root": { + "borderColor": "transparent", + "borderRadius": 8, + "color": "#ffffff", + "gap": 4, + "padding": 4, + "transitionDuration": 180 + }, + "baseItem": { + "borderRadius": 8, + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "item": { + "focusBackground": "#2b2e33", + "activeBackground": "#f0f0f1", + "color": "#ffffff", + "focusColor": "#ffffff", + "activeColor": "#181a1f", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "gap": 8, + "icon": { + "color": "#ffffff", + "focusColor": "#ffffff", + "activeColor": "#181a1f" + } + }, + "submenu": { + "padding": 4, + "gap": 4, + "background": "#56595f", + "borderColor": "#404348", + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "mobileIndent": 14, + "icon": { + "size": 20, + "color": "#ffffff", + "focusColor": "#ffffff", + "activeColor": "#181a1f" + } + }, + "separator": { "borderColor": "#404348" }, + "mobileButton": { + "borderRadius": 8, + "size": 32, + "color": "#ffffff", + "hoverColor": "#cecfd2", + "hoverBackground": "#2b2e33", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "message": { + "extend": { + "width": 400, + "extText": { "gap": 4 }, + "extInfo": { + "color": "#77baf4", + "closeButton": { "color": "#77baf4", "borderColor": "#4496e8" }, + "caption": { "color": "#ffffff" } + }, + "extAccentLine": { "width": 4 }, + "extCloseButton": { "width": 1 }, + "extSuccess": { + "color": "#77f48a", + "closeButton": { "color": "#77f48a", "borderColor": "#44e858" }, + "caption": { "color": "#ffffff" } + }, + "extWarn": { + "color": "#facb75", + "closeButton": { "color": "#facb75", "borderColor": "#f5b83d" }, + "caption": { "color": "#ffffff" } + }, + "extError": { + "color": "#f47f77", + "closeButton": { "color": "#f47f77", "borderColor": "#e85244" }, + "caption": { "color": "#ffffff" } + } + }, + "colorScheme": { + "contrast": { + "background": "#2b2e33", + "borderColor": "transparent", + "closeButton": { + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "transparent" + }, + "color": "#ffffff", + "outlined": { "borderColor": "transparent", "color": "transparent" }, + "shadow": "none", + "simple": { "color": "transparent" } + }, + "error": { + "background": "#3b100c", + "borderColor": "#e85244", + "closeButton": { + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "#611912" + }, + "color": "#2b2e33", + "outlined": { "borderColor": "#e85244", "color": "#2b2e33" }, + "shadow": "none", + "simple": { "color": "#2b2e33" } + }, + "info": { + "background": "#0c243b", + "borderColor": "#4496e8", + "closeButton": { + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "#123a61" + }, + "color": "#2b2e33", + "outlined": { "borderColor": "#4496e8", "color": "#2b2e33" }, + "shadow": "none", + "simple": { "color": "#2b2e33" } + }, + "secondary": { + "background": "#f0f0f1", + "borderColor": "transparent", + "closeButton": { + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "transparent" + }, + "color": "#2b2e33", + "outlined": { "borderColor": "transparent", "color": "transparent" }, + "shadow": "none", + "simple": { "color": "transparent" } + }, + "success": { + "background": "#0c3b11", + "borderColor": "#44e858", + "closeButton": { + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "#12611b" + }, + "color": "#2b2e33", + "outlined": { "borderColor": "#44e858", "color": "#2b2e33" }, + "shadow": "none", + "simple": { "color": "#2b2e33" } + }, + "warn": { + "background": "#453008", + "borderColor": "#f5b83d", + "closeButton": { + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "#6d4c0b" + }, + "color": "#2b2e33", + "outlined": { "borderColor": "#f5b83d", "color": "#2b2e33" }, + "shadow": "none", + "simple": { "color": "#2b2e33" } + }, + "outlined": { + "root": { "borderWidth": 0 }, + "closeButton": { + "hoverBackground": "transparent", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "outlined": { "color": "transparent", "borderColor": "transparent" }, + "simple": { "color": "transparent" } + }, + "simple": { "content": { "padding": 0 } } + }, + "root": { "borderRadius": 14, "borderWidth": 1, "transitionDuration": 180 }, + "content": { + "padding": 14, + "gap": 14, + "sm": { "padding": 14 }, + "lg": { "padding": 14 } + }, + "text": { + "fontSize": 16, + "fontWeight": "700", + "sm": { "fontSize": 16 }, + "lg": { "fontSize": 16 } + }, + "icon": { "size": 36, "sm": { "size": 36 }, "lg": { "size": 36 } }, + "closeButton": { + "width": 32, + "height": 32, + "borderRadius": 14, + "focusRing": { "width": 4, "style": "none", "offset": 0 } + }, + "closeIcon": { "size": 16, "sm": { "size": 16 }, "lg": { "size": 16 } }, + "outlined": { "root": { "borderWidth": 1 } }, + "simple": { "content": { "padding": 0 } } + }, + "metergroup": { + "extend": { "extLabel": { "color": "#a2a5a9" } }, + "root": { "borderRadius": 14, "gap": 14 }, + "meters": { "size": 8, "background": "#404348" }, + "label": { "gap": 4 }, + "labelMarker": { "size": 8 }, + "labelIcon": { "size": 16 }, + "labelList": { "verticalGap": 8, "horizontalGap": 14 } + }, + "multiselect": { + "extend": { + "paddingX": 6, + "paddingY": 6, + "borderWidth": 1, + "iconSize": 16, + "width": 272, + "readonlyBackground": "#2b2e33" + }, + "root": { + "shadow": "none", + "paddingX": 14, + "paddingY": 14, + "borderRadius": 14, + "transitionDuration": 180, + "sm": { "fontSize": 16, "paddingX": 8, "paddingY": 8 }, + "lg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "focusRing": { + "width": 4, + "style": "none", + "offset": 0, + "shadow": "none", + "color": "#d4fedc" + }, + "background": "#404348", + "borderColor": "#56595f", + "color": "#ffffff", + "disabledBackground": "#404348", + "disabledColor": "#a2a5a9", + "filledBackground": "#404348", + "filledFocusBackground": "#404348", + "filledHoverBackground": "#404348", + "focusBorderColor": "#77f48a", + "hoverBorderColor": "#77f48a", + "invalidBorderColor": "#db3424", + "invalidPlaceholderColor": "#fbacaa", + "placeholderColor": "#a2a5a9" + }, + "dropdown": { "width": 272, "color": "#f0f0f1" }, + "overlay": { + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "background": "#404348", + "borderColor": "#404348", + "color": "#ffffff" + }, + "list": { + "padding": 4, + "header": { + "paddingTop": 14, + "paddingRight": 14, + "paddingBottom": 0, + "paddingLeft": 14 + }, + "gap": 4 + }, + "chip": { "borderRadius": 8 }, + "option": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "gap": 8, + "color": "#ffffff", + "focusBackground": "#2b2e33", + "focusColor": "#ffffff", + "selectedBackground": "#f0f0f1", + "selectedColor": "#ffffff", + "selectedFocusBackground": "#cecfd2", + "selectedFocusColor": "#ffffff" + }, + "optionGroup": { + "fontWeight": "600", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "background": "#56595f", + "color": "#a2a5a9" + }, + "emptyMessage": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "clearIcon": { "color": "#f0f0f1" } + }, + "paginator": { + "root": { + "paddingTop": 0, + "paddingRight": 8, + "paddingBottom": 0, + "paddingLeft": 8, + "gap": 8, + "borderRadius": 14, + "background": "transparent", + "color": "#ffffff", + "transitionDuration": 180 + }, + "currentPageReport": { "color": "#a2a5a9" }, + "navButton": { + "background": "transparent", + "hoverBackground": "#2b2e33", + "selectedBackground": "#f0f0f1", + "color": "#ffffff", + "hoverColor": "#cecfd2", + "selectedColor": "#ffffff", + "width": 40, + "height": 40, + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "focus": "0 0 4px rgba(0, 0, 0, 0.2000)", + "shadow": "none" + } + }, + "jumpToPageInput": { "maxWidth": 80 } + }, + "panelmenu": { + "extend": { + "iconSize": 20, + "extPanel": { "gap": 4 }, + "extItem": { + "activeBackground": "#f0f0f1", + "activeColor": "#181a1f", + "caption": { "color": "#a2a5a9", "gap": 4 } + } + }, + "root": { "gap": 4, "transitionDuration": 180 }, + "panel": { + "background": "transparent", + "borderColor": "transparent", + "borderWidth": 1, + "color": "#ffffff", + "padding": 4, + "borderRadius": 14, + "first": { + "borderTopWidth": 1, + "borderRightWidth": 1, + "borderBottomWidth": 0, + "borderLeftWidth": 1, + "topBorderRadius": 14 + }, + "last": { + "borderTopWidth": 0, + "borderRightWidth": 1, + "borderBottomWidth": 1, + "borderLeftWidth": 1, + "topBorderRadius": 14, + "bottomBorderRadius": 14 + } + }, + "item": { + "focusBackground": "#2b2e33", + "color": "#ffffff", + "focusColor": "#ffffff", + "gap": 8, + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "icon": { "color": "#ffffff", "focusColor": "#ffffff" } + }, + "submenu": { "indent": 24 }, + "separator": { "borderColor": "#404348" }, + "submenuIcon": { "color": "#ffffff", "focusColor": "#ffffff" } + }, + "password": { + "extend": { "borderWidth": 1 }, + "colorScheme": { + "strength": { + "mediumBackground": "#f5b83d", + "strongBackground": "#1dc831", + "weakBackground": "#e85244" + }, + "icon": { "color": "#85888e" } + }, + "meter": { "background": "#404348", "borderRadius": 14, "height": 8 }, + "overlay": { + "background": "#404348", + "borderColor": "#56595f", + "borderRadius": 8, + "color": "#ffffff", + "padding": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "content": { "gap": 8 }, + "icon": { "color": "#ffffff" } + }, + "popover": { + "extend": { "borderWidth": 1, "arrow": { "width": 12, "height": 8 } }, + "root": { + "background": "#404348", + "borderColor": "#56595f", + "color": "#ffffff", + "borderRadius": 8, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "gutter": 4, + "arrowOffset": 20 + }, + "content": { "padding": 14 } + }, + "progressbar": { + "label": { "color": "#ffffff", "fontSize": 12, "fontWeight": "400" }, + "root": { "background": "#404348", "borderRadius": 14, "height": 16 }, + "value": { "background": "#44e858" } + }, + "progressspinner": { + "extend": { "small": 16, "medium": 32, "large": 48, "xlarge": 56 }, + "colorScheme": { + "root": { + "colorFour": "#f5b83d", + "colorOne": "#44e858", + "colorThree": "#e85244", + "colorTwo": "#4496e8" + } + }, + "root": { "borderWidth": 4 } + }, + "radiobutton": { + "root": { + "width": 24, + "height": 24, + "background": "#404348", + "checkedBackground": "#f0f0f1", + "checkedHoverBackground": "#e2e2e4", + "disabledBackground": "#404348", + "filledBackground": "#404348", + "borderColor": "#56595f", + "hoverBorderColor": "#f0f0f1", + "focusBorderColor": "#56595f", + "checkedBorderColor": "#f0f0f1", + "checkedHoverBorderColor": "#f0f0f1", + "checkedFocusBorderColor": "#f0f0f1", + "checkedDisabledBorderColor": "#56595f", + "invalidBorderColor": "#db3424", + "shadow": "none", + "transitionDuration": 180, + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + }, + "lg": { "height": 20, "width": 20 }, + "sm": { "height": 8, "width": 8 } + }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "sm": { "width": 16, "height": 16 }, + "lg": { "width": 20, "height": 20 }, + "icon": { + "size": 12, + "checkedColor": "#ffffff", + "checkedHoverColor": "#ffffff", + "disabledColor": "#a2a5a9", + "sm": { "size": 8 }, + "lg": { "size": 16 } + } + }, + "rating": { + "root": { + "gap": 8, + "transitionDuration": 180, + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + } + }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "icon": { + "size": 24, + "color": "#a2a5a9", + "hoverColor": "#facb75", + "activeColor": "#facb75" + } + }, + "ripple": { "colorScheme": { "root": { "background": "#404348" } } }, + "scrollpanel": { + "colorScheme": { "bar": { "background": "#cecfd2" } }, + "root": { "transitionDuration": 180 }, + "bar": { + "size": 8, + "borderRadius": 8, + "focusRing": { + "width": 0, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "select": { + "extend": { + "extOption": { "background": "#56595f", "gap": 8 }, + "extOptionGroup": { "gap": 8 }, + "readonlyBackground": "#2b2e33", + "borderWidth": 1, + "iconSize": 16 + }, + "root": { + "background": "#404348", + "disabledBackground": "#404348", + "filledBackground": "#404348", + "filledHoverBackground": "#404348", + "filledFocusBackground": "#404348", + "borderColor": "#56595f", + "hoverBorderColor": "#77f48a", + "focusBorderColor": "#77f48a", + "invalidBorderColor": "#db3424", + "color": "#ffffff", + "disabledColor": "#a2a5a9", + "placeholderColor": "#a2a5a9", + "invalidPlaceholderColor": "#fbacaa", + "shadow": "none", + "paddingX": 14, + "paddingY": 14, + "borderRadius": 14, + "transitionDuration": 180, + "sm": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "lg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + } + }, + "dropdown": { "width": 272, "color": "#f0f0f1" }, + "overlay": { + "background": "#404348", + "borderColor": "#404348", + "borderRadius": 14, + "color": "#ffffff", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "list": { + "padding": 4, + "gap": 4, + "header": { + "paddingTop": 14, + "paddingRight": 14, + "paddingBottom": 0, + "paddingLeft": 14 + } + }, + "option": { + "focusBackground": "#2b2e33", + "selectedBackground": "#f0f0f1", + "selectedFocusBackground": "#cecfd2", + "color": "#ffffff", + "focusColor": "#ffffff", + "selectedColor": "#ffffff", + "selectedFocusColor": "#ffffff", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8 + }, + "optionGroup": { + "background": "#56595f", + "color": "#a2a5a9", + "fontWeight": "600", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "clearIcon": { "color": "#f0f0f1" }, + "checkmark": { "color": "#ffffff", "gutterStart": -8, "gutterEnd": 8 }, + "emptyMessage": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + } + }, + "selectbutton": { + "extend": { + "gap": 4, + "paddingX": 4, + "paddingY": 4, + "iconSize": { "sm": 16, "md": 20, "lg": 24, "xlg": 28 }, + "checkedBackground": "#56595f", + "checkedBorderColor": "#2b2e33", + "checkedColor": "#f0f0f1", + "ext": { "borderRadius": 8 } + }, + "colorScheme": { + "root": { "invalidBorderColor": "#f47f77" }, + "extend": { "background": "#e2e2e4" } + }, + "root": { "borderRadius": 14 } + }, + "skeleton": { + "extend": { "minWidth": 32, "height": 32 }, + "colorScheme": { + "root": { "background": "#56595f", "animationBackground": "#6d7076" } + }, + "root": { "borderRadius": 14 } + }, + "slider": { + "colorScheme": { "handle": { "content": { "background": "#2b2e33" } } }, + "root": { "transitionDuration": 180 }, + "track": { "background": "#404348", "borderRadius": 14, "size": 4 }, + "range": { "background": "#f0f0f1" }, + "handle": { + "width": 20, + "height": 20, + "borderRadius": 1600, + "background": "#f0f0f1", + "hoverBackground": "#f0f0f1", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "content": { + "borderRadius": 1600, + "hoverBackground": "#f0f0f1", + "width": 12, + "height": 12, + "shadow": "none" + } + } + }, + "splitter": { + "colorScheme": { "handle": { "background": "#2b2e33" } }, + "gutter": { "background": "#2b2e33" }, + "root": { + "background": "#404348", + "borderColor": "#404348", + "color": "#ffffff", + "transitionDuration": 180 + }, + "handle": { + "size": 4, + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "stepper": { + "extend": { + "extCaption": { "gap": 4 }, + "extStepNumber": { + "invalidBackground": "#db3424", + "invalidColor": "#fff0f0", + "invalidBorderColor": "#db3424", + "borderWidth": 1, + "iconSize": 24 + } + }, + "root": { "transitionDuration": 180 }, + "separator": { + "background": "#404348", + "activeBackground": "#f0f0f1", + "marginTop": 0, + "marginRight": 0, + "marginBottom": 0, + "marginLeft": 24, + "size": 1 + }, + "step": { "padding": 8, "gap": 8 }, + "stepHeader": { + "padding": 0, + "borderRadius": 0, + "gap": 8, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "stepTitle": { + "color": "#ffffff", + "activeColor": "#ffffff", + "fontWeight": "400" + }, + "stepNumber": { + "background": "#56595f", + "activeBackground": "#44e858", + "borderColor": "#404348", + "activeBorderColor": "#44e858", + "color": "#ffffff", + "activeColor": "#ffffff", + "size": 24, + "fontSize": 16, + "fontWeight": "700", + "borderRadius": 1600, + "shadow": "none" + }, + "steppanels": { "padding": 14 }, + "steppanel": { + "background": "#56595f", + "color": "#ffffff", + "padding": 0, + "indent": 0 + } + }, + "steps": { + "itemLink": { + "gap": 8, + "borderRadius": 14, + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + } + }, + "itemLabel": { + "fontWeight": "400", + "activeColor": "#cecfd2", + "color": "#ffffff" + }, + "itemNumber": { + "background": "#56595f", + "size": 32, + "fontSize": 16, + "fontWeight": "700", + "borderRadius": 1600, + "shadow": "none", + "activeBackground": "#56595f", + "activeBorderColor": "#404348", + "activeColor": "#cecfd2", + "borderColor": "#404348", + "color": "#ffffff" + }, + "root": { "transitionDuration": 180 }, + "separator": { "background": "#404348" } + }, + "tabs": { + "colorScheme": { + "navButton": { "shadow": "none" }, + "tab": { + "activeBackground": "transparent", + "background": "transparent", + "hoverBackground": "transparent" + } + }, + "root": { "transitionDuration": 180 }, + "tablist": { + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "background": "transparent", + "borderColor": "#404348" + }, + "tab": { + "borderWidth": 0, + "borderColor": "#404348", + "hoverBorderColor": "#404348", + "activeBorderColor": "#e2e2e4", + "color": "#a2a5a9", + "hoverColor": "#ffffff", + "activeColor": "#ffffff", + "padding": 14, + "fontWeight": "600", + "margin": 0, + "gap": 8, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "tabpanel": { + "background": "transparent", + "color": "#ffffff", + "padding": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "navButton": { + "background": "#56595f", + "color": "#ffffff", + "hoverColor": "#cecfd2", + "width": 24, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "activeBar": { "height": 2, "bottom": -2, "background": "#f0f0f1" } + }, + "toast": { + "extend": { + "extInfo": { + "color": "#77baf4", + "closeButton": { "color": "#77baf4", "borderColor": "#4496e8" }, + "caption": { "color": "#ffffff" } + }, + "extAccentLine": { "width": 4 }, + "extCloseButton": { "width": 1 }, + "extSuccess": { + "color": "#77f48a", + "closeButton": { "color": "#77f48a", "borderColor": "#44e858" }, + "caption": { "color": "#ffffff" } + }, + "extWarn": { + "color": "#facb75", + "closeButton": { "color": "#facb75", "borderColor": "#f5b83d" }, + "caption": { "color": "#ffffff" } + }, + "extError": { + "color": "#f47f77", + "closeButton": { "color": "#f47f77", "borderColor": "#e85244" }, + "caption": { "color": "#ffffff" } + } + }, + "colorScheme": { + "contrast": { + "background": "#2b2e33", + "borderColor": "#2b2e33", + "closeButton": { + "focusRing": { "color": "#d4fedc", "shadow": "none" }, + "hoverBackground": "#404348" + }, + "color": "#ffffff", + "detailColor": "#e2e2e4", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "error": { + "background": "#3b100c", + "borderColor": "#e85244", + "closeButton": { + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "#611912" + }, + "color": "#2b2e33", + "detailColor": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "info": { + "background": "#0c243b", + "borderColor": "#4496e8", + "closeButton": { + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "#123a61" + }, + "color": "#2b2e33", + "detailColor": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "root": { "blur": 0 }, + "secondary": { + "background": "#f0f0f1", + "borderColor": "#56595f", + "closeButton": { + "focusRing": { "color": "#d4fedc", "shadow": "none" }, + "hoverBackground": "#f0f0f1" + }, + "color": "#2b2e33", + "detailColor": "#a2a5a9", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "success": { + "background": "#0c3b11", + "borderColor": "#44e858", + "closeButton": { + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "hoverBackground": "#12611b" + }, + "color": "#2b2e33", + "detailColor": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "warn": { + "background": "#453008", + "borderColor": "#f5b83d", + "closeButton": { + "focusRing": { "color": "#d4fedc", "shadow": "none" }, + "hoverBackground": "#6d4c0b" + }, + "color": "#2b2e33", + "detailColor": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + } + }, + "root": { + "width": 400, + "borderWidth": 1, + "borderRadius": 14, + "transitionDuration": 180 + }, + "icon": { "size": 36 }, + "content": { "padding": 14, "gap": 14 }, + "text": { "gap": 4 }, + "summary": { "fontWeight": "700", "fontSize": 16 }, + "detail": { "fontWeight": "400", "fontSize": 14 }, + "closeButton": { + "width": 32, + "height": 32, + "borderRadius": 14, + "focusRing": { "width": 4, "style": "none", "offset": 0 } + }, + "closeIcon": { "size": 16 } + }, + "tag": { + "colorScheme": { + "contrast": { "background": "#2b2e33", "color": "#ffffff" }, + "danger": { "background": "#8d2218", "color": "#fff0f0" }, + "info": { "background": "#18538d", "color": "#f0f9ff" }, + "primary": { "background": "#44e858", "color": "#2b2e33" }, + "secondary": { "background": "#e2e2e4", "color": "#2b2e33" }, + "success": { "background": "#77f48a", "color": "#f0fff3" }, + "warn": { "background": "#9d6d0e", "color": "#fff9f0" } + }, + "root": { + "fontSize": 12, + "fontWeight": "400", + "paddingTop": 4, + "paddingRight": 8, + "paddingBottom": 4, + "paddingLeft": 8, + "gap": 4, + "borderRadius": 8, + "roundedBorderRadius": 1600 + }, + "icon": { "size": 16 } + }, + "textarea": { + "extend": { + "readonlyBackground": "#2b2e33", + "borderWidth": 1, + "iconSize": 16, + "minHeight": 80 + }, + "root": { + "background": "#404348", + "disabledBackground": "#404348", + "filledBackground": "#404348", + "filledHoverBackground": "#404348", + "filledFocusBackground": "#404348", + "borderColor": "#56595f", + "hoverBorderColor": "#77f48a", + "focusBorderColor": "#77f48a", + "invalidBorderColor": "#db3424", + "color": "#f0f0f1", + "disabledColor": "#a2a5a9", + "placeholderColor": "#a2a5a9", + "invalidPlaceholderColor": "#fbacaa", + "shadow": "none", + "paddingX": 14, + "paddingY": 14, + "borderRadius": 14, + "transitionDuration": 180, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + }, + "lg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "sm": { "fontSize": 16, "paddingX": 14, "paddingY": 14 } + }, + "sm": { "fontSize": 16, "paddingX": 8, "paddingY": 8 }, + "lg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 } + }, + "tieredmenu": { + "extend": { + "iconSize": 20, + "extSubmenu": { "borderColor": "#404348", "background": "#56595f" }, + "extItem": { "caption": { "gap": 4, "color": "#a2a5a9" } } + }, + "root": { + "background": "#404348", + "borderColor": "transparent", + "color": "#ffffff", + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "transitionDuration": 180 + }, + "list": { "padding": 4, "gap": 4 }, + "item": { + "focusBackground": "#2b2e33", + "activeBackground": "#f0f0f1", + "color": "#ffffff", + "focusColor": "#ffffff", + "activeColor": "#181a1f", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "gap": 8, + "icon": { + "color": "#ffffff", + "focusColor": "#ffffff", + "activeColor": "#181a1f" + } + }, + "submenu": { "mobileIndent": 14 }, + "separator": { "borderColor": "#404348" }, + "submenuIcon": { + "activeColor": "#cecfd2", + "color": "#ffffff", + "focusColor": "#cecfd2", + "size": 14 + } + }, + "timeline": { + "extend": { "extEvent": { "gap": 4 } }, + "event": { "minHeight": 64 }, + "vertical": { + "eventContent": { + "paddingTop": 0, + "paddingRight": 20, + "paddingBottom": 0, + "paddingLeft": 20 + } + }, + "horizontal": { + "eventContent": { + "paddingTop": 20, + "paddingRight": 0, + "paddingBottom": 20, + "paddingLeft": 0 + } + }, + "eventMarker": { + "size": 16, + "borderRadius": 14, + "borderWidth": 4, + "background": "#56595f", + "borderColor": "#44e858", + "content": { + "borderRadius": 14, + "size": 12, + "background": "transparent", + "insetShadow": "none" + } + }, + "eventConnector": { "color": "#404348", "size": 1 } + }, + "togglebutton": { + "extend": { + "ext": { "gap": 14 }, + "iconSize": { "sm": 16, "md": 20, "lg": 24 }, + "iconOnlyWidth": 40, + "hoverBorderColor": "#56595f", + "checkedHoverColor": "#ffffff", + "checkedHoverBackground": "#e2e2e4", + "checkedHoverBorderColor": "#e2e2e4", + "extXlg": { + "paddingTop": 20, + "paddingRight": 20, + "paddingBottom": 20, + "paddingLeft": 20, + "iconOnlyWidth": 64 + }, + "extSm": { "iconOnlyWidth": 32 }, + "extLg": { "iconOnlyWidth": 56 } + }, + "colorScheme": { + "root": { + "hoverBackground": "#cecfd2", + "background": "#e2e2e4", + "borderColor": "#e2e2e4", + "color": "#2b2e33", + "hoverColor": "#2b2e33", + "checkedBackground": "#2b2e33", + "checkedColor": "#ffffff", + "checkedBorderColor": "#2b2e33", + "disabledBackground": "#e2e2e4", + "disabledBorderColor": "#e2e2e4", + "disabledColor": "#85888e", + "invalidBorderColor": "#f47f77" + }, + "icon": { + "color": "#2b2e33", + "hoverColor": "#2b2e33", + "checkedColor": "#ffffff", + "disabledColor": "#85888e" + }, + "content": { "checkedBackground": "transparent" } + }, + "root": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 1600, + "gap": 8, + "fontWeight": "600", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "sm": { + "fontSize": 14, + "paddingTop": 4, + "paddingRight": 14, + "paddingBottom": 4, + "paddingLeft": 14 + }, + "lg": { + "fontSize": 20, + "paddingTop": 14, + "paddingRight": 24, + "paddingBottom": 14, + "paddingLeft": 24 + }, + "transitionDuration": 180, + "background": "#404348", + "borderColor": "#404348", + "checkedBackground": "#404348", + "checkedBorderColor": "#404348", + "checkedColor": "#ffffff", + "color": "#ffffff", + "disabledBackground": "#404348", + "disabledBorderColor": "#404348", + "disabledColor": "#a2a5a9", + "hoverColor": "#cecfd2", + "invalidBorderColor": "#db3424" + }, + "content": { + "checkedShadow": "none", + "padding": 0, + "borderRadius": 0, + "sm": { "padding": 0 }, + "lg": { "padding": 0 }, + "checkedBackground": "#404348" + }, + "icon": { + "checkedColor": "#ffffff", + "color": "#ffffff", + "disabledColor": "#a2a5a9", + "hoverColor": "#cecfd2" + } + }, + "toggleswitch": { + "colorScheme": { + "handle": { + "background": "#56595f", + "checkedBackground": "#56595f", + "checkedColor": "#2b2e33", + "checkedHoverBackground": "#56595f", + "checkedHoverColor": "#2b2e33", + "color": "#2b2e33", + "disabledBackground": "#85888e", + "hoverBackground": "#56595f", + "hoverColor": "#2b2e33" + }, + "root": { + "background": "#6d7076", + "checkedBackground": "#2b2e33", + "checkedHoverBackground": "#404348", + "disabledBackground": "#e2e2e4", + "hoverBackground": "#85888e" + } + }, + "root": { + "width": 40, + "height": 24, + "borderRadius": 1600, + "gap": 4, + "borderWidth": 1, + "shadow": "none", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + }, + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "checkedBorderColor": "transparent", + "checkedHoverBorderColor": "transparent", + "invalidBorderColor": "#db3424", + "transitionDuration": 180, + "slideDuration": 180 + }, + "handle": { "borderRadius": 1600, "size": 16 } + }, + "tooltip": { + "colorScheme": { "root": { "background": "#2b2e33", "color": "#ffffff" } }, + "root": { + "maxWidth": 400, + "gutter": 4, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8 + } + }, + "tree": { + "root": { + "background": "#404348", + "color": "#ffffff", + "padding": 14, + "gap": 4, + "indent": 14, + "transitionDuration": 180 + }, + "node": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "color": "#ffffff", + "selectedColor": "#ffffff", + "gap": 4, + "borderRadius": 14, + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + }, + "hoverBackground": "#2b2e33", + "hoverColor": "#ffffff", + "selectedBackground": "#f0f0f1" + }, + "nodeIcon": { + "selectedColor": "#ffffff", + "color": "#ffffff", + "hoverColor": "#cecfd2" + }, + "nodeToggleButton": { + "borderRadius": 4, + "size": 28, + "selectedHoverBackground": "#f0f0f1", + "color": "#ffffff", + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + }, + "hoverBackground": "#2b2e33", + "hoverColor": "#cecfd2", + "selectedHoverColor": "#cecfd2" + }, + "loadingIcon": { "size": 16 }, + "filter": { + "marginTop": 0, + "marginRight": 0, + "marginBottom": 8, + "marginLeft": 0 + } + }, + "overlaybadge": { + "root": { "outline": { "width": 0, "color": "transparent" } } + } +} diff --git a/src/theme/tokens/components/light.json b/src/theme/tokens/components/light.json new file mode 100644 index 00000000..ab86e22f --- /dev/null +++ b/src/theme/tokens/components/light.json @@ -0,0 +1,2920 @@ +{ + "accordion": { + "extend": { "extHeader": { "iconSize": 20, "gap": 8 } }, + "colorScheme": { + "header": { + "background": "transparent", + "hoverBackground": "transparent", + "activeBackground": "transparent", + "activeHoverBackground": "transparent" + } + }, + "header": { + "color": "#2b2e33", + "hoverColor": "#56595f", + "activeColor": "#2b2e33", + "activeHoverColor": "#56595f", + "borderColor": "transparent", + "paddingTop": 14, + "paddingRight": 0, + "paddingBottom": 14, + "paddingLeft": 0, + "fontWeight": "700", + "borderRadius": 0, + "borderWidth": 0, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "inset 0 0 0 4px #d4fedc" + }, + "toggleIcon": { + "color": "#2b2e33", + "hoverColor": "#56595f", + "activeColor": "#2b2e33", + "activeHoverColor": "#56595f" + }, + "last": { "bottomBorderRadius": 0, "activeBottomBorderRadius": 0 }, + "first": { "borderWidth": 0, "topBorderRadius": 0 } + }, + "root": { "transitionDuration": 180 }, + "panel": { + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 4, + "borderLeftWidth": 0, + "borderColor": "#cecfd2" + }, + "content": { + "borderTopWidth": 1, + "borderRightWidth": 0, + "borderBottomWidth": 0, + "borderLeftWidth": 0, + "borderColor": "transparent", + "background": "transparent", + "color": "#2b2e33", + "paddingTop": 0, + "paddingRight": 24, + "paddingBottom": 14, + "paddingLeft": 24 + } + }, + "autocomplete": { + "extend": { "extOption": { "gap": 8 }, "extOptionGroup": { "gap": 8 } }, + "colorScheme": { + "chip": { "focusBackground": "#e2e2e4", "focusColor": "#2b2e33" }, + "dropdown": { + "background": "#ffffff", + "hoverBackground": "#ffffff", + "activeBackground": "#ffffff", + "color": "#181a1f", + "hoverColor": "#181a1f", + "activeColor": "#181a1f" + } + }, + "root": { + "background": "#ffffff", + "disabledBackground": "#e2e2e4", + "filledBackground": "#ffffff", + "filledHoverBackground": "#ffffff", + "filledFocusBackground": "#ffffff", + "borderColor": "#cecfd2", + "hoverBorderColor": "#1dc831", + "focusBorderColor": "#1dc831", + "invalidBorderColor": "#f47f77", + "color": "#181a1f", + "disabledColor": "#85888e", + "placeholderColor": "#85888e", + "invalidPlaceholderColor": "#db3424", + "shadow": "none", + "paddingX": 14, + "paddingY": 14, + "borderRadius": 14, + "transitionDuration": 180, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + } + }, + "overlay": { + "background": "#ffffff", + "borderColor": "#e2e2e4", + "borderRadius": 14, + "color": "#2b2e33", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "list": { "padding": 4, "gap": 4 }, + "option": { + "focusBackground": "#f0f0f1", + "selectedBackground": "#2b2e33", + "selectedFocusBackground": "#56595f", + "color": "#2b2e33", + "focusColor": "#2b2e33", + "selectedColor": "#ffffff", + "selectedFocusColor": "#ffffff", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8 + }, + "optionGroup": { + "background": "#ffffff", + "color": "#85888e", + "fontWeight": "600", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "dropdown": { + "width": 272, + "borderColor": "#cecfd2", + "hoverBorderColor": "#1dc831", + "activeBorderColor": "#1dc831", + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + }, + "sm": { "width": 240 }, + "lg": { "width": 304 } + }, + "chip": { "borderRadius": 8 }, + "emptyMessage": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + } + }, + "avatar": { + "extend": { "borderColor": "#cecfd2", "circle": { "borderRadius": 1600 } }, + "root": { + "width": 32, + "height": 32, + "fontSize": 16, + "color": "#2b2e33", + "background": "#44e858", + "borderRadius": 14 + }, + "icon": { "size": 16 }, + "group": { "borderColor": "#ffffff", "offset": -12 }, + "lg": { + "width": 40, + "height": 40, + "fontSize": 16, + "icon": { "size": 16 }, + "group": { "offset": -12 } + }, + "xl": { + "width": 56, + "height": 56, + "icon": { "size": 24 }, + "group": { "offset": -24 }, + "fontSize": 16 + } + }, + "badge": { + "extend": { + "extDot": { + "success": { "background": "#77f48a" }, + "info": { "background": "#77baf4" }, + "warn": { "background": "#facb75" }, + "danger": { "background": "#f47f77" }, + "lg": { "size": 12 }, + "xlg": { "size": 16 } + }, + "ext": { "padding": 0 } + }, + "colorScheme": { + "primary": { "color": "#2b2e33", "background": "#44e858" }, + "secondary": { "color": "#ffffff", "background": "#2b2e33" }, + "success": { "color": "#0e4514", "background": "#aafbb7" }, + "info": { "color": "#0e2a45", "background": "#aad7fb" }, + "warn": { "color": "#4f3709", "background": "#fddeaa" }, + "danger": { "color": "#45120e", "background": "#fbacaa" }, + "contrast": { "background": "#2b2e33", "color": "#ffffff" } + }, + "root": { + "borderRadius": 8, + "padding": 8, + "fontSize": 12, + "fontWeight": "400", + "minWidth": 24, + "height": 24 + }, + "dot": { "size": 8 }, + "sm": { "fontSize": 12, "minWidth": 0, "height": 0 }, + "lg": { "fontSize": 12, "minWidth": 28, "height": 28 }, + "xl": { "fontSize": 12, "minWidth": 32, "height": 32 } + }, + "breadcrumb": { + "extend": { + "hoverBackground": "#f0f0f1", + "iconSize": 20, + "extItem": { "padding": 4 } + }, + "root": { + "padding": 0, + "background": "transparent", + "gap": 0, + "transitionDuration": 180 + }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "item": { + "color": "#2b2e33", + "hoverColor": "#56595f", + "borderRadius": 4, + "gap": 8, + "icon": { "color": "#2b2e33", "hoverColor": "#56595f" }, + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + } + }, + "separator": { "color": "#2b2e33" } + }, + "button": { + "extend": { + "disabledBackground": "#e2e2e4", + "extOutlined": { + "danger": { "focusBackground": "transparent" }, + "warn": { "focusBackground": "transparent" }, + "info": { "focusBackground": "transparent" }, + "help": { "focusBackground": "transparent" }, + "success": { "focusBackground": "transparent" } + }, + "disabledColor": "#85888e", + "extText": { + "danger": { "focusBackground": "transparent" }, + "warn": { "focusBackground": "transparent" }, + "info": { "focusBackground": "transparent" }, + "help": { "focusBackground": "transparent" }, + "success": { "focusBackground": "transparent" } + }, + "extLink": { + "background": "transparent", + "colorHover": "#56595f", + "paddingX": 0, + "paddingY": 4, + "sm": { "iconOnlyWidth": 16 }, + "base": { "iconOnlyWidth": 24 }, + "lg": { "iconOnlyWidth": 28 }, + "xlg": { "iconOnlyWidth": 32 } + }, + "extSm": { "borderRadius": 14, "gap": 8 }, + "extLg": { "borderRadius": 14, "gap": 14, "height": 56 }, + "extXlg": { + "borderRadius": 14, + "gap": 14, + "iconOnlyWidth": 64, + "paddingX": 24, + "paddingY": 20, + "height": 64 + }, + "borderWidth": 1, + "iconSize": { "sm": 16, "md": 20, "lg": 24 } + }, + "colorScheme": { + "root": { + "primary": { + "background": "#44e858", + "hoverBackground": "#1dc831", + "activeBackground": "#168322", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "#2b2e33", + "hoverColor": "#2b2e33", + "activeColor": "#2b2e33", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "secondary": { + "background": "#2b2e33", + "hoverBackground": "#404348", + "activeBackground": "#56595f", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "#ffffff", + "hoverColor": "#ffffff", + "activeColor": "#ffffff", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "contrast": { + "background": "#e2e2e4", + "hoverBackground": "#cecfd2", + "activeBackground": "#a2a5a9", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "#2b2e33", + "hoverColor": "#2b2e33", + "activeColor": "#2b2e33", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "info": { + "background": "#aad7fb", + "hoverBackground": "#77baf4", + "activeBackground": "#4496e8", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "#0e2a45", + "hoverColor": "#0c243b", + "activeColor": "#0e2a45", + "focusRing": { "color": "#d4fedc", "shadow": "none" } + }, + "success": { + "background": "#aafbb7", + "hoverBackground": "#77f48a", + "activeBackground": "#44e858", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "#0e4514", + "hoverColor": "#0c3b11", + "activeColor": "#0e4514", + "focusRing": { "color": "#d4fedc", "shadow": "none" } + }, + "warn": { + "background": "#fddeaa", + "hoverBackground": "#facb75", + "activeBackground": "#f5b83d", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "#4f3709", + "hoverColor": "#453008", + "activeColor": "#4f3709", + "focusRing": { "color": "#d4fedc", "shadow": "none" } + }, + "help": { + "background": "#d8b4fe", + "hoverBackground": "#c084fc", + "activeBackground": "#a855f7", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "#581c87", + "hoverColor": "#3b0764", + "activeColor": "#581c87", + "focusRing": { "color": "#d4fedc", "shadow": "none" } + }, + "danger": { + "background": "#fbacaa", + "hoverBackground": "#f47f77", + "activeBackground": "#e85244", + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "activeBorderColor": "transparent", + "color": "#45120e", + "hoverColor": "#3b100c", + "activeColor": "#45120e", + "focusRing": { "color": "#d4fedc", "shadow": "none" } + } + }, + "outlined": { + "primary": { + "hoverBackground": "#fafffb", + "activeBackground": "#f0fff3", + "borderColor": "#d4fedc", + "color": "#44e858" + }, + "success": { + "hoverBackground": "#f0fff3", + "activeBackground": "#d4fedc", + "borderColor": "#1dc831", + "color": "#1dc831" + }, + "info": { + "hoverBackground": "#f0f9ff", + "activeBackground": "#d4ecfe", + "borderColor": "#1e76cd", + "color": "#1e76cd" + }, + "warn": { + "hoverBackground": "#fff9f0", + "activeBackground": "#ffeed4", + "borderColor": "#dc9710", + "color": "#dc9710" + }, + "help": { + "hoverBackground": "#f3e8ff", + "activeBackground": "#e9d5ff", + "borderColor": "#9333ea", + "color": "#9333ea" + }, + "danger": { + "hoverBackground": "#fff0f0", + "activeBackground": "#fed4d4", + "borderColor": "#db3424", + "color": "#db3424" + }, + "contrast": { + "activeBackground": "#56595f", + "borderColor": "#2b2e33", + "color": "#ffffff", + "hoverBackground": "#404348" + }, + "plain": { + "activeBackground": "#e2e2e4", + "borderColor": "#cecfd2", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1" + }, + "secondary": { + "activeBackground": "#e2e2e4", + "borderColor": "#cecfd2", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1" + } + }, + "text": { + "primary": { + "hoverBackground": "#f0f0f1", + "activeBackground": "#e2e2e4", + "color": "#2b2e33" + }, + "success": { + "hoverBackground": "#f0fff3", + "activeBackground": "#d4fedc", + "color": "#1dc831" + }, + "info": { + "hoverBackground": "#f0f9ff", + "activeBackground": "#d4ecfe", + "color": "#1e76cd" + }, + "warn": { + "hoverBackground": "#fff9f0", + "activeBackground": "#ffeed4", + "color": "#dc9710" + }, + "help": { + "hoverBackground": "#f3e8ff", + "activeBackground": "#e9d5ff", + "color": "#9333ea" + }, + "danger": { + "hoverBackground": "#fff0f0", + "activeBackground": "#fed4d4", + "color": "#db3424" + }, + "contrast": { + "activeBackground": "#56595f", + "color": "#ffffff", + "hoverBackground": "#404348" + }, + "plain": { + "activeBackground": "#e2e2e4", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1" + }, + "secondary": { + "activeBackground": "#e2e2e4", + "color": "#2b2e33", + "hoverBackground": "#f0f0f1" + } + }, + "link": { + "color": "#2b2e33", + "hoverColor": "#56595f", + "activeColor": "#85888e" + } + }, + "root": { + "borderRadius": 14, + "roundedBorderRadius": 1600, + "gap": 8, + "paddingX": 14, + "paddingY": 8, + "iconOnlyWidth": 40, + "raisedShadow": "none", + "badgeSize": 16, + "transitionDuration": 180, + "focusRing": { "width": 4, "style": "none", "offset": 0 }, + "sm": { + "fontSize": 14, + "iconOnlyWidth": 32, + "paddingX": 14, + "paddingY": 8 + }, + "lg": { + "fontSize": 20, + "iconOnlyWidth": 56, + "paddingX": 24, + "paddingY": 14 + }, + "label": { "fontWeight": "600" } + } + }, + "card": { + "extend": { "borderColor": "#e2e2e4", "borderWidth": 1 }, + "root": { + "background": "#ffffff", + "borderRadius": 14, + "color": "#2b2e33", + "shadow": "none" + }, + "body": { "padding": 14, "gap": 14 }, + "caption": { "gap": 4 }, + "title": { "fontSize": 18, "fontWeight": "600" }, + "subtitle": { "color": "#85888e" } + }, + "carousel": { + "colorScheme": { + "indicator": { + "background": "#cecfd2", + "hoverBackground": "#a2a5a9", + "activeBackground": "#2b2e33" + } + }, + "root": { "transitionDuration": 180 }, + "content": { "gap": 8 }, + "indicatorList": { "padding": 14, "gap": 8 }, + "indicator": { + "width": 8, + "height": 8, + "borderRadius": 1600, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "checkbox": { + "root": { + "borderRadius": 8, + "extend": { "borderWidth": 1 }, + "width": 24, + "height": 24, + "background": "#ffffff", + "checkedBackground": "#2b2e33", + "checkedHoverBackground": "#404348", + "disabledBackground": "#e2e2e4", + "filledBackground": "#ffffff", + "borderColor": "#cecfd2", + "hoverBorderColor": "#2b2e33", + "focusBorderColor": "#2b2e33", + "checkedBorderColor": "#2b2e33", + "checkedHoverBorderColor": "#404348", + "checkedFocusBorderColor": "#44e858", + "checkedDisabledBorderColor": "#cecfd2", + "invalidBorderColor": "#f47f77", + "shadow": "none", + "focusRing": { + "focusRing": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)", + "width": 4 + }, + "sm": { "width": 8, "height": 8 }, + "lg": { "width": 20, "height": 20 }, + "transitionDuration": 180 + }, + "icon": { + "size": 16, + "color": "#181a1f", + "checkedColor": "#ffffff", + "checkedHoverColor": "#ffffff", + "disabledColor": "#85888e", + "sm": { "size": 12 }, + "lg": { "size": 20 } + } + }, + "chip": { + "extend": { "borderColor": "transparent", "borderWidth": 1 }, + "root": { + "borderRadius": 8, + "paddingX": 8, + "paddingY": 4, + "gap": 8, + "transitionDuration": 180 + }, + "colorScheme": { + "root": { "background": "#e2e2e4", "color": "#2b2e33" }, + "icon": { "color": "#2b2e33" }, + "removeIcon": { "color": "#2b2e33" } + }, + "image": { "width": 0, "height": 0 }, + "icon": { "size": 16 }, + "removeIcon": { + "size": 16, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "confirmdialog": { + "extend": { + "extIcon": { + "success": "#44e858", + "info": "#4496e8", + "help": "#a855f7", + "warn": "#f5b83d", + "danger": "#e85244" + } + }, + "icon": { "size": 24, "color": "#2b2e33" }, + "content": { "gap": 0 } + }, + "confirmpopup": { + "root": { + "background": "#ffffff", + "color": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "gutter": 14, + "arrowOffset": 20, + "borderColor": "#e2e2e4", + "borderRadius": 14 + }, + "content": { "padding": 14, "gap": 14 }, + "icon": { "size": 24, "color": "#2b2e33" }, + "footer": { + "gap": 8, + "paddingTop": 0, + "paddingRight": 24, + "paddingBottom": 24, + "paddingLeft": 24 + } + }, + "contextmenu": { + "root": { + "background": "#ffffff", + "color": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "borderColor": "#e2e2e4", + "borderRadius": 14, + "transitionDuration": 180 + }, + "list": { + "paddingTop": 8, + "paddingRight": 0, + "paddingBottom": 8, + "paddingLeft": 0, + "gap": 4 + }, + "item": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "gap": 8, + "activeBackground": "#e2e2e4", + "activeColor": "#56595f", + "borderRadius": 14, + "color": "#2b2e33", + "focusBackground": "#f0f0f1", + "focusColor": "#56595f", + "icon": { + "activeColor": "#56595f", + "color": "#2b2e33", + "focusColor": "#56595f" + } + }, + "submenu": { "mobileIndent": 20 }, + "separator": { "borderColor": "#e2e2e4" }, + "submenuIcon": { + "activeColor": "#56595f", + "color": "#2b2e33", + "focusColor": "#56595f", + "size": 14 + } + }, + "datatable": { + "colorScheme": { + "root": { "color": "#2b2e33", "borderColor": "#e2e2e4" }, + "header": { "background": "#fafafa", "color": "#2b2e33" }, + "headerCell": { + "background": "#fafafa", + "hoverBackground": "#f0f0f1", + "color": "#2b2e33" + }, + "footer": { "background": "#f0f0f1", "color": "#2b2e33" }, + "footerCell": { "background": "#f0f0f1", "color": "#2b2e33" }, + "row": { "stripedBackground": "#f0f0f1" }, + "bodyCell": { "selectedBorderColor": "#e2e2e4" } + }, + "extended": { + "extHeaderCell": { "selectedHoverBackground": "#404348" }, + "extRow": { + "selectedHoverBackground": "#404348", + "stripedHoverBackground": "#f0f0f1", + "iconSize": 20 + } + }, + "root": { "transitionDuration": 180 }, + "header": { + "borderColor": "#e2e2e4", + "borderTopWidth": 1, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "padding": 14, + "sm": { "padding": 8 }, + "lg": { "padding": 20 } + }, + "headerCell": { + "selectedBackground": "#2b2e33", + "borderColor": "#e2e2e4", + "hoverColor": "#56595f", + "selectedColor": "#ffffff", + "gap": 8, + "padding": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "inset 0 0 0 4px #d4fedc" + }, + "sm": { "padding": 8 }, + "lg": { "padding": 20 } + }, + "columnTitle": { "fontWeight": "700" }, + "row": { + "background": "#ffffff", + "hoverBackground": "#f0f0f1", + "selectedBackground": "#2b2e33", + "color": "#2b2e33", + "hoverColor": "#56595f", + "selectedColor": "#ffffff", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "inset 0 0 0 4px #d4fedc" + } + }, + "bodyCell": { + "borderColor": "#e2e2e4", + "padding": 14, + "sm": { "padding": 8 }, + "lg": { "padding": 20 } + }, + "footerCell": { + "borderColor": "#e2e2e4", + "padding": 14, + "sm": { "padding": 8 }, + "lg": { "padding": 20 } + }, + "columnFooter": { "fontWeight": "700" }, + "dropPoint": { "color": "#2b2e33" }, + "footer": { + "borderColor": "#e2e2e4", + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "padding": 14, + "sm": { "padding": 8 }, + "lg": { "padding": 20 } + }, + "columnResizer": { "width": 8 }, + "resizeIndicator": { "width": 1, "color": "#2b2e33" }, + "sortIcon": { "color": "#2b2e33", "hoverColor": "#56595f", "size": 16 }, + "loadingIcon": { "size": 32 }, + "rowToggleButton": { + "hoverBackground": "#f0f0f1", + "selectedHoverBackground": "#f0f0f1", + "color": "#2b2e33", + "hoverColor": "#2b2e33", + "selectedHoverColor": "#2b2e33", + "size": 32, + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "filter": { + "inlineGap": 8, + "rule": { "borderColor": "#e2e2e4" }, + "constraintList": { "padding": 4, "gap": 4 }, + "constraint": { + "focusBackground": "#f0f0f1", + "selectedBackground": "#2b2e33", + "selectedFocusBackground": "#56595f", + "color": "#2b2e33", + "focusColor": "#2b2e33", + "selectedColor": "#ffffff", + "selectedFocusColor": "#ffffff", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "separator": { "borderColor": "#e2e2e4" } + }, + "overlaySelect": { + "background": "#ffffff", + "color": "#2b2e33", + "borderColor": "#e2e2e4", + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "overlayPopover": { + "background": "#ffffff", + "color": "#2b2e33", + "borderColor": "#e2e2e4", + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "padding": 14, + "gap": 4 + } + }, + "paginatorTop": { + "borderColor": "#cecfd2", + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0 + }, + "paginatorBottom": { + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "borderColor": "#e2e2e4" + } + }, + "dataview": { + "root": { + "borderWidth": 1, + "borderRadius": 4, + "padding": 0, + "borderColor": "#e2e2e4" + }, + "header": { + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": "0px 0px 0px 0px", + "color": "#2b2e33", + "borderColor": "#e2e2e4" + }, + "content": { + "background": "#ffffff", + "color": "#2b2e33", + "borderColor": "#e2e2e4", + "borderWidth": 0, + "padding": 0, + "borderRadius": 0 + }, + "footer": { + "background": "#f0f0f1", + "color": "#2b2e33", + "borderTopWidth": 1, + "borderRightWidth": 0, + "borderBottomWidth": 0, + "borderLeftWidth": 0, + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": "0px 0px 0px 0px", + "borderColor": "#e2e2e4" + }, + "paginatorTop": { + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "borderColor": "#e2e2e4" + }, + "paginatorBottom": { + "borderTopWidth": 1, + "borderRightWidth": 0, + "borderBottomWidth": 0, + "borderLeftWidth": 0, + "borderColor": "#e2e2e4" + }, + "colorScheme": { "header": { "background": "#ffffff", "color": "#2b2e33" } } + }, + "datepicker": { + "extend": { + "extDate": { "selectedHoverBackground": "#404348" }, + "extToday": { "hoverBackground": "#f0f0f1", "borderColor": "#404348" }, + "extTitle": { "width": 336 }, + "extTimePicker": { "minWidth": 304, "color": "#2b2e33" } + }, + "colorScheme": { + "dropdown": { + "background": "#ffffff", + "hoverBackground": "#f0f0f1", + "activeBackground": "#2b2e33", + "color": "#2b2e33", + "hoverColor": "#2b2e33", + "activeColor": "#ffffff" + }, + "today": { "background": "transparent", "color": "#2b2e33" } + }, + "panel": { + "background": "#ffffff", + "borderColor": "#e2e2e4", + "color": "#2b2e33", + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "padding": 0 + }, + "header": { + "background": "#ffffff", + "borderColor": "#e2e2e4", + "color": "#2b2e33", + "padding": 14 + }, + "title": { "gap": 8, "fontWeight": "700" }, + "selectMonth": { + "hoverBackground": "#f0f0f1", + "color": "#2b2e33", + "hoverColor": "#56595f", + "borderRadius": 14, + "padding": 8 + }, + "inputIcon": { "color": "#85888e" }, + "dropdown": { + "width": 272, + "borderColor": "#cecfd2", + "hoverBorderColor": "#cecfd2", + "activeBorderColor": "#cecfd2", + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "sm": { "width": 0 }, + "lg": { "width": 0 } + }, + "group": { "borderColor": "#e2e2e4", "gap": 14 }, + "selectYear": { + "hoverBackground": "#f0f0f1", + "color": "#2b2e33", + "hoverColor": "#56595f", + "borderRadius": 14, + "padding": 4 + }, + "dayView": { "margin": 14 }, + "weekDay": { "padding": 4, "fontWeight": "700", "color": "#2b2e33" }, + "date": { + "hoverBackground": "#f0f0f1", + "selectedBackground": "#2b2e33", + "rangeSelectedBackground": "#f0f0f1", + "color": "#2b2e33", + "hoverColor": "#2b2e33", + "selectedColor": "#ffffff", + "rangeSelectedColor": "#2b2e33", + "width": 32, + "height": 32, + "borderRadius": 8, + "padding": 4, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "monthView": { + "marginTop": 0, + "marginRight": 0, + "marginBottom": 0, + "marginLeft": 0 + }, + "month": { "padding": 0, "borderRadius": 0 }, + "yearView": { + "marginTop": 0, + "marginRight": 0, + "marginBottom": 0, + "marginLeft": 0 + }, + "year": { "padding": 0, "borderRadius": 0 }, + "buttonbar": { "padding": 14, "borderColor": "#e2e2e4" }, + "timePicker": { + "padding": 14, + "borderColor": "#e2e2e4", + "gap": 8, + "buttonGap": 4 + }, + "root": { "transitionDuration": 180 } + }, + "dialog": { + "extend": { "borderWidth": 1, "backdrop": "rgba(0, 0, 0, 0.4000)" }, + "root": { + "background": "#ffffff", + "borderColor": "#e2e2e4", + "color": "#2b2e33", + "borderRadius": 1600, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "header": { + "paddingTop": 24, + "paddingRight": 24, + "paddingBottom": 14, + "paddingLeft": 24, + "gap": 8 + }, + "title": { "fontSize": 20, "fontWeight": "600" }, + "content": { "padding": 24 }, + "footer": { + "paddingTop": 0, + "paddingRight": 24, + "paddingBottom": 24, + "paddingLeft": 24, + "gap": 8 + } + }, + "divider": { + "extend": { "content": { "gap": 8 }, "iconSize": 16 }, + "horizontal": { + "marginTop": 14, + "marginRight": 0, + "marginBottom": 14, + "marginLeft": 0, + "paddingTop": 0, + "paddingRight": 14, + "paddingBottom": 0, + "paddingLeft": 14, + "content": { + "paddingTop": 0, + "paddingRight": 8, + "paddingBottom": 0, + "paddingLeft": 8 + } + }, + "vertical": { + "marginTop": 0, + "marginRight": 14, + "marginBottom": 0, + "marginLeft": 14, + "paddingTop": 14, + "paddingRight": 0, + "paddingBottom": 14, + "paddingLeft": 0, + "content": { + "paddingTop": 8, + "paddingRight": 0, + "paddingBottom": 8, + "paddingLeft": 0 + } + }, + "content": { "background": "#ffffff", "color": "#2b2e33" }, + "root": { "borderColor": "#e2e2e4" } + }, + "drawer": { + "extend": { + "borderRadius": 8, + "borderWidth": 1, + "width": 400, + "extHeader": { "gap": 8, "borderColor": "#e2e2e4" }, + "margin": 8, + "scale": 2, + "backdrop": "rgba(0, 0, 0, 0.4000)" + }, + "root": { + "background": "#ffffff", + "borderColor": "#e2e2e4", + "color": "#2b2e33", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "header": { + "paddingTop": 24, + "paddingRight": 24, + "paddingBottom": 14, + "paddingLeft": 24 + }, + "title": { "fontSize": 20, "fontWeight": "600" }, + "content": { "padding": 24 }, + "footer": { + "paddingTop": 0, + "paddingRight": 24, + "paddingBottom": 24, + "paddingLeft": 24 + } + }, + "fileupload": { + "extend": { + "extDragNdrop": { + "background": "#ffffff", + "borderRadius": 14, + "iconSize": 32, + "padding": 14, + "info": { "gap": 4 } + }, + "extFile": { "iconSize": 20 }, + "extContent": { "borderRadius": 14, "highlightBorderDefault": "#cecfd2" } + }, + "colorScheme": { + "header": { "background": "#ffffff", "color": "#2b2e33" } + }, + "root": { + "background": "#ffffff", + "borderColor": "#e2e2e4", + "color": "#2b2e33", + "borderRadius": 14, + "transitionDuration": 180 + }, + "header": { + "borderColor": "#e2e2e4", + "borderWidth": 0, + "padding": 0, + "borderRadius": 0, + "gap": 8 + }, + "content": { "highlightBorderColor": "#2b2e33", "padding": 0, "gap": 8 }, + "file": { + "padding": 8, + "gap": 8, + "borderColor": "#cecfd2", + "info": { "gap": 4 } + }, + "fileList": { "gap": 8 }, + "progressbar": { "height": 8 }, + "basic": { "gap": 8 } + }, + "floatlabel": { + "extend": { "height": 64, "iconSize": 20 }, + "root": { + "color": "#85888e", + "focusColor": "#85888e", + "activeColor": "#85888e", + "invalidColor": "#db3424", + "transitionDuration": 180, + "positionX": 14, + "positionY": 14, + "fontWeight": "400", + "active": { "fontSize": 12, "fontWeight": "400" } + }, + "over": { "active": { "top": 14 } }, + "inside": { + "input": { "paddingTop": 28, "paddingBottom": 14 }, + "active": { "top": 14 } + }, + "on": { + "borderRadius": 0, + "active": { + "paddingTop": 0, + "paddingRight": 4, + "paddingBottom": 0, + "paddingLeft": 4, + "background": "#ffffff" + } + } + }, + "galleria": { + "extend": { "backdrop": "rgba(0, 0, 0, 0.4000)" }, + "colorScheme": { + "thumbnailContent": { "background": "#f0f0f1" }, + "thumbnailNavButton": { + "hoverBackground": "#e2e2e4", + "color": "#2b2e33", + "hoverColor": "#56595f" + }, + "indicatorButton": { + "background": "#cecfd2", + "hoverBackground": "#a2a5a9" + }, + "thumbnailsContent": { "background": "#e2e2e4" } + }, + "root": { + "borderWidth": 1, + "borderColor": "#e2e2e4", + "borderRadius": 14, + "transitionDuration": 180 + }, + "navButton": { + "background": "transparent", + "hoverBackground": "#e2e2e4", + "color": "#ffffff", + "hoverColor": "#ffffff", + "size": 64, + "gutter": 8, + "prev": { "borderRadius": 8 }, + "next": { "borderRadius": 8 }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "navIcon": { "size": 32 }, + "thumbnailsContent": { "padding": 4 }, + "thumbnailNavButton": { + "size": 32, + "borderRadius": 14, + "gutter": 8, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "thumbnailNavButtonIcon": { "size": 16 }, + "caption": { "background": "#e2e2e4", "color": "#2b2e33", "padding": 8 }, + "indicatorList": { "gap": 8, "padding": 14 }, + "indicatorButton": { + "width": 8, + "height": 8, + "activeBackground": "#2b2e33", + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "insetIndicatorList": { "background": "rgba(0, 0, 0, 0.4000)" }, + "insetIndicatorButton": { + "background": "#e2e2e4", + "hoverBackground": "#e2e2e4", + "activeBackground": "#e2e2e4" + }, + "closeButton": { + "size": 64, + "gutter": 8, + "background": "#e2e2e4", + "hoverBackground": "#e2e2e4", + "color": "#ffffff", + "hoverColor": "#ffffff", + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "closeButtonIcon": { "size": 32 } + }, + "inputgroup": { + "extend": { "borderWidth": 1, "iconSize": 16 }, + "colorScheme": { + "addon": { + "background": "#ffffff", + "borderColor": "#cecfd2", + "color": "#85888e" + } + }, + "addon": { "borderRadius": 14, "padding": 14, "minWidth": 272 } + }, + "inputnumber": { + "extend": { + "borderWidth": 1, + "extButton": { "height": 40, "iconSize": 16 } + }, + "colorScheme": { + "button": { + "background": "#ffffff", + "hoverBackground": "#f0f0f1", + "activeBackground": "transparent", + "borderColor": "#cecfd2", + "hoverBorderColor": "#cecfd2", + "activeBorderColor": "#cecfd2", + "color": "#2b2e33", + "hoverColor": "#56595f", + "activeColor": "#2b2e33" + } + }, + "transitionDuration": { "transitionDuration": 180 }, + "button": { "width": 272, "borderRadius": 14, "verticalPadding": 14 }, + "root": { "transitionDuration": 180 } + }, + "inputotp": { + "extend": { "height": 40, "borderWidth": 1 }, + "root": { "gap": 8 }, + "input": { "width": 304, "lg": { "width": 336 }, "sm": { "width": 272 } }, + "sm": { "width": 0 }, + "lg": { "width": 0 } + }, + "inputtext": { + "extend": { + "readonlyBackground": "#f0f0f1", + "iconSize": 16, + "borderWidth": 1, + "extXlg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 } + }, + "root": { + "background": "#ffffff", + "disabledBackground": "#e2e2e4", + "filledBackground": "#ffffff", + "filledHoverBackground": "#ffffff", + "filledFocusBackground": "#ffffff", + "borderColor": "#cecfd2", + "hoverBorderColor": "#1dc831", + "focusBorderColor": "#1dc831", + "invalidBorderColor": "#f47f77", + "color": "#2b2e33", + "disabledColor": "#85888e", + "placeholderColor": "#85888e", + "invalidPlaceholderColor": "#db3424", + "shadow": "none", + "paddingX": 14, + "paddingY": 14, + "borderRadius": 14, + "transitionDuration": 180, + "sm": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "lg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + } + } + }, + "listbox": { + "extend": { + "extOption": { + "label": { "gap": 4 }, + "caption": { "color": "#85888e", "stripedColor": "#85888e" }, + "gap": 8 + } + }, + "colorScheme": { "option": { "stripedBackground": "#fafafa" } }, + "root": { + "background": "#ffffff", + "disabledBackground": "#e2e2e4", + "borderColor": "#cecfd2", + "invalidBorderColor": "#f47f77", + "color": "#181a1f", + "disabledColor": "#85888e", + "shadow": "none", + "borderRadius": 14, + "transitionDuration": 180 + }, + "list": { + "padding": 4, + "gap": 4, + "header": { + "paddingTop": 14, + "paddingRight": 14, + "paddingBottom": 0, + "paddingLeft": 14 + } + }, + "option": { + "focusBackground": "#f0f0f1", + "selectedBackground": "#2b2e33", + "selectedFocusBackground": "#56595f", + "color": "#2b2e33", + "focusColor": "#2b2e33", + "selectedColor": "#ffffff", + "selectedFocusColor": "#ffffff", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8 + }, + "optionGroup": { + "background": "#ffffff", + "color": "#85888e", + "fontWeight": "600", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "checkmark": { "color": "#2b2e33", "gutterStart": -8, "gutterEnd": 8 }, + "emptyMessage": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + } + }, + "megamenu": { + "extend": { + "extItem": { "caption": { "color": "#85888e", "gap": 4 } }, + "iconSize": 20 + }, + "colorScheme": { "root": { "background": "transparent" } }, + "root": { + "borderColor": "transparent", + "borderRadius": 14, + "color": "#2b2e33", + "gap": 4, + "transitionDuration": 180, + "verticalOrientation": { "padding": 4, "gap": 4 }, + "horizontalOrientation": { "padding": 4, "gap": 4 } + }, + "baseItem": { + "borderRadius": 14, + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "item": { + "focusBackground": "#f0f0f1", + "activeBackground": "#2b2e33", + "color": "#2b2e33", + "focusColor": "#2b2e33", + "activeColor": "#ffffff", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "gap": 8, + "icon": { + "color": "#2b2e33", + "focusColor": "#2b2e33", + "activeColor": "#ffffff" + } + }, + "overlay": { + "padding": 4, + "background": "#ffffff", + "borderColor": "#e2e2e4", + "borderRadius": 14, + "color": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "gap": 0 + }, + "submenu": { "padding": 4, "gap": 4 }, + "submenuLabel": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "background": "transparent", + "color": "#85888e", + "fontWeight": "600" + }, + "submenuIcon": { + "size": 20, + "color": "#2b2e33", + "focusColor": "#2b2e33", + "activeColor": "#ffffff" + }, + "separator": { "borderColor": "#e2e2e4" }, + "mobileButton": { + "borderRadius": 8, + "size": 32, + "color": "#2b2e33", + "hoverColor": "#56595f", + "hoverBackground": "#f0f0f1", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "menu": { + "extend": { + "paddingX": 4, + "iconSize": 20, + "paddingY": 4, + "extItem": { + "caption": { "gap": 4, "color": "#85888e" }, + "activeBackground": "#2b2e33", + "activeColor": "#ffffff", + "icon": { "activeColor": "#ffffff" } + } + }, + "root": { + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "transitionDuration": 180, + "background": "#ffffff", + "borderColor": "#e2e2e4", + "color": "#2b2e33" + }, + "list": { "padding": 4, "gap": 4 }, + "submenuLabel": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "fontWeight": "600", + "background": "transparent", + "color": "#85888e" + }, + "separator": { "borderColor": "#e2e2e4" }, + "item": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "gap": 8, + "color": "#2b2e33", + "focusBackground": "#f0f0f1", + "focusColor": "#56595f", + "icon": { "color": "#2b2e33", "focusColor": "#56595f" } + } + }, + "menubar": { + "extend": { + "iconSize": 20, + "extItem": { "caption": { "color": "#85888e", "gap": 4 } }, + "extSubmenuLabel": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "fontWeight": "600", + "background": "transparent", + "color": "#85888e" + } + }, + "colorScheme": { "root": { "background": "transparent" } }, + "root": { + "borderColor": "transparent", + "borderRadius": 8, + "color": "#2b2e33", + "gap": 4, + "padding": 4, + "transitionDuration": 180 + }, + "baseItem": { + "borderRadius": 8, + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "item": { + "focusBackground": "#f0f0f1", + "activeBackground": "#2b2e33", + "color": "#2b2e33", + "focusColor": "#2b2e33", + "activeColor": "#ffffff", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "gap": 8, + "icon": { + "color": "#2b2e33", + "focusColor": "#2b2e33", + "activeColor": "#ffffff" + } + }, + "submenu": { + "padding": 4, + "gap": 4, + "background": "#ffffff", + "borderColor": "#e2e2e4", + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "mobileIndent": 14, + "icon": { + "size": 20, + "color": "#2b2e33", + "focusColor": "#2b2e33", + "activeColor": "#ffffff" + } + }, + "separator": { "borderColor": "#e2e2e4" }, + "mobileButton": { + "borderRadius": 8, + "size": 32, + "color": "#2b2e33", + "hoverColor": "#56595f", + "hoverBackground": "#f0f0f1", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "message": { + "extend": { + "width": 400, + "extText": { "gap": 4 }, + "extInfo": { + "color": "#4496e8", + "closeButton": { "color": "#4496e8", "borderColor": "#4496e8" }, + "caption": { "color": "#2b2e33" } + }, + "extAccentLine": { "width": 4 }, + "extCloseButton": { "width": 1 }, + "extSuccess": { + "color": "#44e858", + "closeButton": { "color": "#44e858", "borderColor": "#44e858" }, + "caption": { "color": "#2b2e33" } + }, + "extWarn": { + "color": "#f5b83d", + "closeButton": { "color": "#f5b83d", "borderColor": "#f5b83d" }, + "caption": { "color": "#2b2e33" } + }, + "extError": { + "color": "#e85244", + "closeButton": { "color": "#e85244", "borderColor": "#e85244" }, + "caption": { "color": "#2b2e33" } + } + }, + "colorScheme": { + "success": { + "background": "#fafffb", + "borderColor": "#44e858", + "color": "#2b2e33", + "shadow": "none", + "outlined": { "color": "#2b2e33", "borderColor": "#44e858" }, + "closeButton": { + "hoverBackground": "#d4fedc", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "simple": { "color": "#2b2e33" } + }, + "outlined": { + "root": { "borderWidth": 0 }, + "closeButton": { + "hoverBackground": "transparent", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "outlined": { "color": "transparent", "borderColor": "transparent" }, + "simple": { "color": "transparent" } + }, + "simple": { "content": { "padding": 0 } }, + "warn": { + "background": "#fffdfa", + "borderColor": "#f5b83d", + "color": "#2b2e33", + "shadow": "none", + "outlined": { "color": "#2b2e33", "borderColor": "#f5b83d" }, + "closeButton": { + "hoverBackground": "#ffeed4", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "simple": { "color": "#2b2e33" } + }, + "error": { + "background": "#fffafa", + "borderColor": "#e85244", + "color": "#2b2e33", + "shadow": "none", + "outlined": { "color": "#2b2e33", "borderColor": "#e85244" }, + "closeButton": { + "hoverBackground": "#fed4d4", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "simple": { "color": "#2b2e33" } + }, + "secondary": { + "borderColor": "transparent", + "shadow": "none", + "closeButton": { + "hoverBackground": "transparent", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "simple": { "color": "transparent" }, + "outlined": { "color": "transparent", "borderColor": "transparent" }, + "background": "#f0f0f1", + "color": "#2b2e33" + }, + "contrast": { + "borderColor": "transparent", + "shadow": "none", + "closeButton": { + "hoverBackground": "transparent", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "simple": { "color": "transparent" }, + "outlined": { "color": "transparent", "borderColor": "transparent" }, + "background": "#2b2e33", + "color": "#ffffff" + }, + "info": { + "background": "#fafdff", + "borderColor": "#4496e8", + "color": "#2b2e33", + "shadow": "none", + "closeButton": { + "hoverBackground": "#d4ecfe", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "outlined": { "color": "#2b2e33", "borderColor": "#4496e8" }, + "simple": { "color": "#2b2e33" } + } + }, + "root": { "borderRadius": 14, "borderWidth": 1, "transitionDuration": 180 }, + "content": { + "padding": 14, + "gap": 14, + "sm": { "padding": 14 }, + "lg": { "padding": 14 } + }, + "text": { + "fontSize": 16, + "fontWeight": "700", + "sm": { "fontSize": 16 }, + "lg": { "fontSize": 16 } + }, + "icon": { "size": 36, "sm": { "size": 36 }, "lg": { "size": 36 } }, + "closeButton": { + "width": 32, + "height": 32, + "borderRadius": 14, + "focusRing": { "width": 4, "style": "none", "offset": 0 } + }, + "closeIcon": { "size": 16, "sm": { "size": 16 }, "lg": { "size": 16 } }, + "outlined": { "root": { "borderWidth": 1 } }, + "simple": { "content": { "padding": 0 } } + }, + "metergroup": { + "extend": { "extLabel": { "color": "#85888e" } }, + "root": { "borderRadius": 14, "gap": 14 }, + "meters": { "size": 8, "background": "#e2e2e4" }, + "label": { "gap": 4 }, + "labelMarker": { "size": 8 }, + "labelIcon": { "size": 16 }, + "labelList": { "verticalGap": 8, "horizontalGap": 14 } + }, + "multiselect": { + "extend": { + "paddingX": 6, + "paddingY": 6, + "borderWidth": 1, + "iconSize": 16, + "width": 272, + "readonlyBackground": "#f0f0f1" + }, + "root": { + "shadow": "none", + "paddingX": 14, + "paddingY": 14, + "borderRadius": 14, + "transitionDuration": 180, + "sm": { "fontSize": 16, "paddingX": 8, "paddingY": 8 }, + "lg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "focusRing": { + "width": 4, + "style": "none", + "offset": 0, + "shadow": "none", + "color": "#d4fedc" + }, + "background": "#ffffff", + "borderColor": "#cecfd2", + "color": "#2b2e33", + "disabledBackground": "#e2e2e4", + "disabledColor": "#85888e", + "filledBackground": "#ffffff", + "filledFocusBackground": "#ffffff", + "filledHoverBackground": "#ffffff", + "focusBorderColor": "#1dc831", + "hoverBorderColor": "#1dc831", + "invalidBorderColor": "#f47f77", + "invalidPlaceholderColor": "#db3424", + "placeholderColor": "#85888e" + }, + "dropdown": { "width": 272, "color": "#181a1f" }, + "overlay": { + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "background": "#ffffff", + "borderColor": "#e2e2e4", + "color": "#2b2e33" + }, + "list": { + "padding": 4, + "header": { + "paddingTop": 14, + "paddingRight": 14, + "paddingBottom": 0, + "paddingLeft": 14 + }, + "gap": 4 + }, + "chip": { "borderRadius": 8 }, + "option": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "gap": 8, + "color": "#2b2e33", + "focusBackground": "#f0f0f1", + "focusColor": "#2b2e33", + "selectedBackground": "#2b2e33", + "selectedColor": "#ffffff", + "selectedFocusBackground": "#56595f", + "selectedFocusColor": "#ffffff" + }, + "optionGroup": { + "fontWeight": "600", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "background": "#ffffff", + "color": "#85888e" + }, + "emptyMessage": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "clearIcon": { "color": "#181a1f" } + }, + "paginator": { + "root": { + "paddingTop": 0, + "paddingRight": 8, + "paddingBottom": 0, + "paddingLeft": 8, + "gap": 8, + "borderRadius": 14, + "background": "transparent", + "color": "#2b2e33", + "transitionDuration": 180 + }, + "currentPageReport": { "color": "#85888e" }, + "navButton": { + "background": "transparent", + "hoverBackground": "#f0f0f1", + "selectedBackground": "#2b2e33", + "color": "#2b2e33", + "hoverColor": "#56595f", + "selectedColor": "#ffffff", + "width": 40, + "height": 40, + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "focus": "0 0 4px rgba(0, 0, 0, 0.2000)", + "shadow": "none" + } + }, + "jumpToPageInput": { "maxWidth": 80 } + }, + "panelmenu": { + "extend": { + "iconSize": 20, + "extPanel": { "gap": 4 }, + "extItem": { + "activeBackground": "#2b2e33", + "activeColor": "#ffffff", + "caption": { "color": "#85888e", "gap": 4 } + } + }, + "root": { "gap": 4, "transitionDuration": 180 }, + "panel": { + "background": "transparent", + "borderColor": "transparent", + "borderWidth": 1, + "color": "#2b2e33", + "padding": 4, + "borderRadius": 14, + "first": { + "borderTopWidth": 1, + "borderRightWidth": 1, + "borderBottomWidth": 0, + "borderLeftWidth": 1, + "topBorderRadius": 14 + }, + "last": { + "borderTopWidth": 0, + "borderRightWidth": 1, + "borderBottomWidth": 1, + "borderLeftWidth": 1, + "topBorderRadius": 14, + "bottomBorderRadius": 14 + } + }, + "item": { + "focusBackground": "#f0f0f1", + "color": "#2b2e33", + "focusColor": "#2b2e33", + "gap": 8, + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "icon": { "color": "#2b2e33", "focusColor": "#2b2e33" } + }, + "submenu": { "indent": 24 }, + "separator": { "borderColor": "#e2e2e4" }, + "submenuIcon": { "color": "#2b2e33", "focusColor": "#2b2e33" } + }, + "password": { + "extend": { "borderWidth": 1 }, + "colorScheme": { + "strength": { + "weakBackground": "#e85244", + "mediumBackground": "#f5b83d", + "strongBackground": "#1dc831" + }, + "icon": { "color": "#85888e" } + }, + "meter": { "background": "#e2e2e4", "borderRadius": 14, "height": 8 }, + "overlay": { + "background": "#ffffff", + "borderColor": "#cecfd2", + "borderRadius": 8, + "color": "#2b2e33", + "padding": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "content": { "gap": 8 }, + "icon": { "color": "#2b2e33" } + }, + "popover": { + "extend": { "borderWidth": 1, "arrow": { "width": 12, "height": 8 } }, + "root": { + "background": "#ffffff", + "borderColor": "#cecfd2", + "color": "#2b2e33", + "borderRadius": 8, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "gutter": 4, + "arrowOffset": 20 + }, + "content": { "padding": 14 } + }, + "progressbar": { + "label": { "color": "#2b2e33", "fontSize": 12, "fontWeight": "400" }, + "root": { "background": "#e2e2e4", "borderRadius": 14, "height": 16 }, + "value": { "background": "#44e858" } + }, + "progressspinner": { + "extend": { "small": 16, "medium": 32, "large": 48, "xlarge": 56 }, + "colorScheme": { + "root": { + "colorOne": "#44e858", + "colorTwo": "#4496e8", + "colorThree": "#e85244", + "colorFour": "#f5b83d" + } + }, + "root": { "borderWidth": 4 } + }, + "radiobutton": { + "root": { + "width": 24, + "height": 24, + "background": "#ffffff", + "checkedBackground": "#2b2e33", + "checkedHoverBackground": "#404348", + "disabledBackground": "#e2e2e4", + "filledBackground": "#ffffff", + "borderColor": "#cecfd2", + "hoverBorderColor": "#2b2e33", + "focusBorderColor": "#cecfd2", + "checkedBorderColor": "#2b2e33", + "checkedHoverBorderColor": "#2b2e33", + "checkedFocusBorderColor": "#2b2e33", + "checkedDisabledBorderColor": "#cecfd2", + "invalidBorderColor": "#f47f77", + "shadow": "none", + "transitionDuration": 180, + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + }, + "lg": { "height": 20, "width": 20 }, + "sm": { "height": 8, "width": 8 } + }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "sm": { "width": 16, "height": 16 }, + "lg": { "width": 20, "height": 20 }, + "icon": { + "size": 12, + "checkedColor": "#ffffff", + "checkedHoverColor": "#ffffff", + "disabledColor": "#85888e", + "sm": { "size": 8 }, + "lg": { "size": 16 } + } + }, + "rating": { + "root": { + "gap": 8, + "transitionDuration": 180, + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + } + }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "icon": { + "size": 24, + "color": "#85888e", + "hoverColor": "#f5b83d", + "activeColor": "#f5b83d" + } + }, + "ripple": { "colorScheme": { "root": { "background": "#e2e2e4" } } }, + "scrollpanel": { + "colorScheme": { "bar": { "background": "#cecfd2" } }, + "root": { "transitionDuration": 180 }, + "bar": { + "size": 8, + "borderRadius": 8, + "focusRing": { + "width": 0, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "select": { + "extend": { + "extOption": { "background": "#ffffff", "gap": 8 }, + "extOptionGroup": { "gap": 8 }, + "readonlyBackground": "#f0f0f1", + "borderWidth": 1, + "iconSize": 16 + }, + "root": { + "background": "#ffffff", + "disabledBackground": "#e2e2e4", + "filledBackground": "#ffffff", + "filledHoverBackground": "#ffffff", + "filledFocusBackground": "#ffffff", + "borderColor": "#cecfd2", + "hoverBorderColor": "#1dc831", + "focusBorderColor": "#1dc831", + "invalidBorderColor": "#f47f77", + "color": "#2b2e33", + "disabledColor": "#85888e", + "placeholderColor": "#85888e", + "invalidPlaceholderColor": "#db3424", + "shadow": "none", + "paddingX": 14, + "paddingY": 14, + "borderRadius": 14, + "transitionDuration": 180, + "sm": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "lg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + } + }, + "dropdown": { "width": 272, "color": "#181a1f" }, + "overlay": { + "background": "#ffffff", + "borderColor": "#e2e2e4", + "borderRadius": 14, + "color": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)" + }, + "list": { + "padding": 4, + "gap": 4, + "header": { + "paddingTop": 14, + "paddingRight": 14, + "paddingBottom": 0, + "paddingLeft": 14 + } + }, + "option": { + "focusBackground": "#f0f0f1", + "selectedBackground": "#2b2e33", + "selectedFocusBackground": "#56595f", + "color": "#2b2e33", + "focusColor": "#2b2e33", + "selectedColor": "#ffffff", + "selectedFocusColor": "#ffffff", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8 + }, + "optionGroup": { + "background": "#ffffff", + "color": "#85888e", + "fontWeight": "600", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + }, + "clearIcon": { "color": "#181a1f" }, + "checkmark": { "color": "#2b2e33", "gutterStart": -8, "gutterEnd": 8 }, + "emptyMessage": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14 + } + }, + "selectbutton": { + "extend": { + "gap": 4, + "paddingX": 4, + "paddingY": 4, + "iconSize": { "sm": 16, "md": 20, "lg": 24, "xlg": 28 }, + "checkedBackground": "#ffffff", + "checkedBorderColor": "#ffffff", + "checkedColor": "#181a1f", + "ext": { "borderRadius": 8 } + }, + "colorScheme": { + "root": { "invalidBorderColor": "#f47f77" }, + "extend": { "background": "#e2e2e4" } + }, + "root": { "borderRadius": 14 } + }, + "skeleton": { + "extend": { "minWidth": 32, "height": 32 }, + "colorScheme": { + "root": { "background": "#e2e2e4", "animationBackground": "#f0f0f1" } + }, + "root": { "borderRadius": 14 } + }, + "slider": { + "colorScheme": { "handle": { "content": { "background": "#ffffff" } } }, + "root": { "transitionDuration": 180 }, + "track": { "background": "#e2e2e4", "borderRadius": 14, "size": 4 }, + "range": { "background": "#2b2e33" }, + "handle": { + "width": 20, + "height": 20, + "borderRadius": 1600, + "background": "#2b2e33", + "hoverBackground": "#2b2e33", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "content": { + "borderRadius": 1600, + "hoverBackground": "#2b2e33", + "width": 12, + "height": 12, + "shadow": "none" + } + } + }, + "splitter": { + "colorScheme": { "handle": { "background": "#2b2e33" } }, + "gutter": { "background": "#f0f0f1" }, + "root": { + "background": "#ffffff", + "borderColor": "#e2e2e4", + "color": "#2b2e33", + "transitionDuration": 180 + }, + "handle": { + "size": 4, + "borderRadius": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "stepper": { + "extend": { + "extCaption": { "gap": 4 }, + "extStepNumber": { + "invalidBackground": "#f47f77", + "invalidColor": "#45120e", + "invalidBorderColor": "#f47f77", + "borderWidth": 1, + "iconSize": 24 + } + }, + "root": { "transitionDuration": 180 }, + "separator": { + "background": "#e2e2e4", + "activeBackground": "#2b2e33", + "marginTop": 0, + "marginRight": 0, + "marginBottom": 0, + "marginLeft": 24, + "size": 1 + }, + "step": { "padding": 8, "gap": 8 }, + "stepHeader": { + "padding": 0, + "borderRadius": 0, + "gap": 8, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "stepTitle": { + "color": "#2b2e33", + "activeColor": "#2b2e33", + "fontWeight": "400" + }, + "stepNumber": { + "background": "#ffffff", + "activeBackground": "#44e858", + "borderColor": "#e2e2e4", + "activeBorderColor": "#44e858", + "color": "#2b2e33", + "activeColor": "#2b2e33", + "size": 24, + "fontSize": 16, + "fontWeight": "700", + "borderRadius": 1600, + "shadow": "none" + }, + "steppanels": { "padding": 14 }, + "steppanel": { + "background": "#ffffff", + "color": "#2b2e33", + "padding": 0, + "indent": 0 + } + }, + "steps": { + "itemLink": { + "gap": 8, + "borderRadius": 14, + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + } + }, + "itemLabel": { + "fontWeight": "400", + "activeColor": "#56595f", + "color": "#2b2e33" + }, + "itemNumber": { + "background": "#ffffff", + "size": 32, + "fontSize": 16, + "fontWeight": "700", + "borderRadius": 1600, + "shadow": "none", + "activeBackground": "#ffffff", + "activeBorderColor": "#e2e2e4", + "activeColor": "#56595f", + "borderColor": "#e2e2e4", + "color": "#2b2e33" + }, + "root": { "transitionDuration": 180 }, + "separator": { "background": "#e2e2e4" } + }, + "tabs": { + "colorScheme": { + "navButton": { "shadow": "none" }, + "tab": { + "background": "transparent", + "hoverBackground": "transparent", + "activeBackground": "transparent" + } + }, + "root": { "transitionDuration": 180 }, + "tablist": { + "borderTopWidth": 0, + "borderRightWidth": 0, + "borderBottomWidth": 1, + "borderLeftWidth": 0, + "background": "transparent", + "borderColor": "#e2e2e4" + }, + "tab": { + "borderWidth": 0, + "borderColor": "#e2e2e4", + "hoverBorderColor": "#e2e2e4", + "activeBorderColor": "#404348", + "color": "#85888e", + "hoverColor": "#2b2e33", + "activeColor": "#2b2e33", + "padding": 14, + "fontWeight": "600", + "margin": 0, + "gap": 8, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "tabpanel": { + "background": "transparent", + "color": "#2b2e33", + "padding": 14, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "navButton": { + "background": "#ffffff", + "color": "#2b2e33", + "hoverColor": "#56595f", + "width": 24, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + }, + "activeBar": { "height": 2, "bottom": -2, "background": "#2b2e33" } + }, + "toast": { + "extend": { + "extInfo": { + "color": "#4496e8", + "closeButton": { "color": "#4496e8", "borderColor": "#4496e8" }, + "caption": { "color": "#2b2e33" } + }, + "extAccentLine": { "width": 4 }, + "extCloseButton": { "width": 1 }, + "extSuccess": { + "color": "#44e858", + "closeButton": { "color": "#44e858", "borderColor": "#44e858" }, + "caption": { "color": "#2b2e33" } + }, + "extWarn": { + "color": "#f5b83d", + "closeButton": { "color": "#f5b83d", "borderColor": "#f5b83d" }, + "caption": { "color": "#2b2e33" } + }, + "extError": { + "color": "#e85244", + "closeButton": { "color": "#e85244", "borderColor": "#e85244" }, + "caption": { "color": "#2b2e33" } + } + }, + "colorScheme": { + "info": { + "background": "#fafdff", + "borderColor": "#4496e8", + "color": "#2b2e33", + "detailColor": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "closeButton": { + "hoverBackground": "#d4ecfe", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "success": { + "background": "#fafffb", + "borderColor": "#44e858", + "color": "#2b2e33", + "detailColor": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "closeButton": { + "hoverBackground": "#d4fedc", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "warn": { + "background": "#fffdfa", + "borderColor": "#f5b83d", + "color": "#2b2e33", + "detailColor": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "closeButton": { + "hoverBackground": "#ffeed4", + "focusRing": { "color": "#d4fedc", "shadow": "none" } + } + }, + "error": { + "background": "#fffafa", + "borderColor": "#e85244", + "color": "#2b2e33", + "detailColor": "#2b2e33", + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "closeButton": { + "hoverBackground": "#fed4d4", + "focusRing": { + "color": "#d4fedc", + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + } + } + }, + "secondary": { + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "background": "#f0f0f1", + "borderColor": "#cecfd2", + "closeButton": { + "focusRing": { "color": "#d4fedc", "shadow": "none" }, + "hoverBackground": "#f0f0f1" + }, + "color": "#2b2e33", + "detailColor": "#6d7076" + }, + "contrast": { + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "background": "#2b2e33", + "borderColor": "#2b2e33", + "closeButton": { + "focusRing": { "color": "#d4fedc", "shadow": "none" }, + "hoverBackground": "#404348" + }, + "color": "#ffffff", + "detailColor": "#e2e2e4" + }, + "root": { "blur": 0 } + }, + "root": { + "width": 400, + "borderWidth": 1, + "borderRadius": 14, + "transitionDuration": 180 + }, + "icon": { "size": 36 }, + "content": { "padding": 14, "gap": 14 }, + "text": { "gap": 4 }, + "summary": { "fontWeight": "700", "fontSize": 16 }, + "detail": { "fontWeight": "400", "fontSize": 14 }, + "closeButton": { + "width": 32, + "height": 32, + "borderRadius": 14, + "focusRing": { "width": 4, "style": "none", "offset": 0 } + }, + "closeIcon": { "size": 16 } + }, + "tag": { + "colorScheme": { + "primary": { "background": "#44e858", "color": "#2b2e33" }, + "secondary": { "background": "#e2e2e4", "color": "#2b2e33" }, + "success": { "background": "#77f48a", "color": "#0e4514" }, + "info": { "background": "#aad7fb", "color": "#0e2a45" }, + "warn": { "background": "#fddeaa", "color": "#4f3709" }, + "danger": { "background": "#fbacaa", "color": "#45120e" }, + "contrast": { "background": "#2b2e33", "color": "#ffffff" } + }, + "root": { + "fontSize": 12, + "fontWeight": "400", + "paddingTop": 4, + "paddingRight": 8, + "paddingBottom": 4, + "paddingLeft": 8, + "gap": 4, + "borderRadius": 8, + "roundedBorderRadius": 1600 + }, + "icon": { "size": 16 } + }, + "textarea": { + "extend": { + "readonlyBackground": "#f0f0f1", + "borderWidth": 1, + "iconSize": 16, + "minHeight": 80 + }, + "root": { + "background": "#ffffff", + "disabledBackground": "#e2e2e4", + "filledBackground": "#ffffff", + "filledHoverBackground": "#ffffff", + "filledFocusBackground": "#ffffff", + "borderColor": "#cecfd2", + "hoverBorderColor": "#1dc831", + "focusBorderColor": "#1dc831", + "invalidBorderColor": "#f47f77", + "color": "#181a1f", + "disabledColor": "#85888e", + "placeholderColor": "#85888e", + "invalidPlaceholderColor": "#db3424", + "shadow": "none", + "paddingX": 14, + "paddingY": 14, + "borderRadius": 14, + "transitionDuration": 180, + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + }, + "lg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 }, + "sm": { "fontSize": 16, "paddingX": 14, "paddingY": 14 } + }, + "sm": { "fontSize": 16, "paddingX": 8, "paddingY": 8 }, + "lg": { "fontSize": 16, "paddingX": 14, "paddingY": 14 } + }, + "tieredmenu": { + "extend": { + "iconSize": 20, + "extSubmenu": { "borderColor": "#e2e2e4", "background": "#ffffff" }, + "extItem": { "caption": { "gap": 4, "color": "#85888e" } } + }, + "root": { + "background": "#ffffff", + "borderColor": "transparent", + "color": "#2b2e33", + "borderRadius": 14, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "transitionDuration": 180 + }, + "list": { "padding": 4, "gap": 4 }, + "item": { + "focusBackground": "#f0f0f1", + "activeBackground": "#2b2e33", + "color": "#2b2e33", + "focusColor": "#2b2e33", + "activeColor": "#ffffff", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8, + "gap": 8, + "icon": { + "color": "#2b2e33", + "focusColor": "#2b2e33", + "activeColor": "#ffffff" + } + }, + "submenu": { "mobileIndent": 14 }, + "separator": { "borderColor": "#e2e2e4" }, + "submenuIcon": { + "activeColor": "#56595f", + "color": "#2b2e33", + "focusColor": "#56595f", + "size": 14 + } + }, + "timeline": { + "extend": { "extEvent": { "gap": 4 } }, + "event": { "minHeight": 64 }, + "vertical": { + "eventContent": { + "paddingTop": 0, + "paddingRight": 20, + "paddingBottom": 0, + "paddingLeft": 20 + } + }, + "horizontal": { + "eventContent": { + "paddingTop": 20, + "paddingRight": 0, + "paddingBottom": 20, + "paddingLeft": 0 + } + }, + "eventMarker": { + "size": 16, + "borderRadius": 14, + "borderWidth": 4, + "background": "#ffffff", + "borderColor": "#44e858", + "content": { + "borderRadius": 14, + "size": 12, + "background": "transparent", + "insetShadow": "none" + } + }, + "eventConnector": { "color": "#e2e2e4", "size": 1 } + }, + "togglebutton": { + "extend": { + "ext": { "gap": 14 }, + "iconSize": { "sm": 16, "md": 20, "lg": 24 }, + "iconOnlyWidth": 40, + "hoverBorderColor": "#cecfd2", + "checkedHoverColor": "#ffffff", + "checkedHoverBackground": "#404348", + "checkedHoverBorderColor": "#404348", + "extXlg": { + "paddingTop": 20, + "paddingRight": 20, + "paddingBottom": 20, + "paddingLeft": 20, + "iconOnlyWidth": 64 + }, + "extSm": { "iconOnlyWidth": 32 }, + "extLg": { "iconOnlyWidth": 56 } + }, + "colorScheme": { + "root": { + "background": "#e2e2e4", + "hoverBackground": "#cecfd2", + "borderColor": "#e2e2e4", + "color": "#2b2e33", + "hoverColor": "#2b2e33", + "checkedBackground": "#2b2e33", + "checkedColor": "#ffffff", + "checkedBorderColor": "#2b2e33", + "disabledBackground": "#e2e2e4", + "disabledBorderColor": "#e2e2e4", + "disabledColor": "#85888e", + "invalidBorderColor": "#f47f77" + }, + "icon": { + "color": "#2b2e33", + "hoverColor": "#2b2e33", + "checkedColor": "#ffffff", + "disabledColor": "#85888e" + }, + "content": { "checkedBackground": "transparent" } + }, + "root": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 1600, + "gap": 8, + "fontWeight": "600", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "0 0 4px rgba(0, 0, 0, 0.2000)" + }, + "sm": { + "fontSize": 14, + "paddingTop": 4, + "paddingRight": 14, + "paddingBottom": 4, + "paddingLeft": 14 + }, + "lg": { + "fontSize": 20, + "paddingTop": 14, + "paddingRight": 24, + "paddingBottom": 14, + "paddingLeft": 24 + }, + "transitionDuration": 180, + "background": "#ffffff", + "borderColor": "#e2e2e4", + "checkedBackground": "#ffffff", + "checkedBorderColor": "#e2e2e4", + "checkedColor": "#2b2e33", + "color": "#2b2e33", + "disabledBackground": "#e2e2e4", + "disabledBorderColor": "#e2e2e4", + "disabledColor": "#85888e", + "hoverColor": "#56595f", + "invalidBorderColor": "#f47f77" + }, + "content": { + "checkedShadow": "none", + "padding": 0, + "borderRadius": 0, + "sm": { "padding": 0 }, + "lg": { "padding": 0 }, + "checkedBackground": "#ffffff" + }, + "icon": { + "checkedColor": "#2b2e33", + "color": "#2b2e33", + "disabledColor": "#85888e", + "hoverColor": "#56595f" + } + }, + "toggleswitch": { + "colorScheme": { + "root": { + "background": "#a2a5a9", + "hoverBackground": "#85888e", + "disabledBackground": "#e2e2e4", + "checkedBackground": "#2b2e33", + "checkedHoverBackground": "#404348" + }, + "handle": { + "background": "#ffffff", + "hoverBackground": "#ffffff", + "disabledBackground": "#85888e", + "checkedBackground": "#ffffff", + "checkedHoverBackground": "#ffffff", + "color": "#2b2e33", + "hoverColor": "#2b2e33", + "checkedColor": "#2b2e33", + "checkedHoverColor": "#2b2e33" + } + }, + "root": { + "width": 40, + "height": 24, + "borderRadius": 1600, + "gap": 4, + "borderWidth": 1, + "shadow": "none", + "focusRing": { + "width": 4, + "style": "none", + "color": "#d4fedc", + "offset": 0, + "shadow": "none" + }, + "borderColor": "transparent", + "hoverBorderColor": "transparent", + "checkedBorderColor": "transparent", + "checkedHoverBorderColor": "transparent", + "invalidBorderColor": "#f47f77", + "transitionDuration": 180, + "slideDuration": 180 + }, + "handle": { "borderRadius": 1600, "size": 16 } + }, + "tooltip": { + "colorScheme": { "root": { "background": "#2b2e33", "color": "#ffffff" } }, + "root": { + "maxWidth": 400, + "gutter": 4, + "shadow": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "borderRadius": 8 + } + }, + "tree": { + "root": { + "background": "#ffffff", + "color": "#2b2e33", + "padding": 14, + "gap": 4, + "indent": 14, + "transitionDuration": 180 + }, + "node": { + "paddingTop": 8, + "paddingRight": 14, + "paddingBottom": 8, + "paddingLeft": 14, + "color": "#2b2e33", + "selectedColor": "#ffffff", + "gap": 4, + "borderRadius": 14, + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + }, + "hoverBackground": "#f0f0f1", + "hoverColor": "#2b2e33", + "selectedBackground": "#2b2e33" + }, + "nodeIcon": { + "selectedColor": "#ffffff", + "color": "#2b2e33", + "hoverColor": "#56595f" + }, + "nodeToggleButton": { + "borderRadius": 4, + "size": 28, + "selectedHoverBackground": "#2b2e33", + "color": "#2b2e33", + "focusRing": { + "color": "#d4fedc", + "offset": 0, + "shadow": "none", + "style": "none", + "width": 4 + }, + "hoverBackground": "#f0f0f1", + "hoverColor": "#56595f", + "selectedHoverColor": "#56595f" + }, + "loadingIcon": { "size": 16 }, + "filter": { + "marginTop": 0, + "marginRight": 0, + "marginBottom": 8, + "marginLeft": 0 + } + }, + "overlaybadge": { + "root": { "outline": { "width": 0, "color": "transparent" } } + } +} diff --git a/src/theme/tokens/semantic/dark.json b/src/theme/tokens/semantic/dark.json new file mode 100644 index 00000000..1a25ff23 --- /dev/null +++ b/src/theme/tokens/semantic/dark.json @@ -0,0 +1,352 @@ +{ + "colorScheme": { + "color": { + "fg": { + "default": "#ffffff", + "hover": "#cecfd2", + "active": "#f0f0f1", + "focus": "#ffffff", + "muted": "#a2a5a9", + "subtle": "#a2a5a9", + "brand": { + "default": "#77f48a", + "hover": "#aafbb7", + "active": "#d4fedc", + "disabled": "#168322", + "visited": "#aafbb7", + "muted": "#44e858" + }, + "inverse": { + "default": "#2b2e33", + "hover": "#56595f", + "active": "#181a1f", + "focus": "#2b2e33", + "muted": "#85888e" + }, + "status": { + "danger": { + "default": "#f47f77", + "hover": "#fbacaa", + "active": "#fed4d4", + "disabled": "#8d2218", + "visited": "#fbacaa", + "muted": "#e85244" + }, + "info": { + "default": "#77baf4", + "hover": "#aad7fb", + "active": "#d4ecfe", + "disabled": "#18538d", + "visited": "#aad7fb", + "muted": "#4496e8" + }, + "warning": { + "default": "#facb75", + "hover": "#fddeaa", + "active": "#ffeed4", + "disabled": "#9d6d0e", + "visited": "#fddeaa", + "muted": "#f5b83d" + }, + "success": { + "default": "#77f48a", + "hover": "#aafbb7", + "active": "#d4fedc", + "disabled": "#168322", + "visited": "#aafbb7", + "muted": "#44e858" + }, + "help": { + "default": "#c084fc", + "hover": "#d8b4fe", + "active": "#e9d5ff", + "disabled": "#7e22ce", + "visited": "#d8b4fe", + "muted": "#a855f7" + } + }, + "on": { + "brand": { + "default": "#2b2e33", + "hover": "#2b2e33", + "active": "#2b2e33" + }, + "fill": { + "default": "#ffffff", + "hover": "#ffffff", + "active": "#ffffff", + "muted": "#e2e2e4" + }, + "status": { + "danger": { "default": "#fff0f0", "hover": "#fffafa" }, + "info": { "default": "#f0f9ff", "hover": "#fafdff" }, + "warning": { "default": "#fff9f0", "hover": "#fffdfa" }, + "success": { "default": "#f0fff3", "hover": "#fafffb" }, + "help": { "default": "#f3e8ff", "hover": "#faf5ff" } + } + } + }, + "bg": { + "status": { + "danger": { + "weak": { + "default": "#3b100c", + "hover": "#45120e", + "active": "#611912" + }, + "strong": { + "default": "#8d2218", + "hover": "#db3424", + "active": "#e85244" + } + }, + "info": { + "weak": { + "default": "#0c243b", + "hover": "#0e2a45", + "active": "#123a61" + }, + "strong": { + "default": "#18538d", + "hover": "#1e76cd", + "active": "#4496e8" + } + }, + "warning": { + "weak": { + "default": "#453008", + "hover": "#4f3709", + "active": "#6d4c0b" + }, + "strong": { + "default": "#9d6d0e", + "hover": "#dc9710", + "active": "#f5b83d" + } + }, + "success": { + "weak": { + "default": "#0c3b11", + "hover": "#0e4514", + "active": "#12611b" + }, + "strong": { + "default": "#168322", + "hover": "#1dc831", + "active": "#44e858" + } + }, + "help": { + "weak": { + "default": "#3b0764", + "hover": "#581c87", + "active": "#6b21a8" + }, + "strong": { + "default": "#7e22ce", + "hover": "#9333ea", + "active": "#a855f7" + } + } + }, + "brand": { + "weak": { "hover": "#0c3b11", "active": "#0e4514" }, + "strong": { + "default": "#44e858", + "hover": "#77f48a", + "active": "#aafbb7" + } + }, + "surface": { + "canvas": { + "default": "#2b2e33", + "hover": "#404348", + "active": "#56595f", + "selected": "#404348" + }, + "default": { + "default": "#404348", + "hover": "#56595f", + "active": "#6d7076", + "selected": "#56595f" + }, + "raised": { + "default": "#56595f", + "hover": "#6d7076", + "active": "#85888e", + "selected": "#6d7076" + }, + "overlay": { "default": "#404348", "hover": "#56595f" }, + "backdrop": "rgba(0, 0, 0, 0.6000)" + }, + "neutral": { + "weak": { + "default": "#2b2e33", + "hover": "#404348", + "active": "#56595f", + "disabled": "#404348" + }, + "medium": { + "default": "#404348", + "hover": "#56595f", + "active": "#6d7076", + "strong": "#85888e" + }, + "strong": { + "default": "#f0f0f1", + "hover": "#e2e2e4", + "active": "#cecfd2", + "selected": "#f0f0f1" + } + } + }, + "border": { + "focus": "#d4fedc", + "neutral": { + "default": "#404348", + "strong": "#56595f", + "bold": { "default": "#f0f0f1", "hover": "#e2e2e4" }, + "inverse": "#2b2e33" + }, + "brand": { + "subtle": "#12611b", + "default": "#44e858", + "strong": "#77f48a" + }, + "status": { + "danger": { + "subtle": "#db3424", + "default": "#e85244", + "strong": "#f47f77" + }, + "info": { "default": "#4496e8", "strong": "#77baf4" }, + "warning": { "default": "#f5b83d", "strong": "#facb75" }, + "success": { "default": "#44e858", "strong": "#77f48a" }, + "help": { "strong": "#c084fc" } + } + } + } + }, + "dimension": { + "space": { + "100": 4, + "150": 6, + "200": 8, + "300": 10, + "400": 14, + "500": 18, + "600": 20, + "700": 24, + "800": 28, + "none": 0, + "negative": { "50": -2, "200": -8, "300": -12, "600": -24 } + }, + "size": { + "50": 2, + "100": 4, + "150": 6, + "200": 8, + "300": 10, + "350": 12, + "400": 14, + "450": 16, + "500": 18, + "600": 20, + "700": 24, + "750": 26, + "800": 28, + "900": 32, + "1000": 36, + "1100": 40, + "1200": 48, + "1300": 56, + "1400": 64, + "1500": 80, + "1600": 240, + "1700": 272, + "1800": 304, + "1900": 336, + "2000": 400, + "none": 0, + "max": 1600 + }, + "borderRadius": { + "100": 4, + "200": 8, + "300": 10, + "400": 14, + "500": 20, + "none": 0, + "max": 1600 + }, + "borderWidth": { "100": 1, "200": 2, "300": 4, "none": 0 }, + "focusRing": { "width": 4, "offset": 0 }, + "depth": { + "100": "1000", + "200": "1100", + "300": "1200", + "400": "1300", + "500": "1400", + "600": "1500", + "700": "1600" + }, + "viewport": { "100": 576, "200": 768, "300": 992, "400": 1200, "500": 1400 } + }, + "effects": { + "opacity": { + "0": 0, + "4": "0.04", + "8": "0.08", + "12": "0.12", + "16": "0.16", + "20": "0.2", + "30": "0.3", + "40": "0.4", + "50": "0.5", + "60": "0.6", + "70": "0.7", + "80": "0.8", + "90": "0.9", + "100": "1" + }, + "blur": { + "100": "4px", + "200": "8px", + "300": "16px", + "400": "24px", + "none": 0 + }, + "transition": { + "easing": { + "linear": "linear", + "in": "cubic-bezier(0.55, 0.06, 0.7, 0.2)", + "out": "cubic-bezier(0.2, 0.6, 0.4, 1)", + "inOut": "cubic-bezier(0.65, 0.05, 0.35, 1)", + "standard": "cubic-bezier(0.2, 0, 0, 1)", + "accelerate": "cubic-bezier(0.3, 0, 1, 1)", + "decelerate": "cubic-bezier(0, 0, 0, 1)", + "emphasizedAccelerate": "cubic-bezier(0.3, 0, 0.8, 0.15)", + "emphasizedDecelerate": "cubic-bezier(0.05, 0.7, 0.1, 1)", + "spring": "cubic-bezier(0.34, 1.56, 0.64, 1)" + }, + "duration": { "100": 140, "200": 180, "300": 240, "400": 320, "500": 400 } + }, + "elevation": { + "100": "0 0 2px rgba(0, 0, 0, 0.2000)", + "200": "0 0 4px rgba(0, 0, 0, 0.2000)", + "300": "0 2px 4px rgba(0, 0, 0, 0.2000)", + "400": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "500": "0 8px 16px 0 rgba(0, 0, 0, 0.2000)", + "none": "none", + "status": { + "info": "0px 4px 8px 0px rgba(68, 150, 232, 0.04)", + "success": "0px 4px 8px 0px rgba(68, 232, 88, 0.04)", + "warning": "0px 4px 8px 0px rgba(245, 184, 61, 0.04)", + "danger": "0px 4px 8px 0px rgba(232, 82, 68, 0.04)", + "secondary": "0px 4px 8px 0px rgba(0, 0, 0, 0.0400)", + "contrast": "0px 4px 8px 0px rgba(0, 0, 0, 0.0400)" + } + }, + "focusRing": { "shadow": "inset 0 0 0 4px #d4fedc" } + } +} diff --git a/src/theme/tokens/semantic/light.json b/src/theme/tokens/semantic/light.json new file mode 100644 index 00000000..687f1010 --- /dev/null +++ b/src/theme/tokens/semantic/light.json @@ -0,0 +1,352 @@ +{ + "colorScheme": { + "color": { + "fg": { + "default": "#2b2e33", + "hover": "#56595f", + "active": "#181a1f", + "focus": "#2b2e33", + "muted": "#85888e", + "subtle": "#6d7076", + "brand": { + "default": "#44e858", + "hover": "#1dc831", + "active": "#168322", + "disabled": "#aafbb7", + "visited": "#12611b", + "muted": "#77f48a" + }, + "inverse": { + "default": "#ffffff", + "hover": "#ffffff", + "active": "#ffffff", + "focus": "#ffffff", + "muted": "rgba(255, 255, 255, 0.7000)" + }, + "status": { + "danger": { + "default": "#e85244", + "hover": "#db3424", + "active": "#8d2218", + "disabled": "#fbacaa", + "visited": "#611912", + "muted": "#f47f77" + }, + "info": { + "default": "#4496e8", + "hover": "#1e76cd", + "active": "#18538d", + "disabled": "#aad7fb", + "visited": "#123a61", + "muted": "#77baf4" + }, + "warning": { + "default": "#f5b83d", + "hover": "#dc9710", + "active": "#9d6d0e", + "disabled": "#fddeaa", + "visited": "#6d4c0b", + "muted": "#facb75" + }, + "success": { + "default": "#44e858", + "hover": "#1dc831", + "active": "#168322", + "disabled": "#aafbb7", + "visited": "#12611b", + "muted": "#77f48a" + }, + "help": { + "default": "#a855f7", + "hover": "#9333ea", + "active": "#7e22ce", + "disabled": "#d8b4fe", + "visited": "#6b21a8", + "muted": "#c084fc" + } + }, + "on": { + "brand": { + "default": "#2b2e33", + "hover": "#2b2e33", + "active": "#2b2e33" + }, + "fill": { + "default": "#ffffff", + "hover": "#ffffff", + "active": "#ffffff", + "muted": "#e2e2e4" + }, + "status": { + "danger": { "default": "#45120e", "hover": "#3b100c" }, + "info": { "default": "#0e2a45", "hover": "#0c243b" }, + "warning": { "default": "#4f3709", "hover": "#453008" }, + "success": { "default": "#0e4514", "hover": "#0c3b11" }, + "help": { "default": "#581c87", "hover": "#3b0764" } + } + } + }, + "bg": { + "status": { + "danger": { + "weak": { + "default": "#fffafa", + "hover": "#fff0f0", + "active": "#fed4d4" + }, + "strong": { + "default": "#fbacaa", + "hover": "#f47f77", + "active": "#e85244" + } + }, + "info": { + "weak": { + "default": "#fafdff", + "hover": "#f0f9ff", + "active": "#d4ecfe" + }, + "strong": { + "default": "#aad7fb", + "hover": "#77baf4", + "active": "#4496e8" + } + }, + "warning": { + "weak": { + "default": "#fffdfa", + "hover": "#fff9f0", + "active": "#ffeed4" + }, + "strong": { + "default": "#fddeaa", + "hover": "#facb75", + "active": "#f5b83d" + } + }, + "success": { + "weak": { + "default": "#fafffb", + "hover": "#f0fff3", + "active": "#d4fedc" + }, + "strong": { + "default": "#aafbb7", + "hover": "#77f48a", + "active": "#44e858" + } + }, + "help": { + "weak": { + "default": "#faf5ff", + "hover": "#f3e8ff", + "active": "#e9d5ff" + }, + "strong": { + "default": "#d8b4fe", + "hover": "#c084fc", + "active": "#a855f7" + } + } + }, + "brand": { + "weak": { "hover": "#fafffb", "active": "#f0fff3" }, + "strong": { + "default": "#44e858", + "hover": "#1dc831", + "active": "#168322" + } + }, + "surface": { + "canvas": { + "default": "#f0f0f1", + "hover": "#e2e2e4", + "active": "#cecfd2", + "selected": "#e2e2e4" + }, + "default": { + "default": "#ffffff", + "hover": "#fafafa", + "active": "#f0f0f1", + "selected": "#fafafa" + }, + "raised": { + "default": "#ffffff", + "hover": "#fafafa", + "active": "#f0f0f1", + "selected": "#fafafa" + }, + "overlay": { "default": "#ffffff", "hover": "#fafafa" }, + "backdrop": "rgba(0, 0, 0, 0.4000)" + }, + "neutral": { + "weak": { + "default": "#f0f0f1", + "hover": "#e2e2e4", + "active": "#cecfd2", + "disabled": "#e2e2e4" + }, + "medium": { + "default": "#e2e2e4", + "hover": "#cecfd2", + "active": "#a2a5a9", + "strong": "#85888e" + }, + "strong": { + "default": "#2b2e33", + "hover": "#404348", + "active": "#56595f", + "selected": "#2b2e33" + } + } + }, + "border": { + "focus": "#d4fedc", + "neutral": { + "default": "#e2e2e4", + "strong": "#cecfd2", + "bold": { "default": "#2b2e33", "hover": "#404348" }, + "inverse": "#ffffff" + }, + "brand": { + "subtle": "#d4fedc", + "default": "#44e858", + "strong": "#1dc831" + }, + "status": { + "danger": { + "subtle": "#f47f77", + "default": "#e85244", + "strong": "#db3424" + }, + "info": { "default": "#4496e8", "strong": "#1e76cd" }, + "warning": { "default": "#f5b83d", "strong": "#dc9710" }, + "success": { "default": "#44e858", "strong": "#1dc831" }, + "help": { "strong": "#9333ea" } + } + } + } + }, + "dimension": { + "space": { + "100": 4, + "150": 6, + "200": 8, + "300": 10, + "400": 14, + "500": 18, + "600": 20, + "700": 24, + "800": 28, + "none": 0, + "negative": { "50": -2, "200": -8, "300": -12, "600": -24 } + }, + "size": { + "50": 2, + "100": 4, + "150": 6, + "200": 8, + "300": 10, + "350": 12, + "400": 14, + "450": 16, + "500": 18, + "600": 20, + "700": 24, + "750": 26, + "800": 28, + "900": 32, + "1000": 36, + "1100": 40, + "1200": 48, + "1300": 56, + "1400": 64, + "1500": 80, + "1600": 240, + "1700": 272, + "1800": 304, + "1900": 336, + "2000": 400, + "none": 0, + "max": 1600 + }, + "borderRadius": { + "100": 4, + "200": 8, + "300": 10, + "400": 14, + "500": 20, + "none": 0, + "max": 1600 + }, + "borderWidth": { "100": 1, "200": 2, "300": 4, "none": 0 }, + "focusRing": { "width": 4, "offset": 0 }, + "depth": { + "100": "1000", + "200": "1100", + "300": "1200", + "400": "1300", + "500": "1400", + "600": "1500", + "700": "1600" + }, + "viewport": { "100": 576, "200": 768, "300": 992, "400": 1200, "500": 1400 } + }, + "effects": { + "opacity": { + "0": 0, + "4": "0.04", + "8": "0.08", + "12": "0.12", + "16": "0.16", + "20": "0.2", + "30": "0.3", + "40": "0.4", + "50": "0.5", + "60": "0.6", + "70": "0.7", + "80": "0.8", + "90": "0.9", + "100": "1" + }, + "blur": { + "100": "4px", + "200": "8px", + "300": "16px", + "400": "24px", + "none": 0 + }, + "transition": { + "easing": { + "linear": "linear", + "in": "cubic-bezier(0.55, 0.06, 0.7, 0.2)", + "out": "cubic-bezier(0.2, 0.6, 0.4, 1)", + "inOut": "cubic-bezier(0.65, 0.05, 0.35, 1)", + "standard": "cubic-bezier(0.2, 0, 0, 1)", + "accelerate": "cubic-bezier(0.3, 0, 1, 1)", + "decelerate": "cubic-bezier(0, 0, 0, 1)", + "emphasizedAccelerate": "cubic-bezier(0.3, 0, 0.8, 0.15)", + "emphasizedDecelerate": "cubic-bezier(0.05, 0.7, 0.1, 1)", + "spring": "cubic-bezier(0.34, 1.56, 0.64, 1)" + }, + "duration": { "100": 140, "200": 180, "300": 240, "400": 320, "500": 400 } + }, + "elevation": { + "100": "0 0 2px rgba(0, 0, 0, 0.2000)", + "200": "0 0 4px rgba(0, 0, 0, 0.2000)", + "300": "0 2px 4px rgba(0, 0, 0, 0.2000)", + "400": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "500": "0 8px 16px 0 rgba(0, 0, 0, 0.2000)", + "none": "none", + "status": { + "info": "0px 4px 8px 0px rgba(68, 150, 232, 0.04)", + "success": "0px 4px 8px 0px rgba(68, 232, 88, 0.04)", + "warning": "0px 4px 8px 0px rgba(245, 184, 61, 0.04)", + "danger": "0px 4px 8px 0px rgba(232, 82, 68, 0.04)", + "secondary": "0px 4px 8px 0px rgba(0, 0, 0, 0.0400)", + "contrast": "0px 4px 8px 0px rgba(0, 0, 0, 0.0400)" + } + }, + "focusRing": { "shadow": "inset 0 0 0 4px #d4fedc" } + } +} diff --git a/src/theme/types.ts b/src/theme/types.ts index 250836a5..7cc9d2dc 100644 --- a/src/theme/types.ts +++ b/src/theme/types.ts @@ -12,6 +12,8 @@ import type sizing from './assets/sizing.json' import type spacing from './assets/spacing.json' import type lightTheme from './assets/themeLight.json' import type typography from './assets/typography.json' +import type lightComponentTokens from './tokens/components/light.json' +import type lightSemanticTokens from './tokens/semantic/light.json' export interface ThemeType { background: typeof background @@ -21,6 +23,8 @@ export interface ThemeType { global: typeof global sizing: typeof sizing spacing: typeof spacing + semantic: typeof lightSemanticTokens + components: typeof lightComponentTokens theme: typeof lightTheme & { custom: typeof customLight InputSize: typeof InputSize From bce2d906732feb56cdd2532b3f53d59e6ae23b06 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Thu, 30 Jul 2026 21:36:19 +0300 Subject: [PATCH 04/40] =?UTF-8?q?fix:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BD=D0=BE=D1=80=D0=BC=D0=B0?= =?UTF-8?q?=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D1=80=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D1=83=D1=81=D0=BE=D0=B2=20=D0=B2=20=D1=82=D0=BE=D0=BA?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/token-generator/README.md | 11 +++++++ .../__tests__/compiler.test.ts | 30 ++++++++++++++++++- scripts/token-generator/core/normalization.ts | 24 +++++++++++++++ scripts/token-generator/core/validation.ts | 3 +- src/theme/tokens/components/dark.json | 4 +-- src/theme/tokens/components/light.json | 4 +-- 6 files changed, 70 insertions(+), 6 deletions(-) diff --git a/scripts/token-generator/README.md b/scripts/token-generator/README.md index bbe25f0b..c2c280f7 100644 --- a/scripts/token-generator/README.md +++ b/scripts/token-generator/README.md @@ -85,6 +85,17 @@ padding: "8 14" -> paddingLeft: 14 ``` +Для `borderRadius` одинаковые значения сворачиваются в число. Разные значения +сохраняются в объекте в порядке углов CSS: + +```text +borderRadius: "0 0 0 0" +-> borderRadius: 0 + +borderRadius: "4 8 12 16" +-> borderRadius: { left: 16, top: 4, right: 8, bottom: 12 } +``` + Генерация завершается с ошибкой при отсутствующей или циклической ссылке, неподдерживаемом shorthand, оставшихся `rem`/`ms`, `NaN` или `Infinity`. diff --git a/scripts/token-generator/__tests__/compiler.test.ts b/scripts/token-generator/__tests__/compiler.test.ts index a0be0dc4..ce899ca0 100644 --- a/scripts/token-generator/__tests__/compiler.test.ts +++ b/scripts/token-generator/__tests__/compiler.test.ts @@ -9,7 +9,11 @@ import { parseArgs, } from '../build' import { compileTokens } from '../core/compiler' -import { convertUnit, parseBoxShorthand } from '../core/normalization' +import { + convertUnit, + normalizeTree, + parseBoxShorthand, +} from '../core/normalization' import { resolveReferences } from '../core/resolution' import { isTokenTree, @@ -121,6 +125,22 @@ describe('token compiler', () => { }) }) + describe('normalizeTree', () => { + test('одинаковые радиусы сворачивает в одно значение', () => { + expect( + normalizeTree({ borderRadius: '0rem 0rem 0rem 0rem' }) + ).toStrictEqual({ borderRadius: 0 }) + }) + + test('разные радиусы сохраняет отдельными значениями', () => { + expect( + normalizeTree({ borderRadius: '0.25rem 0.5rem 0.75rem 1rem' }) + ).toStrictEqual({ + borderRadius: { left: 16, top: 4, right: 8, bottom: 12 }, + }) + }) + }) + test('разделяет один источник на темы, разрешает ссылки и нормализует значения', () => { const source: TokenTree = { primitive: { @@ -303,6 +323,14 @@ describe('production input tokens', () => { expect(compiled.components.dark.accordion).toHaveProperty( 'colorScheme.header.background' ) + expect(compiled.components.light.dataview).toHaveProperty( + 'header.borderRadius', + 0 + ) + expect(compiled.components.dark.dataview).toHaveProperty( + 'footer.borderRadius', + 0 + ) }) test('после записи повторная проверка не находит изменений', () => { diff --git a/scripts/token-generator/core/normalization.ts b/scripts/token-generator/core/normalization.ts index 6856ba86..4bf548ca 100644 --- a/scripts/token-generator/core/normalization.ts +++ b/scripts/token-generator/core/normalization.ts @@ -78,6 +78,25 @@ export const parseBoxShorthand = ( return { top, right, bottom, left } } +const normalizeBorderRadius = ( + value: string | number, + tokenPath: string +): number | TokenTree => { + const corners = parseBoxShorthand(value, tokenPath) + const values = Object.values(corners) + + if (values.every((corner) => corner === corners.top)) { + return corners.top + } + + return { + left: corners.left, + top: corners.top, + right: corners.right, + bottom: corners.bottom, + } +} + const edgePropertyName = ( property: BoxProperty, edge: keyof BoxEdges @@ -128,6 +147,11 @@ export const normalizeTree = ( const boxProperty = BOX_PROPERTIES.find((property) => property === key) if ( + key === 'borderRadius' && + (typeof value === 'string' || typeof value === 'number') + ) { + normalized[key] = normalizeBorderRadius(value, currentPath) + } else if ( boxProperty && (typeof value === 'string' || typeof value === 'number') ) { diff --git a/scripts/token-generator/core/validation.ts b/scripts/token-generator/core/validation.ts index 3e02b946..e1d5ad6b 100644 --- a/scripts/token-generator/core/validation.ts +++ b/scripts/token-generator/core/validation.ts @@ -19,7 +19,8 @@ export const assertValidOutput = ( if (isTokenTree(node)) { for (const [key, value] of Object.entries(node)) { if ( - BOX_PROPERTIES.includes(key as BoxProperty) && + (BOX_PROPERTIES.includes(key as BoxProperty) || + key === 'borderRadius') && typeof value === 'string' ) { throw new Error(`Unconverted box shorthand at "${tokenPath}.${key}"`) diff --git a/src/theme/tokens/components/dark.json b/src/theme/tokens/components/dark.json index 111be1c4..dad859e7 100644 --- a/src/theme/tokens/components/dark.json +++ b/src/theme/tokens/components/dark.json @@ -894,7 +894,7 @@ "paddingRight": 14, "paddingBottom": 8, "paddingLeft": 14, - "borderRadius": "0px 0px 0px 0px", + "borderRadius": 0, "color": "#ffffff", "borderColor": "#404348" }, @@ -917,7 +917,7 @@ "paddingRight": 14, "paddingBottom": 8, "paddingLeft": 14, - "borderRadius": "0px 0px 0px 0px", + "borderRadius": 0, "borderColor": "#404348" }, "paginatorTop": { diff --git a/src/theme/tokens/components/light.json b/src/theme/tokens/components/light.json index ab86e22f..837beb80 100644 --- a/src/theme/tokens/components/light.json +++ b/src/theme/tokens/components/light.json @@ -894,7 +894,7 @@ "paddingRight": 14, "paddingBottom": 8, "paddingLeft": 14, - "borderRadius": "0px 0px 0px 0px", + "borderRadius": 0, "color": "#2b2e33", "borderColor": "#e2e2e4" }, @@ -917,7 +917,7 @@ "paddingRight": 14, "paddingBottom": 8, "paddingLeft": 14, - "borderRadius": "0px 0px 0px 0px", + "borderRadius": 0, "borderColor": "#e2e2e4" }, "paginatorTop": { From c435a3f5d8cfdc47d89dc5bf1da199a2c727d353 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Fri, 31 Jul 2026 13:03:03 +0300 Subject: [PATCH 05/40] =?UTF-8?q?fix:=20=D0=B4=D0=BE=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=B0=D0=BD=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D1=80=20=D0=B4=D0=B8=D0=B7=D0=B0=D0=B9=D0=BD-?= =?UTF-8?q?=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/token-generator/README.md | 26 +++-- .../__tests__/compiler.test.ts | 105 ++++++++++++++---- scripts/token-generator/build.ts | 23 +++- scripts/token-generator/core/normalization.ts | 60 ++++++++-- scripts/token-generator/core/validation.ts | 23 +++- scripts/token-generator/io.ts | 53 ++++++--- src/theme/tokens/components/dark.json | 60 +++++----- src/theme/tokens/components/light.json | 60 +++++----- src/theme/tokens/semantic/dark.json | 48 ++++---- src/theme/tokens/semantic/light.json | 48 ++++---- 10 files changed, 335 insertions(+), 171 deletions(-) diff --git a/scripts/token-generator/README.md b/scripts/token-generator/README.md index c2c280f7..e8e7dfa1 100644 --- a/scripts/token-generator/README.md +++ b/scripts/token-generator/README.md @@ -10,8 +10,9 @@ 4. Запустить `yarn tokens:validate`. 5. Закоммитить входные и сгенерированные токены вместе. -`tokens:generate` записывает и форматирует файлы. `tokens:validate` ничего не -меняет: проверяет TypeScript генератора и актуальность сгенерированных токенов. +`tokens:generate` нормализует значения, удаляет лишние JSON и записывает +результат. `tokens:validate` ничего не меняет: проверяет TypeScript генератора и +актуальность сгенерированных токенов. ## Использование в компонентах @@ -71,14 +72,18 @@ Light- и dark-файлы должны иметь одинаковую стру ```text "1.5rem" -> 24 +"4px" -> 4 "150ms" -> 150 +"0.4" -> 0.4 "0" -> 0 ``` +Числовые строки преобразуются в числа, включая `fontWeight`. + CSS shorthand из 2–4 значений раскрывается в поля React Native: ```text -padding: "8 14" +padding: "8px 14px" -> paddingTop: 8 -> paddingRight: 14 -> paddingBottom: 8 @@ -96,14 +101,21 @@ borderRadius: "4 8 12 16" -> borderRadius: { left: 16, top: 4, right: 8, bottom: 12 } ``` +Значения `boxShadow` сохраняются строками. Размеры внутри строки записываются в +`px`, поэтому ссылка на `0.25rem` превращается в `4px`. `boxShadow` требует New +Architecture. На Android обычные тени поддерживаются с API 28, `inset` — с +API 29. Fallback для более ранних версий намеренно не предусмотрен. + Генерация завершается с ошибкой при отсутствующей или циклической ссылке, -неподдерживаемом shorthand, оставшихся `rem`/`ms`, `NaN` или `Infinity`. +неподдерживаемом shorthand, непреобразованных числовых значениях и единицах, +составных `rem`/`px` вне `boxShadow`, `NaN` или `Infinity`. ## Автоматические проверки -`yarn tokens:validate` запускается при сборке, в CI и перед push. Если -сгенерированные файлы устарели, нужно выполнить `yarn tokens:generate` и -проверить diff. +`yarn tokens:check` только проверяет файлы и отдельно показывает отсутствующие, +изменённые и лишние JSON. `yarn tokens:validate` дополнительно проверяет +TypeScript генератора. Если проверка не прошла, нужно выполнить +`yarn tokens:generate` и проверить diff. ## Устройство генератора diff --git a/scripts/token-generator/__tests__/compiler.test.ts b/scripts/token-generator/__tests__/compiler.test.ts index ce899ca0..97fd6983 100644 --- a/scripts/token-generator/__tests__/compiler.test.ts +++ b/scripts/token-generator/__tests__/compiler.test.ts @@ -1,4 +1,10 @@ -import { readdirSync, mkdtempSync, writeFileSync, rmSync } from 'node:fs' +import { + accessSync, + readdirSync, + mkdtempSync, + writeFileSync, + rmSync, +} from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' @@ -21,9 +27,10 @@ import { type TokenTree, type TokenValue, } from '../core/types' +import { assertValidOutput } from '../core/validation' import { OUTPUT_FILES, - findStaleGeneratedTokens, + findGeneratedTokenIssues, loadTokenTree, writeGeneratedTokens, } from '../io' @@ -65,6 +72,8 @@ describe('token compiler', () => { { name: 'положительный rem', value: '1.5rem', expected: 24 }, { name: 'отрицательный rem', value: '-0.5rem', expected: -8 }, { name: 'миллисекунды', value: '150ms', expected: 150 }, + { name: 'пиксели', value: '4px', expected: 4 }, + { name: 'числовая строка', value: '0.4', expected: 0.4 }, { name: 'строковый ноль', value: '0', expected: 0 }, { name: 'rem внутри составной строки', @@ -75,6 +84,12 @@ describe('token compiler', () => { ])('$name преобразуется в ожидаемое значение', ({ value, expected }) => { expect(convertUnit(value)).toBe(expected) }) + + test('отклоняет rem внутри неподдерживаемой составной строки', () => { + expect(() => convertUnit('blur(1rem)', 'semantic.effects.blur')).toThrow( + 'Unsupported composite unit value "blur(1rem)" at "semantic.effects.blur"' + ) + }) }) describe('parseBoxShorthand', () => { @@ -99,6 +114,11 @@ describe('token compiler', () => { value: '0rem 1.5rem 0.875rem 1.5rem', expected: { top: 0, right: 24, bottom: 14, left: 24 }, }, + { + name: 'значения с px', + value: '4px 8px 12px 16px', + expected: { top: 4, right: 8, bottom: 12, left: 16 }, + }, ])('$name раскрывается по правилам CSS', ({ value, expected }) => { expect(parseBoxShorthand(value)).toStrictEqual(expected) }) @@ -112,7 +132,7 @@ describe('token compiler', () => { }, { name: 'неподдерживаемая единица', - value: '1px 2px', + value: '1em 2em', message: 'Invalid box value', }, { @@ -139,6 +159,29 @@ describe('token compiler', () => { borderRadius: { left: 16, top: 4, right: 8, bottom: 12 }, }) }) + + test('преобразует числовые строки, включая fontWeight', () => { + expect( + normalizeTree({ depth: '1000', opacity: '0.4', fontWeight: '600' }) + ).toStrictEqual({ depth: 1000, opacity: 0.4, fontWeight: 600 }) + }) + }) + + describe('assertValidOutput', () => { + test.each(['4px', '0.4', 'blur(4px)'])( + 'отклоняет непреобразованное значение %s', + (value) => { + expect(() => assertValidOutput(value, 'semantic.value')).toThrow( + 'Unconverted token' + ) + } + ) + + test('разрешает boxShadow', () => { + expect(() => + assertValidOutput('0 0 4px #000', 'components.button.shadow') + ).not.toThrow() + }) }) test('разделяет один источник на темы, разрешает ссылки и нормализует значения', () => { @@ -309,8 +352,20 @@ describe('production input tokens', () => { }) test('совпадает с закоммиченными сгенерированными токенами', () => { - expect(findStaleGeneratedTokens(compiled, TOKENS_DIRECTORY)).toStrictEqual( - [] + expect(findGeneratedTokenIssues(compiled, TOKENS_DIRECTORY)).toStrictEqual({ + missing: [], + changed: [], + unexpected: [], + }) + }) + + test('преобразует числовые RN-значения', () => { + expect(compiled.semantic.light).toHaveProperty('dimension.depth.100', 1000) + expect(compiled.semantic.light).toHaveProperty('effects.opacity.4', 0.04) + expect(compiled.semantic.light).toHaveProperty('effects.blur.100', 4) + expect(compiled.components.light).toHaveProperty( + 'button.root.label.fontWeight', + 600 ) }) @@ -333,8 +388,12 @@ describe('production input tokens', () => { ) }) - test('после записи повторная проверка не находит изменений', () => { + test('check находит расхождения, а generate приводит файлы к актуальному состоянию', () => { const temporaryDirectory = mkdtempSync(join(tmpdir(), 'token-generator-')) + const unexpectedFile = join(temporaryDirectory, 'common.json') + const preservedFile = join(temporaryDirectory, 'README.md') + const missingFile = OUTPUT_FILES.semantic.dark + const changedFile = OUTPUT_FILES.semantic.light try { writeGeneratedTokens(compiled, temporaryDirectory) @@ -345,23 +404,31 @@ describe('production input tokens', () => { .sort() ) expect( - findStaleGeneratedTokens(compiled, temporaryDirectory) - ).toStrictEqual([]) + findGeneratedTokenIssues(compiled, temporaryDirectory) + ).toStrictEqual({ missing: [], changed: [], unexpected: [] }) - writeFileSync(join(temporaryDirectory, 'common.json'), '{}\n') + writeFileSync(unexpectedFile, '{}\n') + writeFileSync(preservedFile, '# Generated tokens\n') + rmSync(join(temporaryDirectory, missingFile)) + writeFileSync(join(temporaryDirectory, changedFile), '{}\n') - expect(findStaleGeneratedTokens(compiled, temporaryDirectory)).toContain( - 'common.json' - ) + expect( + findGeneratedTokenIssues(compiled, temporaryDirectory) + ).toStrictEqual({ + missing: [missingFile], + changed: [changedFile], + unexpected: ['common.json'], + }) + expect(() => accessSync(unexpectedFile)).not.toThrow() + expect(() => accessSync(preservedFile)).not.toThrow() - writeFileSync( - join(temporaryDirectory, OUTPUT_FILES.semantic.light), - '{}\n' - ) + writeGeneratedTokens(compiled, temporaryDirectory) - expect(findStaleGeneratedTokens(compiled, temporaryDirectory)).toContain( - OUTPUT_FILES.semantic.light - ) + expect( + findGeneratedTokenIssues(compiled, temporaryDirectory) + ).toStrictEqual({ missing: [], changed: [], unexpected: [] }) + expect(() => accessSync(unexpectedFile)).toThrow('ENOENT') + expect(() => accessSync(preservedFile)).not.toThrow() } finally { rmSync(temporaryDirectory, { recursive: true, force: true }) } diff --git a/scripts/token-generator/build.ts b/scripts/token-generator/build.ts index d4fb1510..e689e838 100644 --- a/scripts/token-generator/build.ts +++ b/scripts/token-generator/build.ts @@ -3,7 +3,8 @@ import { resolve, join } from 'node:path' import { compileTokens } from './core/compiler' import type { CompiledTokens } from './core/types' import { - findStaleGeneratedTokens, + findGeneratedTokenIssues, + type GeneratedTokenIssues, loadTokenTree, writeGeneratedTokens, } from './io' @@ -43,6 +44,19 @@ export const parseArgs = (arguments_: string[]): CliOptions => { export const compileInputTokens = (): CompiledTokens => compileTokens(loadTokenTree(INPUT_FILE)) +const formatTokenIssues = (issues: GeneratedTokenIssues): string => + [ + issues.missing.length > 0 + ? `Отсутствуют: ${issues.missing.join(', ')}` + : '', + issues.changed.length > 0 ? `Изменены: ${issues.changed.join(', ')}` : '', + issues.unexpected.length > 0 + ? `Лишние: ${issues.unexpected.join(', ')}` + : '', + ] + .filter(Boolean) + .join('\n') + export const run = (arguments_: string[]): void => { const options = parseArgs(arguments_) @@ -55,11 +69,12 @@ export const run = (arguments_: string[]): void => { const compiled = compileInputTokens() if (options.check) { - const staleFiles = findStaleGeneratedTokens(compiled, TOKENS_DIRECTORY) + const issues = findGeneratedTokenIssues(compiled, TOKENS_DIRECTORY) + const issueDescription = formatTokenIssues(issues) - if (staleFiles.length > 0) { + if (issueDescription) { throw new Error( - `Сгенерированные токены устарели: ${staleFiles.join(', ')}. ` + + `Сгенерированные токены неактуальны:\n${issueDescription}\n` + 'Запустите yarn tokens:generate.' ) } diff --git a/scripts/token-generator/core/normalization.ts b/scripts/token-generator/core/normalization.ts index 4bf548ca..dbde5671 100644 --- a/scripts/token-generator/core/normalization.ts +++ b/scripts/token-generator/core/normalization.ts @@ -7,11 +7,46 @@ import { } from './types' const REM_BASE = 16 +const NUMBER_PATTERN = /^-?\d*\.?\d+$/ +const PIXEL_PATTERN = /^-?\d*\.?\d+px$/ +const SHADOW_LENGTH_PATTERN = /^(?:0|-?\d*\.?\d+(?:rem|px))$/ export const BOX_PROPERTIES = ['padding', 'margin', 'borderWidth'] as const export type BoxProperty = (typeof BOX_PROPERTIES)[number] -export const convertUnit = (value: TokenPrimitive): TokenPrimitive => { +export const isBoxShadowValue = (value: string): boolean => { + const parts = value + .trim() + .split(/\s+(?![^(]*\))/) + .filter(Boolean) + const insetIndex = parts.indexOf('inset') + + if (insetIndex > 0 && insetIndex < parts.length - 1) return false + + const shadowParts = parts.filter((_, index) => index !== insetIndex) + const colorIndexes = shadowParts + .map((part, index) => (SHADOW_LENGTH_PATTERN.test(part) ? -1 : index)) + .filter((index) => index !== -1) + + if (colorIndexes.length !== 1) return false + + const [colorIndex] = colorIndexes + + if (colorIndex !== 0 && colorIndex !== shadowParts.length - 1) return false + + const lengths = shadowParts.filter((_, index) => index !== colorIndex) + + return ( + lengths.length >= 2 && + lengths.length <= 4 && + lengths.every((part) => SHADOW_LENGTH_PATTERN.test(part)) + ) +} + +export const convertUnit = ( + value: TokenPrimitive, + tokenPath = 'root' +): TokenPrimitive => { if (typeof value !== 'string') return value const isRem = /^-?\d*\.?\d+rem$/.test(value) @@ -22,22 +57,33 @@ export const convertUnit = (value: TokenPrimitive): TokenPrimitive => { if (isMilliseconds) return Number(value.slice(0, -2)) - if (value === '0') return 0 + if (PIXEL_PATTERN.test(value)) return Number(value.slice(0, -2)) - return value.replace(/-?\d*\.?\d+rem\b/g, (token) => { + if (NUMBER_PATTERN.test(value)) return Number(value) + + const converted = value.replace(/-?\d*\.?\d+rem\b/g, (token) => { const pixels = Number(token.slice(0, -3)) * REM_BASE return `${pixels}px` }) + + if (converted !== value && !isBoxShadowValue(converted)) { + throw new Error( + `Unsupported composite unit value "${value}" at "${tokenPath}"` + ) + } + + return converted } const parseBoxPart = (part: string, tokenPath: string): number => { - if (!/^-?\d*\.?\d+(?:rem)?$/.test(part)) { + if (!/^-?\d*\.?\d+(?:rem|px)?$/.test(part)) { throw new Error(`Invalid box value "${part}" at "${tokenPath}"`) } - const isRem = part.endsWith('rem') - const value = Number(isRem ? part.slice(0, -3) : part) + const unit = part.endsWith('rem') ? 'rem' : part.endsWith('px') ? 'px' : '' + const value = Number(unit ? part.slice(0, -unit.length) : part) + const isRem = unit === 'rem' const normalized = isRem ? value * REM_BASE : value if (!Number.isFinite(normalized)) { @@ -138,7 +184,7 @@ export const normalizeTree = ( ) } - if (!isTokenTree(node)) return convertUnit(node) + if (!isTokenTree(node)) return convertUnit(node, tokenPath) const normalized: TokenTree = {} diff --git a/scripts/token-generator/core/validation.ts b/scripts/token-generator/core/validation.ts index e1d5ad6b..7923ad75 100644 --- a/scripts/token-generator/core/validation.ts +++ b/scripts/token-generator/core/validation.ts @@ -1,8 +1,14 @@ -import { BOX_PROPERTIES, type BoxProperty } from './normalization' +import { + BOX_PROPERTIES, + isBoxShadowValue, + type BoxProperty, +} from './normalization' import { isTokenTree, type TokenTree, type TokenValue } from './types' const REFERENCE_PATTERN = /\{[^}]+\}/ const UNCONVERTED_UNIT_PATTERN = /-?\d*\.?\d+(?:rem|ms)\b/ +const PIXEL_PATTERN = /-?\d*\.?\d+px\b/ +const NUMERIC_STRING_PATTERN = /^-?\d*\.?\d+$/ export const assertValidOutput = ( node: TokenValue, @@ -36,11 +42,16 @@ export const assertValidOutput = ( throw new Error(`Non-finite number at "${tokenPath}"`) } - if ( - typeof node === 'string' && - (REFERENCE_PATTERN.test(node) || UNCONVERTED_UNIT_PATTERN.test(node)) - ) { - throw new Error(`Unconverted token "${node}" at "${tokenPath}"`) + if (typeof node === 'string') { + const hasUnconvertedValue = + REFERENCE_PATTERN.test(node) || + UNCONVERTED_UNIT_PATTERN.test(node) || + (PIXEL_PATTERN.test(node) && !isBoxShadowValue(node)) || + NUMERIC_STRING_PATTERN.test(node) + + if (hasUnconvertedValue) { + throw new Error(`Unconverted token "${node}" at "${tokenPath}"`) + } } } diff --git a/scripts/token-generator/io.ts b/scripts/token-generator/io.ts index d4c0e85f..301d159c 100644 --- a/scripts/token-generator/io.ts +++ b/scripts/token-generator/io.ts @@ -5,6 +5,7 @@ import { writeFileSync, renameSync, existsSync, + unlinkSync, } from 'node:fs' import { dirname, join } from 'node:path' import { isDeepStrictEqual } from 'node:util' @@ -56,6 +57,16 @@ export const writeGeneratedTokens = ( ): void => { mkdirSync(outputDirectory, { recursive: true }) + const expectedFiles = new Set( + outputEntries(compiled).map(([fileName]) => fileName) + ) + + for (const fileName of findJsonFiles(outputDirectory)) { + if (!expectedFiles.has(fileName)) { + unlinkSync(join(outputDirectory, fileName)) + } + } + for (const [fileName, value] of outputEntries(compiled)) { const outputPath = join(outputDirectory, fileName) const temporaryPath = `${outputPath}.tmp` @@ -84,26 +95,40 @@ const findJsonFiles = (directory: string, prefix = ''): string[] => { .sort() } -export const findStaleGeneratedTokens = ( +export interface GeneratedTokenIssues { + missing: string[] + changed: string[] + unexpected: string[] +} + +export const findGeneratedTokenIssues = ( compiled: CompiledTokens, outputDirectory: string -): string[] => { +): GeneratedTokenIssues => { const entries = outputEntries(compiled) const expectedFiles = new Set(entries.map(([fileName]) => fileName)) - const staleFiles = entries - .filter(([fileName, value]) => { - const outputPath = join(outputDirectory, fileName) - - return ( - !existsSync(outputPath) || - !isDeepStrictEqual(loadTokenTree(outputPath), value) - ) - }) - .map(([fileName]) => fileName) + const missing: string[] = [] + const changed: string[] = [] + + for (const [fileName, value] of entries) { + const outputPath = join(outputDirectory, fileName) + + if (existsSync(outputPath)) { + try { + if (!isDeepStrictEqual(loadTokenTree(outputPath), value)) { + changed.push(fileName) + } + } catch { + changed.push(fileName) + } + } else { + missing.push(fileName) + } + } - const unexpectedFiles = findJsonFiles(outputDirectory).filter( + const unexpected = findJsonFiles(outputDirectory).filter( (fileName) => !expectedFiles.has(fileName) ) - return [...staleFiles, ...unexpectedFiles] + return { missing, changed, unexpected } } diff --git a/src/theme/tokens/components/dark.json b/src/theme/tokens/components/dark.json index dad859e7..3bef7b42 100644 --- a/src/theme/tokens/components/dark.json +++ b/src/theme/tokens/components/dark.json @@ -19,7 +19,7 @@ "paddingRight": 0, "paddingBottom": 14, "paddingLeft": 0, - "fontWeight": "700", + "fontWeight": 700, "borderRadius": 0, "borderWidth": 0, "focusRing": { @@ -125,7 +125,7 @@ "optionGroup": { "background": "#56595f", "color": "#a2a5a9", - "fontWeight": "600", + "fontWeight": 600, "paddingTop": 8, "paddingRight": 14, "paddingBottom": 8, @@ -207,7 +207,7 @@ "borderRadius": 8, "padding": 8, "fontSize": 12, - "fontWeight": "400", + "fontWeight": 400, "minWidth": 24, "height": 24 }, @@ -532,7 +532,7 @@ "paddingX": 24, "paddingY": 14 }, - "label": { "fontWeight": "600" } + "label": { "fontWeight": 600 } } }, "card": { @@ -545,7 +545,7 @@ }, "body": { "padding": 14, "gap": 14 }, "caption": { "gap": 4 }, - "title": { "fontSize": 18, "fontWeight": "600" }, + "title": { "fontSize": 18, "fontWeight": 600 }, "subtitle": { "color": "#a2a5a9" } }, "carousel": { @@ -767,7 +767,7 @@ "sm": { "padding": 8 }, "lg": { "padding": 20 } }, - "columnTitle": { "fontWeight": "700" }, + "columnTitle": { "fontWeight": 700 }, "row": { "background": "#56595f", "hoverBackground": "#2b2e33", @@ -795,7 +795,7 @@ "sm": { "padding": 8 }, "lg": { "padding": 20 } }, - "columnFooter": { "fontWeight": "700" }, + "columnFooter": { "fontWeight": 700 }, "dropPoint": { "color": "#ffffff" }, "footer": { "borderColor": "#404348", @@ -968,7 +968,7 @@ "color": "#ffffff", "padding": 14 }, - "title": { "gap": 8, "fontWeight": "700" }, + "title": { "gap": 8, "fontWeight": 700 }, "selectMonth": { "hoverBackground": "#2b2e33", "color": "#ffffff", @@ -1002,7 +1002,7 @@ "padding": 4 }, "dayView": { "margin": 14 }, - "weekDay": { "padding": 4, "fontWeight": "700", "color": "#ffffff" }, + "weekDay": { "padding": 4, "fontWeight": 700, "color": "#ffffff" }, "date": { "hoverBackground": "#2b2e33", "selectedBackground": "#f0f0f1", @@ -1062,7 +1062,7 @@ "paddingLeft": 24, "gap": 8 }, - "title": { "fontSize": 20, "fontWeight": "600" }, + "title": { "fontSize": 20, "fontWeight": 600 }, "content": { "padding": 24 }, "footer": { "paddingTop": 0, @@ -1131,7 +1131,7 @@ "paddingBottom": 14, "paddingLeft": 24 }, - "title": { "fontSize": 20, "fontWeight": "600" }, + "title": { "fontSize": 20, "fontWeight": 600 }, "content": { "padding": 24 }, "footer": { "paddingTop": 0, @@ -1190,8 +1190,8 @@ "transitionDuration": 180, "positionX": 14, "positionY": 14, - "fontWeight": "400", - "active": { "fontSize": 12, "fontWeight": "400" } + "fontWeight": 400, + "active": { "fontSize": 12, "fontWeight": 400 } }, "over": { "active": { "top": 14 } }, "inside": { @@ -1425,7 +1425,7 @@ "optionGroup": { "background": "#56595f", "color": "#a2a5a9", - "fontWeight": "600", + "fontWeight": 600, "paddingTop": 8, "paddingRight": 14, "paddingBottom": 8, @@ -1496,7 +1496,7 @@ "paddingLeft": 14, "background": "transparent", "color": "#a2a5a9", - "fontWeight": "600" + "fontWeight": 600 }, "submenuIcon": { "size": 20, @@ -1546,7 +1546,7 @@ "paddingRight": 14, "paddingBottom": 8, "paddingLeft": 14, - "fontWeight": "600", + "fontWeight": 600, "background": "transparent", "color": "#a2a5a9" }, @@ -1573,7 +1573,7 @@ "paddingRight": 14, "paddingBottom": 8, "paddingLeft": 14, - "fontWeight": "600", + "fontWeight": 600, "background": "transparent", "color": "#a2a5a9" } @@ -1784,7 +1784,7 @@ }, "text": { "fontSize": 16, - "fontWeight": "700", + "fontWeight": 700, "sm": { "fontSize": 16 }, "lg": { "fontSize": 16 } }, @@ -1881,7 +1881,7 @@ "selectedFocusColor": "#ffffff" }, "optionGroup": { - "fontWeight": "600", + "fontWeight": 600, "paddingTop": 8, "paddingRight": 14, "paddingBottom": 8, @@ -2017,7 +2017,7 @@ "content": { "padding": 14 } }, "progressbar": { - "label": { "color": "#ffffff", "fontSize": 12, "fontWeight": "400" }, + "label": { "color": "#ffffff", "fontSize": 12, "fontWeight": 400 }, "root": { "background": "#404348", "borderRadius": 14, "height": 16 }, "value": { "background": "#44e858" } }, @@ -2194,7 +2194,7 @@ "optionGroup": { "background": "#56595f", "color": "#a2a5a9", - "fontWeight": "600", + "fontWeight": 600, "paddingTop": 8, "paddingRight": 14, "paddingBottom": 8, @@ -2318,7 +2318,7 @@ "stepTitle": { "color": "#ffffff", "activeColor": "#ffffff", - "fontWeight": "400" + "fontWeight": 400 }, "stepNumber": { "background": "#56595f", @@ -2329,7 +2329,7 @@ "activeColor": "#ffffff", "size": 24, "fontSize": 16, - "fontWeight": "700", + "fontWeight": 700, "borderRadius": 1600, "shadow": "none" }, @@ -2354,7 +2354,7 @@ } }, "itemLabel": { - "fontWeight": "400", + "fontWeight": 400, "activeColor": "#cecfd2", "color": "#ffffff" }, @@ -2362,7 +2362,7 @@ "background": "#56595f", "size": 32, "fontSize": 16, - "fontWeight": "700", + "fontWeight": 700, "borderRadius": 1600, "shadow": "none", "activeBackground": "#56595f", @@ -2401,7 +2401,7 @@ "hoverColor": "#ffffff", "activeColor": "#ffffff", "padding": 14, - "fontWeight": "600", + "fontWeight": 600, "margin": 0, "gap": 8, "focusRing": { @@ -2551,8 +2551,8 @@ "icon": { "size": 36 }, "content": { "padding": 14, "gap": 14 }, "text": { "gap": 4 }, - "summary": { "fontWeight": "700", "fontSize": 16 }, - "detail": { "fontWeight": "400", "fontSize": 14 }, + "summary": { "fontWeight": 700, "fontSize": 16 }, + "detail": { "fontWeight": 400, "fontSize": 14 }, "closeButton": { "width": 32, "height": 32, @@ -2573,7 +2573,7 @@ }, "root": { "fontSize": 12, - "fontWeight": "400", + "fontWeight": 400, "paddingTop": 4, "paddingRight": 8, "paddingBottom": 4, @@ -2748,7 +2748,7 @@ "paddingLeft": 14, "borderRadius": 1600, "gap": 8, - "fontWeight": "600", + "fontWeight": 600, "focusRing": { "width": 4, "style": "none", diff --git a/src/theme/tokens/components/light.json b/src/theme/tokens/components/light.json index 837beb80..be686424 100644 --- a/src/theme/tokens/components/light.json +++ b/src/theme/tokens/components/light.json @@ -19,7 +19,7 @@ "paddingRight": 0, "paddingBottom": 14, "paddingLeft": 0, - "fontWeight": "700", + "fontWeight": 700, "borderRadius": 0, "borderWidth": 0, "focusRing": { @@ -125,7 +125,7 @@ "optionGroup": { "background": "#ffffff", "color": "#85888e", - "fontWeight": "600", + "fontWeight": 600, "paddingTop": 8, "paddingRight": 14, "paddingBottom": 8, @@ -207,7 +207,7 @@ "borderRadius": 8, "padding": 8, "fontSize": 12, - "fontWeight": "400", + "fontWeight": 400, "minWidth": 24, "height": 24 }, @@ -532,7 +532,7 @@ "paddingX": 24, "paddingY": 14 }, - "label": { "fontWeight": "600" } + "label": { "fontWeight": 600 } } }, "card": { @@ -545,7 +545,7 @@ }, "body": { "padding": 14, "gap": 14 }, "caption": { "gap": 4 }, - "title": { "fontSize": 18, "fontWeight": "600" }, + "title": { "fontSize": 18, "fontWeight": 600 }, "subtitle": { "color": "#85888e" } }, "carousel": { @@ -767,7 +767,7 @@ "sm": { "padding": 8 }, "lg": { "padding": 20 } }, - "columnTitle": { "fontWeight": "700" }, + "columnTitle": { "fontWeight": 700 }, "row": { "background": "#ffffff", "hoverBackground": "#f0f0f1", @@ -795,7 +795,7 @@ "sm": { "padding": 8 }, "lg": { "padding": 20 } }, - "columnFooter": { "fontWeight": "700" }, + "columnFooter": { "fontWeight": 700 }, "dropPoint": { "color": "#2b2e33" }, "footer": { "borderColor": "#e2e2e4", @@ -968,7 +968,7 @@ "color": "#2b2e33", "padding": 14 }, - "title": { "gap": 8, "fontWeight": "700" }, + "title": { "gap": 8, "fontWeight": 700 }, "selectMonth": { "hoverBackground": "#f0f0f1", "color": "#2b2e33", @@ -1002,7 +1002,7 @@ "padding": 4 }, "dayView": { "margin": 14 }, - "weekDay": { "padding": 4, "fontWeight": "700", "color": "#2b2e33" }, + "weekDay": { "padding": 4, "fontWeight": 700, "color": "#2b2e33" }, "date": { "hoverBackground": "#f0f0f1", "selectedBackground": "#2b2e33", @@ -1062,7 +1062,7 @@ "paddingLeft": 24, "gap": 8 }, - "title": { "fontSize": 20, "fontWeight": "600" }, + "title": { "fontSize": 20, "fontWeight": 600 }, "content": { "padding": 24 }, "footer": { "paddingTop": 0, @@ -1131,7 +1131,7 @@ "paddingBottom": 14, "paddingLeft": 24 }, - "title": { "fontSize": 20, "fontWeight": "600" }, + "title": { "fontSize": 20, "fontWeight": 600 }, "content": { "padding": 24 }, "footer": { "paddingTop": 0, @@ -1190,8 +1190,8 @@ "transitionDuration": 180, "positionX": 14, "positionY": 14, - "fontWeight": "400", - "active": { "fontSize": 12, "fontWeight": "400" } + "fontWeight": 400, + "active": { "fontSize": 12, "fontWeight": 400 } }, "over": { "active": { "top": 14 } }, "inside": { @@ -1425,7 +1425,7 @@ "optionGroup": { "background": "#ffffff", "color": "#85888e", - "fontWeight": "600", + "fontWeight": 600, "paddingTop": 8, "paddingRight": 14, "paddingBottom": 8, @@ -1496,7 +1496,7 @@ "paddingLeft": 14, "background": "transparent", "color": "#85888e", - "fontWeight": "600" + "fontWeight": 600 }, "submenuIcon": { "size": 20, @@ -1546,7 +1546,7 @@ "paddingRight": 14, "paddingBottom": 8, "paddingLeft": 14, - "fontWeight": "600", + "fontWeight": 600, "background": "transparent", "color": "#85888e" }, @@ -1573,7 +1573,7 @@ "paddingRight": 14, "paddingBottom": 8, "paddingLeft": 14, - "fontWeight": "600", + "fontWeight": 600, "background": "transparent", "color": "#85888e" } @@ -1784,7 +1784,7 @@ }, "text": { "fontSize": 16, - "fontWeight": "700", + "fontWeight": 700, "sm": { "fontSize": 16 }, "lg": { "fontSize": 16 } }, @@ -1881,7 +1881,7 @@ "selectedFocusColor": "#ffffff" }, "optionGroup": { - "fontWeight": "600", + "fontWeight": 600, "paddingTop": 8, "paddingRight": 14, "paddingBottom": 8, @@ -2017,7 +2017,7 @@ "content": { "padding": 14 } }, "progressbar": { - "label": { "color": "#2b2e33", "fontSize": 12, "fontWeight": "400" }, + "label": { "color": "#2b2e33", "fontSize": 12, "fontWeight": 400 }, "root": { "background": "#e2e2e4", "borderRadius": 14, "height": 16 }, "value": { "background": "#44e858" } }, @@ -2194,7 +2194,7 @@ "optionGroup": { "background": "#ffffff", "color": "#85888e", - "fontWeight": "600", + "fontWeight": 600, "paddingTop": 8, "paddingRight": 14, "paddingBottom": 8, @@ -2318,7 +2318,7 @@ "stepTitle": { "color": "#2b2e33", "activeColor": "#2b2e33", - "fontWeight": "400" + "fontWeight": 400 }, "stepNumber": { "background": "#ffffff", @@ -2329,7 +2329,7 @@ "activeColor": "#2b2e33", "size": 24, "fontSize": 16, - "fontWeight": "700", + "fontWeight": 700, "borderRadius": 1600, "shadow": "none" }, @@ -2354,7 +2354,7 @@ } }, "itemLabel": { - "fontWeight": "400", + "fontWeight": 400, "activeColor": "#56595f", "color": "#2b2e33" }, @@ -2362,7 +2362,7 @@ "background": "#ffffff", "size": 32, "fontSize": 16, - "fontWeight": "700", + "fontWeight": 700, "borderRadius": 1600, "shadow": "none", "activeBackground": "#ffffff", @@ -2401,7 +2401,7 @@ "hoverColor": "#2b2e33", "activeColor": "#2b2e33", "padding": 14, - "fontWeight": "600", + "fontWeight": 600, "margin": 0, "gap": 8, "focusRing": { @@ -2551,8 +2551,8 @@ "icon": { "size": 36 }, "content": { "padding": 14, "gap": 14 }, "text": { "gap": 4 }, - "summary": { "fontWeight": "700", "fontSize": 16 }, - "detail": { "fontWeight": "400", "fontSize": 14 }, + "summary": { "fontWeight": 700, "fontSize": 16 }, + "detail": { "fontWeight": 400, "fontSize": 14 }, "closeButton": { "width": 32, "height": 32, @@ -2573,7 +2573,7 @@ }, "root": { "fontSize": 12, - "fontWeight": "400", + "fontWeight": 400, "paddingTop": 4, "paddingRight": 8, "paddingBottom": 4, @@ -2748,7 +2748,7 @@ "paddingLeft": 14, "borderRadius": 1600, "gap": 8, - "fontWeight": "600", + "fontWeight": 600, "focusRing": { "width": 4, "style": "none", diff --git a/src/theme/tokens/semantic/dark.json b/src/theme/tokens/semantic/dark.json index 1a25ff23..57ea1bc0 100644 --- a/src/theme/tokens/semantic/dark.json +++ b/src/theme/tokens/semantic/dark.json @@ -282,40 +282,34 @@ "borderWidth": { "100": 1, "200": 2, "300": 4, "none": 0 }, "focusRing": { "width": 4, "offset": 0 }, "depth": { - "100": "1000", - "200": "1100", - "300": "1200", - "400": "1300", - "500": "1400", - "600": "1500", - "700": "1600" + "100": 1000, + "200": 1100, + "300": 1200, + "400": 1300, + "500": 1400, + "600": 1500, + "700": 1600 }, "viewport": { "100": 576, "200": 768, "300": 992, "400": 1200, "500": 1400 } }, "effects": { "opacity": { "0": 0, - "4": "0.04", - "8": "0.08", - "12": "0.12", - "16": "0.16", - "20": "0.2", - "30": "0.3", - "40": "0.4", - "50": "0.5", - "60": "0.6", - "70": "0.7", - "80": "0.8", - "90": "0.9", - "100": "1" - }, - "blur": { - "100": "4px", - "200": "8px", - "300": "16px", - "400": "24px", - "none": 0 + "4": 0.04, + "8": 0.08, + "12": 0.12, + "16": 0.16, + "20": 0.2, + "30": 0.3, + "40": 0.4, + "50": 0.5, + "60": 0.6, + "70": 0.7, + "80": 0.8, + "90": 0.9, + "100": 1 }, + "blur": { "100": 4, "200": 8, "300": 16, "400": 24, "none": 0 }, "transition": { "easing": { "linear": "linear", diff --git a/src/theme/tokens/semantic/light.json b/src/theme/tokens/semantic/light.json index 687f1010..0ba6a30c 100644 --- a/src/theme/tokens/semantic/light.json +++ b/src/theme/tokens/semantic/light.json @@ -282,40 +282,34 @@ "borderWidth": { "100": 1, "200": 2, "300": 4, "none": 0 }, "focusRing": { "width": 4, "offset": 0 }, "depth": { - "100": "1000", - "200": "1100", - "300": "1200", - "400": "1300", - "500": "1400", - "600": "1500", - "700": "1600" + "100": 1000, + "200": 1100, + "300": 1200, + "400": 1300, + "500": 1400, + "600": 1500, + "700": 1600 }, "viewport": { "100": 576, "200": 768, "300": 992, "400": 1200, "500": 1400 } }, "effects": { "opacity": { "0": 0, - "4": "0.04", - "8": "0.08", - "12": "0.12", - "16": "0.16", - "20": "0.2", - "30": "0.3", - "40": "0.4", - "50": "0.5", - "60": "0.6", - "70": "0.7", - "80": "0.8", - "90": "0.9", - "100": "1" - }, - "blur": { - "100": "4px", - "200": "8px", - "300": "16px", - "400": "24px", - "none": 0 + "4": 0.04, + "8": 0.08, + "12": 0.12, + "16": 0.16, + "20": 0.2, + "30": 0.3, + "40": 0.4, + "50": 0.5, + "60": 0.6, + "70": 0.7, + "80": 0.8, + "90": 0.9, + "100": 1 }, + "blur": { "100": 4, "200": 8, "300": 16, "400": 24, "none": 0 }, "transition": { "easing": { "linear": "linear", From defc48edc4e9ada5b7296a4451ebb7d3b6de5ad0 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Fri, 31 Jul 2026 13:03:34 +0300 Subject: [PATCH 06/40] =?UTF-8?q?chore:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD?= =?UTF-8?q?=D0=B4=D1=8B=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=B4=D0=B8=D0=B7=D0=B0=D0=B9=D0=BD-=D1=82=D0=BE=D0=BA?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lefthook.yml | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lefthook.yml b/lefthook.yml index 849f2579..1fa2a1e0 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -70,8 +70,8 @@ pre-push: exit 1 fi eslint: - run: npx yarn eslint . + run: yarn eslint . type-check: - run: npx yarn tsc --noEmit + run: yarn tsc --noEmit tokens-validate: - run: npx yarn tokens:validate + run: yarn tokens:validate diff --git a/package.json b/package.json index 16255f20..05472dc5 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "storybook-generate": "sb-rn-get-stories --config-path .storybook && sed -i -e 's/export const view = global.view/export const view: ReturnType = global.view/' .storybook/storybook.requires.ts && prettier .storybook --write", "tokens:generate": "ts-node --project scripts/token-generator/tsconfig.json scripts/token-generator/build.ts && yarn tokens:format", "tokens:format": "prettier 'design-tokens/input/*.json' 'src/theme/tokens/**/*.json' --write", - "tokens:check": "ts-node --project scripts/token-generator/tsconfig.json scripts/token-generator/build.ts --check", + "tokens:check": "ts-node --transpile-only --project scripts/token-generator/tsconfig.json scripts/token-generator/build.ts --check", "tokens:typecheck": "tsc --noEmit -p scripts/token-generator/tsconfig.json", "tokens:validate": "yarn tokens:typecheck && yarn tokens:check", "doctor": "expo-doctor", From 2facbdde9709271d73b729a56008304c241effad Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Fri, 31 Jul 2026 14:43:07 +0300 Subject: [PATCH 07/40] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80?= =?UTF-8?q?=D0=B6=D0=BA=D0=B0=20focusRing-=D1=82=D0=BE=D0=BA=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/token-generator/README.md | 6 ++ .../__tests__/compiler.test.ts | 71 +++++++++++++++++++ src/theme/tokens/README.md | 4 ++ 3 files changed, 81 insertions(+) diff --git a/scripts/token-generator/README.md b/scripts/token-generator/README.md index e8e7dfa1..ebfd2493 100644 --- a/scripts/token-generator/README.md +++ b/scripts/token-generator/README.md @@ -106,6 +106,12 @@ borderRadius: "4 8 12 16" Architecture. На Android обычные тени поддерживаются с API 28, `inset` — с API 29. Fallback для более ранних версий намеренно не предусмотрен. +`focusRing` сохраняет исходную структуру. Его размеры нормализуются, а `shadow` +обрабатывается по правилам `boxShadow`. Значение `style: "none"` отключает +только применение `width`, `color` и `offset` как outline-свойств: генератор не +зануляет эти токены. `shadow` остаётся независимым и может использоваться как +`boxShadow`. + Генерация завершается с ошибкой при отсутствующей или циклической ссылке, неподдерживаемом shorthand, непреобразованных числовых значениях и единицах, составных `rem`/`px` вне `boxShadow`, `NaN` или `Infinity`. diff --git a/scripts/token-generator/__tests__/compiler.test.ts b/scripts/token-generator/__tests__/compiler.test.ts index 97fd6983..19c3c036 100644 --- a/scripts/token-generator/__tests__/compiler.test.ts +++ b/scripts/token-generator/__tests__/compiler.test.ts @@ -264,6 +264,60 @@ describe('token compiler', () => { expect(compiled.components.dark.demo).not.toHaveProperty('colorScheme.dark') }) + test('сохраняет focusRing и нормализует его значения', () => { + const source: TokenTree = { + primitive: { + sizing: { focusRing: '0.25rem' }, + colors: { focus: '#d4fedc' }, + }, + semantic: { + dimension: { + focusRing: { width: '{sizing.focusRing}', offset: '0px' }, + }, + effects: { + focusRing: { + shadow: 'inset 0 0 0 {dimension.focusRing.width} {colors.focus}', + }, + }, + colorScheme: { light: {}, dark: {} }, + }, + components: { + demo: { + root: { + focusRing: { + width: '{dimension.focusRing.width}', + style: 'none', + color: '{colors.focus}', + offset: '{dimension.focusRing.offset}', + shadow: '{effects.focusRing.shadow}', + }, + }, + }, + }, + } + + const compiled = compileTokens(source) + + expect(compiled.semantic.light).toStrictEqual({ + dimension: { focusRing: { width: 4, offset: 0 } }, + effects: { focusRing: { shadow: 'inset 0 0 0 4px #d4fedc' } }, + colorScheme: {}, + }) + expect(compiled.semantic.dark).toStrictEqual(compiled.semantic.light) + expect(compiled.components.light.demo).toStrictEqual({ + root: { + focusRing: { + width: 4, + style: 'none', + color: '#d4fedc', + offset: 0, + shadow: 'inset 0 0 0 4px #d4fedc', + }, + }, + }) + expect(compiled.components.dark).toStrictEqual(compiled.components.light) + }) + test('отклоняет источник без одной из цветовых схем semantic', () => { const source: TokenTree = { primitive: {}, @@ -351,6 +405,23 @@ describe('production input tokens', () => { expect(serialized).not.toMatch(/-?\d*\.?\d+(?:rem|ms)\b/) }) + test('экспортирует focusRing без изменения его структуры', () => { + expect(compiled.semantic.light).toHaveProperty( + 'effects.focusRing.shadow', + 'inset 0 0 0 4px #d4fedc' + ) + expect(compiled.components.light).toHaveProperty( + 'accordion.header.focusRing', + { + width: 4, + style: 'none', + color: '#d4fedc', + offset: 0, + shadow: 'inset 0 0 0 4px #d4fedc', + } + ) + }) + test('совпадает с закоммиченными сгенерированными токенами', () => { expect(findGeneratedTokenIssues(compiled, TOKENS_DIRECTORY)).toStrictEqual({ missing: [], diff --git a/src/theme/tokens/README.md b/src/theme/tokens/README.md index 3badaaae..c702dde1 100644 --- a/src/theme/tokens/README.md +++ b/src/theme/tokens/README.md @@ -7,3 +7,7 @@ `design-tokens/input/tokens.json` и не редактируется вручную. Подробности: [генератор токенов](../../../scripts/token-generator/README.md). + +`focusRing` сохраняет структуру входных токенов. При `style: "none"` компонент +не применяет `width`, `color` и `offset` как outline-свойства, но может +использовать независимый `shadow` как `boxShadow`. From 0a7ef47355bcff7c99f2edb9ebab9e5497c14af4 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Fri, 31 Jul 2026 13:49:08 +0300 Subject: [PATCH 08/40] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80?= =?UTF-8?q?=D0=B6=D0=BA=D0=B0=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B0=D0=BD=D0=B8=D0=BC=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +++ scripts/token-generator/README.md | 15 +++- .../__tests__/compiler.test.ts | 75 +++++++++++++++++++ scripts/token-generator/core/normalization.ts | 52 +++++++++++++ scripts/token-generator/core/validation.ts | 6 +- src/index.ts | 2 + src/theme/__tests__/tokenAdapters.test.ts | 11 +++ src/theme/index.ts | 1 + src/theme/tokenAdapters.ts | 15 ++++ src/theme/tokens/README.md | 8 ++ src/theme/tokens/semantic/dark.json | 20 ++--- src/theme/tokens/semantic/light.json | 20 ++--- 12 files changed, 211 insertions(+), 25 deletions(-) create mode 100644 src/theme/__tests__/tokenAdapters.test.ts create mode 100644 src/theme/tokenAdapters.ts diff --git a/README.md b/README.md index b74edb56..1b382f18 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,17 @@ UI kit использует следующие виды шрифтов. ``` +## Токены анимации + +Длительность анимации хранится в теме числом в миллисекундах. Easing-токен +нужно передать в Reanimated через публичный адаптер: + +```ts +import { toEasing } from '@cdek-it/react-native-ui-kit' + +const easing = toEasing(theme.semantic.effects.transition.easing.standard) +``` + ## Dependencies Для использования данной библиотеки необходимо: diff --git a/scripts/token-generator/README.md b/scripts/token-generator/README.md index ebfd2493..5894c4b8 100644 --- a/scripts/token-generator/README.md +++ b/scripts/token-generator/README.md @@ -61,13 +61,10 @@ Light- и dark-файлы должны иметь одинаковую стру ## Преобразование значений Ссылки разрешаются до нормализации. Поддерживаются ссылки на всё значение и -вставки внутри строк: +вставки внутри поддерживаемых shorthand и `boxShadow`: ```text "{dimension.space.400}" -> "0.875rem" -> 14 - -"inset 0 0 0 {dimension.focusRing.width} {colors.solid.green.200}" --> "inset 0 0 0 4px #d4fedc" ``` ```text @@ -80,6 +77,16 @@ Light- и dark-файлы должны иметь одинаковую стру Числовые строки преобразуются в числа, включая `fontWeight`. +Animation duration преобразуется из `ms` в число. Easing записывается как +коэффициенты для `Easing.bezier`: + +```text +"linear" -> { x1: 0, y1: 0, x2: 1, y2: 1 } +"cubic-bezier(0.2, 0, 0, 1)" -> { x1: 0.2, y1: 0, x2: 0, y2: 1 } +``` + +Коэффициенты `x1` и `x2` должны находиться в диапазоне от `0` до `1`. + CSS shorthand из 2–4 значений раскрывается в поля React Native: ```text diff --git a/scripts/token-generator/__tests__/compiler.test.ts b/scripts/token-generator/__tests__/compiler.test.ts index 19c3c036..a32d2611 100644 --- a/scripts/token-generator/__tests__/compiler.test.ts +++ b/scripts/token-generator/__tests__/compiler.test.ts @@ -17,6 +17,7 @@ import { import { compileTokens } from '../core/compiler' import { convertUnit, + normalizeEasing, normalizeTree, parseBoxShorthand, } from '../core/normalization' @@ -67,6 +68,56 @@ const containsColorSchemeThemeBranch = (node: TokenValue): boolean => { } describe('token compiler', () => { + describe('normalizeEasing', () => { + test.each([ + { + name: 'linear', + value: 'linear', + expected: { x1: 0, y1: 0, x2: 1, y2: 1 }, + }, + { + name: 'cubic-bezier', + value: 'cubic-bezier(0.2, 0, 0, 1)', + expected: { x1: 0.2, y1: 0, x2: 0, y2: 1 }, + }, + { + name: 'spring с y больше единицы', + value: 'cubic-bezier(0.34, 1.56, 0.64, 1)', + expected: { x1: 0.34, y1: 1.56, x2: 0.64, y2: 1 }, + }, + ])('$name преобразуется в коэффициенты', ({ value, expected }) => { + expect(normalizeEasing(value)).toStrictEqual(expected) + }) + + test('отклоняет неподдерживаемый формат', () => { + expect(() => normalizeEasing('ease-in')).toThrow('Unsupported easing') + }) + + test('отклоняет объект вместо easing-строки при нормализации дерева', () => { + expect(() => + normalizeTree( + { + effects: { + transition: { easing: { standard: { unexpected: 'value' } } }, + }, + }, + 'semantic' + ) + ).toThrow( + 'Expected easing string at "semantic.effects.transition.easing.standard"' + ) + }) + + test.each([ + { name: 'x1 меньше нуля', value: 'cubic-bezier(-0.1, 0, 1, 1)' }, + { name: 'x2 больше единицы', value: 'cubic-bezier(0, 0, 1.1, 1)' }, + ])('$name отклоняется', ({ value }) => { + expect(() => normalizeEasing(value)).toThrow( + 'Easing x coordinates must be between 0 and 1' + ) + }) + }) + describe('convertUnit', () => { test.each([ { name: 'положительный rem', value: '1.5rem', expected: 24 }, @@ -405,6 +456,30 @@ describe('production input tokens', () => { expect(serialized).not.toMatch(/-?\d*\.?\d+(?:rem|ms)\b/) }) + test('преобразует animation-токены в runtime-формат', () => { + expect(compiled.semantic.light).toHaveProperty( + 'effects.transition.easing.linear', + { x1: 0, y1: 0, x2: 1, y2: 1 } + ) + expect(compiled.semantic.dark).toHaveProperty( + 'effects.transition.easing.spring', + { x1: 0.34, y1: 1.56, x2: 0.64, y2: 1 } + ) + expect(compiled.semantic.light).toHaveProperty( + 'effects.transition.duration.200', + 180 + ) + expect(compiled.components.light).toHaveProperty( + 'button.root.transitionDuration', + 180 + ) + expect(compiled.components.dark).toHaveProperty( + 'toggleswitch.root.slideDuration', + 180 + ) + expect(JSON.stringify(compiled)).not.toMatch(/cubic-bezier\s*\(/) + }) + test('экспортирует focusRing без изменения его структуры', () => { expect(compiled.semantic.light).toHaveProperty( 'effects.focusRing.shadow', diff --git a/scripts/token-generator/core/normalization.ts b/scripts/token-generator/core/normalization.ts index dbde5671..ee351b77 100644 --- a/scripts/token-generator/core/normalization.ts +++ b/scripts/token-generator/core/normalization.ts @@ -7,13 +7,61 @@ import { } from './types' const REM_BASE = 16 +const NUMBER_SOURCE = '[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)' const NUMBER_PATTERN = /^-?\d*\.?\d+$/ const PIXEL_PATTERN = /^-?\d*\.?\d+px$/ const SHADOW_LENGTH_PATTERN = /^(?:0|-?\d*\.?\d+(?:rem|px))$/ +const CUBIC_BEZIER_PATTERN = new RegExp( + `^cubic-bezier\\(\\s*(${NUMBER_SOURCE})\\s*,\\s*(${NUMBER_SOURCE})\\s*,\\s*(${NUMBER_SOURCE})\\s*,\\s*(${NUMBER_SOURCE})\\s*\\)$` +) export const BOX_PROPERTIES = ['padding', 'margin', 'borderWidth'] as const export type BoxProperty = (typeof BOX_PROPERTIES)[number] +export const isEasingTokenPath = (tokenPath: string): boolean => + /\.effects\.transition\.easing\.[^.]+$/.test(tokenPath) + +export const normalizeEasing = ( + value: TokenValue, + tokenPath = 'semantic.effects.transition.easing' +): TokenTree => { + if (typeof value !== 'string') { + throw new Error(`Expected easing string at "${tokenPath}"`) + } + + const easing = value.trim() + + if (easing === 'linear') return { x1: 0, y1: 0, x2: 1, y2: 1 } + + const match = CUBIC_BEZIER_PATTERN.exec(easing) + + if (!match) { + throw new Error(`Unsupported easing "${value}" at "${tokenPath}"`) + } + + const [, x1Source, y1Source, x2Source, y2Source] = match + const coordinates = [x1Source, y1Source, x2Source, y2Source].map(Number) + const [x1, y1, x2, y2] = coordinates + + if ( + coordinates.some((coordinate) => !Number.isFinite(coordinate)) || + x1 === undefined || + y1 === undefined || + x2 === undefined || + y2 === undefined + ) { + throw new Error(`Invalid easing "${value}" at "${tokenPath}"`) + } + + if (x1 < 0 || x1 > 1 || x2 < 0 || x2 > 1) { + throw new Error( + `Easing x coordinates must be between 0 and 1 at "${tokenPath}"` + ) + } + + return { x1, y1, x2, y2 } +} + export const isBoxShadowValue = (value: string): boolean => { const parts = value .trim() @@ -178,6 +226,10 @@ export const normalizeTree = ( node: TokenValue, tokenPath = 'root' ): TokenValue => { + if (isEasingTokenPath(tokenPath)) { + return normalizeEasing(node, tokenPath) + } + if (Array.isArray(node)) { return node.map((item, index) => normalizeTree(item, `${tokenPath}.${index}`) diff --git a/scripts/token-generator/core/validation.ts b/scripts/token-generator/core/validation.ts index 7923ad75..d93dcdec 100644 --- a/scripts/token-generator/core/validation.ts +++ b/scripts/token-generator/core/validation.ts @@ -1,5 +1,6 @@ import { BOX_PROPERTIES, + isEasingTokenPath, isBoxShadowValue, type BoxProperty, } from './normalization' @@ -9,6 +10,7 @@ const REFERENCE_PATTERN = /\{[^}]+\}/ const UNCONVERTED_UNIT_PATTERN = /-?\d*\.?\d+(?:rem|ms)\b/ const PIXEL_PATTERN = /-?\d*\.?\d+px\b/ const NUMERIC_STRING_PATTERN = /^-?\d*\.?\d+$/ +const CUBIC_BEZIER_PATTERN = /cubic-bezier\s*\(/ export const assertValidOutput = ( node: TokenValue, @@ -47,7 +49,9 @@ export const assertValidOutput = ( REFERENCE_PATTERN.test(node) || UNCONVERTED_UNIT_PATTERN.test(node) || (PIXEL_PATTERN.test(node) && !isBoxShadowValue(node)) || - NUMERIC_STRING_PATTERN.test(node) + NUMERIC_STRING_PATTERN.test(node) || + CUBIC_BEZIER_PATTERN.test(node) || + (node === 'linear' && isEasingTokenPath(tokenPath)) if (hasUnconvertedValue) { throw new Error(`Unconverted token "${node}" at "${tokenPath}"`) diff --git a/src/index.ts b/src/index.ts index 0a2d5231..35bfb92a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,9 @@ export { ThemeVariant, darkTheme, lightTheme, + toEasing, type ThemeType, + type EasingToken, type FontsConfig, type FontsConfigType, type ThemeContextProviderProps, diff --git a/src/theme/__tests__/tokenAdapters.test.ts b/src/theme/__tests__/tokenAdapters.test.ts new file mode 100644 index 00000000..f11c67b4 --- /dev/null +++ b/src/theme/__tests__/tokenAdapters.test.ts @@ -0,0 +1,11 @@ +import { toEasing } from '../tokenAdapters' + +describe('toEasing', () => { + test('создаёт Reanimated easing из коэффициентов токена', () => { + const easing = toEasing({ x1: 0, y1: 0, x2: 1, y2: 1 }).factory() + + expect(easing(0)).toBe(0) + expect(easing(0.5)).toBeCloseTo(0.5) + expect(easing(1)).toBe(1) + }) +}) diff --git a/src/theme/index.ts b/src/theme/index.ts index f1312be7..d00250c0 100644 --- a/src/theme/index.ts +++ b/src/theme/index.ts @@ -1,5 +1,6 @@ export { darkTheme } from './darkTheme' export { lightTheme } from './lightTheme' +export { toEasing, type EasingToken } from './tokenAdapters' export { ThemeContext, ThemeContextProvider, diff --git a/src/theme/tokenAdapters.ts b/src/theme/tokenAdapters.ts new file mode 100644 index 00000000..855e15e8 --- /dev/null +++ b/src/theme/tokenAdapters.ts @@ -0,0 +1,15 @@ +import { Easing, type EasingFunctionFactory } from 'react-native-reanimated' + +export interface EasingToken { + readonly x1: number + readonly y1: number + readonly x2: number + readonly y2: number +} + +export const toEasing = ({ + x1, + y1, + x2, + y2, +}: EasingToken): EasingFunctionFactory => Easing.bezier(x1, y1, x2, y2) diff --git a/src/theme/tokens/README.md b/src/theme/tokens/README.md index c702dde1..0d61579b 100644 --- a/src/theme/tokens/README.md +++ b/src/theme/tokens/README.md @@ -11,3 +11,11 @@ `focusRing` сохраняет структуру входных токенов. При `style: "none"` компонент не применяет `width`, `color` и `offset` как outline-свойства, но может использовать независимый `shadow` как `boxShadow`. + +Для передачи easing в Reanimated используйте адаптер: + +```ts +import { toEasing } from '@cdek-it/react-native-ui-kit' + +const easing = toEasing(theme.semantic.effects.transition.easing.standard) +``` diff --git a/src/theme/tokens/semantic/dark.json b/src/theme/tokens/semantic/dark.json index 57ea1bc0..32086ae3 100644 --- a/src/theme/tokens/semantic/dark.json +++ b/src/theme/tokens/semantic/dark.json @@ -312,16 +312,16 @@ "blur": { "100": 4, "200": 8, "300": 16, "400": 24, "none": 0 }, "transition": { "easing": { - "linear": "linear", - "in": "cubic-bezier(0.55, 0.06, 0.7, 0.2)", - "out": "cubic-bezier(0.2, 0.6, 0.4, 1)", - "inOut": "cubic-bezier(0.65, 0.05, 0.35, 1)", - "standard": "cubic-bezier(0.2, 0, 0, 1)", - "accelerate": "cubic-bezier(0.3, 0, 1, 1)", - "decelerate": "cubic-bezier(0, 0, 0, 1)", - "emphasizedAccelerate": "cubic-bezier(0.3, 0, 0.8, 0.15)", - "emphasizedDecelerate": "cubic-bezier(0.05, 0.7, 0.1, 1)", - "spring": "cubic-bezier(0.34, 1.56, 0.64, 1)" + "linear": { "x1": 0, "y1": 0, "x2": 1, "y2": 1 }, + "in": { "x1": 0.55, "y1": 0.06, "x2": 0.7, "y2": 0.2 }, + "out": { "x1": 0.2, "y1": 0.6, "x2": 0.4, "y2": 1 }, + "inOut": { "x1": 0.65, "y1": 0.05, "x2": 0.35, "y2": 1 }, + "standard": { "x1": 0.2, "y1": 0, "x2": 0, "y2": 1 }, + "accelerate": { "x1": 0.3, "y1": 0, "x2": 1, "y2": 1 }, + "decelerate": { "x1": 0, "y1": 0, "x2": 0, "y2": 1 }, + "emphasizedAccelerate": { "x1": 0.3, "y1": 0, "x2": 0.8, "y2": 0.15 }, + "emphasizedDecelerate": { "x1": 0.05, "y1": 0.7, "x2": 0.1, "y2": 1 }, + "spring": { "x1": 0.34, "y1": 1.56, "x2": 0.64, "y2": 1 } }, "duration": { "100": 140, "200": 180, "300": 240, "400": 320, "500": 400 } }, diff --git a/src/theme/tokens/semantic/light.json b/src/theme/tokens/semantic/light.json index 0ba6a30c..b3ff8316 100644 --- a/src/theme/tokens/semantic/light.json +++ b/src/theme/tokens/semantic/light.json @@ -312,16 +312,16 @@ "blur": { "100": 4, "200": 8, "300": 16, "400": 24, "none": 0 }, "transition": { "easing": { - "linear": "linear", - "in": "cubic-bezier(0.55, 0.06, 0.7, 0.2)", - "out": "cubic-bezier(0.2, 0.6, 0.4, 1)", - "inOut": "cubic-bezier(0.65, 0.05, 0.35, 1)", - "standard": "cubic-bezier(0.2, 0, 0, 1)", - "accelerate": "cubic-bezier(0.3, 0, 1, 1)", - "decelerate": "cubic-bezier(0, 0, 0, 1)", - "emphasizedAccelerate": "cubic-bezier(0.3, 0, 0.8, 0.15)", - "emphasizedDecelerate": "cubic-bezier(0.05, 0.7, 0.1, 1)", - "spring": "cubic-bezier(0.34, 1.56, 0.64, 1)" + "linear": { "x1": 0, "y1": 0, "x2": 1, "y2": 1 }, + "in": { "x1": 0.55, "y1": 0.06, "x2": 0.7, "y2": 0.2 }, + "out": { "x1": 0.2, "y1": 0.6, "x2": 0.4, "y2": 1 }, + "inOut": { "x1": 0.65, "y1": 0.05, "x2": 0.35, "y2": 1 }, + "standard": { "x1": 0.2, "y1": 0, "x2": 0, "y2": 1 }, + "accelerate": { "x1": 0.3, "y1": 0, "x2": 1, "y2": 1 }, + "decelerate": { "x1": 0, "y1": 0, "x2": 0, "y2": 1 }, + "emphasizedAccelerate": { "x1": 0.3, "y1": 0, "x2": 0.8, "y2": 0.15 }, + "emphasizedDecelerate": { "x1": 0.05, "y1": 0.7, "x2": 0.1, "y2": 1 }, + "spring": { "x1": 0.34, "y1": 1.56, "x2": 0.64, "y2": 1 } }, "duration": { "100": 140, "200": 180, "300": 240, "400": 320, "500": 400 } }, From 4a05ec0241e5e42c53623b91e948a139c5163c55 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Mon, 3 Aug 2026 18:24:48 +0300 Subject: [PATCH 09/40] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=20=D1=88=D1=80=D0=B8=D1=84=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design-tokens/README.md | 2 +- scripts/token-generator/README.md | 11 +++-- .../__tests__/compiler.test.ts | 44 +++++++++++++----- scripts/token-generator/core/compiler.ts | 22 ++++++++- scripts/token-generator/core/types.ts | 1 + scripts/token-generator/io.ts | 2 + src/theme/tokens/README.md | 10 +++-- src/theme/tokens/fonts.json | 45 +++++++++++++++++++ 8 files changed, 118 insertions(+), 19 deletions(-) create mode 100644 src/theme/tokens/fonts.json diff --git a/design-tokens/README.md b/design-tokens/README.md index 73d1cf5c..a7592028 100644 --- a/design-tokens/README.md +++ b/design-tokens/README.md @@ -1,6 +1,6 @@ # Design tokens `input/tokens.json` содержит входные токены из Figma, из которых генерируются -light- и dark-токены проекта. +light- и dark-токены проекта, а также общий `fonts.json`. Подробности: [генератор токенов](../scripts/token-generator/README.md). diff --git a/scripts/token-generator/README.md b/scripts/token-generator/README.md index 5894c4b8..cc2dd9e8 100644 --- a/scripts/token-generator/README.md +++ b/scripts/token-generator/README.md @@ -31,10 +31,11 @@ Semantic-токены доступны потребителям библиоте ## Результат генерации -Из `design-tokens/input/tokens.json` создаются четыре файла: +Из `design-tokens/input/tokens.json` создаются пять файлов: ```text src/theme/tokens +├── fonts.json ├── semantic │ ├── light.json │ └── dark.json @@ -55,8 +56,12 @@ components.button.colorScheme.light.outlined → components/light.json: button.colorScheme.outlined ``` -`primitive` нужен только для подстановки ссылок и не записывается в результат. -Light- и dark-файлы должны иметь одинаковую структуру и типы значений. +`fonts.json` собирается из `primitive.fonts`, нормализуется по общим правилам и +не разделяется по цветовым схемам. Пока файл не экспортируется из библиотеки. + +Остальная часть `primitive` нужна только для подстановки ссылок и не +записывается в результат. Light- и dark-файлы должны иметь одинаковую структуру +и типы значений. ## Преобразование значений diff --git a/scripts/token-generator/__tests__/compiler.test.ts b/scripts/token-generator/__tests__/compiler.test.ts index a32d2611..63b1d8fa 100644 --- a/scripts/token-generator/__tests__/compiler.test.ts +++ b/scripts/token-generator/__tests__/compiler.test.ts @@ -49,6 +49,12 @@ const listJsonFiles = (directory: string, prefix = ''): string[] => }) .sort() +const expectedOutputFiles = [ + OUTPUT_FILES.fonts, + ...Object.values(OUTPUT_FILES.semantic), + ...Object.values(OUTPUT_FILES.components), +].sort() + const containsColorSchemeThemeBranch = (node: TokenValue): boolean => { if (Array.isArray(node)) return node.some(containsColorSchemeThemeBranch) @@ -238,6 +244,11 @@ describe('token compiler', () => { test('разделяет один источник на темы, разрешает ссылки и нормализует значения', () => { const source: TokenTree = { primitive: { + fonts: { + fontFamily: { base: 'Noto Sans' }, + fontWeight: { regular: '400' }, + fontSize: { base: '1rem' }, + }, sizing: { small: '0.5rem', base: '1rem' }, motion: { fast: '150ms' }, }, @@ -273,6 +284,11 @@ describe('token compiler', () => { const compiled = compileTokens(source) expect(compiled).not.toHaveProperty('primitive') + expect(compiled.fonts).toStrictEqual({ + fontFamily: { base: 'Noto Sans' }, + fontWeight: { regular: 400 }, + fontSize: { base: 16 }, + }) expect(compiled.semantic).toStrictEqual({ light: { colorScheme: { color: { text: '#111111' } }, @@ -318,6 +334,7 @@ describe('token compiler', () => { test('сохраняет focusRing и нормализует его значения', () => { const source: TokenTree = { primitive: { + fonts: {}, sizing: { focusRing: '0.25rem' }, colors: { focus: '#d4fedc' }, }, @@ -371,7 +388,7 @@ describe('token compiler', () => { test('отклоняет источник без одной из цветовых схем semantic', () => { const source: TokenTree = { - primitive: {}, + primitive: { fonts: {} }, semantic: { colorScheme: { light: {} } }, components: {}, } @@ -402,8 +419,12 @@ describe('production input tokens', () => { expect(tokenFiles).toStrictEqual(['tokens.json']) }) - test('не экспортирует primitive и убирает разделение тем из colorScheme', () => { - expect(Object.keys(compiled)).toStrictEqual(['semantic', 'components']) + test('экспортирует fonts без primitive и убирает темы из colorScheme', () => { + expect(Object.keys(compiled)).toStrictEqual([ + 'fonts', + 'semantic', + 'components', + ]) expect(compiled).not.toHaveProperty('primitive') const inputComponents = source.components @@ -440,13 +461,18 @@ describe('production input tokens', () => { ).toHaveLength(0) }) + test('собирает и нормализует primitive.fonts без цветовой схемы', () => { + expect(compiled.fonts).toHaveProperty('fontFamily.base', 'Noto Sans') + expect(compiled.fonts).toHaveProperty('fontWeight.demibold', 600) + expect(compiled.fonts).toHaveProperty('fontSize.300', 16) + expect(compiled.fonts).toHaveProperty('lineHeight.auto', 'auto') + expect(compiled.fonts).toHaveProperty('letterSpacing.400', -0.48) + }) + test('содержит только целевые файлы', () => { const tokenFiles = listJsonFiles(TOKENS_DIRECTORY) - const expectedFiles = Object.values(OUTPUT_FILES) - .flatMap((group) => Object.values(group)) - .sort() - expect(tokenFiles).toStrictEqual(expectedFiles) + expect(tokenFiles).toStrictEqual(expectedOutputFiles) }) test('не содержит неразрешённых ссылок и CSS-единиц', () => { @@ -545,9 +571,7 @@ describe('production input tokens', () => { writeGeneratedTokens(compiled, temporaryDirectory) expect(listJsonFiles(temporaryDirectory)).toStrictEqual( - Object.values(OUTPUT_FILES) - .flatMap((group) => Object.values(group)) - .sort() + expectedOutputFiles ) expect( findGeneratedTokenIssues(compiled, temporaryDirectory) diff --git a/scripts/token-generator/core/compiler.ts b/scripts/token-generator/core/compiler.ts index 1c57644a..240e471f 100644 --- a/scripts/token-generator/core/compiler.ts +++ b/scripts/token-generator/core/compiler.ts @@ -43,6 +43,25 @@ const getGroup = ( return value } +const compileFonts = (primitive: TokenTree): TokenTree => { + const fonts = resolvePath(primitive, 'fonts') + + if (!isTokenTree(fonts)) { + throw new Error('Expected an object at "primitive.fonts" in input tokens') + } + + const resolvedFonts = resolveReferences(fonts, primitive, 'fonts') + const normalizedFonts = normalizeTree(resolvedFonts, 'fonts') + + if (!isTokenTree(normalizedFonts)) { + throw new Error('Expected an object at "fonts" in output tokens') + } + + assertValidOutput(normalizedFonts, 'fonts') + + return normalizedFonts +} + const selectColorScheme = ( group: TokenTree, scheme: ColorScheme, @@ -184,6 +203,7 @@ export const compileTokens = (source: TokenTree): CompiledTokens => { const primitive = getGroup(source, 'primitive') const semanticSource = getGroup(source, 'semantic') const componentsSource = getGroup(source, 'components') + const fonts = compileFonts(primitive) const light = compileScheme( primitive, semanticSource, @@ -202,5 +222,5 @@ export const compileTokens = (source: TokenTree): CompiledTokens => { assertSameShape(semantic.light, semantic.dark) assertSameShape(components.light, components.dark) - return { semantic, components } + return { fonts, semantic, components } } diff --git a/scripts/token-generator/core/types.ts b/scripts/token-generator/core/types.ts index 2c98a251..216aaa8a 100644 --- a/scripts/token-generator/core/types.ts +++ b/scripts/token-generator/core/types.ts @@ -13,6 +13,7 @@ export interface BoxEdges { } export interface CompiledTokens { + fonts: TokenTree semantic: ThemeTokens components: ThemeTokens } diff --git a/scripts/token-generator/io.ts b/scripts/token-generator/io.ts index 301d159c..074eb8ce 100644 --- a/scripts/token-generator/io.ts +++ b/scripts/token-generator/io.ts @@ -13,6 +13,7 @@ import { isDeepStrictEqual } from 'node:util' import { isTokenTree, type CompiledTokens, type TokenTree } from './core/types' export const OUTPUT_FILES = { + fonts: 'fonts.json', semantic: { light: join('semantic', 'light.json'), dark: join('semantic', 'dark.json'), @@ -45,6 +46,7 @@ export const renderJson = (value: TokenTree): string => const outputEntries = ( compiled: CompiledTokens ): Array<[string, TokenTree]> => [ + [OUTPUT_FILES.fonts, compiled.fonts], [OUTPUT_FILES.semantic.light, compiled.semantic.light], [OUTPUT_FILES.semantic.dark, compiled.semantic.dark], [OUTPUT_FILES.components.light, compiled.components.light], diff --git a/src/theme/tokens/README.md b/src/theme/tokens/README.md index 0d61579b..e3d127f2 100644 --- a/src/theme/tokens/README.md +++ b/src/theme/tokens/README.md @@ -1,10 +1,12 @@ # Сгенерированные токены `semantic` подключается к темам как `ThemeType.semantic`. `components` хранит -внутренние токены компонентов для `ThemeType.components`. В сгенерированных -файлах нет `primitive`; `colorScheme` содержит только выбранную ветку без -вложенных `light` и `dark`. Всё генерируется из -`design-tokens/input/tokens.json` и не редактируется вручную. +внутренние токены компонентов для `ThemeType.components`. `fonts.json` содержит +общие для цветовых схем токены из `primitive.fonts`, но пока не подключён к теме +и не экспортируется из библиотеки. Остальная часть `primitive` не записывается; +`colorScheme` содержит только выбранную ветку без вложенных `light` и `dark`. +Всё генерируется из `design-tokens/input/tokens.json` и не редактируется +вручную. Подробности: [генератор токенов](../../../scripts/token-generator/README.md). diff --git a/src/theme/tokens/fonts.json b/src/theme/tokens/fonts.json new file mode 100644 index 00000000..bec6ffbc --- /dev/null +++ b/src/theme/tokens/fonts.json @@ -0,0 +1,45 @@ +{ + "fontFamily": { "base": "Noto Sans", "heading": "TT Fellows" }, + "fontWeight": { "regular": 400, "medium": 500, "demibold": 600, "bold": 700 }, + "fontSize": { + "100": 12, + "200": 14, + "300": 16, + "400": 18, + "500": 20, + "600": 24, + "650": 30, + "700": 36, + "750": 48, + "800": 60, + "900": 72, + "1000": 96 + }, + "lineHeight": { + "100": 12, + "150": 14, + "200": 14, + "250": 16, + "300": 18, + "350": 18, + "400": 20, + "450": 22, + "500": 24, + "550": 26, + "600": 28, + "700": 30, + "800": 36, + "850": 38, + "900": 44, + "1000": 54, + "none": 1, + "auto": "auto" + }, + "letterSpacing": { + "200": -0.32, + "400": -0.48, + "500": 0, + "600": 0.32, + "700": 0.48 + } +} From 1bd208dd8b33999a135a05cf5c319febd8232656 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 12:25:57 +0300 Subject: [PATCH 10/40] =?UTF-8?q?refactor(tokens):=20=D1=80=D0=B0=D0=B7?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D1=8B=20semantic-=D1=82=D0=BE?= =?UTF-8?q?=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +- scripts/token-generator/README.md | 28 +- .../__tests__/compiler.test.ts | 76 ++-- scripts/token-generator/core/compiler.ts | 52 ++- scripts/token-generator/core/types.ts | 8 +- scripts/token-generator/io.ts | 17 +- src/index.ts | 2 + src/theme/__tests__/ThemeContext.test.tsx | 20 +- src/theme/darkTheme.ts | 4 +- src/theme/index.ts | 1 + src/theme/lightTheme.ts | 4 +- src/theme/tokens/README.md | 18 +- src/theme/tokens/index.ts | 6 + .../tokens/semantic/colorScheme/dark.json | 228 ++++++++++++ .../tokens/semantic/colorScheme/light.json | 228 ++++++++++++ src/theme/tokens/semantic/dark.json | 346 ------------------ src/theme/tokens/semantic/dimensions.json | 65 ++++ src/theme/tokens/semantic/effects.json | 51 +++ src/theme/tokens/semantic/light.json | 346 ------------------ src/theme/types.ts | 4 +- 20 files changed, 749 insertions(+), 763 deletions(-) create mode 100644 src/theme/tokens/index.ts create mode 100644 src/theme/tokens/semantic/colorScheme/dark.json create mode 100644 src/theme/tokens/semantic/colorScheme/light.json delete mode 100644 src/theme/tokens/semantic/dark.json create mode 100644 src/theme/tokens/semantic/dimensions.json create mode 100644 src/theme/tokens/semantic/effects.json delete mode 100644 src/theme/tokens/semantic/light.json diff --git a/README.md b/README.md index 1b382f18..4460ccdb 100644 --- a/README.md +++ b/README.md @@ -162,13 +162,13 @@ UI kit использует следующие виды шрифтов. ## Токены анимации -Длительность анимации хранится в теме числом в миллисекундах. Easing-токен -нужно передать в Reanimated через публичный адаптер: +Длительность анимации хранится в `semanticTokens` числом в миллисекундах. +Easing-токен нужно передать в Reanimated через публичный адаптер: ```ts -import { toEasing } from '@cdek-it/react-native-ui-kit' +import { semanticTokens, toEasing } from '@cdek-it/react-native-ui-kit' -const easing = toEasing(theme.semantic.effects.transition.easing.standard) +const easing = toEasing(semanticTokens.effects.transition.easing.standard) ``` ## Dependencies diff --git a/scripts/token-generator/README.md b/scripts/token-generator/README.md index cc2dd9e8..29b8a12f 100644 --- a/scripts/token-generator/README.md +++ b/scripts/token-generator/README.md @@ -26,36 +26,46 @@ StyleSheet.create(({ components }) => ({ })) ``` -Semantic-токены доступны потребителям библиотеки в `semantic`. Unistyles -подставляет соответствующие light- или dark-токены при переключении темы. +В `semantic` темы находится только `colorScheme`: Unistyles подставляет +соответствующие light- или dark-токены при переключении темы. Не зависящие от +темы `dimension` и `effects` доступны в статическом `semanticTokens`. ## Результат генерации -Из `design-tokens/input/tokens.json` создаются пять файлов: +Из `design-tokens/input/tokens.json` создаются семь файлов: ```text src/theme/tokens ├── fonts.json ├── semantic -│ ├── light.json -│ └── dark.json +│ ├── colorScheme +│ │ ├── light.json +│ │ └── dark.json +│ ├── dimensions.json +│ └── effects.json └── components ├── light.json └── dark.json ``` -Для каждого выходного файла выбирается соответствующая ветка `colorScheme.light` -или `colorScheme.dark`. Ключ `colorScheme` сохраняется, а уровень `light`/`dark` -удаляется: +Для `semantic/colorScheme` и component-файлов выбирается соответствующая ветка +`colorScheme.light` или `colorScheme.dark`, а уровень `light`/`dark` удаляется. +Semantic-файл подключается в тему как `semantic.colorScheme`; в component-файлах +ключ `colorScheme` сохраняется: ```text semantic.colorScheme.light.color -→ semantic/light.json: colorScheme.color +→ semantic/colorScheme/light.json: color components.button.colorScheme.light.outlined → components/light.json: button.colorScheme.outlined ``` +`semantic.dimension` записывается в `semantic/dimensions.json`, а +`semantic.effects` — в `semantic/effects.json`. Эти секции генерируются один раз +и не входят в тему. Если их итоговые значения зависят от `colorScheme`, +генератор завершится с ошибкой. + `fonts.json` собирается из `primitive.fonts`, нормализуется по общим правилам и не разделяется по цветовым схемам. Пока файл не экспортируется из библиотеки. diff --git a/scripts/token-generator/__tests__/compiler.test.ts b/scripts/token-generator/__tests__/compiler.test.ts index 63b1d8fa..7d68397e 100644 --- a/scripts/token-generator/__tests__/compiler.test.ts +++ b/scripts/token-generator/__tests__/compiler.test.ts @@ -51,7 +51,9 @@ const listJsonFiles = (directory: string, prefix = ''): string[] => const expectedOutputFiles = [ OUTPUT_FILES.fonts, - ...Object.values(OUTPUT_FILES.semantic), + ...Object.values(OUTPUT_FILES.semantic.colorScheme), + OUTPUT_FILES.semantic.dimensions, + OUTPUT_FILES.semantic.effects, ...Object.values(OUTPUT_FILES.components), ].sort() @@ -290,16 +292,12 @@ describe('token compiler', () => { fontSize: { base: 16 }, }) expect(compiled.semantic).toStrictEqual({ - light: { - colorScheme: { color: { text: '#111111' } }, - dimension: { spacing: { small: 8, base: 16 } }, - effects: { duration: 150 }, - }, - dark: { - colorScheme: { color: { text: '#eeeeee' } }, - dimension: { spacing: { small: 8, base: 16 } }, - effects: { duration: 150 }, + colorScheme: { + light: { color: { text: '#111111' } }, + dark: { color: { text: '#eeeeee' } }, }, + dimension: { spacing: { small: 8, base: 16 } }, + effects: { duration: 150 }, }) expect(compiled.components.light).toStrictEqual({ demo: { @@ -366,12 +364,11 @@ describe('token compiler', () => { const compiled = compileTokens(source) - expect(compiled.semantic.light).toStrictEqual({ + expect(compiled.semantic).toStrictEqual({ + colorScheme: { light: {}, dark: {} }, dimension: { focusRing: { width: 4, offset: 0 } }, effects: { focusRing: { shadow: 'inset 0 0 0 4px #d4fedc' } }, - colorScheme: {}, }) - expect(compiled.semantic.dark).toStrictEqual(compiled.semantic.light) expect(compiled.components.light.demo).toStrictEqual({ root: { focusRing: { @@ -398,6 +395,25 @@ describe('token compiler', () => { ) }) + test('отклоняет общие semantic-токены, зависящие от цветовой схемы', () => { + const source: TokenTree = { + primitive: { fonts: {} }, + semantic: { + colorScheme: { + light: { color: { spacing: '1rem' } }, + dark: { color: { spacing: '2rem' } }, + }, + dimension: { spacing: '{color.spacing}' }, + effects: {}, + }, + components: {}, + } + + expect(() => compileTokens(source)).toThrow( + 'Semantic "dimension" tokens must not depend on colorScheme' + ) + }) + test('отклоняет циклические ссылки', () => { const references: TokenTree = { first: '{second}', second: '{first}' } @@ -449,12 +465,12 @@ describe('production input tokens', () => { expect(lightOutputComponents.button).toHaveProperty('root') expect(lightOutputComponents.button).toHaveProperty('colorScheme') expect(darkOutputComponents.button).toHaveProperty('colorScheme') - expect(compiled.semantic.light).toHaveProperty('colorScheme.color') - expect(compiled.semantic.dark).toHaveProperty('colorScheme.color') + expect(compiled.semantic.colorScheme.light).toHaveProperty('color') + expect(compiled.semantic.colorScheme.dark).toHaveProperty('color') expect( [ - compiled.semantic.light, - compiled.semantic.dark, + compiled.semantic.colorScheme.light, + compiled.semantic.colorScheme.dark, compiled.components.light, compiled.components.dark, ].filter(containsColorSchemeThemeBranch) @@ -483,16 +499,16 @@ describe('production input tokens', () => { }) test('преобразует animation-токены в runtime-формат', () => { - expect(compiled.semantic.light).toHaveProperty( - 'effects.transition.easing.linear', + expect(compiled.semantic.effects).toHaveProperty( + 'transition.easing.linear', { x1: 0, y1: 0, x2: 1, y2: 1 } ) - expect(compiled.semantic.dark).toHaveProperty( - 'effects.transition.easing.spring', + expect(compiled.semantic.effects).toHaveProperty( + 'transition.easing.spring', { x1: 0.34, y1: 1.56, x2: 0.64, y2: 1 } ) - expect(compiled.semantic.light).toHaveProperty( - 'effects.transition.duration.200', + expect(compiled.semantic.effects).toHaveProperty( + 'transition.duration.200', 180 ) expect(compiled.components.light).toHaveProperty( @@ -507,8 +523,8 @@ describe('production input tokens', () => { }) test('экспортирует focusRing без изменения его структуры', () => { - expect(compiled.semantic.light).toHaveProperty( - 'effects.focusRing.shadow', + expect(compiled.semantic.effects).toHaveProperty( + 'focusRing.shadow', 'inset 0 0 0 4px #d4fedc' ) expect(compiled.components.light).toHaveProperty( @@ -532,9 +548,9 @@ describe('production input tokens', () => { }) test('преобразует числовые RN-значения', () => { - expect(compiled.semantic.light).toHaveProperty('dimension.depth.100', 1000) - expect(compiled.semantic.light).toHaveProperty('effects.opacity.4', 0.04) - expect(compiled.semantic.light).toHaveProperty('effects.blur.100', 4) + expect(compiled.semantic.dimension).toHaveProperty('depth.100', 1000) + expect(compiled.semantic.effects).toHaveProperty('opacity.4', 0.04) + expect(compiled.semantic.effects).toHaveProperty('blur.100', 4) expect(compiled.components.light).toHaveProperty( 'button.root.label.fontWeight', 600 @@ -564,8 +580,8 @@ describe('production input tokens', () => { const temporaryDirectory = mkdtempSync(join(tmpdir(), 'token-generator-')) const unexpectedFile = join(temporaryDirectory, 'common.json') const preservedFile = join(temporaryDirectory, 'README.md') - const missingFile = OUTPUT_FILES.semantic.dark - const changedFile = OUTPUT_FILES.semantic.light + const missingFile = OUTPUT_FILES.semantic.colorScheme.dark + const changedFile = OUTPUT_FILES.semantic.dimensions try { writeGeneratedTokens(compiled, temporaryDirectory) diff --git a/scripts/token-generator/core/compiler.ts b/scripts/token-generator/core/compiler.ts index 240e471f..4dfe18c0 100644 --- a/scripts/token-generator/core/compiler.ts +++ b/scripts/token-generator/core/compiler.ts @@ -1,9 +1,12 @@ +import { isDeepStrictEqual } from 'node:util' + import { normalizeTree } from './normalization' import { resolveReferences } from './resolution' import { mergeTrees, resolvePath } from './tree' import { isTokenTree, type CompiledTokens, + type SemanticTokens, type ThemeTokens, type TokenTree, type TokenValue, @@ -199,6 +202,46 @@ const compileScheme = ( } } +const getSemanticGroup = ( + semantic: TokenTree, + group: 'colorScheme' | 'dimension' | 'effects', + scheme: ColorScheme +): TokenTree => { + const value = semantic[group] + + if (!isTokenTree(value)) { + throw new Error(`Expected an object at "${scheme}.semantic.${group}"`) + } + + return value +} + +const splitSemantic = (light: TokenTree, dark: TokenTree): SemanticTokens => { + const dimension = getSemanticGroup(light, 'dimension', 'light') + const darkDimension = getSemanticGroup(dark, 'dimension', 'dark') + const effects = getSemanticGroup(light, 'effects', 'light') + const darkEffects = getSemanticGroup(dark, 'effects', 'dark') + + if (!isDeepStrictEqual(dimension, darkDimension)) { + throw new Error( + 'Semantic "dimension" tokens must not depend on colorScheme' + ) + } + + if (!isDeepStrictEqual(effects, darkEffects)) { + throw new Error('Semantic "effects" tokens must not depend on colorScheme') + } + + return { + colorScheme: { + light: getSemanticGroup(light, 'colorScheme', 'light'), + dark: getSemanticGroup(dark, 'colorScheme', 'dark'), + }, + dimension, + effects, + } +} + export const compileTokens = (source: TokenTree): CompiledTokens => { const primitive = getGroup(source, 'primitive') const semanticSource = getGroup(source, 'semantic') @@ -216,11 +259,14 @@ export const compileTokens = (source: TokenTree): CompiledTokens => { componentsSource, 'dark' ) - const semantic = { light: light.semantic, dark: dark.semantic } const components = { light: light.components, dark: dark.components } - assertSameShape(semantic.light, semantic.dark) + assertSameShape(light.semantic, dark.semantic) assertSameShape(components.light, components.dark) - return { fonts, semantic, components } + return { + fonts, + semantic: splitSemantic(light.semantic, dark.semantic), + components, + } } diff --git a/scripts/token-generator/core/types.ts b/scripts/token-generator/core/types.ts index 216aaa8a..89522e41 100644 --- a/scripts/token-generator/core/types.ts +++ b/scripts/token-generator/core/types.ts @@ -14,10 +14,16 @@ export interface BoxEdges { export interface CompiledTokens { fonts: TokenTree - semantic: ThemeTokens + semantic: SemanticTokens components: ThemeTokens } +export interface SemanticTokens { + colorScheme: ThemeTokens + dimension: TokenTree + effects: TokenTree +} + export interface ThemeTokens { light: TokenTree dark: TokenTree diff --git a/scripts/token-generator/io.ts b/scripts/token-generator/io.ts index 074eb8ce..bcf07389 100644 --- a/scripts/token-generator/io.ts +++ b/scripts/token-generator/io.ts @@ -15,8 +15,12 @@ import { isTokenTree, type CompiledTokens, type TokenTree } from './core/types' export const OUTPUT_FILES = { fonts: 'fonts.json', semantic: { - light: join('semantic', 'light.json'), - dark: join('semantic', 'dark.json'), + colorScheme: { + light: join('semantic', 'colorScheme', 'light.json'), + dark: join('semantic', 'colorScheme', 'dark.json'), + }, + dimensions: join('semantic', 'dimensions.json'), + effects: join('semantic', 'effects.json'), }, components: { light: join('components', 'light.json'), @@ -47,8 +51,13 @@ const outputEntries = ( compiled: CompiledTokens ): Array<[string, TokenTree]> => [ [OUTPUT_FILES.fonts, compiled.fonts], - [OUTPUT_FILES.semantic.light, compiled.semantic.light], - [OUTPUT_FILES.semantic.dark, compiled.semantic.dark], + [ + OUTPUT_FILES.semantic.colorScheme.light, + compiled.semantic.colorScheme.light, + ], + [OUTPUT_FILES.semantic.colorScheme.dark, compiled.semantic.colorScheme.dark], + [OUTPUT_FILES.semantic.dimensions, compiled.semantic.dimension], + [OUTPUT_FILES.semantic.effects, compiled.semantic.effects], [OUTPUT_FILES.components.light, compiled.components.light], [OUTPUT_FILES.components.dark, compiled.components.dark], ] diff --git a/src/index.ts b/src/index.ts index 35bfb92a..12678ece 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,9 @@ export { ThemeVariant, darkTheme, lightTheme, + semanticTokens, toEasing, + type SemanticTokens, type ThemeType, type EasingToken, type FontsConfig, diff --git a/src/theme/__tests__/ThemeContext.test.tsx b/src/theme/__tests__/ThemeContext.test.tsx index 0106d5ff..14499cc5 100644 --- a/src/theme/__tests__/ThemeContext.test.tsx +++ b/src/theme/__tests__/ThemeContext.test.tsx @@ -6,10 +6,13 @@ import { UnistylesRuntime } from 'react-native-unistyles' import { ThemeContextProvider } from '../ThemeContext' import { darkTheme } from '../darkTheme' import { lightTheme } from '../lightTheme' +import { semanticTokens } from '../tokens' import darkComponentTokens from '../tokens/components/dark.json' import lightComponentTokens from '../tokens/components/light.json' -import darkSemanticTokens from '../tokens/semantic/dark.json' -import lightSemanticTokens from '../tokens/semantic/light.json' +import darkSemanticColorSchemeTokens from '../tokens/semantic/colorScheme/dark.json' +import lightSemanticColorSchemeTokens from '../tokens/semantic/colorScheme/light.json' +import semanticDimensions from '../tokens/semantic/dimensions.json' +import semanticEffects from '../tokens/semantic/effects.json' import { ThemeVariant } from '../types' describe('ThemeContextProvider', () => { @@ -72,9 +75,16 @@ describe('ThemeContextProvider', () => { expect(UnistylesRuntime.updateTheme).not.toHaveBeenCalled() }) - test('каждая тема содержит соответствующие semantic-токены', () => { - expect(lightTheme.semantic).toBe(lightSemanticTokens) - expect(darkTheme.semantic).toBe(darkSemanticTokens) + test('каждая тема содержит только соответствующую цветовую схему', () => { + expect(lightTheme.semantic.colorScheme).toBe(lightSemanticColorSchemeTokens) + expect(darkTheme.semantic.colorScheme).toBe(darkSemanticColorSchemeTokens) + expect(lightTheme.semantic).not.toHaveProperty('dimension') + expect(lightTheme.semantic).not.toHaveProperty('effects') + }) + + test('общие semantic-токены не зависят от темы', () => { + expect(semanticTokens.dimension).toBe(semanticDimensions) + expect(semanticTokens.effects).toBe(semanticEffects) }) test('каждая тема содержит соответствующие component-токены', () => { diff --git a/src/theme/darkTheme.ts b/src/theme/darkTheme.ts index aa8bf3f0..4cce3ec9 100644 --- a/src/theme/darkTheme.ts +++ b/src/theme/darkTheme.ts @@ -4,11 +4,11 @@ import { customDark } from './assets/customDark' import darkThemeAssets from './assets/themeDark.json' import { commonTheme } from './commonTheme' import darkComponentTokens from './tokens/components/dark.json' -import darkSemanticTokens from './tokens/semantic/dark.json' +import darkSemanticColorSchemeTokens from './tokens/semantic/colorScheme/dark.json' import type { ThemeType } from './types' export const darkTheme: ThemeType = { - semantic: darkSemanticTokens, + semantic: { colorScheme: darkSemanticColorSchemeTokens }, components: darkComponentTokens, theme: { ...darkThemeAssets, InputSize, ModalSize, custom: customDark }, ...commonTheme, diff --git a/src/theme/index.ts b/src/theme/index.ts index d00250c0..4266d324 100644 --- a/src/theme/index.ts +++ b/src/theme/index.ts @@ -1,6 +1,7 @@ export { darkTheme } from './darkTheme' export { lightTheme } from './lightTheme' export { toEasing, type EasingToken } from './tokenAdapters' +export { semanticTokens, type SemanticTokens } from './tokens' export { ThemeContext, ThemeContextProvider, diff --git a/src/theme/lightTheme.ts b/src/theme/lightTheme.ts index b91a6008..2abc1957 100644 --- a/src/theme/lightTheme.ts +++ b/src/theme/lightTheme.ts @@ -4,11 +4,11 @@ import { customLight } from './assets/customLight' import lightThemeAssets from './assets/themeLight.json' import { commonTheme } from './commonTheme' import lightComponentTokens from './tokens/components/light.json' -import lightSemanticTokens from './tokens/semantic/light.json' +import lightSemanticColorSchemeTokens from './tokens/semantic/colorScheme/light.json' import type { ThemeType } from './types' export const lightTheme: ThemeType = { - semantic: lightSemanticTokens, + semantic: { colorScheme: lightSemanticColorSchemeTokens }, components: lightComponentTokens, theme: { ...lightThemeAssets, InputSize, ModalSize, custom: customLight }, ...commonTheme, diff --git a/src/theme/tokens/README.md b/src/theme/tokens/README.md index e3d127f2..9cbee6d0 100644 --- a/src/theme/tokens/README.md +++ b/src/theme/tokens/README.md @@ -1,12 +1,12 @@ # Сгенерированные токены -`semantic` подключается к темам как `ThemeType.semantic`. `components` хранит -внутренние токены компонентов для `ThemeType.components`. `fonts.json` содержит -общие для цветовых схем токены из `primitive.fonts`, но пока не подключён к теме -и не экспортируется из библиотеки. Остальная часть `primitive` не записывается; -`colorScheme` содержит только выбранную ветку без вложенных `light` и `dark`. -Всё генерируется из `design-tokens/input/tokens.json` и не редактируется -вручную. +В `ThemeType.semantic` подключается только выбранный `colorScheme`. Общие +`dimension` и `effects` экспортируются как статический `semanticTokens`, поэтому +не участвуют в переключении темы. `components` хранит внутренние токены +компонентов для `ThemeType.components`. `fonts.json` содержит общие для цветовых +схем токены из `primitive.fonts`, но пока не подключён к теме и не +экспортируется из библиотеки. Всё генерируется из +`design-tokens/input/tokens.json` и не редактируется вручную. Подробности: [генератор токенов](../../../scripts/token-generator/README.md). @@ -17,7 +17,7 @@ Для передачи easing в Reanimated используйте адаптер: ```ts -import { toEasing } from '@cdek-it/react-native-ui-kit' +import { semanticTokens, toEasing } from '@cdek-it/react-native-ui-kit' -const easing = toEasing(theme.semantic.effects.transition.easing.standard) +const easing = toEasing(semanticTokens.effects.transition.easing.standard) ``` diff --git a/src/theme/tokens/index.ts b/src/theme/tokens/index.ts new file mode 100644 index 00000000..9344acc6 --- /dev/null +++ b/src/theme/tokens/index.ts @@ -0,0 +1,6 @@ +import dimensions from './semantic/dimensions.json' +import effects from './semantic/effects.json' + +export const semanticTokens = { dimension: dimensions, effects } as const + +export type SemanticTokens = typeof semanticTokens diff --git a/src/theme/tokens/semantic/colorScheme/dark.json b/src/theme/tokens/semantic/colorScheme/dark.json new file mode 100644 index 00000000..4ae11e18 --- /dev/null +++ b/src/theme/tokens/semantic/colorScheme/dark.json @@ -0,0 +1,228 @@ +{ + "color": { + "fg": { + "default": "#ffffff", + "hover": "#cecfd2", + "active": "#f0f0f1", + "focus": "#ffffff", + "muted": "#a2a5a9", + "subtle": "#a2a5a9", + "brand": { + "default": "#77f48a", + "hover": "#aafbb7", + "active": "#d4fedc", + "disabled": "#168322", + "visited": "#aafbb7", + "muted": "#44e858" + }, + "inverse": { + "default": "#2b2e33", + "hover": "#56595f", + "active": "#181a1f", + "focus": "#2b2e33", + "muted": "#85888e" + }, + "status": { + "danger": { + "default": "#f47f77", + "hover": "#fbacaa", + "active": "#fed4d4", + "disabled": "#8d2218", + "visited": "#fbacaa", + "muted": "#e85244" + }, + "info": { + "default": "#77baf4", + "hover": "#aad7fb", + "active": "#d4ecfe", + "disabled": "#18538d", + "visited": "#aad7fb", + "muted": "#4496e8" + }, + "warning": { + "default": "#facb75", + "hover": "#fddeaa", + "active": "#ffeed4", + "disabled": "#9d6d0e", + "visited": "#fddeaa", + "muted": "#f5b83d" + }, + "success": { + "default": "#77f48a", + "hover": "#aafbb7", + "active": "#d4fedc", + "disabled": "#168322", + "visited": "#aafbb7", + "muted": "#44e858" + }, + "help": { + "default": "#c084fc", + "hover": "#d8b4fe", + "active": "#e9d5ff", + "disabled": "#7e22ce", + "visited": "#d8b4fe", + "muted": "#a855f7" + } + }, + "on": { + "brand": { + "default": "#2b2e33", + "hover": "#2b2e33", + "active": "#2b2e33" + }, + "fill": { + "default": "#ffffff", + "hover": "#ffffff", + "active": "#ffffff", + "muted": "#e2e2e4" + }, + "status": { + "danger": { "default": "#fff0f0", "hover": "#fffafa" }, + "info": { "default": "#f0f9ff", "hover": "#fafdff" }, + "warning": { "default": "#fff9f0", "hover": "#fffdfa" }, + "success": { "default": "#f0fff3", "hover": "#fafffb" }, + "help": { "default": "#f3e8ff", "hover": "#faf5ff" } + } + } + }, + "bg": { + "status": { + "danger": { + "weak": { + "default": "#3b100c", + "hover": "#45120e", + "active": "#611912" + }, + "strong": { + "default": "#8d2218", + "hover": "#db3424", + "active": "#e85244" + } + }, + "info": { + "weak": { + "default": "#0c243b", + "hover": "#0e2a45", + "active": "#123a61" + }, + "strong": { + "default": "#18538d", + "hover": "#1e76cd", + "active": "#4496e8" + } + }, + "warning": { + "weak": { + "default": "#453008", + "hover": "#4f3709", + "active": "#6d4c0b" + }, + "strong": { + "default": "#9d6d0e", + "hover": "#dc9710", + "active": "#f5b83d" + } + }, + "success": { + "weak": { + "default": "#0c3b11", + "hover": "#0e4514", + "active": "#12611b" + }, + "strong": { + "default": "#168322", + "hover": "#1dc831", + "active": "#44e858" + } + }, + "help": { + "weak": { + "default": "#3b0764", + "hover": "#581c87", + "active": "#6b21a8" + }, + "strong": { + "default": "#7e22ce", + "hover": "#9333ea", + "active": "#a855f7" + } + } + }, + "brand": { + "weak": { "hover": "#0c3b11", "active": "#0e4514" }, + "strong": { + "default": "#44e858", + "hover": "#77f48a", + "active": "#aafbb7" + } + }, + "surface": { + "canvas": { + "default": "#2b2e33", + "hover": "#404348", + "active": "#56595f", + "selected": "#404348" + }, + "default": { + "default": "#404348", + "hover": "#56595f", + "active": "#6d7076", + "selected": "#56595f" + }, + "raised": { + "default": "#56595f", + "hover": "#6d7076", + "active": "#85888e", + "selected": "#6d7076" + }, + "overlay": { "default": "#404348", "hover": "#56595f" }, + "backdrop": "rgba(0, 0, 0, 0.6000)" + }, + "neutral": { + "weak": { + "default": "#2b2e33", + "hover": "#404348", + "active": "#56595f", + "disabled": "#404348" + }, + "medium": { + "default": "#404348", + "hover": "#56595f", + "active": "#6d7076", + "strong": "#85888e" + }, + "strong": { + "default": "#f0f0f1", + "hover": "#e2e2e4", + "active": "#cecfd2", + "selected": "#f0f0f1" + } + } + }, + "border": { + "focus": "#d4fedc", + "neutral": { + "default": "#404348", + "strong": "#56595f", + "bold": { "default": "#f0f0f1", "hover": "#e2e2e4" }, + "inverse": "#2b2e33" + }, + "brand": { + "subtle": "#12611b", + "default": "#44e858", + "strong": "#77f48a" + }, + "status": { + "danger": { + "subtle": "#db3424", + "default": "#e85244", + "strong": "#f47f77" + }, + "info": { "default": "#4496e8", "strong": "#77baf4" }, + "warning": { "default": "#f5b83d", "strong": "#facb75" }, + "success": { "default": "#44e858", "strong": "#77f48a" }, + "help": { "strong": "#c084fc" } + } + } + } +} diff --git a/src/theme/tokens/semantic/colorScheme/light.json b/src/theme/tokens/semantic/colorScheme/light.json new file mode 100644 index 00000000..695bff01 --- /dev/null +++ b/src/theme/tokens/semantic/colorScheme/light.json @@ -0,0 +1,228 @@ +{ + "color": { + "fg": { + "default": "#2b2e33", + "hover": "#56595f", + "active": "#181a1f", + "focus": "#2b2e33", + "muted": "#85888e", + "subtle": "#6d7076", + "brand": { + "default": "#44e858", + "hover": "#1dc831", + "active": "#168322", + "disabled": "#aafbb7", + "visited": "#12611b", + "muted": "#77f48a" + }, + "inverse": { + "default": "#ffffff", + "hover": "#ffffff", + "active": "#ffffff", + "focus": "#ffffff", + "muted": "rgba(255, 255, 255, 0.7000)" + }, + "status": { + "danger": { + "default": "#e85244", + "hover": "#db3424", + "active": "#8d2218", + "disabled": "#fbacaa", + "visited": "#611912", + "muted": "#f47f77" + }, + "info": { + "default": "#4496e8", + "hover": "#1e76cd", + "active": "#18538d", + "disabled": "#aad7fb", + "visited": "#123a61", + "muted": "#77baf4" + }, + "warning": { + "default": "#f5b83d", + "hover": "#dc9710", + "active": "#9d6d0e", + "disabled": "#fddeaa", + "visited": "#6d4c0b", + "muted": "#facb75" + }, + "success": { + "default": "#44e858", + "hover": "#1dc831", + "active": "#168322", + "disabled": "#aafbb7", + "visited": "#12611b", + "muted": "#77f48a" + }, + "help": { + "default": "#a855f7", + "hover": "#9333ea", + "active": "#7e22ce", + "disabled": "#d8b4fe", + "visited": "#6b21a8", + "muted": "#c084fc" + } + }, + "on": { + "brand": { + "default": "#2b2e33", + "hover": "#2b2e33", + "active": "#2b2e33" + }, + "fill": { + "default": "#ffffff", + "hover": "#ffffff", + "active": "#ffffff", + "muted": "#e2e2e4" + }, + "status": { + "danger": { "default": "#45120e", "hover": "#3b100c" }, + "info": { "default": "#0e2a45", "hover": "#0c243b" }, + "warning": { "default": "#4f3709", "hover": "#453008" }, + "success": { "default": "#0e4514", "hover": "#0c3b11" }, + "help": { "default": "#581c87", "hover": "#3b0764" } + } + } + }, + "bg": { + "status": { + "danger": { + "weak": { + "default": "#fffafa", + "hover": "#fff0f0", + "active": "#fed4d4" + }, + "strong": { + "default": "#fbacaa", + "hover": "#f47f77", + "active": "#e85244" + } + }, + "info": { + "weak": { + "default": "#fafdff", + "hover": "#f0f9ff", + "active": "#d4ecfe" + }, + "strong": { + "default": "#aad7fb", + "hover": "#77baf4", + "active": "#4496e8" + } + }, + "warning": { + "weak": { + "default": "#fffdfa", + "hover": "#fff9f0", + "active": "#ffeed4" + }, + "strong": { + "default": "#fddeaa", + "hover": "#facb75", + "active": "#f5b83d" + } + }, + "success": { + "weak": { + "default": "#fafffb", + "hover": "#f0fff3", + "active": "#d4fedc" + }, + "strong": { + "default": "#aafbb7", + "hover": "#77f48a", + "active": "#44e858" + } + }, + "help": { + "weak": { + "default": "#faf5ff", + "hover": "#f3e8ff", + "active": "#e9d5ff" + }, + "strong": { + "default": "#d8b4fe", + "hover": "#c084fc", + "active": "#a855f7" + } + } + }, + "brand": { + "weak": { "hover": "#fafffb", "active": "#f0fff3" }, + "strong": { + "default": "#44e858", + "hover": "#1dc831", + "active": "#168322" + } + }, + "surface": { + "canvas": { + "default": "#f0f0f1", + "hover": "#e2e2e4", + "active": "#cecfd2", + "selected": "#e2e2e4" + }, + "default": { + "default": "#ffffff", + "hover": "#fafafa", + "active": "#f0f0f1", + "selected": "#fafafa" + }, + "raised": { + "default": "#ffffff", + "hover": "#fafafa", + "active": "#f0f0f1", + "selected": "#fafafa" + }, + "overlay": { "default": "#ffffff", "hover": "#fafafa" }, + "backdrop": "rgba(0, 0, 0, 0.4000)" + }, + "neutral": { + "weak": { + "default": "#f0f0f1", + "hover": "#e2e2e4", + "active": "#cecfd2", + "disabled": "#e2e2e4" + }, + "medium": { + "default": "#e2e2e4", + "hover": "#cecfd2", + "active": "#a2a5a9", + "strong": "#85888e" + }, + "strong": { + "default": "#2b2e33", + "hover": "#404348", + "active": "#56595f", + "selected": "#2b2e33" + } + } + }, + "border": { + "focus": "#d4fedc", + "neutral": { + "default": "#e2e2e4", + "strong": "#cecfd2", + "bold": { "default": "#2b2e33", "hover": "#404348" }, + "inverse": "#ffffff" + }, + "brand": { + "subtle": "#d4fedc", + "default": "#44e858", + "strong": "#1dc831" + }, + "status": { + "danger": { + "subtle": "#f47f77", + "default": "#e85244", + "strong": "#db3424" + }, + "info": { "default": "#4496e8", "strong": "#1e76cd" }, + "warning": { "default": "#f5b83d", "strong": "#dc9710" }, + "success": { "default": "#44e858", "strong": "#1dc831" }, + "help": { "strong": "#9333ea" } + } + } + } +} diff --git a/src/theme/tokens/semantic/dark.json b/src/theme/tokens/semantic/dark.json deleted file mode 100644 index 32086ae3..00000000 --- a/src/theme/tokens/semantic/dark.json +++ /dev/null @@ -1,346 +0,0 @@ -{ - "colorScheme": { - "color": { - "fg": { - "default": "#ffffff", - "hover": "#cecfd2", - "active": "#f0f0f1", - "focus": "#ffffff", - "muted": "#a2a5a9", - "subtle": "#a2a5a9", - "brand": { - "default": "#77f48a", - "hover": "#aafbb7", - "active": "#d4fedc", - "disabled": "#168322", - "visited": "#aafbb7", - "muted": "#44e858" - }, - "inverse": { - "default": "#2b2e33", - "hover": "#56595f", - "active": "#181a1f", - "focus": "#2b2e33", - "muted": "#85888e" - }, - "status": { - "danger": { - "default": "#f47f77", - "hover": "#fbacaa", - "active": "#fed4d4", - "disabled": "#8d2218", - "visited": "#fbacaa", - "muted": "#e85244" - }, - "info": { - "default": "#77baf4", - "hover": "#aad7fb", - "active": "#d4ecfe", - "disabled": "#18538d", - "visited": "#aad7fb", - "muted": "#4496e8" - }, - "warning": { - "default": "#facb75", - "hover": "#fddeaa", - "active": "#ffeed4", - "disabled": "#9d6d0e", - "visited": "#fddeaa", - "muted": "#f5b83d" - }, - "success": { - "default": "#77f48a", - "hover": "#aafbb7", - "active": "#d4fedc", - "disabled": "#168322", - "visited": "#aafbb7", - "muted": "#44e858" - }, - "help": { - "default": "#c084fc", - "hover": "#d8b4fe", - "active": "#e9d5ff", - "disabled": "#7e22ce", - "visited": "#d8b4fe", - "muted": "#a855f7" - } - }, - "on": { - "brand": { - "default": "#2b2e33", - "hover": "#2b2e33", - "active": "#2b2e33" - }, - "fill": { - "default": "#ffffff", - "hover": "#ffffff", - "active": "#ffffff", - "muted": "#e2e2e4" - }, - "status": { - "danger": { "default": "#fff0f0", "hover": "#fffafa" }, - "info": { "default": "#f0f9ff", "hover": "#fafdff" }, - "warning": { "default": "#fff9f0", "hover": "#fffdfa" }, - "success": { "default": "#f0fff3", "hover": "#fafffb" }, - "help": { "default": "#f3e8ff", "hover": "#faf5ff" } - } - } - }, - "bg": { - "status": { - "danger": { - "weak": { - "default": "#3b100c", - "hover": "#45120e", - "active": "#611912" - }, - "strong": { - "default": "#8d2218", - "hover": "#db3424", - "active": "#e85244" - } - }, - "info": { - "weak": { - "default": "#0c243b", - "hover": "#0e2a45", - "active": "#123a61" - }, - "strong": { - "default": "#18538d", - "hover": "#1e76cd", - "active": "#4496e8" - } - }, - "warning": { - "weak": { - "default": "#453008", - "hover": "#4f3709", - "active": "#6d4c0b" - }, - "strong": { - "default": "#9d6d0e", - "hover": "#dc9710", - "active": "#f5b83d" - } - }, - "success": { - "weak": { - "default": "#0c3b11", - "hover": "#0e4514", - "active": "#12611b" - }, - "strong": { - "default": "#168322", - "hover": "#1dc831", - "active": "#44e858" - } - }, - "help": { - "weak": { - "default": "#3b0764", - "hover": "#581c87", - "active": "#6b21a8" - }, - "strong": { - "default": "#7e22ce", - "hover": "#9333ea", - "active": "#a855f7" - } - } - }, - "brand": { - "weak": { "hover": "#0c3b11", "active": "#0e4514" }, - "strong": { - "default": "#44e858", - "hover": "#77f48a", - "active": "#aafbb7" - } - }, - "surface": { - "canvas": { - "default": "#2b2e33", - "hover": "#404348", - "active": "#56595f", - "selected": "#404348" - }, - "default": { - "default": "#404348", - "hover": "#56595f", - "active": "#6d7076", - "selected": "#56595f" - }, - "raised": { - "default": "#56595f", - "hover": "#6d7076", - "active": "#85888e", - "selected": "#6d7076" - }, - "overlay": { "default": "#404348", "hover": "#56595f" }, - "backdrop": "rgba(0, 0, 0, 0.6000)" - }, - "neutral": { - "weak": { - "default": "#2b2e33", - "hover": "#404348", - "active": "#56595f", - "disabled": "#404348" - }, - "medium": { - "default": "#404348", - "hover": "#56595f", - "active": "#6d7076", - "strong": "#85888e" - }, - "strong": { - "default": "#f0f0f1", - "hover": "#e2e2e4", - "active": "#cecfd2", - "selected": "#f0f0f1" - } - } - }, - "border": { - "focus": "#d4fedc", - "neutral": { - "default": "#404348", - "strong": "#56595f", - "bold": { "default": "#f0f0f1", "hover": "#e2e2e4" }, - "inverse": "#2b2e33" - }, - "brand": { - "subtle": "#12611b", - "default": "#44e858", - "strong": "#77f48a" - }, - "status": { - "danger": { - "subtle": "#db3424", - "default": "#e85244", - "strong": "#f47f77" - }, - "info": { "default": "#4496e8", "strong": "#77baf4" }, - "warning": { "default": "#f5b83d", "strong": "#facb75" }, - "success": { "default": "#44e858", "strong": "#77f48a" }, - "help": { "strong": "#c084fc" } - } - } - } - }, - "dimension": { - "space": { - "100": 4, - "150": 6, - "200": 8, - "300": 10, - "400": 14, - "500": 18, - "600": 20, - "700": 24, - "800": 28, - "none": 0, - "negative": { "50": -2, "200": -8, "300": -12, "600": -24 } - }, - "size": { - "50": 2, - "100": 4, - "150": 6, - "200": 8, - "300": 10, - "350": 12, - "400": 14, - "450": 16, - "500": 18, - "600": 20, - "700": 24, - "750": 26, - "800": 28, - "900": 32, - "1000": 36, - "1100": 40, - "1200": 48, - "1300": 56, - "1400": 64, - "1500": 80, - "1600": 240, - "1700": 272, - "1800": 304, - "1900": 336, - "2000": 400, - "none": 0, - "max": 1600 - }, - "borderRadius": { - "100": 4, - "200": 8, - "300": 10, - "400": 14, - "500": 20, - "none": 0, - "max": 1600 - }, - "borderWidth": { "100": 1, "200": 2, "300": 4, "none": 0 }, - "focusRing": { "width": 4, "offset": 0 }, - "depth": { - "100": 1000, - "200": 1100, - "300": 1200, - "400": 1300, - "500": 1400, - "600": 1500, - "700": 1600 - }, - "viewport": { "100": 576, "200": 768, "300": 992, "400": 1200, "500": 1400 } - }, - "effects": { - "opacity": { - "0": 0, - "4": 0.04, - "8": 0.08, - "12": 0.12, - "16": 0.16, - "20": 0.2, - "30": 0.3, - "40": 0.4, - "50": 0.5, - "60": 0.6, - "70": 0.7, - "80": 0.8, - "90": 0.9, - "100": 1 - }, - "blur": { "100": 4, "200": 8, "300": 16, "400": 24, "none": 0 }, - "transition": { - "easing": { - "linear": { "x1": 0, "y1": 0, "x2": 1, "y2": 1 }, - "in": { "x1": 0.55, "y1": 0.06, "x2": 0.7, "y2": 0.2 }, - "out": { "x1": 0.2, "y1": 0.6, "x2": 0.4, "y2": 1 }, - "inOut": { "x1": 0.65, "y1": 0.05, "x2": 0.35, "y2": 1 }, - "standard": { "x1": 0.2, "y1": 0, "x2": 0, "y2": 1 }, - "accelerate": { "x1": 0.3, "y1": 0, "x2": 1, "y2": 1 }, - "decelerate": { "x1": 0, "y1": 0, "x2": 0, "y2": 1 }, - "emphasizedAccelerate": { "x1": 0.3, "y1": 0, "x2": 0.8, "y2": 0.15 }, - "emphasizedDecelerate": { "x1": 0.05, "y1": 0.7, "x2": 0.1, "y2": 1 }, - "spring": { "x1": 0.34, "y1": 1.56, "x2": 0.64, "y2": 1 } - }, - "duration": { "100": 140, "200": 180, "300": 240, "400": 320, "500": 400 } - }, - "elevation": { - "100": "0 0 2px rgba(0, 0, 0, 0.2000)", - "200": "0 0 4px rgba(0, 0, 0, 0.2000)", - "300": "0 2px 4px rgba(0, 0, 0, 0.2000)", - "400": "0 4px 8px rgba(0, 0, 0, 0.2000)", - "500": "0 8px 16px 0 rgba(0, 0, 0, 0.2000)", - "none": "none", - "status": { - "info": "0px 4px 8px 0px rgba(68, 150, 232, 0.04)", - "success": "0px 4px 8px 0px rgba(68, 232, 88, 0.04)", - "warning": "0px 4px 8px 0px rgba(245, 184, 61, 0.04)", - "danger": "0px 4px 8px 0px rgba(232, 82, 68, 0.04)", - "secondary": "0px 4px 8px 0px rgba(0, 0, 0, 0.0400)", - "contrast": "0px 4px 8px 0px rgba(0, 0, 0, 0.0400)" - } - }, - "focusRing": { "shadow": "inset 0 0 0 4px #d4fedc" } - } -} diff --git a/src/theme/tokens/semantic/dimensions.json b/src/theme/tokens/semantic/dimensions.json new file mode 100644 index 00000000..28c7802d --- /dev/null +++ b/src/theme/tokens/semantic/dimensions.json @@ -0,0 +1,65 @@ +{ + "space": { + "100": 4, + "150": 6, + "200": 8, + "300": 10, + "400": 14, + "500": 18, + "600": 20, + "700": 24, + "800": 28, + "none": 0, + "negative": { "50": -2, "200": -8, "300": -12, "600": -24 } + }, + "size": { + "50": 2, + "100": 4, + "150": 6, + "200": 8, + "300": 10, + "350": 12, + "400": 14, + "450": 16, + "500": 18, + "600": 20, + "700": 24, + "750": 26, + "800": 28, + "900": 32, + "1000": 36, + "1100": 40, + "1200": 48, + "1300": 56, + "1400": 64, + "1500": 80, + "1600": 240, + "1700": 272, + "1800": 304, + "1900": 336, + "2000": 400, + "none": 0, + "max": 1600 + }, + "borderRadius": { + "100": 4, + "200": 8, + "300": 10, + "400": 14, + "500": 20, + "none": 0, + "max": 1600 + }, + "borderWidth": { "100": 1, "200": 2, "300": 4, "none": 0 }, + "focusRing": { "width": 4, "offset": 0 }, + "depth": { + "100": 1000, + "200": 1100, + "300": 1200, + "400": 1300, + "500": 1400, + "600": 1500, + "700": 1600 + }, + "viewport": { "100": 576, "200": 768, "300": 992, "400": 1200, "500": 1400 } +} diff --git a/src/theme/tokens/semantic/effects.json b/src/theme/tokens/semantic/effects.json new file mode 100644 index 00000000..1a1a6294 --- /dev/null +++ b/src/theme/tokens/semantic/effects.json @@ -0,0 +1,51 @@ +{ + "opacity": { + "0": 0, + "4": 0.04, + "8": 0.08, + "12": 0.12, + "16": 0.16, + "20": 0.2, + "30": 0.3, + "40": 0.4, + "50": 0.5, + "60": 0.6, + "70": 0.7, + "80": 0.8, + "90": 0.9, + "100": 1 + }, + "blur": { "100": 4, "200": 8, "300": 16, "400": 24, "none": 0 }, + "transition": { + "easing": { + "linear": { "x1": 0, "y1": 0, "x2": 1, "y2": 1 }, + "in": { "x1": 0.55, "y1": 0.06, "x2": 0.7, "y2": 0.2 }, + "out": { "x1": 0.2, "y1": 0.6, "x2": 0.4, "y2": 1 }, + "inOut": { "x1": 0.65, "y1": 0.05, "x2": 0.35, "y2": 1 }, + "standard": { "x1": 0.2, "y1": 0, "x2": 0, "y2": 1 }, + "accelerate": { "x1": 0.3, "y1": 0, "x2": 1, "y2": 1 }, + "decelerate": { "x1": 0, "y1": 0, "x2": 0, "y2": 1 }, + "emphasizedAccelerate": { "x1": 0.3, "y1": 0, "x2": 0.8, "y2": 0.15 }, + "emphasizedDecelerate": { "x1": 0.05, "y1": 0.7, "x2": 0.1, "y2": 1 }, + "spring": { "x1": 0.34, "y1": 1.56, "x2": 0.64, "y2": 1 } + }, + "duration": { "100": 140, "200": 180, "300": 240, "400": 320, "500": 400 } + }, + "elevation": { + "100": "0 0 2px rgba(0, 0, 0, 0.2000)", + "200": "0 0 4px rgba(0, 0, 0, 0.2000)", + "300": "0 2px 4px rgba(0, 0, 0, 0.2000)", + "400": "0 4px 8px rgba(0, 0, 0, 0.2000)", + "500": "0 8px 16px 0 rgba(0, 0, 0, 0.2000)", + "none": "none", + "status": { + "info": "0px 4px 8px 0px rgba(68, 150, 232, 0.04)", + "success": "0px 4px 8px 0px rgba(68, 232, 88, 0.04)", + "warning": "0px 4px 8px 0px rgba(245, 184, 61, 0.04)", + "danger": "0px 4px 8px 0px rgba(232, 82, 68, 0.04)", + "secondary": "0px 4px 8px 0px rgba(0, 0, 0, 0.0400)", + "contrast": "0px 4px 8px 0px rgba(0, 0, 0, 0.0400)" + } + }, + "focusRing": { "shadow": "inset 0 0 0 4px #d4fedc" } +} diff --git a/src/theme/tokens/semantic/light.json b/src/theme/tokens/semantic/light.json deleted file mode 100644 index b3ff8316..00000000 --- a/src/theme/tokens/semantic/light.json +++ /dev/null @@ -1,346 +0,0 @@ -{ - "colorScheme": { - "color": { - "fg": { - "default": "#2b2e33", - "hover": "#56595f", - "active": "#181a1f", - "focus": "#2b2e33", - "muted": "#85888e", - "subtle": "#6d7076", - "brand": { - "default": "#44e858", - "hover": "#1dc831", - "active": "#168322", - "disabled": "#aafbb7", - "visited": "#12611b", - "muted": "#77f48a" - }, - "inverse": { - "default": "#ffffff", - "hover": "#ffffff", - "active": "#ffffff", - "focus": "#ffffff", - "muted": "rgba(255, 255, 255, 0.7000)" - }, - "status": { - "danger": { - "default": "#e85244", - "hover": "#db3424", - "active": "#8d2218", - "disabled": "#fbacaa", - "visited": "#611912", - "muted": "#f47f77" - }, - "info": { - "default": "#4496e8", - "hover": "#1e76cd", - "active": "#18538d", - "disabled": "#aad7fb", - "visited": "#123a61", - "muted": "#77baf4" - }, - "warning": { - "default": "#f5b83d", - "hover": "#dc9710", - "active": "#9d6d0e", - "disabled": "#fddeaa", - "visited": "#6d4c0b", - "muted": "#facb75" - }, - "success": { - "default": "#44e858", - "hover": "#1dc831", - "active": "#168322", - "disabled": "#aafbb7", - "visited": "#12611b", - "muted": "#77f48a" - }, - "help": { - "default": "#a855f7", - "hover": "#9333ea", - "active": "#7e22ce", - "disabled": "#d8b4fe", - "visited": "#6b21a8", - "muted": "#c084fc" - } - }, - "on": { - "brand": { - "default": "#2b2e33", - "hover": "#2b2e33", - "active": "#2b2e33" - }, - "fill": { - "default": "#ffffff", - "hover": "#ffffff", - "active": "#ffffff", - "muted": "#e2e2e4" - }, - "status": { - "danger": { "default": "#45120e", "hover": "#3b100c" }, - "info": { "default": "#0e2a45", "hover": "#0c243b" }, - "warning": { "default": "#4f3709", "hover": "#453008" }, - "success": { "default": "#0e4514", "hover": "#0c3b11" }, - "help": { "default": "#581c87", "hover": "#3b0764" } - } - } - }, - "bg": { - "status": { - "danger": { - "weak": { - "default": "#fffafa", - "hover": "#fff0f0", - "active": "#fed4d4" - }, - "strong": { - "default": "#fbacaa", - "hover": "#f47f77", - "active": "#e85244" - } - }, - "info": { - "weak": { - "default": "#fafdff", - "hover": "#f0f9ff", - "active": "#d4ecfe" - }, - "strong": { - "default": "#aad7fb", - "hover": "#77baf4", - "active": "#4496e8" - } - }, - "warning": { - "weak": { - "default": "#fffdfa", - "hover": "#fff9f0", - "active": "#ffeed4" - }, - "strong": { - "default": "#fddeaa", - "hover": "#facb75", - "active": "#f5b83d" - } - }, - "success": { - "weak": { - "default": "#fafffb", - "hover": "#f0fff3", - "active": "#d4fedc" - }, - "strong": { - "default": "#aafbb7", - "hover": "#77f48a", - "active": "#44e858" - } - }, - "help": { - "weak": { - "default": "#faf5ff", - "hover": "#f3e8ff", - "active": "#e9d5ff" - }, - "strong": { - "default": "#d8b4fe", - "hover": "#c084fc", - "active": "#a855f7" - } - } - }, - "brand": { - "weak": { "hover": "#fafffb", "active": "#f0fff3" }, - "strong": { - "default": "#44e858", - "hover": "#1dc831", - "active": "#168322" - } - }, - "surface": { - "canvas": { - "default": "#f0f0f1", - "hover": "#e2e2e4", - "active": "#cecfd2", - "selected": "#e2e2e4" - }, - "default": { - "default": "#ffffff", - "hover": "#fafafa", - "active": "#f0f0f1", - "selected": "#fafafa" - }, - "raised": { - "default": "#ffffff", - "hover": "#fafafa", - "active": "#f0f0f1", - "selected": "#fafafa" - }, - "overlay": { "default": "#ffffff", "hover": "#fafafa" }, - "backdrop": "rgba(0, 0, 0, 0.4000)" - }, - "neutral": { - "weak": { - "default": "#f0f0f1", - "hover": "#e2e2e4", - "active": "#cecfd2", - "disabled": "#e2e2e4" - }, - "medium": { - "default": "#e2e2e4", - "hover": "#cecfd2", - "active": "#a2a5a9", - "strong": "#85888e" - }, - "strong": { - "default": "#2b2e33", - "hover": "#404348", - "active": "#56595f", - "selected": "#2b2e33" - } - } - }, - "border": { - "focus": "#d4fedc", - "neutral": { - "default": "#e2e2e4", - "strong": "#cecfd2", - "bold": { "default": "#2b2e33", "hover": "#404348" }, - "inverse": "#ffffff" - }, - "brand": { - "subtle": "#d4fedc", - "default": "#44e858", - "strong": "#1dc831" - }, - "status": { - "danger": { - "subtle": "#f47f77", - "default": "#e85244", - "strong": "#db3424" - }, - "info": { "default": "#4496e8", "strong": "#1e76cd" }, - "warning": { "default": "#f5b83d", "strong": "#dc9710" }, - "success": { "default": "#44e858", "strong": "#1dc831" }, - "help": { "strong": "#9333ea" } - } - } - } - }, - "dimension": { - "space": { - "100": 4, - "150": 6, - "200": 8, - "300": 10, - "400": 14, - "500": 18, - "600": 20, - "700": 24, - "800": 28, - "none": 0, - "negative": { "50": -2, "200": -8, "300": -12, "600": -24 } - }, - "size": { - "50": 2, - "100": 4, - "150": 6, - "200": 8, - "300": 10, - "350": 12, - "400": 14, - "450": 16, - "500": 18, - "600": 20, - "700": 24, - "750": 26, - "800": 28, - "900": 32, - "1000": 36, - "1100": 40, - "1200": 48, - "1300": 56, - "1400": 64, - "1500": 80, - "1600": 240, - "1700": 272, - "1800": 304, - "1900": 336, - "2000": 400, - "none": 0, - "max": 1600 - }, - "borderRadius": { - "100": 4, - "200": 8, - "300": 10, - "400": 14, - "500": 20, - "none": 0, - "max": 1600 - }, - "borderWidth": { "100": 1, "200": 2, "300": 4, "none": 0 }, - "focusRing": { "width": 4, "offset": 0 }, - "depth": { - "100": 1000, - "200": 1100, - "300": 1200, - "400": 1300, - "500": 1400, - "600": 1500, - "700": 1600 - }, - "viewport": { "100": 576, "200": 768, "300": 992, "400": 1200, "500": 1400 } - }, - "effects": { - "opacity": { - "0": 0, - "4": 0.04, - "8": 0.08, - "12": 0.12, - "16": 0.16, - "20": 0.2, - "30": 0.3, - "40": 0.4, - "50": 0.5, - "60": 0.6, - "70": 0.7, - "80": 0.8, - "90": 0.9, - "100": 1 - }, - "blur": { "100": 4, "200": 8, "300": 16, "400": 24, "none": 0 }, - "transition": { - "easing": { - "linear": { "x1": 0, "y1": 0, "x2": 1, "y2": 1 }, - "in": { "x1": 0.55, "y1": 0.06, "x2": 0.7, "y2": 0.2 }, - "out": { "x1": 0.2, "y1": 0.6, "x2": 0.4, "y2": 1 }, - "inOut": { "x1": 0.65, "y1": 0.05, "x2": 0.35, "y2": 1 }, - "standard": { "x1": 0.2, "y1": 0, "x2": 0, "y2": 1 }, - "accelerate": { "x1": 0.3, "y1": 0, "x2": 1, "y2": 1 }, - "decelerate": { "x1": 0, "y1": 0, "x2": 0, "y2": 1 }, - "emphasizedAccelerate": { "x1": 0.3, "y1": 0, "x2": 0.8, "y2": 0.15 }, - "emphasizedDecelerate": { "x1": 0.05, "y1": 0.7, "x2": 0.1, "y2": 1 }, - "spring": { "x1": 0.34, "y1": 1.56, "x2": 0.64, "y2": 1 } - }, - "duration": { "100": 140, "200": 180, "300": 240, "400": 320, "500": 400 } - }, - "elevation": { - "100": "0 0 2px rgba(0, 0, 0, 0.2000)", - "200": "0 0 4px rgba(0, 0, 0, 0.2000)", - "300": "0 2px 4px rgba(0, 0, 0, 0.2000)", - "400": "0 4px 8px rgba(0, 0, 0, 0.2000)", - "500": "0 8px 16px 0 rgba(0, 0, 0, 0.2000)", - "none": "none", - "status": { - "info": "0px 4px 8px 0px rgba(68, 150, 232, 0.04)", - "success": "0px 4px 8px 0px rgba(68, 232, 88, 0.04)", - "warning": "0px 4px 8px 0px rgba(245, 184, 61, 0.04)", - "danger": "0px 4px 8px 0px rgba(232, 82, 68, 0.04)", - "secondary": "0px 4px 8px 0px rgba(0, 0, 0, 0.0400)", - "contrast": "0px 4px 8px 0px rgba(0, 0, 0, 0.0400)" - } - }, - "focusRing": { "shadow": "inset 0 0 0 4px #d4fedc" } - } -} diff --git a/src/theme/types.ts b/src/theme/types.ts index 7cc9d2dc..1c5056af 100644 --- a/src/theme/types.ts +++ b/src/theme/types.ts @@ -13,7 +13,7 @@ import type spacing from './assets/spacing.json' import type lightTheme from './assets/themeLight.json' import type typography from './assets/typography.json' import type lightComponentTokens from './tokens/components/light.json' -import type lightSemanticTokens from './tokens/semantic/light.json' +import type lightSemanticColorSchemeTokens from './tokens/semantic/colorScheme/light.json' export interface ThemeType { background: typeof background @@ -23,7 +23,7 @@ export interface ThemeType { global: typeof global sizing: typeof sizing spacing: typeof spacing - semantic: typeof lightSemanticTokens + semantic: { colorScheme: typeof lightSemanticColorSchemeTokens } components: typeof lightComponentTokens theme: typeof lightTheme & { custom: typeof customLight From 542c6c622d05437669b1e3eba51973023a768093 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 12:32:23 +0300 Subject: [PATCH 11/40] =?UTF-8?q?refactor(tokens):=20component-=D1=82?= =?UTF-8?q?=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B=20=D1=81=D0=BA=D1=80=D1=8B=D1=82?= =?UTF-8?q?=D1=8B=20=D0=B8=D0=B7=20=D0=BF=D1=83=D0=B1=D0=BB=D0=B8=D1=87?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/token-generator/README.md | 13 +++---------- src/theme/__tests__/ThemeContext.test.tsx | 8 +++----- src/theme/darkTheme.ts | 2 -- src/theme/lightTheme.ts | 2 -- src/theme/tokens/README.md | 6 +++--- src/theme/types.ts | 2 -- 6 files changed, 9 insertions(+), 24 deletions(-) diff --git a/scripts/token-generator/README.md b/scripts/token-generator/README.md index 29b8a12f..796dc9ed 100644 --- a/scripts/token-generator/README.md +++ b/scripts/token-generator/README.md @@ -14,17 +14,10 @@ результат. `tokens:validate` ничего не меняет: проверяет TypeScript генератора и актуальность сгенерированных токенов. -## Использование в компонентах +## Использование токенов -Внутри UI Kit используются component-токены: - -```ts -StyleSheet.create(({ components }) => ({ - header: { - backgroundColor: components.accordion.colorScheme.header.background, - }, -})) -``` +Component-токены предназначены только для реализации компонентов UI Kit. Они не +входят в темы и публичные экспорты библиотеки. В `semantic` темы находится только `colorScheme`: Unistyles подставляет соответствующие light- или dark-токены при переключении темы. Не зависящие от diff --git a/src/theme/__tests__/ThemeContext.test.tsx b/src/theme/__tests__/ThemeContext.test.tsx index 14499cc5..71425de8 100644 --- a/src/theme/__tests__/ThemeContext.test.tsx +++ b/src/theme/__tests__/ThemeContext.test.tsx @@ -7,8 +7,6 @@ import { ThemeContextProvider } from '../ThemeContext' import { darkTheme } from '../darkTheme' import { lightTheme } from '../lightTheme' import { semanticTokens } from '../tokens' -import darkComponentTokens from '../tokens/components/dark.json' -import lightComponentTokens from '../tokens/components/light.json' import darkSemanticColorSchemeTokens from '../tokens/semantic/colorScheme/dark.json' import lightSemanticColorSchemeTokens from '../tokens/semantic/colorScheme/light.json' import semanticDimensions from '../tokens/semantic/dimensions.json' @@ -87,8 +85,8 @@ describe('ThemeContextProvider', () => { expect(semanticTokens.effects).toBe(semanticEffects) }) - test('каждая тема содержит соответствующие component-токены', () => { - expect(lightTheme.components).toBe(lightComponentTokens) - expect(darkTheme.components).toBe(darkComponentTokens) + test('component-токены не входят в публичные темы', () => { + expect(lightTheme).not.toHaveProperty('components') + expect(darkTheme).not.toHaveProperty('components') }) }) diff --git a/src/theme/darkTheme.ts b/src/theme/darkTheme.ts index 4cce3ec9..bbc330fe 100644 --- a/src/theme/darkTheme.ts +++ b/src/theme/darkTheme.ts @@ -3,13 +3,11 @@ import { ModalSize } from './assets/ModalSize' import { customDark } from './assets/customDark' import darkThemeAssets from './assets/themeDark.json' import { commonTheme } from './commonTheme' -import darkComponentTokens from './tokens/components/dark.json' import darkSemanticColorSchemeTokens from './tokens/semantic/colorScheme/dark.json' import type { ThemeType } from './types' export const darkTheme: ThemeType = { semantic: { colorScheme: darkSemanticColorSchemeTokens }, - components: darkComponentTokens, theme: { ...darkThemeAssets, InputSize, ModalSize, custom: customDark }, ...commonTheme, fonts: { primary: 'TT Fellows', secondary: 'Noto Sans' }, diff --git a/src/theme/lightTheme.ts b/src/theme/lightTheme.ts index 2abc1957..e3c80bfb 100644 --- a/src/theme/lightTheme.ts +++ b/src/theme/lightTheme.ts @@ -3,13 +3,11 @@ import { ModalSize } from './assets/ModalSize' import { customLight } from './assets/customLight' import lightThemeAssets from './assets/themeLight.json' import { commonTheme } from './commonTheme' -import lightComponentTokens from './tokens/components/light.json' import lightSemanticColorSchemeTokens from './tokens/semantic/colorScheme/light.json' import type { ThemeType } from './types' export const lightTheme: ThemeType = { semantic: { colorScheme: lightSemanticColorSchemeTokens }, - components: lightComponentTokens, theme: { ...lightThemeAssets, InputSize, ModalSize, custom: customLight }, ...commonTheme, fonts: { primary: 'TT Fellows', secondary: 'Noto Sans' }, diff --git a/src/theme/tokens/README.md b/src/theme/tokens/README.md index 9cbee6d0..6547d0fb 100644 --- a/src/theme/tokens/README.md +++ b/src/theme/tokens/README.md @@ -3,9 +3,9 @@ В `ThemeType.semantic` подключается только выбранный `colorScheme`. Общие `dimension` и `effects` экспортируются как статический `semanticTokens`, поэтому не участвуют в переключении темы. `components` хранит внутренние токены -компонентов для `ThemeType.components`. `fonts.json` содержит общие для цветовых -схем токены из `primitive.fonts`, но пока не подключён к теме и не -экспортируется из библиотеки. Всё генерируется из +компонентов и не входит в темы или публичные экспорты. `fonts.json` содержит +общие для цветовых схем токены из `primitive.fonts`, но пока не подключён к теме +и не экспортируется из библиотеки. Всё генерируется из `design-tokens/input/tokens.json` и не редактируется вручную. Подробности: [генератор токенов](../../../scripts/token-generator/README.md). diff --git a/src/theme/types.ts b/src/theme/types.ts index 1c5056af..a73c9ea9 100644 --- a/src/theme/types.ts +++ b/src/theme/types.ts @@ -12,7 +12,6 @@ import type sizing from './assets/sizing.json' import type spacing from './assets/spacing.json' import type lightTheme from './assets/themeLight.json' import type typography from './assets/typography.json' -import type lightComponentTokens from './tokens/components/light.json' import type lightSemanticColorSchemeTokens from './tokens/semantic/colorScheme/light.json' export interface ThemeType { @@ -24,7 +23,6 @@ export interface ThemeType { sizing: typeof sizing spacing: typeof spacing semantic: { colorScheme: typeof lightSemanticColorSchemeTokens } - components: typeof lightComponentTokens theme: typeof lightTheme & { custom: typeof customLight InputSize: typeof InputSize From fcd450887ff5735324e289c1a94018e6584dfb96 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 12:49:45 +0300 Subject: [PATCH 12/40] =?UTF-8?q?docs:=20=D0=B0=D0=BA=D1=82=D1=83=D0=B0?= =?UTF-8?q?=D0=BB=D0=B8=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D1=82=D0=B5=D0=BC=20=D0=B8=20=D1=82=D0=BE=D0=BA?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MIGRATION.md | 86 +++++++++++++++++------------------------ README.md | 5 +-- design-tokens/README.md | 2 +- 3 files changed, 37 insertions(+), 56 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 42303352..074c690b 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1,18 +1,14 @@ # Миграция на Unistyles V3 -Стили переведены на `react-native-unistyles`. `ThemeContextProvider` доступен -как внешний конфигуратор тем и шрифтов, но чтение темы и шрифтов теперь идет -через API `unistyles`. +Стили переведены на `react-native-unistyles`. UI kit предоставляет провайдер и +хуки для настройки темы и шрифтов, а стили создаются через API `unistyles`. ## Изменения -### `ThemeContextProvider` — доступен +### Настройка темы и шрифтов -UI kit по-прежнему использует `react-native-unistyles` внутри, но для внешнего -потребителя снова доступен `ThemeContextProvider` как единая точка конфигурации -тем и шрифтов. - -Если приложению нужны кастомные шрифты, настройте их через провайдер: +Оберните приложение в `ThemeContextProvider`. Через `initialTheme` задаётся +начальная тема, через `fonts` — используемые семейства шрифтов: ```tsx import { @@ -30,18 +26,17 @@ export const Root = () => ( ) ``` -Провайдер также принимает `lightTheme` и `darkTheme`, если нужно передать -полностью кастомные темы. +Провайдер не принимает пользовательские объекты тем. Он настраивает +зарегистрированные внутри UI kit темы `light` и `dark`. ### `useFonts` -Используйте `useUnistyles`: +Для получения настроенных шрифтов используйте экспортируемый UI kit хук: ```tsx -import { useUnistyles } from '@cdek-it/react-native-ui-kit' +import { useFonts } from '@cdek-it/react-native-ui-kit' -const { theme } = useUnistyles() -theme.fonts +const fonts = useFonts() ``` Или прямо в стилях через `StyleSheet.create(...)`: @@ -54,25 +49,37 @@ const styles = StyleSheet.create(({ fonts }) => ({ })) ``` -### `useTheme()` / `useChangeTheme()` +### Чтение и переключение темы + +Для чтения и переключения темы используйте публичные хуки UI kit: + +```tsx +import { + ThemeVariant, + useChangeTheme, + useTheme, +} from '@cdek-it/react-native-ui-kit' + +const theme = useTheme() +const changeTheme = useChangeTheme() -`ThemeContextProvider` больше не является источником `theme/fonts` через React -context. Он только конфигурирует `react-native-unistyles`. +changeTheme(ThemeVariant.Dark) +``` -- `useTheme()` читает `UnistylesRuntime.themeName` -- `useFonts()` читает `useUnistyles().theme.fonts` -- `ThemeContext` остается пустым и имеет значение `null` -- `useChangeTheme()` всегда вызывает `UnistylesRuntime.setTheme(...)` +`ThemeContextProvider` не хранит тему и шрифты в React Context: `ThemeContext` +имеет значение `null`, а источником состояния остаётся Unistyles. ### `makeStyles` — removed Используйте `StyleSheet.create(...)`: ```tsx -import { StyleSheet } from '@cdek-it/react-native-ui-kit' +import { StyleSheet } from 'react-native-unistyles' -const styles = StyleSheet.create((theme) => ({ - container: { backgroundColor: theme.Button.Brand.buttonBg }, +const styles = StyleSheet.create(({ semantic }) => ({ + container: { + backgroundColor: semantic.colorScheme.color.bg.surface.default.default, + }, })) ``` @@ -80,32 +87,9 @@ const styles = StyleSheet.create((theme) => ({ темы. `StyleSheet.create(...)` — нативный путь, обновляет стили **без** ререндеров. -SDK реэкспортирует `StyleSheet`, `useUnistyles`, `UnistylesRuntime` и -`withUnistyles`, поэтому потребителям не нужно импортировать -`react-native-unistyles` напрямую. - -### `useTheme()` — removed - -```tsx -import { UnistylesRuntime, useUnistyles } from '@cdek-it/react-native-ui-kit' - -const themeName = UnistylesRuntime.themeName // 'light' | 'dark' -``` - -Для реактивного поведения используйте `useUnistyles()`: - -```tsx -const { rt } = useUnistyles() -rt.themeName -``` - -### `useChangeTheme()` — removed - -```tsx -import { UnistylesRuntime } from '@cdek-it/react-native-ui-kit' - -UnistylesRuntime.setTheme('dark') -``` +UI kit не реэкспортирует `StyleSheet`, `useUnistyles`, `UnistylesRuntime` и +`withUnistyles`. Если они нужны приложению напрямую, импортируйте их из +`react-native-unistyles`. ## ESLint Правила для Unistyles diff --git a/README.md b/README.md index 4460ccdb..b95d6112 100644 --- a/README.md +++ b/README.md @@ -54,12 +54,9 @@ UI kit использует следующие виды шрифтов. После этого шрифты доступны через `useUnistyles().theme.fonts` или прямо в `StyleSheet.create(({ fonts }) => ...)`. -`ThemeContextProvider` только настраивает темы и шрифты для `unistyles`. +`ThemeContextProvider` настраивает активную тему и шрифты для `unistyles`. `ThemeContext` остается пустым и всегда имеет значение `null`. -Провайдер также принимает `lightTheme` и `darkTheme`, если нужно переопределить -темы целиком. - ### Пример подключения шрифтов с помощью expo-fonts через плагин ```ts diff --git a/design-tokens/README.md b/design-tokens/README.md index a7592028..bba3daab 100644 --- a/design-tokens/README.md +++ b/design-tokens/README.md @@ -1,6 +1,6 @@ # Design tokens `input/tokens.json` содержит входные токены из Figma, из которых генерируются -light- и dark-токены проекта, а также общий `fonts.json`. +токены проекта. Подробности: [генератор токенов](../scripts/token-generator/README.md). From 2c469c2d7795b99f8f6c4a13cd652927efac2a91 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 13:00:05 +0300 Subject: [PATCH 13/40] =?UTF-8?q?refactor(tokens):=20=D0=BE=D0=B1=D1=8A?= =?UTF-8?q?=D0=B5=D0=B4=D0=B8=D0=BD=D0=B5=D0=BD=D1=8B=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D0=BA=D0=B0=20=D0=B8=20=D1=84=D0=BE=D1=80?= =?UTF-8?q?=D0=BC=D0=B0=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/actions/typecheck/action.yml | 10 ++-- lefthook.yml | 4 +- package.json | 6 +-- scripts/token-generator/README.md | 17 +++--- .../__tests__/compiler.test.ts | 32 +++++------ scripts/token-generator/build.ts | 12 ++--- scripts/token-generator/io.ts | 53 ++++++++++++------- 7 files changed, 74 insertions(+), 60 deletions(-) diff --git a/.github/actions/typecheck/action.yml b/.github/actions/typecheck/action.yml index 9c14c2dd..5b74884c 100644 --- a/.github/actions/typecheck/action.yml +++ b/.github/actions/typecheck/action.yml @@ -1,5 +1,5 @@ name: Run Typechecks -description: Typecheck the project and validate generated tokens +description: Typecheck the project and check generated tokens runs: using: composite @@ -10,6 +10,10 @@ runs: shell: bash run: yarn tsc --noEmit - - name: Validate Design Tokens + - name: Typecheck Token Generator shell: bash - run: yarn tokens:validate + run: yarn tokens:typecheck + + - name: Check Generated Tokens + shell: bash + run: yarn tokens:check diff --git a/lefthook.yml b/lefthook.yml index 1fa2a1e0..9f70f8e1 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -73,5 +73,5 @@ pre-push: run: yarn eslint . type-check: run: yarn tsc --noEmit - tokens-validate: - run: yarn tokens:validate + tokens-check: + run: yarn tokens:typecheck && yarn tokens:check diff --git a/package.json b/package.json index 05472dc5..f9df8a09 100644 --- a/package.json +++ b/package.json @@ -31,17 +31,15 @@ } }, "scripts": { - "build": "yarn tokens:validate && rm -rf dist && tsc -p tsconfig.build.json", + "build": "yarn tokens:typecheck && yarn tokens:check && rm -rf dist && tsc -p tsconfig.build.json", "test": "jest", "start": "expo start --dev-client --clear", "android": "expo run:android", "ios": "expo run:ios --no-install", "storybook-generate": "sb-rn-get-stories --config-path .storybook && sed -i -e 's/export const view = global.view/export const view: ReturnType = global.view/' .storybook/storybook.requires.ts && prettier .storybook --write", - "tokens:generate": "ts-node --project scripts/token-generator/tsconfig.json scripts/token-generator/build.ts && yarn tokens:format", - "tokens:format": "prettier 'design-tokens/input/*.json' 'src/theme/tokens/**/*.json' --write", + "tokens:generate": "ts-node --project scripts/token-generator/tsconfig.json scripts/token-generator/build.ts", "tokens:check": "ts-node --transpile-only --project scripts/token-generator/tsconfig.json scripts/token-generator/build.ts --check", "tokens:typecheck": "tsc --noEmit -p scripts/token-generator/tsconfig.json", - "tokens:validate": "yarn tokens:typecheck && yarn tokens:check", "doctor": "expo-doctor", "check": "expo install --check", "lint:check": "eslint --cache .", diff --git a/scripts/token-generator/README.md b/scripts/token-generator/README.md index 796dc9ed..e179f802 100644 --- a/scripts/token-generator/README.md +++ b/scripts/token-generator/README.md @@ -7,12 +7,11 @@ 1. Обновить `design-tokens/input/tokens.json`. 2. Запустить `yarn tokens:generate`. 3. Проверить изменения в `src/theme/tokens`. -4. Запустить `yarn tokens:validate`. -5. Закоммитить входные и сгенерированные токены вместе. +4. Закоммитить входные и сгенерированные токены вместе. -`tokens:generate` нормализует значения, удаляет лишние JSON и записывает -результат. `tokens:validate` ничего не меняет: проверяет TypeScript генератора и -актуальность сгенерированных токенов. +`tokens:generate` сначала собирает и валидирует весь результат в памяти. При +ошибке файлы не изменяются. После успешной проверки команда удаляет лишние JSON +и записывает отформатированный результат. ## Использование токенов @@ -133,10 +132,10 @@ API 29. Fallback для более ранних версий намеренно ## Автоматические проверки -`yarn tokens:check` только проверяет файлы и отдельно показывает отсутствующие, -изменённые и лишние JSON. `yarn tokens:validate` дополнительно проверяет -TypeScript генератора. Если проверка не прошла, нужно выполнить -`yarn tokens:generate` и проверить diff. +`yarn tokens:check` ничего не изменяет и отдельно показывает отсутствующие, +изменённые и лишние JSON. `yarn tokens:typecheck` проверяет TypeScript-код +генератора. Обе команды запускаются при сборке и в CI. Если проверка файлов не +прошла, нужно выполнить `yarn tokens:generate` и проверить diff. ## Устройство генератора diff --git a/scripts/token-generator/__tests__/compiler.test.ts b/scripts/token-generator/__tests__/compiler.test.ts index 7d68397e..4094276c 100644 --- a/scripts/token-generator/__tests__/compiler.test.ts +++ b/scripts/token-generator/__tests__/compiler.test.ts @@ -539,12 +539,10 @@ describe('production input tokens', () => { ) }) - test('совпадает с закоммиченными сгенерированными токенами', () => { - expect(findGeneratedTokenIssues(compiled, TOKENS_DIRECTORY)).toStrictEqual({ - missing: [], - changed: [], - unexpected: [], - }) + test('совпадает с закоммиченными сгенерированными токенами', async () => { + await expect( + findGeneratedTokenIssues(compiled, TOKENS_DIRECTORY) + ).resolves.toStrictEqual({ missing: [], changed: [], unexpected: [] }) }) test('преобразует числовые RN-значения', () => { @@ -576,7 +574,7 @@ describe('production input tokens', () => { ) }) - test('check находит расхождения, а generate приводит файлы к актуальному состоянию', () => { + test('check находит расхождения, а generate приводит файлы к актуальному состоянию', async () => { const temporaryDirectory = mkdtempSync(join(tmpdir(), 'token-generator-')) const unexpectedFile = join(temporaryDirectory, 'common.json') const preservedFile = join(temporaryDirectory, 'README.md') @@ -584,23 +582,25 @@ describe('production input tokens', () => { const changedFile = OUTPUT_FILES.semantic.dimensions try { - writeGeneratedTokens(compiled, temporaryDirectory) + await writeGeneratedTokens(compiled, temporaryDirectory) expect(listJsonFiles(temporaryDirectory)).toStrictEqual( expectedOutputFiles ) - expect( + await expect( findGeneratedTokenIssues(compiled, temporaryDirectory) - ).toStrictEqual({ missing: [], changed: [], unexpected: [] }) + ).resolves.toStrictEqual({ missing: [], changed: [], unexpected: [] }) writeFileSync(unexpectedFile, '{}\n') writeFileSync(preservedFile, '# Generated tokens\n') rmSync(join(temporaryDirectory, missingFile)) - writeFileSync(join(temporaryDirectory, changedFile), '{}\n') + const changedPath = join(temporaryDirectory, changedFile) - expect( + writeFileSync(changedPath, JSON.stringify(loadTokenTree(changedPath))) + + await expect( findGeneratedTokenIssues(compiled, temporaryDirectory) - ).toStrictEqual({ + ).resolves.toStrictEqual({ missing: [missingFile], changed: [changedFile], unexpected: ['common.json'], @@ -608,11 +608,11 @@ describe('production input tokens', () => { expect(() => accessSync(unexpectedFile)).not.toThrow() expect(() => accessSync(preservedFile)).not.toThrow() - writeGeneratedTokens(compiled, temporaryDirectory) + await writeGeneratedTokens(compiled, temporaryDirectory) - expect( + await expect( findGeneratedTokenIssues(compiled, temporaryDirectory) - ).toStrictEqual({ missing: [], changed: [], unexpected: [] }) + ).resolves.toStrictEqual({ missing: [], changed: [], unexpected: [] }) expect(() => accessSync(unexpectedFile)).toThrow('ENOENT') expect(() => accessSync(preservedFile)).not.toThrow() } finally { diff --git a/scripts/token-generator/build.ts b/scripts/token-generator/build.ts index e689e838..3c8f2531 100644 --- a/scripts/token-generator/build.ts +++ b/scripts/token-generator/build.ts @@ -57,7 +57,7 @@ const formatTokenIssues = (issues: GeneratedTokenIssues): string => .filter(Boolean) .join('\n') -export const run = (arguments_: string[]): void => { +export const run = async (arguments_: string[]): Promise => { const options = parseArgs(arguments_) if (options.help) { @@ -69,7 +69,7 @@ export const run = (arguments_: string[]): void => { const compiled = compileInputTokens() if (options.check) { - const issues = findGeneratedTokenIssues(compiled, TOKENS_DIRECTORY) + const issues = await findGeneratedTokenIssues(compiled, TOKENS_DIRECTORY) const issueDescription = formatTokenIssues(issues) if (issueDescription) { @@ -84,16 +84,14 @@ export const run = (arguments_: string[]): void => { return } - writeGeneratedTokens(compiled, TOKENS_DIRECTORY) + await writeGeneratedTokens(compiled, TOKENS_DIRECTORY) console.log(`Сгенерированные токены записаны в ${TOKENS_DIRECTORY}`) } if (require.main === module) { - try { - run(process.argv.slice(2)) - } catch (error: unknown) { + void run(process.argv.slice(2)).catch((error: unknown) => { const message = error instanceof Error ? error.message : String(error) console.error(message) process.exitCode = 1 - } + }) } diff --git a/scripts/token-generator/io.ts b/scripts/token-generator/io.ts index bcf07389..63974c4b 100644 --- a/scripts/token-generator/io.ts +++ b/scripts/token-generator/io.ts @@ -8,7 +8,8 @@ import { unlinkSync, } from 'node:fs' import { dirname, join } from 'node:path' -import { isDeepStrictEqual } from 'node:util' + +import { format, resolveConfig, type Options } from 'prettier' import { isTokenTree, type CompiledTokens, type TokenTree } from './core/types' @@ -44,8 +45,11 @@ export const parseTokenTree = ( export const loadTokenTree = (filePath: string): TokenTree => parseTokenTree(readFileSync(filePath, 'utf8'), filePath) -export const renderJson = (value: TokenTree): string => - `${JSON.stringify(value, null, 2)}\n` +export const renderJson = ( + value: TokenTree, + options: Options = {} +): Promise => + format(JSON.stringify(value), { ...options, parser: 'json' }) const outputEntries = ( compiled: CompiledTokens @@ -62,15 +66,30 @@ const outputEntries = ( [OUTPUT_FILES.components.dark, compiled.components.dark], ] -export const writeGeneratedTokens = ( +const renderOutputEntries = async ( compiled: CompiledTokens, outputDirectory: string -): void => { +): Promise> => { + const options = + (await resolveConfig(join(outputDirectory, OUTPUT_FILES.fonts))) ?? {} + + return Promise.all( + outputEntries(compiled).map(async ([fileName, value]) => [ + fileName, + await renderJson(value, options), + ]) + ) +} + +export const writeGeneratedTokens = async ( + compiled: CompiledTokens, + outputDirectory: string +): Promise => { + const entries = await renderOutputEntries(compiled, outputDirectory) + mkdirSync(outputDirectory, { recursive: true }) - const expectedFiles = new Set( - outputEntries(compiled).map(([fileName]) => fileName) - ) + const expectedFiles = new Set(entries.map(([fileName]) => fileName)) for (const fileName of findJsonFiles(outputDirectory)) { if (!expectedFiles.has(fileName)) { @@ -78,12 +97,12 @@ export const writeGeneratedTokens = ( } } - for (const [fileName, value] of outputEntries(compiled)) { + for (const [fileName, contents] of entries) { const outputPath = join(outputDirectory, fileName) const temporaryPath = `${outputPath}.tmp` mkdirSync(dirname(outputPath), { recursive: true }) - writeFileSync(temporaryPath, renderJson(value)) + writeFileSync(temporaryPath, contents) renameSync(temporaryPath, outputPath) } } @@ -112,24 +131,20 @@ export interface GeneratedTokenIssues { unexpected: string[] } -export const findGeneratedTokenIssues = ( +export const findGeneratedTokenIssues = async ( compiled: CompiledTokens, outputDirectory: string -): GeneratedTokenIssues => { - const entries = outputEntries(compiled) +): Promise => { + const entries = await renderOutputEntries(compiled, outputDirectory) const expectedFiles = new Set(entries.map(([fileName]) => fileName)) const missing: string[] = [] const changed: string[] = [] - for (const [fileName, value] of entries) { + for (const [fileName, contents] of entries) { const outputPath = join(outputDirectory, fileName) if (existsSync(outputPath)) { - try { - if (!isDeepStrictEqual(loadTokenTree(outputPath), value)) { - changed.push(fileName) - } - } catch { + if (readFileSync(outputPath, 'utf8') !== contents) { changed.push(fileName) } } else { From 48680828697cc3403bdf3793211bf08a4c969ac7 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:00:02 +0300 Subject: [PATCH 14/40] =?UTF-8?q?feat(Theme):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jest.setup.ts | 30 ++++++++---- src/hooks/useFonts.ts | 3 +- src/theme/ThemeContext.tsx | 58 ++++++++++++++++++++--- src/theme/__tests__/ThemeContext.test.tsx | 49 +++++++++++++++++-- src/theme/tokens/README.md | 13 +++-- src/theme/tokens/index.ts | 14 ++++++ src/theme/types.ts | 10 ++++ src/utils/SvgUniversal.tsx | 8 ++-- 8 files changed, 154 insertions(+), 31 deletions(-) diff --git a/jest.setup.ts b/jest.setup.ts index 8c1471d8..850baa92 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -13,8 +13,12 @@ jest.mock('react-native-worklets', () => ) interface MockedUnistylesModule { - StyleSheet: { create: (...args: unknown[]) => unknown } + StyleSheet: { + configure: jest.Mock + create: (...args: unknown[]) => unknown + } UnistylesRuntime: { + getTheme: jest.Mock miniRuntime: unknown setTheme: jest.Mock updateTheme: jest.Mock unknown]> @@ -32,23 +36,28 @@ const unistyles = jest.requireMock( // загрузки src/theme (и как следствие — src/utils/SvgUniversal с // `withUnistyles(...)` на top-level) в модуле уже стояли наши моки, а не // исходные identity-заглушки. -const themeRef: { - current: { darkTheme: unknown; lightTheme: unknown } | null -} = { current: null } +const themeRef: { current: { dark: unknown; light: unknown } | null } = { + current: null, +} const getTheme = (themeName: ThemeName | undefined) => - themeName === 'dark' - ? themeRef.current?.darkTheme - : themeRef.current?.lightTheme + themeName === 'dark' ? themeRef.current?.dark : themeRef.current?.light const runtime = unistyles.UnistylesRuntime runtime.themeName = 'light' +runtime.getTheme = jest.fn(getTheme) runtime.setTheme = jest.fn((themeName: ThemeName) => { runtime.themeName = themeName }) runtime.updateTheme = jest.fn() +unistyles.StyleSheet.configure = jest.fn(({ themes }) => { + if (themes) { + themeRef.current = themes + } +}) + unistyles.useUnistyles = jest.fn(() => ({ theme: getTheme(runtime.themeName), rt: runtime, @@ -174,11 +183,16 @@ unistyles.withUnistyles = jest.fn( } ) -themeRef.current = require('./src/theme') as { +const publicThemes = require('./src/theme') as { darkTheme: unknown lightTheme: unknown } +themeRef.current ??= { + dark: publicThemes.darkTheme, + light: publicThemes.lightTheme, +} + generatePropsCombinations = (properties: PropertyCombinations): T[] => { const keys = Object.keys(properties) as Array diff --git a/src/hooks/useFonts.ts b/src/hooks/useFonts.ts index b47218dc..e83308db 100644 --- a/src/hooks/useFonts.ts +++ b/src/hooks/useFonts.ts @@ -4,6 +4,7 @@ import type { FontsConfig } from '../theme' export const useFonts = (): FontsConfig => { const { theme } = useUnistyles() + const { primary, secondary } = theme.fonts - return theme.fonts + return { primary, secondary } } diff --git a/src/theme/ThemeContext.tsx b/src/theme/ThemeContext.tsx index e26905a3..f20afb5b 100644 --- a/src/theme/ThemeContext.tsx +++ b/src/theme/ThemeContext.tsx @@ -6,17 +6,54 @@ import { SkeletonContextProvider } from '../utils/SkeletonContext' import { darkTheme } from './darkTheme' import { lightTheme } from './lightTheme' -import { type FontsConfig, ThemeVariant } from './types' +import { + componentTokens, + fontTokens, + semanticTokens, + type ComponentTokens, + type SemanticTokens, +} from './tokens' +import { + type FontsConfig, + type FontTokens, + type ThemeType, + ThemeVariant, +} from './types' + +type InternalTheme = Omit & { + components: ComponentTokens + fonts: FontsConfig & FontTokens + semantic: ThemeType['semantic'] & SemanticTokens +} + +const createInternalTheme = ( + theme: ThemeType, + components: ComponentTokens +): InternalTheme => ({ + ...theme, + components, + fonts: { + ...fontTokens, + ...theme.fonts, + fontFamily: { base: theme.fonts.secondary, heading: theme.fonts.primary }, + }, + semantic: { ...semanticTokens, ...theme.semantic }, +}) + +const internalThemes = { + light: createInternalTheme(lightTheme, componentTokens.light), + dark: createInternalTheme(darkTheme, componentTokens.dark), +} StyleSheet.configure({ settings: { initialTheme: 'light' }, - themes: { light: lightTheme, dark: darkTheme }, + themes: internalThemes, }) declare module 'react-native-unistyles' { export interface UnistylesThemes { - light: typeof lightTheme - dark: typeof darkTheme + light: (typeof internalThemes)['light'] + dark: (typeof internalThemes)['dark'] } } @@ -42,8 +79,17 @@ export const ThemeContextProvider = ({ UnistylesRuntime.setTheme(THEME_NAME_MAP[initialTheme]) if (fonts) { - UnistylesRuntime.updateTheme('light', (t) => ({ ...t, fonts })) - UnistylesRuntime.updateTheme('dark', (t) => ({ ...t, fonts })) + const updateFonts = (theme: InternalTheme): InternalTheme => ({ + ...theme, + fonts: { + ...theme.fonts, + ...fonts, + fontFamily: { base: fonts.secondary, heading: fonts.primary }, + }, + }) + + UnistylesRuntime.updateTheme('light', updateFonts) + UnistylesRuntime.updateTheme('dark', updateFonts) } // eslint-disable-next-line react-hooks/exhaustive-deps -- initial* props применяем только на mount }, []) diff --git a/src/theme/__tests__/ThemeContext.test.tsx b/src/theme/__tests__/ThemeContext.test.tsx index 71425de8..2edec632 100644 --- a/src/theme/__tests__/ThemeContext.test.tsx +++ b/src/theme/__tests__/ThemeContext.test.tsx @@ -6,7 +6,9 @@ import { UnistylesRuntime } from 'react-native-unistyles' import { ThemeContextProvider } from '../ThemeContext' import { darkTheme } from '../darkTheme' import { lightTheme } from '../lightTheme' -import { semanticTokens } from '../tokens' +import { componentTokens, fontTokens, semanticTokens } from '../tokens' +import darkComponentTokens from '../tokens/components/dark.json' +import lightComponentTokens from '../tokens/components/light.json' import darkSemanticColorSchemeTokens from '../tokens/semantic/colorScheme/dark.json' import lightSemanticColorSchemeTokens from '../tokens/semantic/colorScheme/light.json' import semanticDimensions from '../tokens/semantic/dimensions.json' @@ -57,10 +59,16 @@ describe('ThemeContextProvider', () => { ) const [, updater] = jest.mocked(UnistylesRuntime.updateTheme).mock.calls[0] - - expect( - updater({ ...lightTheme, fonts: { primary: 'old', secondary: 'old' } }) - ).toStrictEqual({ ...lightTheme, fonts }) + const theme = UnistylesRuntime.getTheme('light') + + expect(updater(theme)).toStrictEqual({ + ...theme, + fonts: { + ...theme.fonts, + ...fonts, + fontFamily: { base: fonts.secondary, heading: fonts.primary }, + }, + }) }) test('без fonts не вызывает updateTheme', () => { @@ -89,4 +97,35 @@ describe('ThemeContextProvider', () => { expect(lightTheme).not.toHaveProperty('components') expect(darkTheme).not.toHaveProperty('components') }) + + test('внутренняя карта component-токенов содержит обе темы', () => { + expect(componentTokens.light).toBe(lightComponentTokens) + expect(componentTokens.dark).toBe(darkComponentTokens) + }) + + test('внутренняя тема Unistyles содержит сгенерированные токены', () => { + const internalLightTheme = UnistylesRuntime.getTheme('light') + const internalDarkTheme = UnistylesRuntime.getTheme('dark') + + expect(internalLightTheme).toMatchObject({ + components: lightComponentTokens, + fonts: fontTokens, + semantic: { + colorScheme: lightSemanticColorSchemeTokens, + dimension: semanticDimensions, + effects: semanticEffects, + }, + }) + + expect(internalDarkTheme).toMatchObject({ + components: darkComponentTokens, + fonts: fontTokens, + semantic: { + colorScheme: darkSemanticColorSchemeTokens, + dimension: semanticDimensions, + effects: semanticEffects, + }, + }) + expect(internalLightTheme.fonts).toStrictEqual(internalDarkTheme.fonts) + }) }) diff --git a/src/theme/tokens/README.md b/src/theme/tokens/README.md index 6547d0fb..c4c6c42c 100644 --- a/src/theme/tokens/README.md +++ b/src/theme/tokens/README.md @@ -1,12 +1,11 @@ # Сгенерированные токены -В `ThemeType.semantic` подключается только выбранный `colorScheme`. Общие -`dimension` и `effects` экспортируются как статический `semanticTokens`, поэтому -не участвуют в переключении темы. `components` хранит внутренние токены -компонентов и не входит в темы или публичные экспорты. `fonts.json` содержит -общие для цветовых схем токены из `primitive.fonts`, но пока не подключён к теме -и не экспортируется из библиотеки. Всё генерируется из -`design-tokens/input/tokens.json` и не редактируется вручную. +В публичный `ThemeType.semantic` подключается только выбранный `colorScheme`. +Общие `dimension`, `effects` и `fonts` добавляются во внутреннюю тему Unistyles и +не зависят от цветовой схемы. В неё же добавляются соответствующие светлой или +тёмной теме `components`. В публичные темы и экспорты component- и font-токены +не входят. Всё генерируется из `design-tokens/input/tokens.json` и не +редактируется вручную. Подробности: [генератор токенов](../../../scripts/token-generator/README.md). diff --git a/src/theme/tokens/index.ts b/src/theme/tokens/index.ts index 9344acc6..08fdcb6f 100644 --- a/src/theme/tokens/index.ts +++ b/src/theme/tokens/index.ts @@ -1,6 +1,20 @@ +import type { FontTokens } from '../types' + +import darkComponentTokens from './components/dark.json' +import lightComponentTokens from './components/light.json' +import generatedFontTokens from './fonts.json' import dimensions from './semantic/dimensions.json' import effects from './semantic/effects.json' export const semanticTokens = { dimension: dimensions, effects } as const export type SemanticTokens = typeof semanticTokens + +export type ComponentTokens = typeof lightComponentTokens + +export const componentTokens = { + light: lightComponentTokens, + dark: darkComponentTokens, +} as const + +export const fontTokens = generatedFontTokens as FontTokens diff --git a/src/theme/types.ts b/src/theme/types.ts index a73c9ea9..c0b3ad20 100644 --- a/src/theme/types.ts +++ b/src/theme/types.ts @@ -1,3 +1,5 @@ +import type { TextStyle } from 'react-native' + import type { InputSize } from './assets/InputSize' import type { ModalSize } from './assets/ModalSize' import type background from './assets/background.json' @@ -12,6 +14,7 @@ import type sizing from './assets/sizing.json' import type spacing from './assets/spacing.json' import type lightTheme from './assets/themeLight.json' import type typography from './assets/typography.json' +import type fontTokens from './tokens/fonts.json' import type lightSemanticColorSchemeTokens from './tokens/semantic/colorScheme/light.json' export interface ThemeType { @@ -47,3 +50,10 @@ export interface FontsConfig { export interface FontsConfigType { fonts: FontsConfig } + +export type FontTokens = Omit & { + fontWeight: Record< + keyof typeof fontTokens.fontWeight, + TextStyle['fontWeight'] + > +} diff --git a/src/utils/SvgUniversal.tsx b/src/utils/SvgUniversal.tsx index 00119d79..e169a63b 100644 --- a/src/utils/SvgUniversal.tsx +++ b/src/utils/SvgUniversal.tsx @@ -6,9 +6,7 @@ import { memo, } from 'react' import { SvgUri, SvgXml, type SvgProps } from 'react-native-svg' -import { withUnistyles } from 'react-native-unistyles' - -import type { ThemeType } from '../theme/types' +import { withUnistyles, type UnistylesThemes } from 'react-native-unistyles' export type SvgSource = | { uri: string } @@ -20,6 +18,8 @@ export interface SvgUniversalProps extends SvgProps { source: SvgSource } +export type SvgUniversalTheme = UnistylesThemes[keyof UnistylesThemes] + /** * Компонент для рендера SVG из разных источников * Поддерживает: @@ -57,7 +57,7 @@ type SvgUniversalComponent = ForwardRefExoticComponent< PropsWithoutRef< Partial & { uniProps?: ( - theme: ThemeType + theme: SvgUniversalTheme ) => Omit< Partial, 'style' | 'contentContainerStyle' From bdf430aa7ba1468a7ef1e83704c832aa7deeb22a Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:40 +0300 Subject: [PATCH 15/40] =?UTF-8?q?feat(Accordion):=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Accordion/Accordion.tsx | 48 ++++++----- .../__snapshots__/Accordion.test.tsx.snap | 82 +++++++++---------- 2 files changed, 68 insertions(+), 62 deletions(-) diff --git a/src/components/Accordion/Accordion.tsx b/src/components/Accordion/Accordion.tsx index 76ffb39e..e04b763f 100644 --- a/src/components/Accordion/Accordion.tsx +++ b/src/components/Accordion/Accordion.tsx @@ -109,9 +109,9 @@ export const Accordion: React.FC = ({ ({ - color: theme.Panel.Accordion.accordionHeaderTextColor, - })} + uniProps={({ components }) => { + return { color: components.accordion.header.color } + }} /> {Icon ? ( @@ -119,9 +119,9 @@ export const Accordion: React.FC = ({ {...styles.icon} source={Icon} testID={AccordionTestIds.icon} - uniProps={({ theme }) => ({ - color: theme.Panel.Accordion.accordionHeaderTextColor, - })} + uniProps={({ components }) => { + return { color: components.accordion.header.color } + }} /> ) : null} {title} @@ -159,36 +159,42 @@ export const AccordionTestIds = { separator: 'Separator', } -const styles = StyleSheet.create(({ theme, fonts }) => ({ +const styles = StyleSheet.create(({ components, semantic, fonts }) => ({ component: { width: '100%' }, header: { - paddingVertical: theme.Panel.Accordion.accordionHeaderPaddingTopBottom, - gap: 7, + paddingVertical: semantic.dimension.space[400], + gap: components.accordion.extend.extHeader.gap, flexDirection: 'row', alignItems: 'center', - backgroundColor: theme.Panel.Accordion.accordionHeaderBg, + backgroundColor: components.accordion.colorScheme.header.background, + }, + icon: { + width: components.accordion.extend.extHeader.iconSize, + height: components.accordion.extend.extHeader.iconSize, }, - icon: { width: 17.5, height: 17.5 }, title: { - fontSize: 15.75, + fontSize: fonts.fontSize[400], includeFontPadding: false, verticalAlign: 'middle', - fontWeight: 700, - color: theme.Panel.Accordion.accordionHeaderTextColor, - fontFamily: fonts.secondary, + fontWeight: fonts.fontWeight.bold, + color: components.accordion.header.color, + fontFamily: fonts.fontFamily.base, }, contentAnimated: { overflow: 'hidden' }, contentWrapper: { position: 'absolute', width: '100%', - paddingLeft: theme.Panel.Accordion.accordionContentPaddingLeft, - paddingTop: theme.Panel.Accordion.accordionContentPaddingTop, - paddingRight: theme.Panel.Accordion.accordionContentPaddingRight, - paddingBottom: theme.Panel.Accordion.accordionContentPaddingBottom, + paddingLeft: components.accordion.content.paddingLeft, + paddingTop: semantic.dimension.space.none, + paddingRight: components.accordion.content.paddingRight, + paddingBottom: semantic.dimension.space[400], }, separator: { - borderTopColor: theme.Panel.Accordion.accordionHeaderBorderColor, + borderTopColor: components.accordion.panel.borderColor, borderTopWidth: 1, }, - disabled: { mixBlendMode: 'luminosity', opacity: 0.6 }, + disabled: { + mixBlendMode: 'luminosity', + opacity: semantic.effects.opacity[60], + }, })) diff --git a/src/components/Accordion/__tests__/__snapshots__/Accordion.test.tsx.snap b/src/components/Accordion/__tests__/__snapshots__/Accordion.test.tsx.snap index 04669b17..a1483e18 100644 --- a/src/components/Accordion/__tests__/__snapshots__/Accordion.test.tsx.snap +++ b/src/components/Accordion/__tests__/__snapshots__/Accordion.test.tsx.snap @@ -8,7 +8,7 @@ exports[`Accordion Header elements maximal 1`] = ` "width": "100%", }, { - "borderTopColor": "#e2e2e4", + "borderTopColor": "#cecfd2", "borderTopWidth": 1, }, ] @@ -51,9 +51,9 @@ exports[`Accordion Header elements maximal 1`] = ` [ { "alignItems": "center", - "backgroundColor": "rgba(255, 255, 255, 0.0001)", + "backgroundColor": "transparent", "flexDirection": "row", - "gap": 7, + "gap": 8, "paddingVertical": 14, }, {}, @@ -95,15 +95,15 @@ exports[`Accordion Header elements maximal 1`] = ` > Date: Tue, 4 Aug 2026 17:05:40 +0300 Subject: [PATCH 16/40] =?UTF-8?q?feat(Avatar):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Avatar/Avatar.tsx | 30 +- .../__snapshots__/Avatar.test.tsx.snap | 274 +++++++++--------- 2 files changed, 152 insertions(+), 152 deletions(-) diff --git a/src/components/Avatar/Avatar.tsx b/src/components/Avatar/Avatar.tsx index 83938627..2c479799 100644 --- a/src/components/Avatar/Avatar.tsx +++ b/src/components/Avatar/Avatar.tsx @@ -188,9 +188,9 @@ export const Avatar = memo( height={iconSize} source={Icon} testID={AvatarTestId.icon} - uniProps={({ theme }) => ({ - color: iconColor ?? theme.Misc.Avatar.avatarTextColor, - })} + uniProps={({ components }) => { + return { color: iconColor ?? components.avatar.root.color } + }} width={iconSize} /> ) @@ -257,30 +257,30 @@ export const Avatar = memo( } ) -const styles = StyleSheet.create(({ theme, border, typography, fonts }) => ({ +const styles = StyleSheet.create(({ components, semantic, fonts }) => ({ container: { justifyContent: 'center', alignItems: 'center', - borderRadius: theme.General.borderRadiusXL, - borderWidth: 1, - borderColor: theme.Misc.Avatar.avatarBorderColor, - backgroundColor: theme.Misc.Avatar.avatarBg, + borderRadius: components.avatar.root.borderRadius, + borderWidth: semantic.dimension.borderWidth[100], + borderColor: components.avatar.extend.borderColor, + backgroundColor: components.avatar.root.background, overflow: 'hidden', }, - backgroundFill: { backgroundColor: theme.Misc.Avatar.avatarBg }, - circle: { borderRadius: border.Radius['rounded-full'] }, + backgroundFill: { backgroundColor: components.avatar.root.background }, + circle: { borderRadius: components.avatar.extend.circle.borderRadius }, text: { - fontSize: typography.Size['text-base'], + fontSize: components.avatar.root.fontSize, textTransform: 'uppercase', - color: theme.Misc.Avatar.avatarTextColor, + color: components.avatar.root.color, includeFontPadding: false, verticalAlign: 'middle', - fontFamily: fonts.secondary, + fontFamily: fonts.fontFamily.base, }, badgeContainer: { position: 'absolute', right: 0, top: -7 }, badgeMeasureContainer: { alignSelf: 'flex-start' }, - icon: { width: typography.Size['text-base'] }, - iconXLarge: { width: typography.Size['text-2xl'] }, + icon: { width: components.avatar.icon.size }, + iconXLarge: { width: components.avatar.xl.icon.size }, })) export const AvatarTestId = { diff --git a/src/components/Avatar/__tests__/__snapshots__/Avatar.test.tsx.snap b/src/components/Avatar/__tests__/__snapshots__/Avatar.test.tsx.snap index 81e73a20..49469718 100644 --- a/src/components/Avatar/__tests__/__snapshots__/Avatar.test.tsx.snap +++ b/src/components/Avatar/__tests__/__snapshots__/Avatar.test.tsx.snap @@ -11,8 +11,8 @@ exports[`Avatar component tests Size: custom, shape: circle, type: icon, with cu { "alignItems": "center", "backgroundColor": "#44e858", - "borderColor": "#e2e2e4", - "borderRadius": 10.5, + "borderColor": "#cecfd2", + "borderRadius": 14, "borderWidth": 1, "justifyContent": "center", "overflow": "hidden", @@ -25,7 +25,7 @@ exports[`Avatar component tests Size: custom, shape: circle, type: icon, with cu "backgroundColor": "#44e858", }, { - "borderRadius": 100, + "borderRadius": 1600, }, undefined, ] @@ -149,8 +149,8 @@ exports[`Avatar component tests Size: large, shape: circle, type: icon 1`] = ` { "alignItems": "center", "backgroundColor": "#44e858", - "borderColor": "#e2e2e4", - "borderRadius": 10.5, + "borderColor": "#cecfd2", + "borderRadius": 14, "borderWidth": 1, "justifyContent": "center", "overflow": "hidden", @@ -163,7 +163,7 @@ exports[`Avatar component tests Size: large, shape: circle, type: icon 1`] = ` "backgroundColor": "#44e858", }, { - "borderRadius": 100, + "borderRadius": 1600, }, undefined, ] @@ -172,15 +172,15 @@ exports[`Avatar component tests Size: large, shape: circle, type: icon 1`] = ` > Date: Tue, 4 Aug 2026 17:05:41 +0300 Subject: [PATCH 17/40] =?UTF-8?q?feat(Badge):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Badge/Badge.tsx | 92 ++++++------ .../__snapshots__/Badge.test.tsx.snap | 136 +++++++++--------- 2 files changed, 113 insertions(+), 115 deletions(-) diff --git a/src/components/Badge/Badge.tsx b/src/components/Badge/Badge.tsx index 8b0e5f6a..2cdf0052 100644 --- a/src/components/Badge/Badge.tsx +++ b/src/components/Badge/Badge.tsx @@ -103,53 +103,51 @@ export const Badge = memo( } ) -const badgeStyles = StyleSheet.create( - ({ theme, border, typography, fonts }) => ({ - container: { alignItems: 'flex-start' }, - dot: { - variants: { - severity: { - basic: { backgroundColor: theme.Misc.Badge.badgeBg }, - info: { - backgroundColor: theme.Button.Severity.Info.Basic.infoButtonBg, - }, - success: { - backgroundColor: - theme.Button.Severity.Success.Basic.successButtonBg, - }, - warning: { - backgroundColor: - theme.Button.Severity.Warning.Basic.warningButtonBg, - }, - danger: { - backgroundColor: theme.Button.Severity.Danger.Basic.dangerButtonBg, - }, +const badgeStyles = StyleSheet.create(({ components, semantic, fonts }) => ({ + container: { alignItems: 'flex-start' }, + dot: { + variants: { + severity: { + basic: { + backgroundColor: components.badge.colorScheme.primary.background, + }, + info: { + backgroundColor: components.badge.extend.extDot.info.background, + }, + success: { + backgroundColor: components.badge.extend.extDot.success.background, + }, + warning: { + backgroundColor: components.badge.extend.extDot.warn.background, + }, + danger: { + backgroundColor: components.badge.extend.extDot.danger.background, }, }, }, - dotShape: { - width: theme.Misc.Badge.badgeDotSize, - height: theme.Misc.Badge.badgeDotSize, - borderRadius: border.Radius['rounded-full'], - }, - textBadgeContainer: { - height: theme.Misc.Badge.badgeHeight, - paddingHorizontal: theme.Misc.Tag.tagPadding, - justifyContent: 'center', - borderRadius: border.Radius['rounded-full'], - }, - textBadge: { - color: theme.Misc.Badge.badgeTextColor, - fontSize: typography.Size['text-xs'], - includeFontPadding: false, - verticalAlign: 'middle', - fontFamily: fonts.primary, - }, - hiddenContainer: { - width: Dimensions.get('window').width, - height: 0, - flexDirection: 'row', - position: 'absolute', - }, - }) -) + }, + dotShape: { + width: components.badge.dot.size, + height: components.badge.dot.size, + borderRadius: components.badge.root.borderRadius, + }, + textBadgeContainer: { + height: components.badge.root.height, + paddingHorizontal: components.badge.root.padding, + justifyContent: 'center', + borderRadius: semantic.dimension.borderRadius.max, + }, + textBadge: { + color: components.badge.colorScheme.primary.color, + fontSize: components.badge.root.fontSize, + includeFontPadding: false, + verticalAlign: 'middle', + fontFamily: fonts.fontFamily.heading, + }, + hiddenContainer: { + width: Dimensions.get('window').width, + height: 0, + flexDirection: 'row', + position: 'absolute', + }, +})) diff --git a/src/components/Badge/__tests__/__snapshots__/Badge.test.tsx.snap b/src/components/Badge/__tests__/__snapshots__/Badge.test.tsx.snap index e4b181ae..c728269d 100644 --- a/src/components/Badge/__tests__/__snapshots__/Badge.test.tsx.snap +++ b/src/components/Badge/__tests__/__snapshots__/Badge.test.tsx.snap @@ -18,9 +18,9 @@ exports[`Badge component tests dot, severity: basic 1`] = ` "backgroundColor": "#44e858", }, { - "borderRadius": 100, - "height": 7, - "width": 7, + "borderRadius": 8, + "height": 8, + "width": 8, }, ] } @@ -43,12 +43,12 @@ exports[`Badge component tests dot, severity: danger 1`] = ` style={ [ { - "backgroundColor": "#fbacaa", + "backgroundColor": "#f47f77", }, { - "borderRadius": 100, - "height": 7, - "width": 7, + "borderRadius": 8, + "height": 8, + "width": 8, }, ] } @@ -71,12 +71,12 @@ exports[`Badge component tests dot, severity: info 1`] = ` style={ [ { - "backgroundColor": "#aad7fb", + "backgroundColor": "#77baf4", }, { - "borderRadius": 100, - "height": 7, - "width": 7, + "borderRadius": 8, + "height": 8, + "width": 8, }, ] } @@ -99,12 +99,12 @@ exports[`Badge component tests dot, severity: success 1`] = ` style={ [ { - "backgroundColor": "#aafbb7", + "backgroundColor": "#77f48a", }, { - "borderRadius": 100, - "height": 7, - "width": 7, + "borderRadius": 8, + "height": 8, + "width": 8, }, ] } @@ -127,12 +127,12 @@ exports[`Badge component tests dot, severity: warning 1`] = ` style={ [ { - "backgroundColor": "#fddeaa", + "backgroundColor": "#facb75", }, { - "borderRadius": 100, - "height": 7, - "width": 7, + "borderRadius": 8, + "height": 8, + "width": 8, }, ] } @@ -158,10 +158,10 @@ exports[`Badge component tests severity: basic 1`] = ` "backgroundColor": "#44e858", }, { - "borderRadius": 100, - "height": 21, + "borderRadius": 1600, + "height": 24, "justifyContent": "center", - "paddingHorizontal": 7, + "paddingHorizontal": 8, }, ] } @@ -171,9 +171,9 @@ exports[`Badge component tests severity: basic 1`] = ` style={ [ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", }, @@ -206,9 +206,9 @@ exports[`Badge component tests severity: basic 1`] = ` onLayout={[Function]} style={ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", } @@ -236,13 +236,13 @@ exports[`Badge component tests severity: basic 2`] = ` style={ [ { - "backgroundColor": "#aad7fb", + "backgroundColor": "#77baf4", }, { - "borderRadius": 100, - "height": 21, + "borderRadius": 1600, + "height": 24, "justifyContent": "center", - "paddingHorizontal": 7, + "paddingHorizontal": 8, }, ] } @@ -252,9 +252,9 @@ exports[`Badge component tests severity: basic 2`] = ` style={ [ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", }, @@ -287,9 +287,9 @@ exports[`Badge component tests severity: basic 2`] = ` onLayout={[Function]} style={ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", } @@ -317,13 +317,13 @@ exports[`Badge component tests severity: basic 3`] = ` style={ [ { - "backgroundColor": "#aafbb7", + "backgroundColor": "#77f48a", }, { - "borderRadius": 100, - "height": 21, + "borderRadius": 1600, + "height": 24, "justifyContent": "center", - "paddingHorizontal": 7, + "paddingHorizontal": 8, }, ] } @@ -333,9 +333,9 @@ exports[`Badge component tests severity: basic 3`] = ` style={ [ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", }, @@ -368,9 +368,9 @@ exports[`Badge component tests severity: basic 3`] = ` onLayout={[Function]} style={ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", } @@ -398,13 +398,13 @@ exports[`Badge component tests severity: basic 4`] = ` style={ [ { - "backgroundColor": "#fddeaa", + "backgroundColor": "#facb75", }, { - "borderRadius": 100, - "height": 21, + "borderRadius": 1600, + "height": 24, "justifyContent": "center", - "paddingHorizontal": 7, + "paddingHorizontal": 8, }, ] } @@ -414,9 +414,9 @@ exports[`Badge component tests severity: basic 4`] = ` style={ [ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", }, @@ -449,9 +449,9 @@ exports[`Badge component tests severity: basic 4`] = ` onLayout={[Function]} style={ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", } @@ -479,13 +479,13 @@ exports[`Badge component tests severity: basic 5`] = ` style={ [ { - "backgroundColor": "#fbacaa", + "backgroundColor": "#f47f77", }, { - "borderRadius": 100, - "height": 21, + "borderRadius": 1600, + "height": 24, "justifyContent": "center", - "paddingHorizontal": 7, + "paddingHorizontal": 8, }, ] } @@ -495,9 +495,9 @@ exports[`Badge component tests severity: basic 5`] = ` style={ [ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", }, @@ -530,9 +530,9 @@ exports[`Badge component tests severity: basic 5`] = ` onLayout={[Function]} style={ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", } @@ -563,10 +563,10 @@ exports[`Badge component tests severity: default 1`] = ` "backgroundColor": "#44e858", }, { - "borderRadius": 100, - "height": 21, + "borderRadius": 1600, + "height": 24, "justifyContent": "center", - "paddingHorizontal": 7, + "paddingHorizontal": 8, }, ] } @@ -576,9 +576,9 @@ exports[`Badge component tests severity: default 1`] = ` style={ [ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", }, @@ -611,9 +611,9 @@ exports[`Badge component tests severity: default 1`] = ` onLayout={[Function]} style={ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", } @@ -646,9 +646,9 @@ exports[`Badge component tests with custom style 1`] = ` "backgroundColor": "#44e858", }, { - "borderRadius": 100, - "height": 7, - "width": 7, + "borderRadius": 8, + "height": 8, + "width": 8, }, ] } From 4ea0b15252c6785f55385cbc755534fb271e0f48 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:41 +0300 Subject: [PATCH 18/40] =?UTF-8?q?feat(Button):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__snapshots__/Button.test.tsx.snap | 25296 ++++++++-------- .../__snapshots__/ButtonBadge.test.tsx.snap | 56 +- .../ButtonSeverity.test.tsx.snap | 64 +- .../Button/utils/ButtonActivityIndicator.tsx | 24 +- .../Button/utils/ButtonContainer.tsx | 298 +- src/components/Button/utils/ButtonIcon.tsx | 215 +- src/components/Button/utils/ButtonLabel.tsx | 205 +- 7 files changed, 12521 insertions(+), 13637 deletions(-) diff --git a/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap b/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap index 2a91e4a6..61172500 100644 --- a/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap +++ b/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap @@ -37,17 +37,15 @@ exports[`Button component tests Button default props 1`] = ` { "alignItems": "center", "backgroundColor": "#44e858", - "borderColor": "rgba(255, 255, 255, 0.0001)", - "borderRadius": 10.5, + "borderColor": "transparent", + "borderRadius": 14, "borderWidth": 1, "flexDirection": "row", - "gap": 7, - "height": 35, + "gap": 8, + "height": "auto", "justifyContent": "center", - "maxHeight": 35, - "minHeight": 35, "paddingHorizontal": 14, - "paddingVertical": 0, + "paddingVertical": 8, }, false, ] @@ -56,9 +54,9 @@ exports[`Button component tests Button default props 1`] = ` ({ - indicator: { - color: theme.Button.Disabled.disabledButtonTextColor, - variants: { - size: { - xlarge: { height: 21 }, - large: { height: 21 }, - base: { height: 17.5 }, - small: { height: 14 }, +const buttonActivityIndicatorStyles = StyleSheet.create( + ({ components: { button } }) => ({ + indicator: { + color: button.extend.disabledColor, + variants: { + size: { + xlarge: { height: 21 }, + large: { height: 21 }, + base: { height: 17.5 }, + small: { height: 14 }, + }, }, }, - }, -})) + }) +) diff --git a/src/components/Button/utils/ButtonContainer.tsx b/src/components/Button/utils/ButtonContainer.tsx index 682cc8ed..91a23db0 100644 --- a/src/components/Button/utils/ButtonContainer.tsx +++ b/src/components/Button/utils/ButtonContainer.tsx @@ -80,96 +80,91 @@ const ButtonContainerComponent = ({ export const ButtonContainer = genericMemo(ButtonContainerComponent) +// `transparent` здесь — отсутствие фона или границы, а не цвет дизайн-системы: +// прозрачность не выражена ни semantic-токеном, ни свойствами button.extend.extText. const buttonContainerStyles = StyleSheet.create( - ({ theme, border, spacing, sizing }) => ({ + ({ components: { button }, semantic }) => ({ container: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', - borderWidth: border.Width.border, + borderWidth: button.extend.borderWidth, variants: { size: { xlarge: { - paddingHorizontal: spacing.Padding['p-6'], - paddingVertical: theme.Button.Common.buttonPaddingTopBottom, - height: theme.Button.Common.buttonHeightXL, - minHeight: theme.Button.Common.buttonHeightXL, - maxHeight: theme.Button.Common.buttonHeightXL, - gap: spacing.Gap['gap-3'], - borderRadius: theme.General.borderRadius2XL, + paddingHorizontal: button.extend.extXlg.paddingX, + paddingVertical: button.extend.extXlg.paddingY, + height: button.extend.extXlg.height, + minHeight: button.extend.extXlg.height, + maxHeight: button.extend.extXlg.height, + gap: button.extend.extXlg.gap, + borderRadius: button.extend.extXlg.borderRadius, }, large: { - paddingHorizontal: spacing.Padding['p-6'], - paddingVertical: theme.Button.Common.buttonPaddingTopBottom, - height: theme.Button.Common.buttonHeightLG, - minHeight: theme.Button.Common.buttonHeightLG, - maxHeight: theme.Button.Common.buttonHeightLG, - gap: spacing.Gap['gap-3'], - borderRadius: theme.General.borderRadius2XL, + paddingHorizontal: button.root.lg.paddingX, + paddingVertical: button.root.lg.paddingY, + height: button.extend.extLg.height, + minHeight: button.extend.extLg.height, + maxHeight: button.extend.extLg.height, + gap: button.extend.extLg.gap, + borderRadius: button.extend.extLg.borderRadius, }, base: { - paddingHorizontal: theme.Button.Common.buttonPaddingLeftRight, - paddingVertical: theme.Button.Common.buttonPaddingTopBottom, - height: theme.Button.Common.buttonHeight, - minHeight: theme.Button.Common.buttonHeight, - maxHeight: theme.Button.Common.buttonHeight, - gap: theme.General.inlineSpacing, - borderRadius: theme.General.borderRadiusXL, + paddingHorizontal: button.root.paddingX, + paddingVertical: button.root.paddingY, + height: 'auto', + gap: button.root.gap, + borderRadius: button.root.borderRadius, }, small: { - paddingHorizontal: spacing.Padding['p-3'], - paddingVertical: theme.Button.Common.buttonPaddingTopBottom, - height: theme.Button.Common.buttonHeightSM, - minHeight: theme.Button.Common.buttonHeightSM, - maxHeight: theme.Button.Common.buttonHeightSM, - gap: theme.General.inlineSpacing, - borderRadius: theme.General.borderRadiusXL, + paddingHorizontal: button.root.sm.paddingX, + paddingVertical: button.root.sm.paddingY, + height: 'auto', + gap: button.extend.extSm.gap, + borderRadius: button.extend.extSm.borderRadius, }, }, shape: { square: {}, - circle: { borderRadius: border.Radius['rounded-full'] }, + circle: { borderRadius: button.root.roundedBorderRadius }, }, variant: { primary: { - borderColor: theme.Button.Brand.buttonBorderColor, - backgroundColor: theme.Button.Brand.buttonBg, + borderColor: button.colorScheme.root.primary.borderColor, + backgroundColor: button.colorScheme.root.primary.background, }, secondary: { - borderColor: theme.Button.Primary.secondaryButtonBorderColor, - backgroundColor: theme.Button.Primary.secondaryButtonBg, + borderColor: button.colorScheme.root.secondary.borderColor, + backgroundColor: button.colorScheme.root.secondary.background, }, tertiary: { - borderColor: theme.Button.Secondary.helpButtonBorderColor, - backgroundColor: theme.Button.Secondary.helpButtonBg, - }, - text: { - borderColor: theme.Button.Brand.buttonBorderColor, - backgroundColor: theme.Button.Text.textButtonBg, + borderColor: button.colorScheme.root.contrast.borderColor, + backgroundColor: button.colorScheme.root.contrast.background, }, + text: { borderColor: 'transparent', backgroundColor: 'transparent' }, link: { - paddingHorizontal: 0, - paddingVertical: spacing.Padding['p-1'], + paddingHorizontal: semantic.dimension.space.none, + paddingVertical: semantic.dimension.space[100], height: 'auto', minHeight: 'auto', - borderColor: theme.Button.Brand.buttonBorderColor, - backgroundColor: theme.Button.Text.textButtonBg, + borderColor: 'transparent', + backgroundColor: button.extend.extLink.background, }, basic: { - borderColor: theme.Button.Brand.buttonBorderColor, - backgroundColor: theme.Button.Brand.buttonBg, + borderColor: button.colorScheme.root.primary.borderColor, + backgroundColor: button.colorScheme.root.primary.background, }, outlined: { - borderColor: theme.Button.Brand.buttonBorderColor, - backgroundColor: theme.Button.Text.textButtonBg, + borderColor: button.colorScheme.outlined.primary.borderColor, + backgroundColor: 'transparent', }, }, severity: { info: {}, success: {}, warning: {}, danger: {} }, pressed: { true: {}, false: {} }, disabled: { true: { - backgroundColor: theme.Button.Disabled.disabledButtonBg, - borderColor: theme.Button.Disabled.disabledButtonBorderColor, + backgroundColor: button.extend.disabledBackground, + borderColor: 'transparent', }, false: {}, }, @@ -181,40 +176,40 @@ const buttonContainerStyles = StyleSheet.create( variant: 'primary', pressed: 'true', styles: { - borderColor: theme.Button.Brand.buttonBorderColor, - backgroundColor: theme.Button.Brand.buttonHoverBg, + borderColor: button.colorScheme.root.primary.hoverBorderColor, + backgroundColor: button.colorScheme.root.primary.hoverBackground, }, }, { variant: 'secondary', pressed: 'true', styles: { - borderColor: theme.Button.Primary.secondaryButtonHoverBorderColor, - backgroundColor: theme.Button.Primary.secondaryButtonHoverBg, + borderColor: button.colorScheme.root.secondary.hoverBorderColor, + backgroundColor: button.colorScheme.root.secondary.hoverBackground, }, }, { variant: 'tertiary', pressed: 'true', styles: { - borderColor: theme.Button.Secondary.helpButtonHoverBorderColor, - backgroundColor: theme.Button.Secondary.helpButtonHoverBg, + borderColor: button.colorScheme.root.contrast.hoverBorderColor, + backgroundColor: button.colorScheme.root.contrast.hoverBackground, }, }, { variant: 'text', pressed: 'true', styles: { - borderColor: theme.Button.Brand.buttonBorderColor, - backgroundColor: theme.Button.Text.textButtonHoverBg, + borderColor: 'transparent', + backgroundColor: button.colorScheme.text.primary.hoverBackground, }, }, { variant: 'link', disabled: 'true', styles: { - borderColor: theme.Button.Brand.buttonBorderColor, - backgroundColor: theme.Button.Text.textButtonBg, + borderColor: 'transparent', + backgroundColor: 'transparent', }, }, @@ -223,118 +218,96 @@ const buttonContainerStyles = StyleSheet.create( variant: 'basic', severity: 'info', styles: { - borderColor: theme.Button.Severity.Info.Basic.infoButtonBorderColor, - backgroundColor: theme.Button.Severity.Info.Basic.infoButtonBg, + borderColor: button.colorScheme.root.info.borderColor, + backgroundColor: button.colorScheme.root.info.background, }, }, { variant: 'outlined', severity: 'info', styles: { - borderColor: - theme.Button.Severity.Info.Outlined.infoOutlinedButtonBorderColor, - backgroundColor: - theme.Button.Severity.Info.Outlined.infoOutlinedButtonBg, + borderColor: button.colorScheme.outlined.info.borderColor, + backgroundColor: 'transparent', }, }, { variant: 'text', severity: 'info', styles: { - borderColor: theme.Button.Severity.Info.Basic.infoButtonBorderColor, - backgroundColor: theme.Button.Severity.Info.Text.infoTextButtonBg, + borderColor: 'transparent', + backgroundColor: 'transparent', }, }, { variant: 'basic', severity: 'success', styles: { - borderColor: - theme.Button.Severity.Success.Basic.successButtonBorderColor, - backgroundColor: - theme.Button.Severity.Success.Basic.successButtonBg, + borderColor: button.colorScheme.root.success.borderColor, + backgroundColor: button.colorScheme.root.success.background, }, }, { variant: 'outlined', severity: 'success', styles: { - borderColor: - theme.Button.Severity.Success.Outlined - .successOutlinedButtonBorderColor, - backgroundColor: - theme.Button.Severity.Success.Outlined.successOutlinedButtonBg, + borderColor: button.colorScheme.outlined.success.borderColor, + backgroundColor: 'transparent', }, }, { variant: 'text', severity: 'success', styles: { - borderColor: - theme.Button.Severity.Success.Basic.successButtonBorderColor, - backgroundColor: - theme.Button.Severity.Success.Text.successTextButtonBg, + borderColor: 'transparent', + backgroundColor: 'transparent', }, }, { variant: 'basic', severity: 'warning', styles: { - borderColor: - theme.Button.Severity.Warning.Basic.warningButtonBorderColor, - backgroundColor: - theme.Button.Severity.Warning.Basic.warningButtonBg, + borderColor: button.colorScheme.root.warn.borderColor, + backgroundColor: button.colorScheme.root.warn.background, }, }, { variant: 'outlined', severity: 'warning', styles: { - borderColor: - theme.Button.Severity.Warning.Outlined - .warningOutlinedButtonBorderColor, - backgroundColor: - theme.Button.Severity.Warning.Outlined.warningOutlinedButtonBg, + borderColor: button.colorScheme.outlined.warn.borderColor, + backgroundColor: 'transparent', }, }, { variant: 'text', severity: 'warning', styles: { - borderColor: - theme.Button.Severity.Warning.Basic.warningButtonBorderColor, - backgroundColor: - theme.Button.Severity.Warning.Text.warningTextButtonBg, + borderColor: 'transparent', + backgroundColor: 'transparent', }, }, { variant: 'basic', severity: 'danger', styles: { - borderColor: - theme.Button.Severity.Danger.Basic.dangerButtonBorderColor, - backgroundColor: theme.Button.Severity.Danger.Basic.dangerButtonBg, + borderColor: button.colorScheme.root.danger.borderColor, + backgroundColor: button.colorScheme.root.danger.background, }, }, { variant: 'outlined', severity: 'danger', styles: { - borderColor: - theme.Button.Severity.Danger.Outlined - .dangerOutlinedButtonBorderColor, - backgroundColor: - theme.Button.Severity.Danger.Outlined.dangerOutlinedButtonBg, + borderColor: button.colorScheme.outlined.danger.borderColor, + backgroundColor: 'transparent', }, }, { variant: 'text', severity: 'danger', styles: { - borderColor: - theme.Button.Severity.Danger.Basic.dangerButtonBorderColor, - backgroundColor: - theme.Button.Severity.Danger.Text.dangerTextButtonBg, + borderColor: 'transparent', + backgroundColor: 'transparent', }, }, @@ -344,8 +317,8 @@ const buttonContainerStyles = StyleSheet.create( severity: 'info', pressed: 'true', styles: { - borderColor: theme.Button.Severity.Info.Basic.infoButtonBorderColor, - backgroundColor: theme.Button.Severity.Info.Basic.infoButtonHoverBg, + borderColor: button.colorScheme.root.info.hoverBorderColor, + backgroundColor: button.colorScheme.root.info.hoverBackground, }, }, { @@ -353,11 +326,8 @@ const buttonContainerStyles = StyleSheet.create( severity: 'info', pressed: 'true', styles: { - borderColor: - theme.Button.Severity.Info.Outlined - .infoOutlinedButtonHoverBorderColor, - backgroundColor: - theme.Button.Severity.Info.Outlined.infoOutlinedButtonHoverBg, + borderColor: button.colorScheme.outlined.info.borderColor, + backgroundColor: button.colorScheme.outlined.info.hoverBackground, }, }, { @@ -365,9 +335,8 @@ const buttonContainerStyles = StyleSheet.create( severity: 'info', pressed: 'true', styles: { - borderColor: theme.Surface['surface-transparent'], - backgroundColor: - theme.Button.Severity.Info.Text.infoTextButtonHoverBg, + borderColor: 'transparent', + backgroundColor: button.colorScheme.text.info.hoverBackground, }, }, { @@ -375,10 +344,8 @@ const buttonContainerStyles = StyleSheet.create( severity: 'success', pressed: 'true', styles: { - borderColor: - theme.Button.Severity.Success.Basic.successButtonBorderColor, - backgroundColor: - theme.Button.Severity.Success.Basic.successButtonHoverBg, + borderColor: button.colorScheme.root.success.hoverBorderColor, + backgroundColor: button.colorScheme.root.success.hoverBackground, }, }, { @@ -386,12 +353,9 @@ const buttonContainerStyles = StyleSheet.create( severity: 'success', pressed: 'true', styles: { - borderColor: - theme.Button.Severity.Success.Outlined - .successOutlinedButtonHoverBorderColor, + borderColor: button.colorScheme.outlined.success.borderColor, backgroundColor: - theme.Button.Severity.Success.Outlined - .successOutlinedButtonHoverBg, + button.colorScheme.outlined.success.hoverBackground, }, }, { @@ -399,9 +363,8 @@ const buttonContainerStyles = StyleSheet.create( severity: 'success', pressed: 'true', styles: { - borderColor: theme.Surface['surface-transparent'], - backgroundColor: - theme.Button.Severity.Success.Text.successTextButtonHoverBg, + borderColor: 'transparent', + backgroundColor: button.colorScheme.text.success.hoverBackground, }, }, { @@ -409,10 +372,8 @@ const buttonContainerStyles = StyleSheet.create( severity: 'warning', pressed: 'true', styles: { - borderColor: - theme.Button.Severity.Warning.Basic.warningButtonBorderColor, - backgroundColor: - theme.Button.Severity.Warning.Basic.warningButtonHoverBg, + borderColor: button.colorScheme.root.warn.hoverBorderColor, + backgroundColor: button.colorScheme.root.warn.hoverBackground, }, }, { @@ -420,12 +381,8 @@ const buttonContainerStyles = StyleSheet.create( severity: 'warning', pressed: 'true', styles: { - borderColor: - theme.Button.Severity.Warning.Outlined - .warningOutlinedButtonHoverBorderColor, - backgroundColor: - theme.Button.Severity.Warning.Outlined - .warningOutlinedButtonHoverBg, + borderColor: button.colorScheme.outlined.warn.borderColor, + backgroundColor: button.colorScheme.outlined.warn.hoverBackground, }, }, { @@ -433,9 +390,8 @@ const buttonContainerStyles = StyleSheet.create( severity: 'warning', pressed: 'true', styles: { - borderColor: theme.Surface['surface-transparent'], - backgroundColor: - theme.Button.Severity.Warning.Text.warningTextButtonHoverBg, + borderColor: 'transparent', + backgroundColor: button.colorScheme.text.warn.hoverBackground, }, }, { @@ -443,10 +399,8 @@ const buttonContainerStyles = StyleSheet.create( severity: 'danger', pressed: 'true', styles: { - borderColor: - theme.Button.Severity.Danger.Basic.dangerButtonBorderColor, - backgroundColor: - theme.Button.Severity.Danger.Basic.dangerButtonHoverBg, + borderColor: button.colorScheme.root.danger.hoverBorderColor, + backgroundColor: button.colorScheme.root.danger.hoverBackground, }, }, { @@ -454,11 +408,8 @@ const buttonContainerStyles = StyleSheet.create( severity: 'danger', pressed: 'true', styles: { - borderColor: - theme.Button.Severity.Danger.Outlined - .dangerOutlinedButtonHoverBorderColor, - backgroundColor: - theme.Button.Severity.Danger.Outlined.dangerOutlinedButtonHoverBg, + borderColor: button.colorScheme.outlined.danger.borderColor, + backgroundColor: button.colorScheme.outlined.danger.hoverBackground, }, }, { @@ -466,9 +417,8 @@ const buttonContainerStyles = StyleSheet.create( severity: 'danger', pressed: 'true', styles: { - borderColor: theme.Surface['surface-transparent'], - backgroundColor: - theme.Button.Severity.Danger.Text.dangerTextButtonHoverBg, + borderColor: 'transparent', + backgroundColor: button.colorScheme.text.danger.hoverBackground, }, }, @@ -478,11 +428,11 @@ const buttonContainerStyles = StyleSheet.create( iconOnly: 'true', size: 'xlarge', styles: { - paddingHorizontal: spacing.Gap['gap-1'], - paddingVertical: spacing.Gap['gap-1'], - height: sizing.Height['h-2'], - minHeight: sizing.Height['h-2'], - maxHeight: sizing.Height['h-2'], + paddingHorizontal: semantic.dimension.space[100], + paddingVertical: semantic.dimension.space[100], + height: button.extend.extLink.xlg.iconOnlyWidth, + minHeight: button.extend.extLink.xlg.iconOnlyWidth, + maxHeight: button.extend.extLink.xlg.iconOnlyWidth, }, }, { @@ -490,11 +440,11 @@ const buttonContainerStyles = StyleSheet.create( iconOnly: 'true', size: 'large', styles: { - paddingHorizontal: spacing.Gap['gap-0'], - paddingVertical: spacing.Gap['gap-0'], - height: 24.5, - minHeight: 24.5, - maxHeight: 24.5, + paddingHorizontal: semantic.dimension.space.none, + paddingVertical: semantic.dimension.space.none, + height: button.extend.extLink.lg.iconOnlyWidth, + minHeight: button.extend.extLink.lg.iconOnlyWidth, + maxHeight: button.extend.extLink.lg.iconOnlyWidth, }, }, { @@ -502,11 +452,11 @@ const buttonContainerStyles = StyleSheet.create( iconOnly: 'true', size: 'base', styles: { - paddingHorizontal: spacing.Gap['gap-1'], - paddingVertical: spacing.Gap['gap-1'], - height: 21.5, - minHeight: 21.5, - maxHeight: 21.5, + paddingHorizontal: semantic.dimension.space[100], + paddingVertical: semantic.dimension.space[100], + height: button.extend.extLink.base.iconOnlyWidth, + minHeight: button.extend.extLink.base.iconOnlyWidth, + maxHeight: button.extend.extLink.base.iconOnlyWidth, }, }, { @@ -514,11 +464,11 @@ const buttonContainerStyles = StyleSheet.create( iconOnly: 'true', size: 'small', styles: { - paddingHorizontal: spacing.Gap['gap-1'], - paddingVertical: spacing.Gap['gap-1'], - height: sizing.Height['h-1'], - minHeight: sizing.Height['h-2'], - maxHeight: sizing.Height['h-2'], + paddingHorizontal: semantic.dimension.space[100], + paddingVertical: semantic.dimension.space[100], + height: button.extend.extLink.sm.iconOnlyWidth, + minHeight: button.extend.extLink.sm.iconOnlyWidth, + maxHeight: button.extend.extLink.sm.iconOnlyWidth, }, }, ], diff --git a/src/components/Button/utils/ButtonIcon.tsx b/src/components/Button/utils/ButtonIcon.tsx index 9dcb9c6c..6be2a77f 100644 --- a/src/components/Button/utils/ButtonIcon.tsx +++ b/src/components/Button/utils/ButtonIcon.tsx @@ -48,140 +48,111 @@ const ButtonIconComponent = ({ export const ButtonIcon = genericMemo(ButtonIconComponent) -const buttonIconStyles = StyleSheet.create(({ theme, typography }) => ({ - icon: { - variants: { - size: { - xlarge: { - height: typography.Size['text-2xl'], - width: typography.Size['text-2xl'], +const buttonIconStyles = StyleSheet.create( + ({ components: { button }, semantic }) => ({ + icon: { + variants: { + size: { + xlarge: { + height: button.extend.iconSize.lg, + width: button.extend.iconSize.lg, + }, + large: { + height: button.extend.iconSize.lg, + width: button.extend.iconSize.lg, + }, + base: { + height: button.extend.iconSize.md, + width: button.extend.iconSize.md, + }, + small: { + height: button.extend.iconSize.sm, + width: button.extend.iconSize.sm, + }, }, - large: { - height: typography.Size['text-2xl'], - width: typography.Size['text-2xl'], + variant: { + primary: { color: button.colorScheme.root.primary.color }, + secondary: { color: button.colorScheme.root.secondary.color }, + tertiary: { color: button.colorScheme.root.contrast.color }, + text: { color: button.colorScheme.text.primary.color }, + link: { color: button.colorScheme.link.color }, + basic: { color: button.colorScheme.root.primary.color }, + outlined: { color: button.colorScheme.outlined.primary.color }, }, - base: { - height: typography.Size['text-xl'], - width: typography.Size['text-xl'], + severity: { info: {}, success: {}, warning: {}, danger: {} }, + pressed: { true: {}, false: {} }, + disabled: { true: { color: button.extend.disabledColor }, false: {} }, + }, + compoundVariants: [ + // link pressed + { + variant: 'link', + pressed: 'true', + styles: { color: semantic.colorScheme.color.fg.muted }, }, - small: { - height: typography.Size['text-base'], - width: typography.Size['text-base'], - }, - }, - variant: { - primary: { color: theme.Button.Brand.buttonTextColor }, - secondary: { color: theme.Button.Primary.secondaryButtonTextColor }, - tertiary: { color: theme.Button.Secondary.helpButtonTextColor }, - text: { color: theme.Button.Text.textButtonTextColor }, - link: { color: theme.Button.Text.textButtonTextColor }, - basic: { color: theme.Button.Brand.buttonTextColor }, - outlined: { color: theme.Button.Brand.buttonTextColor }, - }, - severity: { info: {}, success: {}, warning: {}, danger: {} }, - pressed: { true: {}, false: {} }, - disabled: { - true: { color: theme.Button.Disabled.disabledButtonTextColor }, - false: {}, - }, - }, - compoundVariants: [ - // link pressed - { - variant: 'link', - pressed: 'true', - styles: { color: typography.Color.Common['text-color-secondary'] }, - }, - // severity icon colors - { - variant: 'basic', - severity: 'info', - styles: { color: theme.Button.Severity.Info.Basic.infoButtonTextColor }, - }, - { - variant: 'outlined', - severity: 'info', - styles: { - color: - theme.Button.Severity.Info.Outlined.infoOutlinedButtonTextColor, + // severity icon colors + { + variant: 'basic', + severity: 'info', + styles: { color: button.colorScheme.root.info.color }, }, - }, - { - variant: 'text', - severity: 'info', - styles: { - color: theme.Button.Severity.Info.Text.infoTextButtonTextColor, + { + variant: 'outlined', + severity: 'info', + styles: { color: button.colorScheme.outlined.info.color }, }, - }, - { - variant: 'basic', - severity: 'success', - styles: { - color: theme.Button.Severity.Success.Basic.successButtonTextColor, + { + variant: 'text', + severity: 'info', + styles: { color: button.colorScheme.text.info.color }, }, - }, - { - variant: 'outlined', - severity: 'success', - styles: { - color: - theme.Button.Severity.Success.Outlined - .successOutlinedButtonTextColor, + { + variant: 'basic', + severity: 'success', + styles: { color: button.colorScheme.root.success.color }, }, - }, - { - variant: 'text', - severity: 'success', - styles: { - color: theme.Button.Severity.Success.Text.successTextButtonTextColor, + { + variant: 'outlined', + severity: 'success', + styles: { color: button.colorScheme.outlined.success.color }, }, - }, - { - variant: 'basic', - severity: 'warning', - styles: { - color: theme.Button.Severity.Warning.Basic.warningButtonTextColor, + { + variant: 'text', + severity: 'success', + styles: { color: button.colorScheme.text.success.color }, }, - }, - { - variant: 'outlined', - severity: 'warning', - styles: { - color: - theme.Button.Severity.Warning.Outlined - .warningOutlinedButtonTextColor, + { + variant: 'basic', + severity: 'warning', + styles: { color: button.colorScheme.root.warn.color }, }, - }, - { - variant: 'text', - severity: 'warning', - styles: { - color: theme.Button.Severity.Warning.Text.warningTextButtonTextColor, + { + variant: 'outlined', + severity: 'warning', + styles: { color: button.colorScheme.outlined.warn.color }, }, - }, - { - variant: 'basic', - severity: 'danger', - styles: { - color: theme.Button.Severity.Danger.Basic.dangerButtonTextColor, + { + variant: 'text', + severity: 'warning', + styles: { color: button.colorScheme.text.warn.color }, }, - }, - { - variant: 'outlined', - severity: 'danger', - styles: { - color: - theme.Button.Severity.Danger.Outlined.dangerOutlinedButtonTextColor, + { + variant: 'basic', + severity: 'danger', + styles: { color: button.colorScheme.root.danger.color }, }, - }, - { - variant: 'text', - severity: 'danger', - styles: { - color: theme.Button.Severity.Danger.Text.dangerTextButtonTextColor, + { + variant: 'outlined', + severity: 'danger', + styles: { color: button.colorScheme.outlined.danger.color }, }, - }, - ], - }, -})) + { + variant: 'text', + severity: 'danger', + styles: { color: button.colorScheme.text.danger.color }, + }, + ], + }, + }) +) diff --git a/src/components/Button/utils/ButtonLabel.tsx b/src/components/Button/utils/ButtonLabel.tsx index 5b541a60..22e315f8 100644 --- a/src/components/Button/utils/ButtonLabel.tsx +++ b/src/components/Button/utils/ButtonLabel.tsx @@ -48,132 +48,103 @@ const ButtonLabelComponent = ({ export const ButtonLabel = genericMemo(ButtonLabelComponent) -const buttonLabelStyles = StyleSheet.create(({ theme, typography, fonts }) => ({ - label: { - fontWeight: 600, - includeFontPadding: false, - verticalAlign: 'middle', - fontFamily: fonts.primary, - variants: { - size: { - xlarge: { fontSize: typography.Size['text-xl'] }, - large: { fontSize: typography.Size['text-xl'] }, - base: { fontSize: typography.Size['text-base'] }, - small: { fontSize: typography.Size['text-sm'] }, - }, - variant: { - primary: { color: theme.Button.Brand.buttonTextColor }, - secondary: { color: theme.Button.Primary.secondaryButtonTextColor }, - tertiary: { color: theme.Button.Secondary.helpButtonTextColor }, - text: { color: theme.Button.Text.textButtonTextColor }, - link: { color: theme.Button.Text.textButtonTextColor }, - basic: { color: theme.Button.Brand.buttonTextColor }, - outlined: { color: theme.Button.Brand.buttonTextColor }, - }, - severity: { info: {}, success: {}, warning: {}, danger: {} }, - pressed: { true: {}, false: {} }, - disabled: { - true: { color: theme.Button.Disabled.disabledButtonTextColor }, - false: {}, - }, - }, - compoundVariants: [ - // link pressed color change - { - variant: 'link', - pressed: 'true', - styles: { color: typography.Color.Common['text-color-secondary'] }, - }, +const buttonLabelStyles = StyleSheet.create( + ({ components: { button }, semantic, fonts }) => ({ + label: { + fontWeight: fonts.fontWeight.demibold, + includeFontPadding: false, + verticalAlign: 'middle', + fontFamily: fonts.fontFamily.heading, + variants: { + size: { + xlarge: { fontSize: fonts.fontSize[500] }, + large: { fontSize: fonts.fontSize[500] }, + base: { fontSize: fonts.fontSize[300] }, + small: { fontSize: fonts.fontSize[100] }, + }, + variant: { + primary: { color: button.colorScheme.root.primary.color }, + secondary: { color: button.colorScheme.root.secondary.color }, + tertiary: { color: button.colorScheme.root.contrast.color }, + text: { color: button.colorScheme.text.primary.color }, + link: { color: button.colorScheme.link.color }, + basic: { color: button.colorScheme.root.primary.color }, + outlined: { color: button.colorScheme.outlined.primary.color }, + }, + severity: { info: {}, success: {}, warning: {}, danger: {} }, + pressed: { true: {}, false: {} }, + disabled: { true: { color: button.extend.disabledColor }, false: {} }, + }, + compoundVariants: [ + // link pressed color change + { + variant: 'link', + pressed: 'true', + styles: { color: semantic.colorScheme.color.fg.muted }, + }, - // severity label colors - { - variant: 'basic', - severity: 'info', - styles: { color: theme.Button.Severity.Info.Basic.infoButtonTextColor }, - }, - { - variant: 'outlined', - severity: 'info', - styles: { - color: - theme.Button.Severity.Info.Outlined.infoOutlinedButtonTextColor, + // severity label colors + { + variant: 'basic', + severity: 'info', + styles: { color: button.colorScheme.root.info.color }, }, - }, - { - variant: 'text', - severity: 'info', - styles: { - color: theme.Button.Severity.Info.Text.infoTextButtonTextColor, + { + variant: 'outlined', + severity: 'info', + styles: { color: button.colorScheme.outlined.info.color }, }, - }, - { - variant: 'basic', - severity: 'success', - styles: { - color: theme.Button.Severity.Success.Basic.successButtonTextColor, + { + variant: 'text', + severity: 'info', + styles: { color: button.colorScheme.text.info.color }, }, - }, - { - variant: 'outlined', - severity: 'success', - styles: { - color: - theme.Button.Severity.Success.Outlined - .successOutlinedButtonTextColor, + { + variant: 'basic', + severity: 'success', + styles: { color: button.colorScheme.root.success.color }, }, - }, - { - variant: 'text', - severity: 'success', - styles: { - color: theme.Button.Severity.Success.Text.successTextButtonTextColor, + { + variant: 'outlined', + severity: 'success', + styles: { color: button.colorScheme.outlined.success.color }, }, - }, - { - variant: 'basic', - severity: 'warning', - styles: { - color: theme.Button.Severity.Warning.Basic.warningButtonTextColor, + { + variant: 'text', + severity: 'success', + styles: { color: button.colorScheme.text.success.color }, }, - }, - { - variant: 'outlined', - severity: 'warning', - styles: { - color: - theme.Button.Severity.Warning.Outlined - .warningOutlinedButtonTextColor, + { + variant: 'basic', + severity: 'warning', + styles: { color: button.colorScheme.root.warn.color }, }, - }, - { - variant: 'text', - severity: 'warning', - styles: { - color: theme.Button.Severity.Warning.Text.warningTextButtonTextColor, + { + variant: 'outlined', + severity: 'warning', + styles: { color: button.colorScheme.outlined.warn.color }, }, - }, - { - variant: 'basic', - severity: 'danger', - styles: { - color: theme.Button.Severity.Danger.Basic.dangerButtonTextColor, + { + variant: 'text', + severity: 'warning', + styles: { color: button.colorScheme.text.warn.color }, }, - }, - { - variant: 'outlined', - severity: 'danger', - styles: { - color: - theme.Button.Severity.Danger.Outlined.dangerOutlinedButtonTextColor, + { + variant: 'basic', + severity: 'danger', + styles: { color: button.colorScheme.root.danger.color }, }, - }, - { - variant: 'text', - severity: 'danger', - styles: { - color: theme.Button.Severity.Danger.Text.dangerTextButtonTextColor, + { + variant: 'outlined', + severity: 'danger', + styles: { color: button.colorScheme.outlined.danger.color }, }, - }, - ], - }, -})) + { + variant: 'text', + severity: 'danger', + styles: { color: button.colorScheme.text.danger.color }, + }, + ], + }, + }) +) From 12922502ec5865962d647463135e6398307c31fb Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:42 +0300 Subject: [PATCH 19/40] =?UTF-8?q?feat(Checkbox):=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Checkbox/Checkbox.tsx | 49 ++++++------- .../__snapshots__/Checkbox.test.tsx.snap | 73 ++++++++----------- 2 files changed, 52 insertions(+), 70 deletions(-) diff --git a/src/components/Checkbox/Checkbox.tsx b/src/components/Checkbox/Checkbox.tsx index 41a89bf7..b1e3b144 100644 --- a/src/components/Checkbox/Checkbox.tsx +++ b/src/components/Checkbox/Checkbox.tsx @@ -97,9 +97,9 @@ export const Checkbox = memo( ({ - color: theme.Form.Checkbox.checkboxIconActiveColor, - })} + uniProps={({ components }) => { + return { color: components.checkbox.icon.checkedColor } + }} /> ) : null} @@ -107,57 +107,52 @@ export const Checkbox = memo( } ) -const styles = StyleSheet.create(({ theme, border, sizing }) => ({ +const styles = StyleSheet.create(({ components, semantic }) => ({ container: { justifyContent: 'center', alignItems: 'center', - width: theme.Form.Checkbox.checkboxWidth, - height: theme.Form.Checkbox.checkboxHeight, + width: components.checkbox.root.width, + height: components.checkbox.root.height, }, background: { ...RNStyleSheet.absoluteFillObject }, backgroundState: { - borderRadius: border.Radius['rounded-lg'], - borderWidth: border.Width.border, + borderRadius: components.checkbox.root.borderRadius, + borderWidth: components.checkbox.root.extend.borderWidth, variants: { filled: { true: { - backgroundColor: theme.Form.Checkbox.checkboxActiveBg, - borderColor: theme.Form.Checkbox.checkboxActiveBorderColor, + backgroundColor: components.checkbox.root.checkedBackground, + borderColor: components.checkbox.root.checkedBorderColor, }, false: { - backgroundColor: theme.Form.InputText.inputBg, - borderColor: theme.Form.InputText.inputBorderColor, + backgroundColor: components.checkbox.root.background, + borderColor: components.checkbox.root.borderColor, }, }, pressed: { - true: { borderColor: theme.Form.InputText.inputHoverBorderColor }, + true: { borderColor: components.checkbox.root.hoverBorderColor }, false: {}, }, state: { - danger: { - borderColor: theme.Form.InputText.inputErrorBorderColor, - outlineStyle: 'solid', - outlineColor: theme.General.focusOutlineErrorColor, - outlineWidth: Math.round(theme.General.focusShadowWidth), - }, + danger: { borderColor: components.checkbox.root.invalidBorderColor }, }, - disabled: { true: { outlineWidth: 0 }, false: {} }, + disabled: { true: {}, false: {} }, }, compoundVariants: [ { filled: 'true', pressed: 'true', styles: { - backgroundColor: theme.Form.Checkbox.checkboxActiveHoverBg, - borderColor: theme.Form.Checkbox.checkboxActiveHoverBorderColor, + backgroundColor: components.checkbox.root.checkedHoverBackground, + borderColor: components.checkbox.root.checkedHoverBorderColor, }, }, { filled: 'false', disabled: 'true', styles: { - backgroundColor: theme.Button.Disabled.disabledButtonBg, - borderColor: theme.Form.InputText.inputBorderColor, + backgroundColor: components.checkbox.root.disabledBackground, + borderColor: components.checkbox.root.borderColor, mixBlendMode: 'luminosity', }, }, @@ -165,12 +160,12 @@ const styles = StyleSheet.create(({ theme, border, sizing }) => ({ filled: 'true', disabled: 'true', styles: { - borderColor: theme.Form.Checkbox.checkboxActiveBorderColor, - opacity: 0.2, + borderColor: components.checkbox.root.checkedBorderColor, + opacity: semantic.effects.opacity[20], mixBlendMode: 'luminosity', }, }, ], }, - icon: { height: sizing.Height['h-1'], width: sizing.Width['w-1'] }, + icon: { height: 14, width: 14 }, })) diff --git a/src/components/Checkbox/__tests__/__snapshots__/Checkbox.test.tsx.snap b/src/components/Checkbox/__tests__/__snapshots__/Checkbox.test.tsx.snap index 872efcb8..11e41577 100644 --- a/src/components/Checkbox/__tests__/__snapshots__/Checkbox.test.tsx.snap +++ b/src/components/Checkbox/__tests__/__snapshots__/Checkbox.test.tsx.snap @@ -36,9 +36,9 @@ exports[`Checkbox snapshots checked = false, indeterminate = false, disabled = f style={ { "alignItems": "center", - "height": 21, + "height": 24, "justifyContent": "center", - "width": 21, + "width": 24, } } testID="CheckboxButton_Pressable" @@ -55,12 +55,9 @@ exports[`Checkbox snapshots checked = false, indeterminate = false, disabled = f }, { "backgroundColor": "#ffffff", - "borderColor": "#db3424", - "borderRadius": 7, + "borderColor": "#f47f77", + "borderRadius": 8, "borderWidth": 1, - "outlineColor": "#fff0f0", - "outlineStyle": "solid", - "outlineWidth": 4, }, ] } @@ -104,9 +101,9 @@ exports[`Checkbox snapshots checked = false, indeterminate = false, disabled = f style={ { "alignItems": "center", - "height": 21, + "height": 24, "justifyContent": "center", - "width": 21, + "width": 24, } } testID="CheckboxButton_Pressable" @@ -124,7 +121,7 @@ exports[`Checkbox snapshots checked = false, indeterminate = false, disabled = f { "backgroundColor": "#ffffff", "borderColor": "#cecfd2", - "borderRadius": 7, + "borderRadius": 8, "borderWidth": 1, }, ] @@ -169,9 +166,9 @@ exports[`Checkbox snapshots checked = true, indeterminate = false, disabled = fa style={ { "alignItems": "center", - "height": 21, + "height": 24, "justifyContent": "center", - "width": 21, + "width": 24, } } testID="CheckboxButton_Pressable" @@ -188,12 +185,9 @@ exports[`Checkbox snapshots checked = true, indeterminate = false, disabled = fa }, { "backgroundColor": "#2b2e33", - "borderColor": "#db3424", - "borderRadius": 7, + "borderColor": "#f47f77", + "borderRadius": 8, "borderWidth": 1, - "outlineColor": "#fff0f0", - "outlineStyle": "solid", - "outlineWidth": 4, }, ] } @@ -316,9 +310,9 @@ exports[`Checkbox snapshots checked = true, indeterminate = false, disabled = fa style={ { "alignItems": "center", - "height": 21, + "height": 24, "justifyContent": "center", - "width": 21, + "width": 24, } } testID="CheckboxButton_Pressable" @@ -336,7 +330,7 @@ exports[`Checkbox snapshots checked = true, indeterminate = false, disabled = fa { "backgroundColor": "#2b2e33", "borderColor": "#2b2e33", - "borderRadius": 7, + "borderRadius": 8, "borderWidth": 1, }, ] @@ -460,9 +454,9 @@ exports[`Checkbox snapshots checked = true, indeterminate = true, disabled = fal style={ { "alignItems": "center", - "height": 21, + "height": 24, "justifyContent": "center", - "width": 21, + "width": 24, } } testID="CheckboxButton_Pressable" @@ -479,12 +473,9 @@ exports[`Checkbox snapshots checked = true, indeterminate = true, disabled = fal }, { "backgroundColor": "#2b2e33", - "borderColor": "#db3424", - "borderRadius": 7, + "borderColor": "#f47f77", + "borderRadius": 8, "borderWidth": 1, - "outlineColor": "#fff0f0", - "outlineStyle": "solid", - "outlineWidth": 4, }, ] } @@ -607,9 +598,9 @@ exports[`Checkbox snapshots checked = true, indeterminate = true, disabled = fal style={ { "alignItems": "center", - "height": 21, + "height": 24, "justifyContent": "center", - "width": 21, + "width": 24, } } testID="CheckboxButton_Pressable" @@ -627,7 +618,7 @@ exports[`Checkbox snapshots checked = true, indeterminate = true, disabled = fal { "backgroundColor": "#2b2e33", "borderColor": "#2b2e33", - "borderRadius": 7, + "borderRadius": 8, "borderWidth": 1, }, ] @@ -751,9 +742,9 @@ exports[`Checkbox snapshots checked = true, indeterminate = true, disabled = tru style={ { "alignItems": "center", - "height": 21, + "height": 24, "justifyContent": "center", - "width": 21, + "width": 24, } } testID="CheckboxButton_Pressable" @@ -771,13 +762,10 @@ exports[`Checkbox snapshots checked = true, indeterminate = true, disabled = tru { "backgroundColor": "#2b2e33", "borderColor": "#2b2e33", - "borderRadius": 7, + "borderRadius": 8, "borderWidth": 1, "mixBlendMode": "luminosity", "opacity": 0.2, - "outlineColor": "#fff0f0", - "outlineStyle": "solid", - "outlineWidth": 0, }, ] } @@ -900,9 +888,9 @@ exports[`Checkbox snapshots checked = true, indeterminate = true, disabled = tru style={ { "alignItems": "center", - "height": 21, + "height": 24, "justifyContent": "center", - "width": 21, + "width": 24, } } testID="CheckboxButton_Pressable" @@ -920,11 +908,10 @@ exports[`Checkbox snapshots checked = true, indeterminate = true, disabled = tru { "backgroundColor": "#2b2e33", "borderColor": "#2b2e33", - "borderRadius": 7, + "borderRadius": 8, "borderWidth": 1, "mixBlendMode": "luminosity", "opacity": 0.2, - "outlineWidth": 0, }, ] } @@ -1047,9 +1034,9 @@ exports[`Checkbox snapshots default 1`] = ` style={ { "alignItems": "center", - "height": 21, + "height": 24, "justifyContent": "center", - "width": 21, + "width": 24, } } testID="CheckboxButton_Pressable" @@ -1067,7 +1054,7 @@ exports[`Checkbox snapshots default 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#cecfd2", - "borderRadius": 7, + "borderRadius": 8, "borderWidth": 1, }, ] From 91b5cddae6a70e37bd7bda4e55fa9d61dba5a8b9 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:43 +0300 Subject: [PATCH 20/40] =?UTF-8?q?feat(Chip):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Chip/Chip.tsx | 76 +-- .../__snapshots__/Chip.test.tsx.snap | 512 +++++++++--------- 2 files changed, 288 insertions(+), 300 deletions(-) diff --git a/src/components/Chip/Chip.tsx b/src/components/Chip/Chip.tsx index 921f630b..fffcb528 100644 --- a/src/components/Chip/Chip.tsx +++ b/src/components/Chip/Chip.tsx @@ -5,9 +5,11 @@ import { Text, Pressable, type PressableProps } from 'react-native' import { StyleSheet } from 'react-native-unistyles' -import type { ThemeType } from '../../theme/types' - -import { type SvgSource, SvgUniversal } from '../../utils/SvgUniversal' +import { + type SvgSource, + SvgUniversal, + type SvgUniversalTheme, +} from '../../utils/SvgUniversal' export interface ChipProps extends PressableProps { /** SVG-иконка */ @@ -44,11 +46,13 @@ export const Chip = memo( showIcon = true, ...rest }) => { - const iconUniProps = ({ theme }: ThemeType) => ({ - color: disabled - ? theme.Button.Disabled.disabledButtonTextColor - : theme.Misc.Chip.chipTextColor, - }) + const iconUniProps = ({ components, semantic }: SvgUniversalTheme) => { + return { + color: disabled + ? semantic.colorScheme.color.fg.muted + : components.chip.colorScheme.root.color, + } + } return ( ( {...styles.icon} source={IconX} style={pressed ? styles.pressedClose : null} - uniProps={({ theme }) => ({ - color: disabled - ? theme.Button.Disabled.disabledButtonTextColor - : theme.Misc.Chip.chipTextColor, - })} + uniProps={({ components, semantic }) => { + return { + color: disabled + ? semantic.colorScheme.color.fg.muted + : components.chip.colorScheme.root.color, + } + }} /> )} @@ -97,46 +103,44 @@ export const Chip = memo( } ) -const styles = StyleSheet.create(({ theme, typography, border, fonts }) => ({ +// `transparent` здесь — отсутствие границы, а не цвет дизайн-системы: +// у chip.root нет borderColor, прозрачность не выражена semantic-токеном. +const styles = StyleSheet.create(({ components, semantic, fonts }) => ({ chip: { - height: theme.Misc.Chip.chipHeight, alignSelf: 'flex-start', justifyContent: 'center', alignItems: 'center', flexDirection: 'row', - gap: theme.General.inlineSpacing, + gap: components.chip.root.gap, - paddingHorizontal: theme.Misc.Chip.chipPaddingLeftRight, - paddingVertical: theme.Misc.Chip.chipPaddingTopBottom, + paddingHorizontal: components.chip.root.paddingX, + paddingVertical: components.chip.root.paddingY, - borderRadius: theme.Misc.Chip.chipBorderRadius, - borderWidth: border.Width.border, + borderRadius: components.chip.root.borderRadius, + borderWidth: components.chip.extend.borderWidth, - backgroundColor: theme.Misc.Chip.chipBg, - borderColor: theme.Misc.Chip.chipBorderColor, + backgroundColor: components.chip.colorScheme.root.background, + borderColor: components.chip.extend.borderColor, }, disabledChip: { - backgroundColor: theme.Button.Disabled.disabledButtonBg, - borderColor: theme.Button.Disabled.disabledButtonBorderColor, - opacity: 0.6, + backgroundColor: semantic.colorScheme.color.bg.neutral.weak.disabled, + borderColor: 'transparent', + opacity: semantic.effects.opacity[60], mixBlendMode: 'luminosity', }, - icon: { - width: typography.Size['text-base'], - height: typography.Size['text-base'], - }, + icon: { width: components.chip.icon.size, height: components.chip.icon.size }, text: { - fontSize: typography.Size['text-base'], + fontSize: fonts.fontSize[300], verticalAlign: 'middle', - color: theme.Misc.Chip.chipTextColor, + color: components.chip.colorScheme.root.color, includeFontPadding: false, - fontFamily: fonts.secondary, + fontFamily: fonts.fontFamily.base, }, - disabledText: { color: theme.General.textSecondaryColor }, + disabledText: { color: semantic.colorScheme.color.fg.muted }, pressedClose: { - borderWidth: border.Width['border-3'], - borderColor: border.Color.Service['border-success'][400], - borderRadius: border.Radius['rounded-full'], + borderWidth: semantic.dimension.borderWidth[300], + borderColor: semantic.colorScheme.color.border.status.success.strong, + borderRadius: semantic.dimension.borderRadius.max, }, })) diff --git a/src/components/Chip/__tests__/__snapshots__/Chip.test.tsx.snap b/src/components/Chip/__tests__/__snapshots__/Chip.test.tsx.snap index d7fe5652..6df9070f 100644 --- a/src/components/Chip/__tests__/__snapshots__/Chip.test.tsx.snap +++ b/src/components/Chip/__tests__/__snapshots__/Chip.test.tsx.snap @@ -42,16 +42,15 @@ exports[`Chip component tests { { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#f0f0f1", - "borderColor": "rgba(255, 255, 255, 0.0001)", - "borderRadius": 7, + "backgroundColor": "#e2e2e4", + "borderColor": "transparent", + "borderRadius": 8, "borderWidth": 1, "flexDirection": "row", - "gap": 7, - "height": 24.5, + "gap": 8, "justifyContent": "center", - "paddingHorizontal": 7, - "paddingVertical": 0, + "paddingHorizontal": 8, + "paddingVertical": 4, }, undefined, ] @@ -63,9 +62,9 @@ exports[`Chip component tests { style={ [ { - "color": "#181a1f", + "color": "#2b2e33", "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, "verticalAlign": "middle", }, @@ -120,16 +119,15 @@ exports[`Chip component tests { { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#f0f0f1", - "borderColor": "rgba(255, 255, 255, 0.0001)", - "borderRadius": 7, + "backgroundColor": "#e2e2e4", + "borderColor": "transparent", + "borderRadius": 8, "borderWidth": 1, "flexDirection": "row", - "gap": 7, - "height": 24.5, + "gap": 8, "justifyContent": "center", - "paddingHorizontal": 7, - "paddingVertical": 0, + "paddingHorizontal": 8, + "paddingVertical": 4, }, undefined, ] @@ -138,15 +136,15 @@ exports[`Chip component tests { > Date: Tue, 4 Aug 2026 17:05:43 +0300 Subject: [PATCH 21/40] =?UTF-8?q?feat(Dialog):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Dialog/DialogComponent.tsx | 18 +- src/components/Dialog/DialogHeader.tsx | 47 +- .../__snapshots__/Dialog.test.tsx.snap | 10 +- .../__snapshots__/DialogHeader.test.tsx.snap | 440 +++++++++--------- 4 files changed, 264 insertions(+), 251 deletions(-) diff --git a/src/components/Dialog/DialogComponent.tsx b/src/components/Dialog/DialogComponent.tsx index 04c95534..15a8a63b 100644 --- a/src/components/Dialog/DialogComponent.tsx +++ b/src/components/Dialog/DialogComponent.tsx @@ -36,18 +36,16 @@ export const DialogComponent: React.FC = ({ ) } -const styles = StyleSheet.create(({ theme }) => ({ +const styles = StyleSheet.create(({ components }) => ({ root: { - backgroundColor: theme.Overlay.Dialog.Header.dialogHeaderBg, - borderColor: theme.Overlay.Overlay.overlayContentBorderColor, - borderRadius: theme.General.borderRadius2XL, - }, - body: { - paddingVertical: theme.Overlay.Dialog.Body.dialogContentPaddingTopBottom, - paddingHorizontal: theme.Overlay.Dialog.Body.dialogContentPaddingLeftRight, + backgroundColor: components.dialog.root.background, + borderColor: components.dialog.root.borderColor, + borderRadius: components.dialog.root.borderRadius, }, + body: { padding: components.dialog.content.padding }, footer: { - paddingBottom: theme.Overlay.Dialog.Footer.dialogFooterPaddingLeftRight, - paddingHorizontal: theme.Overlay.Dialog.Footer.dialogFooterPaddingLeftRight, + paddingTop: components.dialog.footer.paddingTop, + paddingBottom: components.dialog.footer.paddingBottom, + paddingHorizontal: components.dialog.footer.paddingLeft, }, })) diff --git a/src/components/Dialog/DialogHeader.tsx b/src/components/Dialog/DialogHeader.tsx index f6dd8042..3620dd43 100644 --- a/src/components/Dialog/DialogHeader.tsx +++ b/src/components/Dialog/DialogHeader.tsx @@ -46,15 +46,17 @@ export const DialogHeader = ({ ({ - color: { - danger: t.Color.Service['text-danger'], - warning: t.Color.Service['text-warning'], - info: t.Color.Service['text-info'], - success: t.Color.Service['text-success'], - help: t.Color.Service['text-help'], - }[severity], - })} + uniProps={({ semantic }) => { + return { + color: { + danger: semantic.colorScheme.color.fg.status.danger.default, + warning: semantic.colorScheme.color.fg.status.warning.default, + info: semantic.colorScheme.color.fg.status.info.default, + success: semantic.colorScheme.color.fg.status.success.default, + help: semantic.colorScheme.color.fg.status.help.default, + }[severity], + } + }} /> ) }, [severity]) @@ -75,9 +77,9 @@ export const DialogHeader = ({ ({ - color: theme.General.actionIconColor, - })} + uniProps={({ components }) => { + return { color: components.dialog.root.color } + }} /> ) : null} @@ -88,27 +90,28 @@ export const DialogHeader = ({ ) } -const styles = StyleSheet.create(({ theme, spacing, typography, border }) => ({ +const styles = StyleSheet.create(({ components, semantic }) => ({ text: { flex: 1 }, header: { flexDirection: 'row', - gap: spacing.Gap['gap-4'], + gap: components.dialog.header.gap, alignItems: 'center', - paddingBottom: theme.Overlay.Dialog.Header.dialogHeaderPaddingTopBottom, - padding: theme.Overlay.Dialog.Header.dialogHeaderPaddingLeftRight, + paddingTop: components.dialog.header.paddingTop, + paddingBottom: components.dialog.header.paddingBottom, + paddingHorizontal: components.dialog.header.paddingLeft, }, closeTouchable: { padding: 8 }, separator: { - height: border.Width.border, - backgroundColor: theme.Overlay.Overlay.overlayContentBorderColor, + height: semantic.dimension.borderWidth[100], + backgroundColor: components.dialog.root.borderColor, }, closeIcon: { - width: typography.Size['text-base'], - height: typography.Size['text-base'], + width: semantic.dimension.size[450], + height: semantic.dimension.size[450], }, severityIcon: { - width: typography.Size['text-2xl'], - height: typography.Size['text-2xl'], + width: semantic.dimension.size[700], + height: semantic.dimension.size[700], }, })) diff --git a/src/components/Dialog/__tests__/__snapshots__/Dialog.test.tsx.snap b/src/components/Dialog/__tests__/__snapshots__/Dialog.test.tsx.snap index 77efd620..8fd76ec3 100644 --- a/src/components/Dialog/__tests__/__snapshots__/Dialog.test.tsx.snap +++ b/src/components/Dialog/__tests__/__snapshots__/Dialog.test.tsx.snap @@ -128,7 +128,7 @@ exports[`Dialog component tests basic dialog with title, body and footer 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#e2e2e4", - "borderRadius": 14, + "borderRadius": 1600, }, { "maxHeight": 1234, @@ -143,8 +143,7 @@ exports[`Dialog component tests basic dialog with title, body and footer 1`] = ` @@ -155,8 +154,9 @@ exports[`Dialog component tests basic dialog with title, body and footer 1`] = ` diff --git a/src/components/Dialog/__tests__/__snapshots__/DialogHeader.test.tsx.snap b/src/components/Dialog/__tests__/__snapshots__/DialogHeader.test.tsx.snap index 5bc35562..92567dca 100644 --- a/src/components/Dialog/__tests__/__snapshots__/DialogHeader.test.tsx.snap +++ b/src/components/Dialog/__tests__/__snapshots__/DialogHeader.test.tsx.snap @@ -7,23 +7,24 @@ exports[`DialogHeader {"onClose": [Function mockConstructor], "severity": "dange { "alignItems": "center", "flexDirection": "row", - "gap": 14, - "padding": 21, + "gap": 8, "paddingBottom": 14, + "paddingHorizontal": 24, + "paddingTop": 24, } } > @@ -1526,14 +1532,14 @@ exports[`DialogHeader {"onClose": [Function mockConstructor], "severity": undefi style={ [ { - "color": "#181a1f", + "color": "#2b2e33", "fontFamily": "TT Fellows", "fontWeight": 700, "includeFontPadding": false, "verticalAlign": "middle", }, { - "fontSize": 15.75, + "fontSize": 18, }, { "flex": 1, @@ -1582,15 +1588,15 @@ exports[`DialogHeader {"onClose": [Function mockConstructor], "severity": undefi > @@ -2526,14 +2538,14 @@ exports[`DialogHeader {"onClose": undefined, "severity": undefined, "title": "Di style={ [ { - "color": "#181a1f", + "color": "#2b2e33", "fontFamily": "TT Fellows", "fontWeight": 700, "includeFontPadding": false, "verticalAlign": "middle", }, { - "fontSize": 15.75, + "fontSize": 18, }, { "flex": 1, From 404062443e3c7873cca12002807855f1f9ce7184 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:44 +0300 Subject: [PATCH 22/40] =?UTF-8?q?feat(Divider):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Divider/Divider.tsx | 32 +++++----- .../__snapshots__/Divider.test.tsx.snap | 64 +++++++++---------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/components/Divider/Divider.tsx b/src/components/Divider/Divider.tsx index f12c2367..2cf5964a 100644 --- a/src/components/Divider/Divider.tsx +++ b/src/components/Divider/Divider.tsx @@ -111,9 +111,9 @@ export const Divider = memo( ({ - color: theme.General.textSecondaryColor, - })} + uniProps={({ components }) => { + return { color: components.divider.content.color } + }} /> ) : null} {text ? ( @@ -133,15 +133,15 @@ export const Divider = memo( } ) -const styles = StyleSheet.create(({ spacing, theme, sizing, typography }) => ({ +const styles = StyleSheet.create(({ components, semantic }) => ({ container: { - minHeight: sizing.Height['h-2'], + minHeight: semantic.dimension.size[800], flexDirection: 'row', justifyContent: 'center', alignItems: 'center', }, containerVertical: { - minWidth: sizing.Width['w-2'], + minWidth: semantic.dimension.size[800], flexDirection: 'column', flexGrow: 1, alignSelf: 'flex-start', @@ -150,7 +150,7 @@ const styles = StyleSheet.create(({ spacing, theme, sizing, typography }) => ({ containerColumnReverse: { flexDirection: 'column-reverse' }, lineContainer: { flexGrow: 1, - flexBasis: spacing.Gap['gap-4'], + flexBasis: semantic.dimension.space[400], width: 1, height: 1, overflow: 'hidden', @@ -159,25 +159,25 @@ const styles = StyleSheet.create(({ spacing, theme, sizing, typography }) => ({ line: { width: '100%', height: '100%', - borderWidth: 1, - borderColor: theme.General.dividerColor, + borderWidth: semantic.dimension.borderWidth[100], + borderColor: components.divider.root.borderColor, }, lineDash: { borderStyle: 'dashed' }, content: { flexShrink: 1, flexDirection: 'row', alignItems: 'center', - paddingHorizontal: theme.General.inlineSpacing, - gap: spacing.Gap['gap-2'], - backgroundColor: theme.Panel.Panel.Body.panelContentBg, + paddingHorizontal: semantic.dimension.space[200], + gap: components.divider.extend.content.gap, + backgroundColor: components.divider.content.background, }, contentVertical: { - paddingHorizontal: 0, - paddingVertical: theme.General.inlineSpacing, + paddingHorizontal: semantic.dimension.space.none, + paddingVertical: semantic.dimension.space[200], }, icon: { - width: typography.Size['text-base'], - height: typography.Size['text-base'], + width: components.divider.extend.iconSize, + height: components.divider.extend.iconSize, }, text: { flexShrink: 1 }, })) diff --git a/src/components/Divider/__tests__/__snapshots__/Divider.test.tsx.snap b/src/components/Divider/__tests__/__snapshots__/Divider.test.tsx.snap index 59628323..a632247d 100644 --- a/src/components/Divider/__tests__/__snapshots__/Divider.test.tsx.snap +++ b/src/components/Divider/__tests__/__snapshots__/Divider.test.tsx.snap @@ -102,11 +102,11 @@ exports[`Divider {"Icon": [Object], "align": "end", "layout": "horizontal", "sho [ { "alignItems": "center", - "backgroundColor": "#f0f0f1", + "backgroundColor": "#ffffff", "flexDirection": "row", "flexShrink": 1, - "gap": 7, - "paddingHorizontal": 7, + "gap": 8, + "paddingHorizontal": 8, }, false, ] @@ -117,9 +117,9 @@ exports[`Divider {"Icon": [Object], "align": "end", "layout": "horizontal", "sho [ { "fontFamily": "Noto Sans", - "fontSize": 10.5, + "fontSize": 12, "fontWeight": 700, - "lineHeight": 15, + "lineHeight": 18, "textTransform": "uppercase", }, { @@ -273,30 +273,30 @@ exports[`Divider {"Icon": [Object], "align": "end", "layout": "vertical", "text" [ { "alignItems": "center", - "backgroundColor": "#f0f0f1", + "backgroundColor": "#ffffff", "flexDirection": "row", "flexShrink": 1, - "gap": 7, - "paddingHorizontal": 7, + "gap": 8, + "paddingHorizontal": 8, }, { "paddingHorizontal": 0, - "paddingVertical": 7, + "paddingVertical": 8, }, ] } > Date: Tue, 4 Aug 2026 17:05:44 +0300 Subject: [PATCH 23/40] =?UTF-8?q?feat(InputSwitch):=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__snapshots__/InputSwitch.test.tsx.snap | 736 +++++++++--------- .../InputSwitch/styles/useHandleStyles.ts | 26 +- .../InputSwitch/styles/useSliderStyles.ts | 38 +- 3 files changed, 399 insertions(+), 401 deletions(-) diff --git a/src/components/Input/InputSwitch/__tests__/__snapshots__/InputSwitch.test.tsx.snap b/src/components/Input/InputSwitch/__tests__/__snapshots__/InputSwitch.test.tsx.snap index 43c39801..9b89404e 100644 --- a/src/components/Input/InputSwitch/__tests__/__snapshots__/InputSwitch.test.tsx.snap +++ b/src/components/Input/InputSwitch/__tests__/__snapshots__/InputSwitch.test.tsx.snap @@ -33,8 +33,8 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -52,25 +52,25 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - } jestInlineStyle={ { - "backgroundColor": ""#85888e"", + "backgroundColor": ""#a2a5a9"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#85888e", + "backgroundColor": "#a2a5a9", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -90,24 +90,24 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - jestInlineStyle={ { "backgroundColor": ""#ffffff"", - "borderRadius": 100, - "height": 14, - "left": "2.5", + "borderRadius": 1600, + "height": 16, + "left": "3", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { "backgroundColor": "#ffffff", - "borderRadius": 100, - "height": 14, - "left": 2.5, + "borderRadius": 1600, + "height": 16, + "left": 3, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -149,8 +149,8 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -168,25 +168,25 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - } jestInlineStyle={ { - "backgroundColor": ""#85888e"", + "backgroundColor": ""#a2a5a9"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#85888e", + "backgroundColor": "#a2a5a9", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -206,24 +206,24 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - jestInlineStyle={ { "backgroundColor": ""#ffffff"", - "borderRadius": 100, - "height": 14, - "left": "2.5", + "borderRadius": 1600, + "height": 16, + "left": "3", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { "backgroundColor": "#ffffff", - "borderRadius": 100, - "height": 14, - "left": 2.5, + "borderRadius": 1600, + "height": 16, + "left": 3, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -265,8 +265,8 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -284,25 +284,25 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - } jestInlineStyle={ { - "backgroundColor": ""#DFDFDF"", + "backgroundColor": ""#e2e2e4"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#DFDFDF", + "backgroundColor": "#e2e2e4", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -322,24 +322,24 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - jestInlineStyle={ { "backgroundColor": ""#ffffff"", - "borderRadius": 100, - "height": 14, - "left": "2.5", + "borderRadius": 1600, + "height": 16, + "left": "3", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { "backgroundColor": "#ffffff", - "borderRadius": 100, - "height": 14, - "left": 2.5, + "borderRadius": 1600, + "height": 16, + "left": 3, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -381,8 +381,8 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -400,25 +400,25 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - } jestInlineStyle={ { - "backgroundColor": ""#DFDFDF"", + "backgroundColor": ""#e2e2e4"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#DFDFDF", + "backgroundColor": "#e2e2e4", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -438,24 +438,24 @@ exports[`InputSwitch component tests checked - false, danger - false, disabled - jestInlineStyle={ { "backgroundColor": ""#ffffff"", - "borderRadius": 100, - "height": 14, - "left": "2.5", + "borderRadius": 1600, + "height": 16, + "left": "3", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { "backgroundColor": "#ffffff", - "borderRadius": 100, - "height": 14, - "left": 2.5, + "borderRadius": 1600, + "height": 16, + "left": 3, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -497,8 +497,8 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -516,25 +516,25 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - } jestInlineStyle={ { - "backgroundColor": ""#85888e"", - "borderColor": ""#db3424"", - "borderRadius": 100, + "backgroundColor": ""#a2a5a9"", + "borderColor": ""#f47f77"", + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#85888e", - "borderColor": "#db3424", - "borderRadius": 100, + "backgroundColor": "#a2a5a9", + "borderColor": "#f47f77", + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -554,24 +554,24 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - jestInlineStyle={ { "backgroundColor": ""#ffffff"", - "borderRadius": 100, - "height": 14, - "left": "2.5", + "borderRadius": 1600, + "height": 16, + "left": "3", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { "backgroundColor": "#ffffff", - "borderRadius": 100, - "height": 14, - "left": 2.5, + "borderRadius": 1600, + "height": 16, + "left": 3, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -613,8 +613,8 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -632,25 +632,25 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - } jestInlineStyle={ { - "backgroundColor": ""#85888e"", - "borderColor": ""#db3424"", - "borderRadius": 100, + "backgroundColor": ""#a2a5a9"", + "borderColor": ""#f47f77"", + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#85888e", - "borderColor": "#db3424", - "borderRadius": 100, + "backgroundColor": "#a2a5a9", + "borderColor": "#f47f77", + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -670,24 +670,24 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - jestInlineStyle={ { "backgroundColor": ""#ffffff"", - "borderRadius": 100, - "height": 14, - "left": "2.5", + "borderRadius": 1600, + "height": 16, + "left": "3", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { "backgroundColor": "#ffffff", - "borderRadius": 100, - "height": 14, - "left": 2.5, + "borderRadius": 1600, + "height": 16, + "left": 3, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -729,8 +729,8 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -748,25 +748,25 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - } jestInlineStyle={ { - "backgroundColor": ""#DFDFDF"", + "backgroundColor": ""#e2e2e4"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#DFDFDF", + "backgroundColor": "#e2e2e4", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -786,24 +786,24 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - jestInlineStyle={ { "backgroundColor": ""#ffffff"", - "borderRadius": 100, - "height": 14, - "left": "2.5", + "borderRadius": 1600, + "height": 16, + "left": "3", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { "backgroundColor": "#ffffff", - "borderRadius": 100, - "height": 14, - "left": 2.5, + "borderRadius": 1600, + "height": 16, + "left": 3, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -845,8 +845,8 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -864,25 +864,25 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - } jestInlineStyle={ { - "backgroundColor": ""#DFDFDF"", + "backgroundColor": ""#e2e2e4"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#DFDFDF", + "backgroundColor": "#e2e2e4", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -902,24 +902,24 @@ exports[`InputSwitch component tests checked - false, danger - true, disabled - jestInlineStyle={ { "backgroundColor": ""#ffffff"", - "borderRadius": 100, - "height": 14, - "left": "2.5", + "borderRadius": 1600, + "height": 16, + "left": "3", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { "backgroundColor": "#ffffff", - "borderRadius": 100, - "height": 14, - "left": 2.5, + "borderRadius": 1600, + "height": 16, + "left": 3, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -961,8 +961,8 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -982,11 +982,11 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - { "backgroundColor": ""#2b2e33"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ @@ -994,11 +994,11 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - { "backgroundColor": "#2b2e33", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -1017,25 +1017,25 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - } jestInlineStyle={ { - "backgroundColor": ""#fafafa"", - "borderRadius": 100, - "height": 14, - "left": "16.5", + "backgroundColor": ""#ffffff"", + "borderRadius": 1600, + "height": 16, + "left": "19", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { - "backgroundColor": "#fafafa", - "borderRadius": 100, - "height": 14, - "left": 16.5, + "backgroundColor": "#ffffff", + "borderRadius": 1600, + "height": 16, + "left": 19, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -1077,8 +1077,8 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -1098,11 +1098,11 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - { "backgroundColor": ""#2b2e33"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ @@ -1110,11 +1110,11 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - { "backgroundColor": "#2b2e33", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -1133,25 +1133,25 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - } jestInlineStyle={ { - "backgroundColor": ""#fafafa"", - "borderRadius": 100, - "height": 14, - "left": "16.5", + "backgroundColor": ""#ffffff"", + "borderRadius": 1600, + "height": 16, + "left": "19", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { - "backgroundColor": "#fafafa", - "borderRadius": 100, - "height": 14, - "left": 16.5, + "backgroundColor": "#ffffff", + "borderRadius": 1600, + "height": 16, + "left": 19, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -1193,8 +1193,8 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -1212,25 +1212,25 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - } jestInlineStyle={ { - "backgroundColor": ""#9A9A9A"", + "backgroundColor": ""#e2e2e4"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#9A9A9A", + "backgroundColor": "#e2e2e4", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -1249,25 +1249,25 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - } jestInlineStyle={ { - "backgroundColor": ""#fafafa"", - "borderRadius": 100, - "height": 14, - "left": "16.5", + "backgroundColor": ""#ffffff"", + "borderRadius": 1600, + "height": 16, + "left": "19", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { - "backgroundColor": "#fafafa", - "borderRadius": 100, - "height": 14, - "left": 16.5, + "backgroundColor": "#ffffff", + "borderRadius": 1600, + "height": 16, + "left": 19, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -1309,8 +1309,8 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -1328,25 +1328,25 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - } jestInlineStyle={ { - "backgroundColor": ""#9A9A9A"", + "backgroundColor": ""#e2e2e4"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#9A9A9A", + "backgroundColor": "#e2e2e4", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -1365,25 +1365,25 @@ exports[`InputSwitch component tests checked - true, danger - false, disabled - } jestInlineStyle={ { - "backgroundColor": ""#fafafa"", - "borderRadius": 100, - "height": 14, - "left": "16.5", + "backgroundColor": ""#ffffff"", + "borderRadius": 1600, + "height": 16, + "left": "19", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { - "backgroundColor": "#fafafa", - "borderRadius": 100, - "height": 14, - "left": 16.5, + "backgroundColor": "#ffffff", + "borderRadius": 1600, + "height": 16, + "left": 19, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -1425,8 +1425,8 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - f onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -1445,24 +1445,24 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - f jestInlineStyle={ { "backgroundColor": ""#2b2e33"", - "borderColor": ""#db3424"", - "borderRadius": 100, + "borderColor": ""#f47f77"", + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { "backgroundColor": "#2b2e33", - "borderColor": "#db3424", - "borderRadius": 100, + "borderColor": "#f47f77", + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -1481,25 +1481,25 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - f } jestInlineStyle={ { - "backgroundColor": ""#fafafa"", - "borderRadius": 100, - "height": 14, - "left": "16.5", + "backgroundColor": ""#ffffff"", + "borderRadius": 1600, + "height": 16, + "left": "19", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { - "backgroundColor": "#fafafa", - "borderRadius": 100, - "height": 14, - "left": 16.5, + "backgroundColor": "#ffffff", + "borderRadius": 1600, + "height": 16, + "left": 19, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -1541,8 +1541,8 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - f onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -1561,24 +1561,24 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - f jestInlineStyle={ { "backgroundColor": ""#2b2e33"", - "borderColor": ""#db3424"", - "borderRadius": 100, + "borderColor": ""#f47f77"", + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { "backgroundColor": "#2b2e33", - "borderColor": "#db3424", - "borderRadius": 100, + "borderColor": "#f47f77", + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -1597,25 +1597,25 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - f } jestInlineStyle={ { - "backgroundColor": ""#fafafa"", - "borderRadius": 100, - "height": 14, - "left": "16.5", + "backgroundColor": ""#ffffff"", + "borderRadius": 1600, + "height": 16, + "left": "19", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { - "backgroundColor": "#fafafa", - "borderRadius": 100, - "height": 14, - "left": 16.5, + "backgroundColor": "#ffffff", + "borderRadius": 1600, + "height": 16, + "left": 19, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -1657,8 +1657,8 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - t onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -1676,25 +1676,25 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - t } jestInlineStyle={ { - "backgroundColor": ""#9A9A9A"", + "backgroundColor": ""#e2e2e4"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#9A9A9A", + "backgroundColor": "#e2e2e4", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -1713,25 +1713,25 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - t } jestInlineStyle={ { - "backgroundColor": ""#fafafa"", - "borderRadius": 100, - "height": 14, - "left": "16.5", + "backgroundColor": ""#ffffff"", + "borderRadius": 1600, + "height": 16, + "left": "19", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { - "backgroundColor": "#fafafa", - "borderRadius": 100, - "height": 14, - "left": 16.5, + "backgroundColor": "#ffffff", + "borderRadius": 1600, + "height": 16, + "left": 19, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } @@ -1773,8 +1773,8 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - t onStartShouldSetResponder={[Function]} style={ { - "height": 21, - "width": 35, + "height": 24, + "width": 40, } } > @@ -1792,25 +1792,25 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - t } jestInlineStyle={ { - "backgroundColor": ""#9A9A9A"", + "backgroundColor": ""#e2e2e4"", "borderColor": ""transparent"", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, } } style={ [ { - "backgroundColor": "#9A9A9A", + "backgroundColor": "#e2e2e4", "borderColor": "transparent", - "borderRadius": 100, + "borderRadius": 1600, "borderWidth": 1, - "height": 21, - "padding": 3.5, - "width": 35, + "height": 24, + "padding": 4, + "width": 40, }, ] } @@ -1829,25 +1829,25 @@ exports[`InputSwitch component tests checked - true, danger - true, disabled - t } jestInlineStyle={ { - "backgroundColor": ""#fafafa"", - "borderRadius": 100, - "height": 14, - "left": "16.5", + "backgroundColor": ""#ffffff"", + "borderRadius": 1600, + "height": 16, + "left": "19", "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, } } style={ [ { - "backgroundColor": "#fafafa", - "borderRadius": 100, - "height": 14, - "left": 16.5, + "backgroundColor": "#ffffff", + "borderRadius": 1600, + "height": 16, + "left": 19, "position": "absolute", - "top": 2.5, - "width": 14, + "top": 3, + "width": 16, }, ] } diff --git a/src/components/Input/InputSwitch/styles/useHandleStyles.ts b/src/components/Input/InputSwitch/styles/useHandleStyles.ts index 1349cbc2..93287f19 100644 --- a/src/components/Input/InputSwitch/styles/useHandleStyles.ts +++ b/src/components/Input/InputSwitch/styles/useHandleStyles.ts @@ -48,27 +48,27 @@ export const useHandleStyles = (checked: boolean) => { return { handleStyle } } -const handleStyles = StyleSheet.create(({ theme, border }) => ({ +const handleStyles = StyleSheet.create(({ components: { toggleswitch } }) => ({ handle: { - height: theme.Form.inputSwitch.inputSwitchHandleHeight, - width: theme.Form.inputSwitch.inputSwitchHandleWidth, - borderRadius: border.Radius['rounded-full'], - backgroundColor: theme.Form.inputSwitch.inputSwitchHandleOffBg, + height: toggleswitch.handle.size, + width: toggleswitch.handle.size, + borderRadius: toggleswitch.handle.borderRadius, + backgroundColor: toggleswitch.colorScheme.handle.background, position: 'absolute', - top: theme.Form.inputSwitch.inputSwitchSliderPadding - border.Width.border, + top: toggleswitch.root.gap - toggleswitch.root.borderWidth, }, handleOff: { - backgroundColor: theme.Form.inputSwitch.inputSwitchHandleOffBg, - left: theme.Form.inputSwitch.inputSwitchSliderPadding - border.Width.border, + backgroundColor: toggleswitch.colorScheme.handle.background, + left: toggleswitch.root.gap - toggleswitch.root.borderWidth, }, handleOn: { - backgroundColor: theme.Form.inputSwitch.inputSwitchHandleOnBg, + backgroundColor: toggleswitch.colorScheme.handle.checkedBackground, left: - theme.Form.inputSwitch.inputSwitchWidth - - theme.Form.inputSwitch.inputSwitchSliderPadding - - theme.Form.inputSwitch.inputSwitchHandleWidth - - 1, + toggleswitch.root.width - + toggleswitch.root.gap - + toggleswitch.handle.size - + toggleswitch.root.borderWidth, }, })) diff --git a/src/components/Input/InputSwitch/styles/useSliderStyles.ts b/src/components/Input/InputSwitch/styles/useSliderStyles.ts index 8739c29b..4741e796 100644 --- a/src/components/Input/InputSwitch/styles/useSliderStyles.ts +++ b/src/components/Input/InputSwitch/styles/useSliderStyles.ts @@ -102,45 +102,43 @@ export const useSliderStyles = ( } } -const switchStyles = StyleSheet.create(({ theme, border }) => ({ +const switchStyles = StyleSheet.create(({ components: { toggleswitch } }) => ({ container: { - height: theme.Form.inputSwitch.inputSwitchHeight, - width: theme.Form.inputSwitch.inputSwitchWidth, + height: toggleswitch.root.height, + width: toggleswitch.root.width, }, slider: { - padding: theme.Form.inputSwitch.inputSwitchSliderPadding, - height: theme.Form.inputSwitch.inputSwitchHeight, - width: theme.Form.inputSwitch.inputSwitchWidth, - borderRadius: border.Radius['rounded-full'], - borderWidth: border.Width.border, + padding: toggleswitch.root.gap, + height: toggleswitch.root.height, + width: toggleswitch.root.width, + borderRadius: toggleswitch.root.borderRadius, + borderWidth: toggleswitch.root.borderWidth, }, - sliderOff: { backgroundColor: theme.Form.inputSwitch.inputSwitchSliderOffBg }, + sliderOff: { backgroundColor: toggleswitch.colorScheme.root.background }, - sliderOn: { backgroundColor: theme.Form.inputSwitch.inputSwitchSliderOnBg }, + sliderOn: { + backgroundColor: toggleswitch.colorScheme.root.checkedBackground, + }, sliderPressed: { - backgroundColor: theme.Form.inputSwitch.inputSwitchSliderOffHoverBg, + backgroundColor: toggleswitch.colorScheme.root.hoverBackground, }, sliderOnPressed: { - backgroundColor: theme.Form.inputSwitch.inputSwitchSliderOnHoverBg, + backgroundColor: toggleswitch.colorScheme.root.checkedHoverBackground, }, sliderDisabled: { - backgroundColor: theme.custom.inputSwitch.inputSwitchSliderOffDisabledBg, + backgroundColor: toggleswitch.colorScheme.root.disabledBackground, }, sliderOnDisabled: { - backgroundColor: theme.custom.inputSwitch.inputSwitchSliderOnDisabledBg, + backgroundColor: toggleswitch.colorScheme.root.disabledBackground, }, - sliderNoDanger: { borderColor: 'transparent' }, + sliderNoDanger: { borderColor: toggleswitch.root.borderColor }, - sliderDanger: { - borderColor: theme.Form.InputText.inputErrorBorderColor, - outlineColor: theme.General.focusOutlineErrorColor, - outlineWidth: Math.round(theme.General.focusShadowWidth), - }, + sliderDanger: { borderColor: toggleswitch.root.invalidBorderColor }, })) From 55940f9fd2bf7047888c7d1bfa98a3ba0330f84c Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:45 +0300 Subject: [PATCH 24/40] =?UTF-8?q?feat(Input):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Input/InputGroupAddon.tsx | 33 +- src/components/Input/InputOtp/InputOtp.tsx | 4 +- .../Input/InputOtp/InputOtpItem.tsx | 45 +- .../__snapshots__/InputOtp.test.tsx.snap | 4848 ++++++++--------- .../Input/InputTextBase/InputTextBase.tsx | 14 +- .../Input/InputTextBase/useInputStyles.ts | 91 +- .../Input/__tests__/InputTextBase.test.tsx | 12 +- .../InputGroupAddon.test.tsx.snap | 38 +- .../__snapshots__/InputTextBase.test.tsx.snap | 6 +- 9 files changed, 2378 insertions(+), 2713 deletions(-) diff --git a/src/components/Input/InputGroupAddon.tsx b/src/components/Input/InputGroupAddon.tsx index dd11ac51..e16c1b8e 100644 --- a/src/components/Input/InputGroupAddon.tsx +++ b/src/components/Input/InputGroupAddon.tsx @@ -41,9 +41,9 @@ export const InputGroupAddon = memo( ({ - color: theme.Form.InputGroup.inputGroupTextColor, - })} + uniProps={({ components }) => { + return { color: components.inputgroup.colorScheme.addon.color } + }} /> )} @@ -51,15 +51,14 @@ export const InputGroupAddon = memo( } ) -const styles = StyleSheet.create(({ theme, typography, fonts }) => ({ +const styles = StyleSheet.create(({ components, semantic, fonts }) => ({ container: { - paddingVertical: theme.Form.InputText.inputPaddingTopBottom, - paddingHorizontal: theme.Form.InputText.inputPaddingLeftRight, + padding: components.inputgroup.addon.padding, justifyContent: 'center', - borderRadius: theme.General.borderRadiusXL, - borderWidth: 1, - borderColor: theme.Form.InputText.inputBorderColor, - backgroundColor: theme.Form.InputGroup.inputGroupBg, + borderRadius: components.inputgroup.addon.borderRadius, + borderWidth: components.inputgroup.extend.borderWidth, + borderColor: components.inputgroup.colorScheme.addon.borderColor, + backgroundColor: components.inputgroup.colorScheme.addon.background, }, left: { borderRightWidth: 0, @@ -73,18 +72,18 @@ const styles = StyleSheet.create(({ theme, typography, fonts }) => ({ borderBottomLeftRadius: 0, }, disabled: { - opacity: 0.6, - backgroundColor: theme.Button.Disabled.disabledButtonBg, + opacity: semantic.effects.opacity[60], + backgroundColor: semantic.colorScheme.color.bg.neutral.weak.disabled, }, text: { - fontSize: typography.Size['text-base'], - color: theme.Form.InputGroup.inputGroupTextColor, + fontSize: fonts.fontSize[300], + color: components.inputgroup.colorScheme.addon.color, includeFontPadding: false, verticalAlign: 'middle', - fontFamily: fonts.secondary, + fontFamily: fonts.fontFamily.base, }, icon: { - width: typography.Size['text-base'], - height: typography.Size['text-base'], + width: components.inputgroup.extend.iconSize, + height: components.inputgroup.extend.iconSize, }, })) diff --git a/src/components/Input/InputOtp/InputOtp.tsx b/src/components/Input/InputOtp/InputOtp.tsx index a43155c3..3923463b 100644 --- a/src/components/Input/InputOtp/InputOtp.tsx +++ b/src/components/Input/InputOtp/InputOtp.tsx @@ -155,10 +155,10 @@ export const InputOtp = memo( } ) -const styles = StyleSheet.create(({ spacing }) => ({ +const styles = StyleSheet.create(({ semantic }) => ({ container: {}, - content: { flexDirection: 'row', gap: spacing.Gap['gap-2'] }, + content: { flexDirection: 'row', gap: semantic.dimension.space[200] }, input: { position: 'absolute', width: 1, height: 1, opacity: 0 }, })) diff --git a/src/components/Input/InputOtp/InputOtpItem.tsx b/src/components/Input/InputOtp/InputOtpItem.tsx index 0e685314..cb719a5c 100644 --- a/src/components/Input/InputOtp/InputOtpItem.tsx +++ b/src/components/Input/InputOtp/InputOtpItem.tsx @@ -5,6 +5,8 @@ import Animated, { type AnimatedStyle } from 'react-native-reanimated' import { StyleSheet } from 'react-native-unistyles' +import effects from '../../../theme/tokens/semantic/effects.json' + export interface InputOtpItemProps extends Pick { value?: string error: boolean @@ -15,8 +17,14 @@ export interface InputOtpItemProps extends Pick { const CURSOR_ANIMATION_DURATION = 500 +// Анимация не может жить в StyleSheet.create: Animated.Text из reanimated не +// принимает Unistyles-стиль. Шкала непрозрачности одинакова в обеих темах, +// поэтому токены берутся из сгенерированного файла напрямую. const cursorAnimationStyle = { - animationName: { from: { opacity: 1 }, to: { opacity: 0.2 } }, + animationName: { + from: { opacity: effects.opacity[100] }, + to: { opacity: effects.opacity[20] }, + }, animationDuration: CURSOR_ANIMATION_DURATION, animationDirection: 'alternate', animationIterationCount: 'infinite', @@ -60,14 +68,16 @@ export const InputOtpItem = memo( } ) -const styles = StyleSheet.create(({ theme, border, fonts, typography }) => ({ +// Рамка, цвет и отступы намеренно берутся у inputtext: поле OTP должно выглядеть +// как обычное поле ввода. Собственные токены inputotp описывают только отличия — +// тот же приём, что в пресете PrimeUIX lara, где inputotp задаёт лишь gap и width. +const styles = StyleSheet.create(({ components, semantic, fonts }) => ({ container: { - minHeight: theme.Button.Common.buttonHeight, - minWidth: theme.Button.Common.buttonHeight, - paddingHorizontal: theme.Form.InputText.inputPaddingLeftRight, - paddingVertical: theme.Form.InputText.inputPaddingTopBottom, - borderBottomWidth: border.Width.border, - borderColor: theme.Form.InputText.inputBorderColor, + minHeight: components.inputotp.extend.height, + minWidth: components.inputotp.extend.height, + paddingHorizontal: components.inputtext.root.paddingX, + borderBottomWidth: components.inputotp.extend.borderWidth, + borderColor: components.inputtext.root.borderColor, alignItems: 'center', justifyContent: 'center', }, @@ -75,18 +85,21 @@ const styles = StyleSheet.create(({ theme, border, fonts, typography }) => ({ textRow: { flexDirection: 'row', alignItems: 'center' }, text: { - fontSize: typography.Size['text-2xl'], - fontFamily: fonts.primary, - fontWeight: '400', - color: theme.Form.InputText.inputTextColor, + fontSize: fonts.fontSize[600], + fontFamily: fonts.fontFamily.heading, + fontWeight: fonts.fontWeight.regular, + color: components.inputtext.root.color, includeFontPadding: false, }, - pressed: { borderColor: theme.Form.InputText.inputHoverBorderColor }, + pressed: { borderColor: components.inputtext.root.hoverBorderColor }, - error: { borderColor: theme.Form.InputText.inputErrorBorderColor }, + error: { borderColor: components.inputtext.root.invalidBorderColor }, - disabled: { mixBlendMode: 'luminosity', opacity: 0.6 }, + disabled: { + mixBlendMode: 'luminosity', + opacity: semantic.effects.opacity[60], + }, - cursor: { color: theme.Form.InputText.inputTextColor, marginBottom: 3 }, + cursor: { color: components.inputtext.root.color, marginBottom: 3 }, })) diff --git a/src/components/Input/InputOtp/__tests__/__snapshots__/InputOtp.test.tsx.snap b/src/components/Input/InputOtp/__tests__/__snapshots__/InputOtp.test.tsx.snap index c48a2c5d..e07be575 100644 --- a/src/components/Input/InputOtp/__tests__/__snapshots__/InputOtp.test.tsx.snap +++ b/src/components/Input/InputOtp/__tests__/__snapshots__/InputOtp.test.tsx.snap @@ -37,7 +37,7 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p style={ { "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -49,10 +49,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -63,10 +62,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p @@ -176,10 +174,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -190,10 +187,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p @@ -305,10 +301,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -319,10 +314,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p @@ -436,10 +430,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -452,10 +445,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p @@ -567,10 +559,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -583,10 +574,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p @@ -700,10 +690,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -716,10 +705,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p @@ -835,10 +823,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -852,10 +839,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr @@ -968,10 +954,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -985,10 +970,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr @@ -1103,10 +1087,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -1120,10 +1103,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr @@ -1240,10 +1222,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -1259,10 +1240,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr @@ -1377,10 +1357,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -1396,10 +1375,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr @@ -1516,10 +1494,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -1535,10 +1512,10 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr @@ -1657,13 +1633,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, false, @@ -1673,10 +1648,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr @@ -1788,13 +1762,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, false, @@ -1804,10 +1777,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr @@ -1921,13 +1893,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, false, @@ -1937,10 +1908,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr @@ -2056,13 +2026,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -2074,10 +2043,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr @@ -2191,13 +2159,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -2209,10 +2176,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr @@ -2328,13 +2294,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -2346,10 +2311,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr @@ -2467,13 +2431,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, { @@ -2486,10 +2449,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre @@ -2604,13 +2566,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, { @@ -2623,10 +2584,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre @@ -2743,13 +2703,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, { @@ -2762,10 +2721,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre @@ -2884,13 +2842,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -2905,10 +2862,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre @@ -3025,13 +2981,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -3046,10 +3001,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre @@ -3168,13 +3122,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -3189,10 +3142,10 @@ exports[`InputOtp component tests length - 2, error - true, disabled - true, pre @@ -3313,10 +3265,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -3327,10 +3278,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p @@ -3504,10 +3452,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -3518,10 +3465,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p @@ -3697,10 +3641,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -3711,10 +3654,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p @@ -3892,10 +3832,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -3908,10 +3847,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p @@ -4091,10 +4027,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -4107,10 +4042,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p @@ -4292,10 +4224,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -4308,10 +4239,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p @@ -4495,10 +4423,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -4512,10 +4439,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr @@ -4698,10 +4622,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -4715,10 +4638,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr @@ -4903,10 +4823,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -4920,10 +4839,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr @@ -5110,10 +5026,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -5129,10 +5044,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr @@ -5321,10 +5233,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -5340,10 +5251,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr @@ -5534,10 +5442,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -5553,10 +5460,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr @@ -5749,13 +5653,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, false, @@ -5765,10 +5668,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr @@ -5948,13 +5848,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, false, @@ -5964,10 +5863,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr @@ -6149,13 +6045,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, false, @@ -6165,10 +6060,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr @@ -6352,13 +6244,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -6370,10 +6261,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr @@ -6559,13 +6447,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -6577,10 +6464,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr @@ -6768,13 +6652,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -6786,10 +6669,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - false, pr @@ -6979,13 +6859,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, { @@ -6998,10 +6877,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre @@ -7190,13 +7066,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, { @@ -7209,10 +7084,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre @@ -7403,13 +7275,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, { @@ -7422,10 +7293,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre @@ -7618,13 +7486,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -7639,10 +7506,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre @@ -7837,13 +7701,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -7858,10 +7721,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre @@ -8058,13 +7918,12 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -8079,10 +7938,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre @@ -8281,10 +8137,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -8295,10 +8150,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p @@ -8600,10 +8448,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -8614,10 +8461,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p @@ -8921,10 +8761,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -8935,10 +8774,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p @@ -9244,10 +9076,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -9260,10 +9091,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p @@ -9579,10 +9403,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -9595,10 +9418,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p @@ -9916,10 +9732,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -9932,10 +9747,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - false, p @@ -10255,10 +10063,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -10272,10 +10079,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr @@ -10598,10 +10398,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -10615,10 +10414,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr @@ -10943,10 +10735,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, false, @@ -10960,10 +10751,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr @@ -11290,10 +11074,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -11309,10 +11092,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr @@ -11649,10 +11425,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -11668,10 +11443,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr @@ -12010,10 +11778,9 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, false, { @@ -12029,10 +11796,10 @@ exports[`InputOtp component tests length - 8, error - false, disabled - true, pr @@ -12373,13 +12133,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, false, @@ -12389,10 +12148,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr @@ -12708,13 +12460,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, false, @@ -12724,10 +12475,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr @@ -13045,13 +12789,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, false, @@ -13061,10 +12804,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr @@ -13384,13 +13120,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -13402,10 +13137,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr @@ -13735,13 +13463,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -13753,10 +13480,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr @@ -14088,13 +13808,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -14106,10 +13825,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr @@ -14443,13 +14155,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, { @@ -14462,10 +14173,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre @@ -14802,13 +14506,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, { @@ -14821,10 +14524,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre @@ -15163,13 +14859,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, false, { @@ -15182,10 +14877,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre @@ -15526,13 +15214,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -15547,10 +15234,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre @@ -15901,13 +15581,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -15922,10 +15601,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre @@ -16278,13 +15950,12 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre "borderBottomWidth": 1, "borderColor": "#cecfd2", "justifyContent": "center", - "minHeight": 35, - "minWidth": 35, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "minHeight": 40, + "minWidth": 40, + "paddingHorizontal": 14, }, { - "borderColor": "#db3424", + "borderColor": "#f47f77", }, { "borderColor": "#1dc831", @@ -16299,10 +15970,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - true, pre ({ - color: theme.Form.InputText.inputIconColor, -}) +const inputIconUniProps = ({ components }: SvgUniversalTheme) => { + return { color: components.inputtext.root.color } +} export const InputTextBase = memo< InputTextBaseProps & PrivateInputTextBaseProps @@ -306,7 +309,6 @@ export const InputTextBase = memo< isFocused && styles.containerFocused, containerStyle, state === 'danger' && styles.danger, - state === 'danger' && isFocused && styles.dangerFocused, disabled && styles.disabled, ]} testID={makeTestId(InputTextBaseTestId.pressableContainer)} diff --git a/src/components/Input/InputTextBase/useInputStyles.ts b/src/components/Input/InputTextBase/useInputStyles.ts index 0d751e34..75977e4b 100644 --- a/src/components/Input/InputTextBase/useInputStyles.ts +++ b/src/components/Input/InputTextBase/useInputStyles.ts @@ -18,37 +18,32 @@ export const useInputContainerMinHeight = ( return { minHeight } } -const containerMinHeight = StyleSheet.create(({ theme }) => ({ - base: { minHeight: theme.InputSize.base['min-height'] }, - large: { minHeight: theme.InputSize.large['min-height'] }, - xlarge: { minHeight: theme.InputSize.xlarge['min-height'] }, +const containerMinHeight = StyleSheet.create(({ semantic }) => ({ + base: { minHeight: semantic.dimension.size[1100] }, + large: { minHeight: semantic.dimension.size[1300] }, + xlarge: { minHeight: semantic.dimension.size[1400] }, })) export const inputStyles = StyleSheet.create( - ({ theme, border, typography, spacing, fonts }) => ({ + ({ components, semantic, fonts }) => ({ container: { flexDirection: 'row', - borderWidth: border.Width.border, - borderRadius: border.Radius['rounded-xl'], - borderColor: theme.Form.InputText.inputBorderColor, - backgroundColor: theme.Form.InputText.inputBg, + borderWidth: semantic.dimension.borderWidth[100], + borderRadius: components.inputtext.root.borderRadius, + borderColor: components.inputtext.root.borderColor, + backgroundColor: components.inputtext.root.background, }, containerFocused: { - outlineColor: theme.General.focusOutlineColor, - outlineWidth: Math.round(theme.General.focusShadowWidth), - borderColor: theme.General.focusBorderColor, + outlineColor: components.inputtext.root.focusRing.color, + outlineWidth: components.inputtext.root.focusRing.width, + borderColor: components.inputtext.root.focusBorderColor, }, - containerFloatLabel: { - minHeight: theme.Button.Common.buttonHeightXL, - maxHeight: theme.Button.Common.buttonHeightXL, - height: theme.Button.Common.buttonHeightXL, - }, - danger: { borderColor: theme.Form.InputText.inputErrorBorderColor }, - dangerFocused: { outlineColor: theme.General.focusOutlineErrorColor }, + containerFloatLabel: { minHeight: 56, maxHeight: 56, height: 56 }, + danger: { borderColor: components.inputtext.root.invalidBorderColor }, disabled: { - opacity: 0.6, - borderColor: theme.Form.InputText.inputBorderColor, - backgroundColor: theme.Button.Disabled.disabledButtonBg, + opacity: semantic.effects.opacity[60], + borderColor: components.inputtext.root.borderColor, + backgroundColor: semantic.colorScheme.color.bg.neutral.weak.disabled, }, inputContainer: { flex: 1, @@ -56,8 +51,8 @@ export const inputStyles = StyleSheet.create( justifyContent: 'center', }, input: { - padding: 0, - paddingHorizontal: theme.Form.InputText.inputPaddingLeftRight, + padding: semantic.dimension.space.none, + paddingHorizontal: components.inputtext.root.paddingX, position: 'absolute', left: 0, right: 0, @@ -67,40 +62,36 @@ export const inputStyles = StyleSheet.create( inputWithRightContent: { paddingRight: 0 }, floatLabelInput: { flex: 1, - paddingHorizontal: theme.Form.InputText.inputPaddingLeftRight, + paddingHorizontal: components.inputtext.root.paddingX, paddingTop: 26, paddingBottom: 12, - borderRadius: border.Radius['rounded-xl'], + borderRadius: semantic.dimension.borderRadius[300], overflow: 'hidden', }, inputFont: { - fontSize: typography.Size['text-base'], - color: theme.Form.InputText.inputTextColor, + fontSize: fonts.fontSize[300], + color: components.inputtext.root.color, includeFontPadding: false, - fontFamily: fonts.secondary, + fontFamily: fonts.fontFamily.base, verticalAlign: 'middle', }, - placeholder: { - paddingHorizontal: theme.Form.InputText.inputPaddingLeftRight, - }, - placeholderTextColor: { - color: theme.Form.InputText.inputPlaceholderTextColor, - }, + placeholder: { paddingHorizontal: components.inputtext.root.paddingX }, + placeholderTextColor: { color: components.inputtext.root.placeholderColor }, rightContainer: { flexDirection: 'row', - paddingHorizontal: theme.Form.InputText.inputPaddingLeftRight, - gap: theme.Form.InputText.inputPaddingLeftRight, + paddingHorizontal: components.inputtext.root.paddingX, + gap: components.inputtext.root.paddingX, overflow: 'hidden', alignItems: 'center', }, rightButtonContainer: { justifyContent: 'center' }, iconSize: { - width: typography.Size['text-base'], - height: typography.Size['text-base'], + width: components.inputtext.extend.iconSize, + height: components.inputtext.extend.iconSize, }, iconSizeFloatLabel: { - width: typography.Size['text-xl'], - height: typography.Size['text-xl'], + width: components.inputtext.extend.iconSize, + height: components.inputtext.extend.iconSize, }, label: { @@ -108,20 +99,20 @@ export const inputStyles = StyleSheet.create( left: 7, right: 7, top: 19, - paddingVertical: 0, - paddingLeft: spacing.Padding['p-1'], - paddingRight: spacing.Padding['p-2'], - color: typography.Color.Common['text-color-secondary'], + paddingVertical: semantic.dimension.space.none, + paddingLeft: semantic.dimension.space[100], + paddingRight: semantic.dimension.space[200], + color: semantic.colorScheme.color.fg.muted, includeFontPadding: false, verticalAlign: 'middle', - fontSize: typography.Size['text-base'], - fontFamily: fonts.secondary, + fontSize: fonts.fontSize[300], + fontFamily: fonts.fontFamily.base, }, labelReducedSize: { - fontSize: typography.Size['text-sm'], - paddingVertical: spacing.Padding['p-1'], + fontSize: fonts.fontSize[100], + paddingVertical: semantic.dimension.space[100], top: 7, - fontFamily: fonts.primary, + fontFamily: fonts.fontFamily.heading, }, hidden: { opacity: 0 }, }) diff --git a/src/components/Input/__tests__/InputTextBase.test.tsx b/src/components/Input/__tests__/InputTextBase.test.tsx index 904989c6..076f6952 100644 --- a/src/components/Input/__tests__/InputTextBase.test.tsx +++ b/src/components/Input/__tests__/InputTextBase.test.tsx @@ -2,7 +2,7 @@ import { fireEvent, render, userEvent } from '@testing-library/react-native' import { TextInput } from 'react-native-gesture-handler' -import { lightTheme } from '../../../theme' +import { semanticTokens } from '../../../theme/tokens' import { InputTextBase } from '../InputTextBase/InputTextBase' import { InputTextBaseTestId } from '../InputTextBase/testIds' import type { RenderTextInputArgs } from '../InputTextBase/types' @@ -190,7 +190,7 @@ describe('InputTextBase component functionality tests', () => { const { getByTestId } = render() expect(getByTestId(containerTestId)).toHaveStyle({ - minHeight: lightTheme.theme.InputSize.base['min-height'], + minHeight: semanticTokens.dimension.size[1100], }) }) @@ -198,7 +198,7 @@ describe('InputTextBase component functionality tests', () => { const { getByTestId } = render() expect(getByTestId(containerTestId)).toHaveStyle({ - minHeight: lightTheme.theme.InputSize.base['min-height'], + minHeight: semanticTokens.dimension.size[1100], }) }) @@ -206,7 +206,7 @@ describe('InputTextBase component functionality tests', () => { const { getByTestId } = render() expect(getByTestId(containerTestId)).toHaveStyle({ - minHeight: lightTheme.theme.InputSize.large['min-height'], + minHeight: semanticTokens.dimension.size[1300], }) }) @@ -214,7 +214,7 @@ describe('InputTextBase component functionality tests', () => { const { getByTestId } = render() expect(getByTestId(containerTestId)).toHaveStyle({ - minHeight: lightTheme.theme.InputSize.xlarge['min-height'], + minHeight: semanticTokens.dimension.size[1400], }) }) @@ -222,7 +222,7 @@ describe('InputTextBase component functionality tests', () => { const { getByTestId } = render() expect(getByTestId(containerTestId)).toHaveStyle({ - minHeight: lightTheme.theme.InputSize.base['min-height'], + minHeight: semanticTokens.dimension.size[1100], }) }) diff --git a/src/components/Input/__tests__/__snapshots__/InputGroupAddon.test.tsx.snap b/src/components/Input/__tests__/__snapshots__/InputGroupAddon.test.tsx.snap index e751df44..4ea15dc6 100644 --- a/src/components/Input/__tests__/__snapshots__/InputGroupAddon.test.tsx.snap +++ b/src/components/Input/__tests__/__snapshots__/InputGroupAddon.test.tsx.snap @@ -8,11 +8,10 @@ exports[`InputGroup component tests content: icon, position: right 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#cecfd2", - "borderRadius": 10.5, + "borderRadius": 14, "borderWidth": 1, "justifyContent": "center", - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "padding": 14, }, { "borderBottomLeftRadius": 0, @@ -26,11 +25,11 @@ exports[`InputGroup component tests content: icon, position: right 1`] = ` > Date: Tue, 4 Aug 2026 17:05:45 +0300 Subject: [PATCH 25/40] =?UTF-8?q?feat(List):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/List/Base/ListBase.tsx | 84 ++++----- .../__snapshots__/ListBase.test.tsx.snap | 172 +++++++++--------- 2 files changed, 128 insertions(+), 128 deletions(-) diff --git a/src/components/List/Base/ListBase.tsx b/src/components/List/Base/ListBase.tsx index da4078aa..dfd1854e 100644 --- a/src/components/List/Base/ListBase.tsx +++ b/src/components/List/Base/ListBase.tsx @@ -141,45 +141,45 @@ const ListBaseTestId = { title: 'Title', } -const styles = StyleSheet.create( - ({ spacing, typography, theme, background }) => ({ - container: { - flexDirection: 'row', - paddingLeft: spacing.Padding['p-4'], - gap: spacing.Padding['p-4'], - alignItems: 'center', - }, - pressed: { backgroundColor: background.Common['bg-surface-ground-hover'] }, - disabled: { opacity: 0.6 }, - leftIcon: { paddingVertical: spacing.Padding['p-4'] }, - content: { - flex: 1, - flexDirection: 'row', - justifyContent: 'space-between', - paddingVertical: spacing.Padding['p-2'], - paddingEnd: spacing.Padding['p-4'], - gap: spacing.Gap['gap-4'], - }, - labelContainer: { - paddingVertical: spacing.Padding['p-2'], - gap: spacing.Gap['gap-2'], - flex: 1, - }, - titleContainer: { gap: spacing.Gap['gap-1'] }, - extraContainer: { paddingVertical: spacing.Padding['p-2'] }, - icon: { - width: typography.Size['text-2xl'], - height: typography.Size['text-2xl'], - }, - rightSection: { - flexDirection: 'row', - alignItems: 'center', - paddingVertical: spacing.Padding['p-2'], - gap: spacing.Gap['gap-4'], - }, - divider: { - borderTopColor: theme.Surface['surface-border'], - borderTopWidth: 1, - }, - }) -) +const styles = StyleSheet.create(({ semantic }) => ({ + container: { + flexDirection: 'row', + paddingLeft: semantic.dimension.space[400], + gap: semantic.dimension.space[400], + alignItems: 'center', + }, + pressed: { + backgroundColor: semantic.colorScheme.color.bg.neutral.weak.hover, + }, + disabled: { opacity: semantic.effects.opacity[60] }, + leftIcon: { paddingVertical: semantic.dimension.space[400] }, + content: { + flex: 1, + flexDirection: 'row', + justifyContent: 'space-between', + paddingVertical: semantic.dimension.space[200], + paddingEnd: semantic.dimension.space[400], + gap: semantic.dimension.space[400], + }, + labelContainer: { + paddingVertical: semantic.dimension.space[200], + gap: semantic.dimension.space[200], + flex: 1, + }, + titleContainer: { gap: semantic.dimension.space[100] }, + extraContainer: { paddingVertical: semantic.dimension.space[200] }, + icon: { + width: semantic.dimension.size[700], + height: semantic.dimension.size[700], + }, + rightSection: { + flexDirection: 'row', + alignItems: 'center', + paddingVertical: semantic.dimension.space[200], + gap: semantic.dimension.space[400], + }, + divider: { + borderTopColor: semantic.colorScheme.color.border.neutral.default, + borderTopWidth: 1, + }, +})) diff --git a/src/components/List/Base/__tests__/__snapshots__/ListBase.test.tsx.snap b/src/components/List/Base/__tests__/__snapshots__/ListBase.test.tsx.snap index 323012bf..0b16ef10 100644 --- a/src/components/List/Base/__tests__/__snapshots__/ListBase.test.tsx.snap +++ b/src/components/List/Base/__tests__/__snapshots__/ListBase.test.tsx.snap @@ -66,11 +66,11 @@ exports[`ListBase tests ListBase centered and full divider 1`] = ` > @@ -281,9 +281,9 @@ exports[`ListBase tests ListBase centered and full divider 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 10.5, + "fontSize": 12, "fontWeight": 700, - "lineHeight": 15, + "lineHeight": 18, "textTransform": "uppercase", }, { @@ -300,7 +300,7 @@ exports[`ListBase tests ListBase centered and full divider 1`] = ` @@ -309,16 +309,16 @@ exports[`ListBase tests ListBase centered and full divider 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, undefined, undefined, @@ -335,10 +335,10 @@ exports[`ListBase tests ListBase centered and full divider 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { @@ -361,14 +361,14 @@ exports[`ListBase tests ListBase centered and full divider 1`] = ` "alignItems": "center", "flexDirection": "row", "gap": 14, - "paddingVertical": 7, + "paddingVertical": 8, } } > @@ -450,11 +450,11 @@ exports[`ListBase tests ListBase centered and full divider 1`] = ` @@ -836,9 +836,9 @@ exports[`ListBase tests ListBase full disabled 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 10.5, + "fontSize": 12, "fontWeight": 700, - "lineHeight": 15, + "lineHeight": 18, "textTransform": "uppercase", }, { @@ -855,7 +855,7 @@ exports[`ListBase tests ListBase full disabled 1`] = ` @@ -864,16 +864,16 @@ exports[`ListBase tests ListBase full disabled 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, undefined, undefined, @@ -890,10 +890,10 @@ exports[`ListBase tests ListBase full disabled 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { @@ -916,14 +916,14 @@ exports[`ListBase tests ListBase full disabled 1`] = ` "alignItems": "center", "flexDirection": "row", "gap": 14, - "paddingVertical": 7, + "paddingVertical": 8, } } > @@ -1005,11 +1005,11 @@ exports[`ListBase tests ListBase full disabled 1`] = ` @@ -1398,9 +1398,9 @@ exports[`ListBase tests ListBase maximal config 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 10.5, + "fontSize": 12, "fontWeight": 700, - "lineHeight": 15, + "lineHeight": 18, "textTransform": "uppercase", }, { @@ -1417,7 +1417,7 @@ exports[`ListBase tests ListBase maximal config 1`] = ` @@ -1426,16 +1426,16 @@ exports[`ListBase tests ListBase maximal config 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, undefined, undefined, @@ -1452,10 +1452,10 @@ exports[`ListBase tests ListBase maximal config 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { @@ -1478,14 +1478,14 @@ exports[`ListBase tests ListBase maximal config 1`] = ` "alignItems": "center", "flexDirection": "row", "gap": 14, - "paddingVertical": 7, + "paddingVertical": 8, } } > @@ -1567,11 +1567,11 @@ exports[`ListBase tests ListBase maximal config 1`] = ` @@ -1760,16 +1760,16 @@ exports[`ListBase tests ListBase minimal config 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, undefined, undefined, @@ -1789,7 +1789,7 @@ exports[`ListBase tests ListBase minimal config 1`] = ` "alignItems": "center", "flexDirection": "row", "gap": 14, - "paddingVertical": 7, + "paddingVertical": 8, } } /> From 7651563c13dee2429afb406ce6175fa98dbf34d8 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:45 +0300 Subject: [PATCH 26/40] =?UTF-8?q?feat(MenuItem):=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MenuItem/MenuItemAccessory.tsx | 12 +- .../MenuItem/Template/MenuItemTemplate.tsx | 46 +- .../MenuItemTemplate.test.tsx.snap | 398 +++++++++--------- 3 files changed, 229 insertions(+), 227 deletions(-) diff --git a/src/components/MenuItem/MenuItemAccessory.tsx b/src/components/MenuItem/MenuItemAccessory.tsx index 958f8e44..e106b745 100644 --- a/src/components/MenuItem/MenuItemAccessory.tsx +++ b/src/components/MenuItem/MenuItemAccessory.tsx @@ -29,19 +29,19 @@ export const MenuItemAccessory = memo( ({ - color: theme.Menu.Item.menuitemIconColor, - })} + uniProps={({ components }) => { + return { color: components.menu.item.icon.color } + }} /> ) } ) -const styles = StyleSheet.create(({ theme }) => ({ +const styles = StyleSheet.create(({ components }) => ({ container: { justifyContent: 'center' }, icon: { - width: theme.Menu.Item.menuitemSubmenuIconFontSize, - height: theme.Menu.Item.menuitemSubmenuIconFontSize, + width: components.menu.extend.iconSize, + height: components.menu.extend.iconSize, }, })) diff --git a/src/components/MenuItem/Template/MenuItemTemplate.tsx b/src/components/MenuItem/Template/MenuItemTemplate.tsx index fb2d4c05..f6733949 100644 --- a/src/components/MenuItem/Template/MenuItemTemplate.tsx +++ b/src/components/MenuItem/Template/MenuItemTemplate.tsx @@ -133,45 +133,47 @@ export const MenuItemTemplate = memo( } ) -const styles = StyleSheet.create(({ theme, spacing, typography, border }) => ({ +// `transparent` здесь — отсутствие фона и границы, а не цвет дизайн-системы: +// у menu.item нет background и borderColor, прозрачность не выражена semantic-токеном. +const styles = StyleSheet.create(({ components, semantic }) => ({ container: { - borderColor: theme.Menu.Item.menuitemBorderColor, - borderWidth: border.Width.border, - borderRadius: theme.Menu.Item.menuitemBorderRadius, - backgroundColor: theme.Menu.Item.menuitemBg, + borderColor: 'transparent', + borderWidth: semantic.dimension.borderWidth[100], + borderRadius: components.menu.item.borderRadius, + backgroundColor: 'transparent', }, - containerPressed: { backgroundColor: theme.Menu.Item.menuitemHoverBg }, + containerPressed: { backgroundColor: components.menu.item.focusBackground }, containerDisabled: { - borderColor: theme.Button.Disabled.disabledButtonBorderColor, - backgroundColor: theme.Button.Disabled.disabledButtonBg, - opacity: 0.6, + borderColor: 'transparent', + backgroundColor: semantic.colorScheme.color.bg.neutral.weak.disabled, + opacity: semantic.effects.opacity[60], }, separator: { borderTopWidth: 1, - borderTopColor: theme.Menu.Overlay.overlayMenuBorderColor, - paddingTop: theme.Menu.Common.menuSeparatorMarginTopBottom, + borderTopColor: components.menu.separator.borderColor, + paddingTop: components.menu.extend.extItem.caption.gap, }, contentContainer: { flexDirection: 'row', alignItems: 'center', - gap: theme.General.inlineSpacing, - paddingHorizontal: theme.Menu.Item.menuitemPaddingLeftRight, - paddingVertical: theme.Menu.Item.menuitemPaddingTopBottom, + gap: components.menu.item.gap, + paddingHorizontal: components.menu.item.paddingLeft, + paddingVertical: components.menu.item.paddingTop, }, accessory: { - color: theme.Menu.Item.menuitemIconColor, - width: theme.Menu.Item.menuitemSubmenuIconFontSize, - height: theme.Menu.Item.menuitemSubmenuIconFontSize, + color: components.menu.item.icon.color, + width: components.menu.extend.iconSize, + height: components.menu.extend.iconSize, }, templateContainer: { flexDirection: 'row', - gap: spacing.Gap['gap-2'], + gap: semantic.dimension.space[200], flex: 1, }, icon: { - width: typography.Size['text-xl'], - height: typography.Size['text-xl'], - color: theme.Menu.Item.menuitemIconColor, + width: components.menu.extend.iconSize, + height: components.menu.extend.iconSize, + color: components.menu.item.icon.color, }, - textContainer: { gap: spacing.Gap['gap-1'], flex: 1 }, + textContainer: { gap: semantic.dimension.space[100], flex: 1 }, })) diff --git a/src/components/MenuItem/Template/__tests__/__snapshots__/MenuItemTemplate.test.tsx.snap b/src/components/MenuItem/Template/__tests__/__snapshots__/MenuItemTemplate.test.tsx.snap index bc4546e9..ffadc7b0 100644 --- a/src/components/MenuItem/Template/__tests__/__snapshots__/MenuItemTemplate.test.tsx.snap +++ b/src/components/MenuItem/Template/__tests__/__snapshots__/MenuItemTemplate.test.tsx.snap @@ -6,7 +6,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate full disabled 1`] = ` { "borderTopColor": "#e2e2e4", "borderTopWidth": 1, - "paddingTop": 3.5, + "paddingTop": 4, } } > @@ -45,16 +45,16 @@ exports[`MenuItemTemplate tests MenuItemTemplate full disabled 1`] = ` style={ [ { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", - "borderColor": "rgba(255, 255, 255, 0.0001)", - "borderRadius": 7, + "backgroundColor": "transparent", + "borderColor": "transparent", + "borderRadius": 8, "borderWidth": 1, }, false, undefined, { "backgroundColor": "#e2e2e4", - "borderColor": "#a2a5a9", + "borderColor": "transparent", "opacity": 0.6, }, ] @@ -66,9 +66,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate full disabled 1`] = ` { "alignItems": "center", "flexDirection": "row", - "gap": 7, - "paddingHorizontal": 10.5, - "paddingVertical": 7, + "gap": 8, + "paddingHorizontal": 14, + "paddingVertical": 8, } } > @@ -77,7 +77,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate full disabled 1`] = ` { "flex": 1, "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -92,15 +92,15 @@ exports[`MenuItemTemplate tests MenuItemTemplate full disabled 1`] = ` @@ -242,20 +242,20 @@ exports[`MenuItemTemplate tests MenuItemTemplate full disabled 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, { - "fontSize": 12.25, - "lineHeight": 18, + "fontSize": 14, + "lineHeight": 20, }, undefined, undefined, @@ -271,10 +271,10 @@ exports[`MenuItemTemplate tests MenuItemTemplate full disabled 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { @@ -396,15 +396,15 @@ exports[`MenuItemTemplate tests MenuItemTemplate full disabled 1`] = ` > @@ -592,7 +592,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate minimal config 1`] = ` { "flex": 1, "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -600,7 +600,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate minimal config 1`] = ` style={ { "flex": 1, - "gap": 3.5, + "gap": 4, } } > @@ -609,20 +609,20 @@ exports[`MenuItemTemplate tests MenuItemTemplate minimal config 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, { - "fontSize": 12.25, - "lineHeight": 18, + "fontSize": 14, + "lineHeight": 20, }, undefined, undefined, @@ -679,9 +679,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate prefix,suffix = right 1`] = ` style={ [ { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", - "borderColor": "rgba(255, 255, 255, 0.0001)", - "borderRadius": 7, + "backgroundColor": "transparent", + "borderColor": "transparent", + "borderRadius": 8, "borderWidth": 1, }, false, @@ -696,9 +696,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate prefix,suffix = right 1`] = ` { "alignItems": "center", "flexDirection": "row", - "gap": 7, - "paddingHorizontal": 10.5, - "paddingVertical": 7, + "gap": 8, + "paddingHorizontal": 14, + "paddingVertical": 8, } } > @@ -711,15 +711,15 @@ exports[`MenuItemTemplate tests MenuItemTemplate prefix,suffix = right 1`] = ` > @@ -802,7 +802,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate prefix,suffix = right 1`] = ` style={ { "flex": 1, - "gap": 3.5, + "gap": 4, } } > @@ -811,20 +811,20 @@ exports[`MenuItemTemplate tests MenuItemTemplate prefix,suffix = right 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, { - "fontSize": 12.25, - "lineHeight": 18, + "fontSize": 14, + "lineHeight": 20, }, undefined, undefined, @@ -840,10 +840,10 @@ exports[`MenuItemTemplate tests MenuItemTemplate prefix,suffix = right 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { @@ -869,15 +869,15 @@ exports[`MenuItemTemplate tests MenuItemTemplate prefix,suffix = right 1`] = ` > @@ -1019,7 +1019,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate with colored icon 1`] = ` { "flex": 1, "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -1034,11 +1034,11 @@ exports[`MenuItemTemplate tests MenuItemTemplate with colored icon 1`] = ` @@ -1149,20 +1149,20 @@ exports[`MenuItemTemplate tests MenuItemTemplate with colored icon 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, { - "fontSize": 12.25, - "lineHeight": 18, + "fontSize": 14, + "lineHeight": 20, }, undefined, undefined, @@ -1219,9 +1219,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate with extra 1`] = ` style={ [ { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", - "borderColor": "rgba(255, 255, 255, 0.0001)", - "borderRadius": 7, + "backgroundColor": "transparent", + "borderColor": "transparent", + "borderRadius": 8, "borderWidth": 1, }, false, @@ -1236,9 +1236,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate with extra 1`] = ` { "alignItems": "center", "flexDirection": "row", - "gap": 7, - "paddingHorizontal": 10.5, - "paddingVertical": 7, + "gap": 8, + "paddingHorizontal": 14, + "paddingVertical": 8, } } > @@ -1247,7 +1247,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate with extra 1`] = ` { "flex": 1, "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -1255,7 +1255,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate with extra 1`] = ` style={ { "flex": 1, - "gap": 3.5, + "gap": 4, } } > @@ -1264,20 +1264,20 @@ exports[`MenuItemTemplate tests MenuItemTemplate with extra 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, { - "fontSize": 12.25, - "lineHeight": 18, + "fontSize": 14, + "lineHeight": 20, }, undefined, undefined, @@ -1430,9 +1430,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate with icon 1`] = ` style={ [ { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", - "borderColor": "rgba(255, 255, 255, 0.0001)", - "borderRadius": 7, + "backgroundColor": "transparent", + "borderColor": "transparent", + "borderRadius": 8, "borderWidth": 1, }, false, @@ -1447,9 +1447,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate with icon 1`] = ` { "alignItems": "center", "flexDirection": "row", - "gap": 7, - "paddingHorizontal": 10.5, - "paddingVertical": 7, + "gap": 8, + "paddingHorizontal": 14, + "paddingVertical": 8, } } > @@ -1458,7 +1458,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate with icon 1`] = ` { "flex": 1, "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -1473,15 +1473,15 @@ exports[`MenuItemTemplate tests MenuItemTemplate with icon 1`] = ` @@ -1588,20 +1588,20 @@ exports[`MenuItemTemplate tests MenuItemTemplate with icon 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, { - "fontSize": 12.25, - "lineHeight": 18, + "fontSize": 14, + "lineHeight": 20, }, undefined, undefined, @@ -1658,9 +1658,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate with icon and badge 1`] = ` style={ [ { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", - "borderColor": "rgba(255, 255, 255, 0.0001)", - "borderRadius": 7, + "backgroundColor": "transparent", + "borderColor": "transparent", + "borderRadius": 8, "borderWidth": 1, }, false, @@ -1675,9 +1675,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate with icon and badge 1`] = ` { "alignItems": "center", "flexDirection": "row", - "gap": 7, - "paddingHorizontal": 10.5, - "paddingVertical": 7, + "gap": 8, + "paddingHorizontal": 14, + "paddingVertical": 8, } } > @@ -1686,7 +1686,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate with icon and badge 1`] = ` { "flex": 1, "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -1701,15 +1701,15 @@ exports[`MenuItemTemplate tests MenuItemTemplate with icon and badge 1`] = ` @@ -1851,20 +1851,20 @@ exports[`MenuItemTemplate tests MenuItemTemplate with icon and badge 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, { - "fontSize": 12.25, - "lineHeight": 18, + "fontSize": 14, + "lineHeight": 20, }, undefined, undefined, @@ -1921,9 +1921,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate with padding 1`] = ` style={ [ { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", - "borderColor": "rgba(255, 255, 255, 0.0001)", - "borderRadius": 7, + "backgroundColor": "transparent", + "borderColor": "transparent", + "borderRadius": 8, "borderWidth": 1, }, false, @@ -1941,9 +1941,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate with padding 1`] = ` { "alignItems": "center", "flexDirection": "row", - "gap": 7, - "paddingHorizontal": 10.5, - "paddingVertical": 7, + "gap": 8, + "paddingHorizontal": 14, + "paddingVertical": 8, } } > @@ -1952,7 +1952,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate with padding 1`] = ` { "flex": 1, "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -1960,7 +1960,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate with padding 1`] = ` style={ { "flex": 1, - "gap": 3.5, + "gap": 4, } } > @@ -1969,20 +1969,20 @@ exports[`MenuItemTemplate tests MenuItemTemplate with padding 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, { - "fontSize": 12.25, - "lineHeight": 18, + "fontSize": 14, + "lineHeight": 20, }, undefined, undefined, @@ -2006,7 +2006,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate with separator 1`] = ` { "borderTopColor": "#e2e2e4", "borderTopWidth": 1, - "paddingTop": 3.5, + "paddingTop": 4, } } > @@ -2045,9 +2045,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate with separator 1`] = ` style={ [ { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", - "borderColor": "rgba(255, 255, 255, 0.0001)", - "borderRadius": 7, + "backgroundColor": "transparent", + "borderColor": "transparent", + "borderRadius": 8, "borderWidth": 1, }, false, @@ -2062,9 +2062,9 @@ exports[`MenuItemTemplate tests MenuItemTemplate with separator 1`] = ` { "alignItems": "center", "flexDirection": "row", - "gap": 7, - "paddingHorizontal": 10.5, - "paddingVertical": 7, + "gap": 8, + "paddingHorizontal": 14, + "paddingVertical": 8, } } > @@ -2073,7 +2073,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate with separator 1`] = ` { "flex": 1, "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -2081,7 +2081,7 @@ exports[`MenuItemTemplate tests MenuItemTemplate with separator 1`] = ` style={ { "flex": 1, - "gap": 3.5, + "gap": 4, } } > @@ -2090,20 +2090,20 @@ exports[`MenuItemTemplate tests MenuItemTemplate with separator 1`] = ` [ { "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, - "lineHeight": 20, + "lineHeight": 22, "verticalAlign": "middle", }, { "fontWeight": 400, }, { - "color": "#181a1f", + "color": "#2b2e33", }, { - "fontSize": 12.25, - "lineHeight": 18, + "fontSize": 14, + "lineHeight": 20, }, undefined, undefined, From 08f2409f5fb2c30d0b70642dd7607bfb341352f9 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:46 +0300 Subject: [PATCH 27/40] =?UTF-8?q?feat(Message):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Message/Message.tsx | 133 +++++---- .../__snapshots__/Message.test.tsx.snap | 252 +++++++++--------- 2 files changed, 187 insertions(+), 198 deletions(-) diff --git a/src/components/Message/Message.tsx b/src/components/Message/Message.tsx index 728468fa..9000650e 100644 --- a/src/components/Message/Message.tsx +++ b/src/components/Message/Message.tsx @@ -16,7 +16,7 @@ import { import { StyleSheet } from 'react-native-unistyles' -import type { ThemeType } from '../../theme/types' +import type { ComponentTokens } from '../../theme/tokens/index' import { type SvgSource, SvgUniversal } from '../../utils/SvgUniversal' import { ButtonSeverity } from '../Button/ButtonSeverity' import { Timer } from '../Timer/Timer' @@ -88,12 +88,12 @@ type MessageSeverityKey = NonNullable const messageIconColor: Record< MessageSeverityKey, - (t: ThemeType['theme']) => string + (t: ComponentTokens) => string > = { - info: (t) => t.Message.Severities.Info.infoMessageIconColor, - success: (t) => t.Message.Severities.Success.successMessageIconColor, - warning: (t) => t.Message.Severities.Warning.warningMessageIconColor, - danger: (t) => t.Message.Severities.Danger.dangerMessageIconColor, + info: (t) => t.message.extend.extInfo.color, + success: (t) => t.message.extend.extSuccess.color, + warning: (t) => t.message.extend.extWarn.color, + danger: (t) => t.message.extend.extError.color, } /** @@ -180,9 +180,9 @@ export const Message = memo( {...messageStyles.iconSize} source={Icon} testID={TestId.Icon} - uniProps={({ theme }) => ({ - color: messageIconColor[severity](theme), - })} + uniProps={({ components }) => { + return { color: messageIconColor[severity](components) } + }} /> ) } @@ -218,73 +218,66 @@ export const Message = memo( } ) -const messageStyles = StyleSheet.create( - ({ theme, typography, spacing, border }) => ({ - container: { - borderRadius: theme.General.borderRadiusXL, - borderWidth: border.Width.border, - overflow: 'hidden', - variants: { - severity: { - info: { - borderColor: theme.Message.Severities.Info.infoMessageBorderColor, - backgroundColor: theme.Message.Severities.Info.infoMessageBg, - }, - success: { - borderColor: - theme.Message.Severities.Success.successMessageBorderColor, - backgroundColor: theme.Message.Severities.Success.successMessageBg, - }, - warning: { - borderColor: - theme.Message.Severities.Warning.warningMessageBorderColor, - backgroundColor: theme.Message.Severities.Warning.warningMessageBg, - }, - danger: { - borderColor: - theme.Message.Severities.Danger.dangerMessageBorderColor, - backgroundColor: theme.Message.Severities.Danger.dangerMessageBg, - }, +const messageStyles = StyleSheet.create(({ components, semantic }) => ({ + container: { + borderRadius: components.message.root.borderRadius, + borderWidth: semantic.dimension.borderWidth[100], + overflow: 'hidden', + variants: { + severity: { + info: { + borderColor: components.message.colorScheme.info.borderColor, + backgroundColor: components.message.colorScheme.info.background, + }, + success: { + borderColor: components.message.colorScheme.success.borderColor, + backgroundColor: components.message.colorScheme.success.background, + }, + warning: { + borderColor: components.message.colorScheme.warn.borderColor, + backgroundColor: components.message.colorScheme.warn.background, + }, + danger: { + borderColor: components.message.colorScheme.error.borderColor, + backgroundColor: components.message.colorScheme.error.background, }, }, }, - content: { - flexGrow: 1, - borderLeftWidth: border.Width['border-3'] - border.Width.border, - padding: spacing.Padding['p-4'], - paddingLeft: spacing.Padding['p-5'], - gap: spacing.Gap['gap-4'], - variants: { - severity: { - info: { - borderColor: theme.Message.Severities.Info.infoMessageIconColor, - }, - success: { - borderColor: - theme.Message.Severities.Success.successMessageIconColor, - }, - warning: { - borderColor: - theme.Message.Severities.Warning.warningMessageIconColor, - }, - danger: { - borderColor: theme.Message.Severities.Danger.dangerMessageIconColor, - }, + }, + content: { + flexGrow: 1, + borderLeftWidth: + components.message.extend.extAccentLine.width - + semantic.dimension.borderWidth[100], + padding: semantic.dimension.space[400], + paddingLeft: components.message.content.padding, + gap: semantic.dimension.space[400], + variants: { + severity: { + info: { borderColor: components.message.colorScheme.info.borderColor }, + success: { + borderColor: components.message.colorScheme.success.borderColor, + }, + warning: { + borderColor: components.message.colorScheme.warn.borderColor, + }, + danger: { + borderColor: components.message.colorScheme.error.borderColor, }, }, }, - titleRow: { flexDirection: 'row', gap: spacing.Gap['gap-4'] }, - titleTextContainer: { - flex: 1, - alignSelf: 'center', - gap: spacing.Gap['gap-1'], - }, - iconSize: { - width: typography.Size['text-4xl'], - height: typography.Size['text-4xl'], - }, - }) -) + }, + titleRow: { flexDirection: 'row', gap: semantic.dimension.space[400] }, + titleTextContainer: { + flex: 1, + alignSelf: 'center', + gap: components.message.extend.extText.gap, + }, + iconSize: { + width: components.message.icon.size, + height: components.message.icon.size, + }, +})) export enum TestId { Container = 'MessageContainer', diff --git a/src/components/Message/__tests__/__snapshots__/Message.test.tsx.snap b/src/components/Message/__tests__/__snapshots__/Message.test.tsx.snap index 06eed4f8..26df81f9 100644 --- a/src/components/Message/__tests__/__snapshots__/Message.test.tsx.snap +++ b/src/components/Message/__tests__/__snapshots__/Message.test.tsx.snap @@ -7,8 +7,8 @@ exports[`Message {"Icon": [Object], "timerValue": 5} 1`] = ` [ { "backgroundColor": "#fafdff", - "borderColor": "#d4ecfe", - "borderRadius": 10.5, + "borderColor": "#4496e8", + "borderRadius": 14, "borderWidth": 1, "overflow": "hidden", }, @@ -21,11 +21,11 @@ exports[`Message {"Icon": [Object], "timerValue": 5} 1`] = ` style={ { "borderColor": "#4496e8", - "borderLeftWidth": 2, + "borderLeftWidth": 3, "flexGrow": 1, "gap": 14, "padding": 14, - "paddingLeft": 17.5, + "paddingLeft": 14, } } > @@ -45,7 +45,7 @@ exports[`Message {"Icon": [Object], "timerValue": 5} 1`] = ` { "alignSelf": "center", "flex": 1, - "gap": 3.5, + "gap": 4, } } > @@ -69,8 +69,8 @@ exports[`Message {"Icon": [Object]} 1`] = ` [ { "backgroundColor": "#fafdff", - "borderColor": "#d4ecfe", - "borderRadius": 10.5, + "borderColor": "#4496e8", + "borderRadius": 14, "borderWidth": 1, "overflow": "hidden", }, @@ -83,11 +83,11 @@ exports[`Message {"Icon": [Object]} 1`] = ` style={ { "borderColor": "#4496e8", - "borderLeftWidth": 2, + "borderLeftWidth": 3, "flexGrow": 1, "gap": 14, "padding": 14, - "paddingLeft": 17.5, + "paddingLeft": 14, } } > @@ -101,11 +101,11 @@ exports[`Message {"Icon": [Object]} 1`] = ` > @@ -230,8 +230,8 @@ exports[`Message {"body": [Object], "caption": "caption", "severity": "info", "s [ { "backgroundColor": "#fafdff", - "borderColor": "#d4ecfe", - "borderRadius": 10.5, + "borderColor": "#4496e8", + "borderRadius": 14, "borderWidth": 1, "overflow": "hidden", }, @@ -246,11 +246,11 @@ exports[`Message {"body": [Object], "caption": "caption", "severity": "info", "s style={ { "borderColor": "#4496e8", - "borderLeftWidth": 2, + "borderLeftWidth": 3, "flexGrow": 1, "gap": 14, "padding": 14, - "paddingLeft": 17.5, + "paddingLeft": 14, } } > @@ -264,11 +264,11 @@ exports[`Message {"body": [Object], "caption": "caption", "severity": "info", "s > @@ -428,8 +428,8 @@ exports[`Message {"body": [Object], "footer": [Object], "severity": "warning"} 1 [ { "backgroundColor": "#fffdfa", - "borderColor": "#ffeed4", - "borderRadius": 10.5, + "borderColor": "#f5b83d", + "borderRadius": 14, "borderWidth": 1, "overflow": "hidden", }, @@ -442,11 +442,11 @@ exports[`Message {"body": [Object], "footer": [Object], "severity": "warning"} 1 style={ { "borderColor": "#f5b83d", - "borderLeftWidth": 2, + "borderLeftWidth": 3, "flexGrow": 1, "gap": 14, "padding": 14, - "paddingLeft": 17.5, + "paddingLeft": 14, } } > @@ -460,11 +460,11 @@ exports[`Message {"body": [Object], "footer": [Object], "severity": "warning"} 1 > @@ -622,8 +622,8 @@ exports[`Message {"closeLabel": "Close", "footer": [Object], "onClose": [Functio [ { "backgroundColor": "#fafffb", - "borderColor": "#d4fedc", - "borderRadius": 10.5, + "borderColor": "#44e858", + "borderRadius": 14, "borderWidth": 1, "overflow": "hidden", }, @@ -636,11 +636,11 @@ exports[`Message {"closeLabel": "Close", "footer": [Object], "onClose": [Functio style={ { "borderColor": "#44e858", - "borderLeftWidth": 2, + "borderLeftWidth": 3, "flexGrow": 1, "gap": 14, "padding": 14, - "paddingLeft": 17.5, + "paddingLeft": 14, } } > @@ -654,11 +654,11 @@ exports[`Message {"closeLabel": "Close", "footer": [Object], "onClose": [Functio > @@ -806,18 +806,16 @@ exports[`Message {"closeLabel": "Close", "footer": [Object], "onClose": [Functio [ { "alignItems": "center", - "backgroundColor": "rgba(255, 255, 255, 0.0001)", - "borderColor": "#44e858", - "borderRadius": 10.5, + "backgroundColor": "transparent", + "borderColor": "#1dc831", + "borderRadius": 14, "borderWidth": 1, "flexDirection": "row", - "gap": 7, - "height": 28, + "gap": 8, + "height": "auto", "justifyContent": "center", - "maxHeight": 28, - "minHeight": 28, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "paddingHorizontal": 14, + "paddingVertical": 8, }, false, ] @@ -827,9 +825,9 @@ exports[`Message {"closeLabel": "Close", "footer": [Object], "onClose": [Functio @@ -887,11 +885,11 @@ exports[`Message {"footer": [Object], "onClose": [Function mockConstructor], "se > @@ -1039,18 +1037,16 @@ exports[`Message {"footer": [Object], "onClose": [Function mockConstructor], "se [ { "alignItems": "center", - "backgroundColor": "rgba(255, 255, 255, 0.0001)", - "borderColor": "#44e858", - "borderRadius": 10.5, + "backgroundColor": "transparent", + "borderColor": "#1dc831", + "borderRadius": 14, "borderWidth": 1, "flexDirection": "row", - "gap": 7, - "height": 28, + "gap": 8, + "height": "auto", "justifyContent": "center", - "maxHeight": 28, - "minHeight": 28, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "paddingHorizontal": 14, + "paddingVertical": 8, }, { "aspectRatio": 1, @@ -1061,15 +1057,15 @@ exports[`Message {"footer": [Object], "onClose": [Function mockConstructor], "se > @@ -1209,11 +1205,11 @@ exports[`Message {"hiddenIcon": false} 1`] = ` > @@ -1361,8 +1357,8 @@ exports[`Message {"onTimerFinish": [Function mockConstructor], "timerValue": 5} [ { "backgroundColor": "#fafdff", - "borderColor": "#d4ecfe", - "borderRadius": 10.5, + "borderColor": "#4496e8", + "borderRadius": 14, "borderWidth": 1, "overflow": "hidden", }, @@ -1375,11 +1371,11 @@ exports[`Message {"onTimerFinish": [Function mockConstructor], "timerValue": 5} style={ { "borderColor": "#4496e8", - "borderLeftWidth": 2, + "borderLeftWidth": 3, "flexGrow": 1, "gap": 14, "padding": 14, - "paddingLeft": 17.5, + "paddingLeft": 14, } } > @@ -1400,7 +1396,7 @@ exports[`Message {"onTimerFinish": [Function mockConstructor], "timerValue": 5} { "alignSelf": "center", "flex": 1, - "gap": 3.5, + "gap": 4, } } > @@ -1424,8 +1420,8 @@ exports[`Message {"severity": "danger"} 1`] = ` [ { "backgroundColor": "#fffafa", - "borderColor": "#fed4d4", - "borderRadius": 10.5, + "borderColor": "#e85244", + "borderRadius": 14, "borderWidth": 1, "overflow": "hidden", }, @@ -1438,11 +1434,11 @@ exports[`Message {"severity": "danger"} 1`] = ` style={ { "borderColor": "#e85244", - "borderLeftWidth": 2, + "borderLeftWidth": 3, "flexGrow": 1, "gap": 14, "padding": 14, - "paddingLeft": 17.5, + "paddingLeft": 14, } } > @@ -1456,11 +1452,11 @@ exports[`Message {"severity": "danger"} 1`] = ` > @@ -1608,8 +1604,8 @@ exports[`Message {} 1`] = ` [ { "backgroundColor": "#fafdff", - "borderColor": "#d4ecfe", - "borderRadius": 10.5, + "borderColor": "#4496e8", + "borderRadius": 14, "borderWidth": 1, "overflow": "hidden", }, @@ -1622,11 +1618,11 @@ exports[`Message {} 1`] = ` style={ { "borderColor": "#4496e8", - "borderLeftWidth": 2, + "borderLeftWidth": 3, "flexGrow": 1, "gap": 14, "padding": 14, - "paddingLeft": 17.5, + "paddingLeft": 14, } } > @@ -1640,11 +1636,11 @@ exports[`Message {} 1`] = ` > From 5e1f2ff6b2c17c505ccd6d32274545522eebaea8 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:46 +0300 Subject: [PATCH 28/40] =?UTF-8?q?feat(ProgressBar):=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ProgressBar/ProgressBar.tsx | 16 +-- .../__snapshots__/ProgressBar.test.tsx.snap | 100 +++++++++--------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/components/ProgressBar/ProgressBar.tsx b/src/components/ProgressBar/ProgressBar.tsx index 2b4630e6..de3c6667 100644 --- a/src/components/ProgressBar/ProgressBar.tsx +++ b/src/components/ProgressBar/ProgressBar.tsx @@ -89,28 +89,28 @@ export const ProgressBar = memo( } ) -const styles = StyleSheet.create(({ theme, typography, border, fonts }) => ({ +const styles = StyleSheet.create(({ components, fonts }) => ({ container: { - borderRadius: border.Radius['rounded-full'], - backgroundColor: theme.Misc.ProgressBar.progressBarBg, + borderRadius: components.progressbar.root.borderRadius, + backgroundColor: components.progressbar.root.background, overflow: 'hidden', }, indicator: { alignItems: 'center', justifyContent: 'center', - backgroundColor: theme.Misc.ProgressBar.progressBarValueBg, + backgroundColor: components.progressbar.value.background, height: '100%', overflow: 'hidden', }, - containerShowValue: { height: theme.Misc.ProgressBar.progressBarHeight }, + containerShowValue: { height: components.progressbar.root.height }, indicatorText: { - fontSize: typography.Size['text-xs'], + fontSize: components.progressbar.label.fontSize, textAlign: 'center', - color: theme.Misc.ProgressBar.progressBarValueTextColor, - fontFamily: fonts.primary, + color: components.progressbar.label.color, + fontFamily: fonts.fontFamily.heading, }, })) diff --git a/src/components/ProgressBar/__tests__/__snapshots__/ProgressBar.test.tsx.snap b/src/components/ProgressBar/__tests__/__snapshots__/ProgressBar.test.tsx.snap index f5afd78f..97a74194 100644 --- a/src/components/ProgressBar/__tests__/__snapshots__/ProgressBar.test.tsx.snap +++ b/src/components/ProgressBar/__tests__/__snapshots__/ProgressBar.test.tsx.snap @@ -7,7 +7,7 @@ exports[`ProgressBar component test value - -50, showValue - false, style - {"he [ { "backgroundColor": "#e2e2e4", - "borderRadius": 100, + "borderRadius": 14, "overflow": "hidden", }, { @@ -69,7 +69,7 @@ exports[`ProgressBar component test value - -50, showValue - false, style - {"he [ { "backgroundColor": "#e2e2e4", - "borderRadius": 100, + "borderRadius": 14, "overflow": "hidden", }, { @@ -131,7 +131,7 @@ exports[`ProgressBar component test value - -50, showValue - true, style - {"hei [ { "backgroundColor": "#e2e2e4", - "borderRadius": 100, + "borderRadius": 14, "overflow": "hidden", }, { @@ -139,7 +139,7 @@ exports[`ProgressBar component test value - -50, showValue - true, style - {"hei "width": 100, }, { - "height": 14, + "height": 16, }, ] } @@ -188,9 +188,9 @@ exports[`ProgressBar component test value - -50, showValue - true, style - {"hei Date: Tue, 4 Aug 2026 17:05:47 +0300 Subject: [PATCH 29/40] =?UTF-8?q?feat(ProgressSpinner):=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B4=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ProgressSpinner/ProgressSpinner.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/ProgressSpinner/ProgressSpinner.tsx b/src/components/ProgressSpinner/ProgressSpinner.tsx index 390467ac..0973a879 100644 --- a/src/components/ProgressSpinner/ProgressSpinner.tsx +++ b/src/components/ProgressSpinner/ProgressSpinner.tsx @@ -125,10 +125,12 @@ export const ProgressSpinner = memo( } ) -const styles = StyleSheet.create(({ theme, global }) => ({ - primary: { color: theme.General.primaryColor }, - white: { color: global.Neutrals.White['white-100'] }, -})) +const styles = StyleSheet.create( + ({ components: { progressspinner }, semantic }) => ({ + primary: { color: progressspinner.colorScheme.root.colorOne }, + white: { color: semantic.colorScheme.color.fg.on.fill.default }, + }) +) enum TestId { ProgressSpinner = 'ProgressSpinner', From c6c2efeaa332da167604a7dc53f9c98da7a979d8 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:47 +0300 Subject: [PATCH 30/40] =?UTF-8?q?feat(RadioButton):=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/RadioButton/RadioButton.tsx | 66 +-- .../__snapshots__/RadioButton.test.tsx.snap | 460 ++++-------------- 2 files changed, 108 insertions(+), 418 deletions(-) diff --git a/src/components/RadioButton/RadioButton.tsx b/src/components/RadioButton/RadioButton.tsx index 8eb0e7a6..e5fddbd0 100644 --- a/src/components/RadioButton/RadioButton.tsx +++ b/src/components/RadioButton/RadioButton.tsx @@ -52,7 +52,6 @@ export const RadioButton = memo( return ( - ( } ) -const radioStyles = StyleSheet.create(({ theme, border }) => ({ +const radioStyles = StyleSheet.create(({ components, semantic }) => ({ container: { - width: theme.Form.RadioButton.radiobuttonWidth, - height: theme.Form.RadioButton.radiobuttonHeight, - borderRadius: border.Radius['rounded-full'], - borderWidth: 1, + width: components.radiobutton.root.width, + height: components.radiobutton.root.height, + borderRadius: semantic.dimension.borderRadius.max, + borderWidth: semantic.dimension.borderWidth[100], alignItems: 'center', justifyContent: 'center', transitionProperty: ['borderColor', 'backgroundColor'], @@ -82,20 +81,20 @@ const radioStyles = StyleSheet.create(({ theme, border }) => ({ variants: { checked: { true: { - borderColor: theme.Form.RadioButton.radiobuttonActiveBorderColor, - backgroundColor: theme.Form.RadioButton.radiobuttonActiveBorderColor, + borderColor: components.radiobutton.root.checkedBorderColor, + backgroundColor: components.radiobutton.root.checkedBackground, }, false: { - borderColor: theme.Form.InputText.inputBorderColor, - backgroundColor: theme.Form.InputText.inputBg, + borderColor: components.radiobutton.root.borderColor, + backgroundColor: components.radiobutton.root.background, }, }, pressed: { true: {}, false: {} }, disabled: { true: { - borderColor: theme.Form.InputText.inputBorderColor, - backgroundColor: theme.Button.Disabled.disabledButtonBg, - opacity: 0.6, + borderColor: components.radiobutton.root.borderColor, + backgroundColor: components.radiobutton.root.disabledBackground, + opacity: semantic.effects.opacity[60], }, false: {}, }, @@ -106,59 +105,38 @@ const radioStyles = StyleSheet.create(({ theme, border }) => ({ checked: 'true', pressed: 'true', styles: { - borderColor: theme.Form.RadioButton.radiobuttonActiveHoverBorderColor, - backgroundColor: theme.Form.RadioButton.radiobuttonActiveHoverBg, + borderColor: components.radiobutton.root.checkedHoverBorderColor, + backgroundColor: components.radiobutton.root.checkedHoverBackground, }, }, { checked: 'true', disabled: 'true', styles: { - borderColor: theme.Form.RadioButton.radiobuttonActiveBorderColor, - backgroundColor: theme.Form.RadioButton.radiobuttonActiveBorderColor, + borderColor: components.radiobutton.root.checkedBorderColor, + backgroundColor: components.radiobutton.root.checkedBackground, }, }, { state: 'danger', disabled: 'false', checked: 'false', - styles: { borderColor: theme.Form.InputText.inputErrorBorderColor }, + styles: { borderColor: components.radiobutton.root.invalidBorderColor }, }, { checked: 'false', pressed: 'true', - styles: { - borderColor: theme.Form.RadioButton.radiobuttonActiveHoverBorderColor, - }, + styles: { borderColor: components.radiobutton.root.hoverBorderColor }, }, ], }, center: { - width: theme.Form.RadioButton.radiobuttonIconSize, - height: theme.Form.RadioButton.radiobuttonIconSize, - borderRadius: border.Radius['rounded-full'], - backgroundColor: theme.Form.InputText.inputBg, + width: components.radiobutton.icon.size, + height: components.radiobutton.icon.size, + borderRadius: semantic.dimension.borderRadius.max, + backgroundColor: components.radiobutton.root.background, transitionProperty: ['opacity'], transitionDuration: 100, variants: { checked: { false: { opacity: 0 }, true: { opacity: 1 } } }, }, - outline: { - position: 'absolute', - top: -theme.General.focusShadowWidth, - left: -theme.General.focusShadowWidth, - width: - theme.Form.RadioButton.radiobuttonWidth + - theme.General.focusShadowWidth * 2, - height: - theme.Form.RadioButton.radiobuttonHeight + - theme.General.focusShadowWidth * 2, - borderRadius: border.Radius['rounded-full'], - backgroundColor: theme.General.focusOutlineErrorColor, - transitionProperty: 'opacity', - transitionDuration: 100, - variants: { - state: { danger: { opacity: 1 }, default: { opacity: 0 } }, - disabled: { true: { opacity: 0 } }, - }, - }, })) diff --git a/src/components/RadioButton/__tests__/__snapshots__/RadioButton.test.tsx.snap b/src/components/RadioButton/__tests__/__snapshots__/RadioButton.test.tsx.snap index cb279583..43b79c4b 100644 --- a/src/components/RadioButton/__tests__/__snapshots__/RadioButton.test.tsx.snap +++ b/src/components/RadioButton/__tests__/__snapshots__/RadioButton.test.tsx.snap @@ -2,48 +2,6 @@ exports[`RadioButton snapshots checked = false, disabled = false, state = danger 1`] = ` - - - - - - - Date: Tue, 4 Aug 2026 17:05:48 +0300 Subject: [PATCH 31/40] =?UTF-8?q?feat(Rating):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Rating/Rating.tsx | 4 +- src/components/Rating/RatingClear.tsx | 22 +- src/components/Rating/RatingItem.tsx | 24 +- src/components/Rating/RatingItemContainer.tsx | 11 +- .../__snapshots__/Rating.test.tsx.snap | 294 ++++++++-------- .../__snapshots__/RatingClear.test.tsx.snap | 176 +++++----- .../__snapshots__/RatingItem.test.tsx.snap | 328 +++++++++--------- 7 files changed, 429 insertions(+), 430 deletions(-) diff --git a/src/components/Rating/Rating.tsx b/src/components/Rating/Rating.tsx index fed0e34e..5aaf52a8 100644 --- a/src/components/Rating/Rating.tsx +++ b/src/components/Rating/Rating.tsx @@ -100,10 +100,10 @@ export const Rating = memo( } ) -const styles = StyleSheet.create(({ theme }) => ({ +const styles = StyleSheet.create(({ components }) => ({ container: { flexDirection: 'row', - gap: theme.General.inlineSpacing, + gap: components.rating.root.gap, alignItems: 'center', }, })) diff --git a/src/components/Rating/RatingClear.tsx b/src/components/Rating/RatingClear.tsx index 5c6d47c1..7560ee92 100644 --- a/src/components/Rating/RatingClear.tsx +++ b/src/components/Rating/RatingClear.tsx @@ -32,22 +32,24 @@ export const RatingClear = memo(({ ...rest }) => { ({ - color: disabled - ? theme.custom.rating.ratingCancelIconDisabledColor - : pressed - ? theme.Form.Rating.ratingCancelIconHoverColor - : theme.Form.Rating.ratingCancelIconColor, - })} + uniProps={({ components }) => { + return { + color: disabled + ? components.rating.icon.color + : pressed + ? components.rating.icon.hoverColor + : components.rating.icon.color, + } + }} /> )} ) }) -const styles = StyleSheet.create(({ theme }) => ({ +const styles = StyleSheet.create(({ components }) => ({ icon: { - height: theme.Form.Rating.ratingIconFontSize, - width: theme.Form.Rating.ratingIconFontSize, + height: components.rating.icon.size, + width: components.rating.icon.size, }, })) diff --git a/src/components/Rating/RatingItem.tsx b/src/components/Rating/RatingItem.tsx index 92fffb31..0cdc6951 100644 --- a/src/components/Rating/RatingItem.tsx +++ b/src/components/Rating/RatingItem.tsx @@ -41,25 +41,25 @@ export const RatingItem = memo(({ checked, ...rest }) => { {...styles.icon} fillOpacity={checked ? 1 : 0} source={Icon} - uniProps={({ theme }) => { + uniProps={({ components }) => { const color = disabled ? checked - ? theme.custom.rating.ratingStarIconOnDisabledColor - : theme.custom.rating.ratingStarIconOffDisabledColor + ? components.rating.icon.activeColor + : components.rating.icon.color : pressed - ? theme.Form.Rating.ratingStarIconHoverColor + ? components.rating.icon.hoverColor : checked - ? theme.Form.Rating.ratingStarIconOnColor - : theme.Form.Rating.ratingStarIconOffColor + ? components.rating.icon.activeColor + : components.rating.icon.color return { color, fill: checked ? disabled - ? theme.custom.rating.ratingStarIconOnDisabledColor + ? components.rating.icon.activeColor : pressed - ? theme.Form.Rating.ratingStarIconHoverColor - : theme.Form.Rating.ratingStarIconOnColor + ? components.rating.icon.hoverColor + : components.rating.icon.activeColor : undefined, } }} @@ -69,9 +69,9 @@ export const RatingItem = memo(({ checked, ...rest }) => { ) }) -const styles = StyleSheet.create(({ theme }) => ({ +const styles = StyleSheet.create(({ components }) => ({ icon: { - height: theme.Form.Rating.ratingIconFontSize, - width: theme.Form.Rating.ratingIconFontSize, + height: components.rating.icon.size, + width: components.rating.icon.size, }, })) diff --git a/src/components/Rating/RatingItemContainer.tsx b/src/components/Rating/RatingItemContainer.tsx index 3776dbc7..c39eceff 100644 --- a/src/components/Rating/RatingItemContainer.tsx +++ b/src/components/Rating/RatingItemContainer.tsx @@ -55,16 +55,13 @@ export const RatingItemContainer = memo( } ) -const styles = StyleSheet.create(({ theme, sizing }) => ({ +const styles = StyleSheet.create(({ components }) => ({ container: { alignItems: 'center', justifyContent: 'center', - width: theme.Form.Rating.ratingIconFontSize, - height: theme.Form.Rating.ratingIconFontSize, + width: components.rating.icon.size, + height: components.rating.icon.size, }, - containerWithPaddings: { - width: sizing.Width['w-3'], - height: sizing.Height['h-3'], - }, + containerWithPaddings: { width: 42, height: 42 }, })) diff --git a/src/components/Rating/__tests__/__snapshots__/Rating.test.tsx.snap b/src/components/Rating/__tests__/__snapshots__/Rating.test.tsx.snap index 9a97587d..19ba0f8e 100644 --- a/src/components/Rating/__tests__/__snapshots__/Rating.test.tsx.snap +++ b/src/components/Rating/__tests__/__snapshots__/Rating.test.tsx.snap @@ -6,7 +6,7 @@ exports[`Rating component tests renders correctly with default props 1`] = ` { "alignItems": "center", "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -44,9 +44,9 @@ exports[`Rating component tests renders correctly with default props 1`] = ` [ { "alignItems": "center", - "height": 17.5, + "height": 24, "justifyContent": "center", - "width": 17.5, + "width": 24, }, false, ] @@ -55,11 +55,11 @@ exports[`Rating component tests renders correctly with default props 1`] = ` > @@ -827,9 +827,9 @@ exports[`Rating component tests renders the correct number of checked items - $r [ { "alignItems": "center", - "height": 17.5, + "height": 24, "justifyContent": "center", - "width": 17.5, + "width": 24, }, false, ] @@ -838,11 +838,11 @@ exports[`Rating component tests renders the correct number of checked items - $r > @@ -1610,9 +1610,9 @@ exports[`Rating component tests renders the correct number of checked items - $r [ { "alignItems": "center", - "height": 17.5, + "height": 24, "justifyContent": "center", - "width": 17.5, + "width": 24, }, false, ] @@ -1621,11 +1621,11 @@ exports[`Rating component tests renders the correct number of checked items - $r > Date: Tue, 4 Aug 2026 17:05:48 +0300 Subject: [PATCH 32/40] =?UTF-8?q?feat(SelectButton):=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SelectButton/SelectButton.tsx | 29 ++-- .../SelectButton/SelectButtonItem.tsx | 129 ++++++++++-------- .../__tests__/SelectButtonItem.test.tsx | 36 +++-- 3 files changed, 101 insertions(+), 93 deletions(-) diff --git a/src/components/SelectButton/SelectButton.tsx b/src/components/SelectButton/SelectButton.tsx index 24fe6ab8..68f6fff5 100644 --- a/src/components/SelectButton/SelectButton.tsx +++ b/src/components/SelectButton/SelectButton.tsx @@ -271,25 +271,26 @@ export const SelectButton = memo((props) => ( )) -const styles = StyleSheet.create(({ theme }) => ({ +// Осознанный обход слоя components: цвет невыбранного пункта — семантическая +// роль «приглушённый текст». Собственного токена у selectbutton нет, а то же +// значение приходит в tabs.tab.color и menu.item.color. +const styles = StyleSheet.create(({ components, semantic }) => ({ container: { flexDirection: 'row', - padding: theme.Form.SelectButton.selectButtonGroupPadding, - gap: theme.Form.SelectButton.selectButtonGroupPadding, - borderRadius: theme.General.borderRadiusXL, - backgroundColor: theme.Form.SelectButton.selectButtonGroupBg, + padding: components.selectbutton.extend.paddingX, + gap: components.selectbutton.extend.paddingX, + borderRadius: components.selectbutton.root.borderRadius, + backgroundColor: components.selectbutton.colorScheme.extend.background, }, frame: { position: 'absolute', - top: theme.Form.SelectButton.selectButtonGroupPadding, - bottom: theme.Form.SelectButton.selectButtonGroupPadding, - left: theme.Form.SelectButton.selectButtonGroupPadding, - borderRadius: theme.Form.SelectButton.selectButtonBorderRadius, - backgroundColor: theme.Form.SelectButton.selectButtonActiveBg, + top: components.selectbutton.extend.paddingY, + bottom: components.selectbutton.extend.paddingY, + left: components.selectbutton.extend.paddingX, + borderRadius: components.selectbutton.extend.ext.borderRadius, + backgroundColor: components.selectbutton.extend.checkedBackground, zIndex: -1, }, - textColor: { color: theme.Form.SelectButton.selectButtonTextColor }, - checkedTextColor: { - color: theme.Form.SelectButton.selectButtonIconActiveColor, - }, + textColor: { color: semantic.colorScheme.color.fg.muted }, + checkedTextColor: { color: components.selectbutton.extend.checkedColor }, })) diff --git a/src/components/SelectButton/SelectButtonItem.tsx b/src/components/SelectButton/SelectButtonItem.tsx index 4c8ca4e6..3f7da2d7 100644 --- a/src/components/SelectButton/SelectButtonItem.tsx +++ b/src/components/SelectButton/SelectButtonItem.tsx @@ -127,13 +127,15 @@ export const SelectButtonItem = memo( {...iconSize} source={Icon} testID='SelectButtonItem_Icon' - uniProps={({ theme }) => ({ - color: disabled - ? theme.Button.Disabled.disabledButtonBorderColor - : isSelected - ? theme.Form.SelectButton.selectButtonIconActiveColor - : theme.Form.SelectButton.selectButtonTextColor, - })} + uniProps={({ components, semantic }) => { + return { + color: disabled + ? semantic.colorScheme.color.border.neutral.strong + : isSelected + ? components.selectbutton.extend.checkedColor + : semantic.colorScheme.color.fg.muted, + } + }} /> ) : null} ( } ) -const styles = StyleSheet.create( - ({ theme, typography, border, spacing, fonts }) => ({ - container: { - flex: 1, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - gap: theme.General.inlineSpacing, - borderWidth: border.Width.border, - borderColor: 'transparent', - }, - small: { height: theme.Button.Common.buttonHeightSM }, - base: { height: theme.Button.Common.buttonHeight }, - large: { - height: theme.Button.Common.buttonHeightLG, - gap: spacing.Gap['gap-3'], - }, - xlarge: { - height: theme.Button.Common.buttonHeightXL, - gap: spacing.Gap['gap-3'], - }, - disabledContainer: { - borderRadius: theme.Form.SelectButton.selectButtonBorderRadius, - borderWidth: 1, - borderColor: theme.Button.Disabled.disabledButtonBorderColor, - }, - iconSmall: { - width: typography.Size['text-base'], - height: typography.Size['text-base'], - }, - iconBase: { - width: typography.Size['text-xl'], - height: typography.Size['text-xl'], - }, - iconLarge: { - width: typography.Size['text-2xl'], - height: typography.Size['text-2xl'], - }, - iconXLarge: { width: 28, height: 28 }, - label: { flexShrink: 1, fontWeight: 600, fontFamily: fonts.primary }, - labelSmall: { fontSize: typography.Size['text-sm'] }, - labelBase: { fontSize: typography.Size['text-base'] }, - labelLarge: { fontSize: typography.Size['text-xl'] }, - labelXLarge: { fontSize: typography.Size['text-2xl'] }, - textColor: { color: theme.Form.SelectButton.selectButtonTextColor }, - checkedTextColor: { - color: theme.Form.SelectButton.selectButtonIconActiveColor, - }, - disabledTextColor: { - color: theme.Button.Disabled.disabledButtonBorderColor, - }, - }) -) +// Осознанный обход слоя components: цвет невыбранного пункта — семантическая +// роль «приглушённый текст». Собственного токена у selectbutton нет, а то же +// значение приходит в tabs.tab.color и menu.item.color. +const styles = StyleSheet.create(({ components, semantic, fonts }) => ({ + container: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + gap: components.selectbutton.extend.gap, + borderWidth: semantic.dimension.borderWidth[100], + borderColor: 'transparent', + }, + small: { height: semantic.dimension.size[800] }, + base: { height: semantic.dimension.size[1100] }, + large: { + height: semantic.dimension.size[1300], + gap: components.selectbutton.extend.gap, + }, + xlarge: { + height: semantic.dimension.size[1400], + gap: components.selectbutton.extend.gap, + }, + disabledContainer: { + borderRadius: components.selectbutton.extend.ext.borderRadius, + borderWidth: semantic.dimension.borderWidth[100], + borderColor: semantic.colorScheme.color.border.neutral.strong, + }, + iconSmall: { + width: components.selectbutton.extend.iconSize.sm, + height: components.selectbutton.extend.iconSize.sm, + }, + iconBase: { + width: components.selectbutton.extend.iconSize.md, + height: components.selectbutton.extend.iconSize.md, + }, + iconLarge: { + width: components.selectbutton.extend.iconSize.lg, + height: components.selectbutton.extend.iconSize.lg, + }, + // Токена iconSize для xlarge в дизайн-системе нет — размер взят semantic-ролью. + iconXLarge: { + width: semantic.dimension.size[800], + height: semantic.dimension.size[800], + }, + label: { + flexShrink: 1, + fontWeight: fonts.fontWeight.demibold, + fontFamily: fonts.fontFamily.heading, + }, + labelSmall: { fontSize: fonts.fontSize[100] }, + labelBase: { fontSize: fonts.fontSize[300] }, + labelLarge: { fontSize: fonts.fontSize[500] }, + labelXLarge: { fontSize: fonts.fontSize[600] }, + textColor: { color: semantic.colorScheme.color.fg.muted }, + checkedTextColor: { color: components.selectbutton.extend.checkedColor }, + disabledTextColor: { + color: semantic.colorScheme.color.border.neutral.strong, + }, +})) diff --git a/src/components/SelectButton/__tests__/SelectButtonItem.test.tsx b/src/components/SelectButton/__tests__/SelectButtonItem.test.tsx index c0a9806a..14a2d4be 100644 --- a/src/components/SelectButton/__tests__/SelectButtonItem.test.tsx +++ b/src/components/SelectButton/__tests__/SelectButtonItem.test.tsx @@ -5,6 +5,8 @@ import { Pressable } from 'react-native' import { useSharedValue } from 'react-native-reanimated' import { lightTheme } from '../../../theme' +import { fontTokens, semanticTokens } from '../../../theme/tokens' +import lightComponentTokens from '../../../theme/tokens/components/light.json' import { type SelectButtonItemProps, SelectButtonItem, @@ -63,30 +65,30 @@ const sizeCases: Array<{ { name: 'маленький', size: 'small', - height: lightTheme.theme.Button.Common.buttonHeightSM, - iconSize: lightTheme.typography.Size['text-base'], - fontSize: lightTheme.typography.Size['text-sm'], + height: semanticTokens.dimension.size[800], + iconSize: fontTokens.fontSize[300], + fontSize: fontTokens.fontSize[100], }, { name: 'базовый', size: 'base', - height: lightTheme.theme.Button.Common.buttonHeight, - iconSize: lightTheme.typography.Size['text-xl'], - fontSize: lightTheme.typography.Size['text-base'], + height: semanticTokens.dimension.size[1100], + iconSize: fontTokens.fontSize[500], + fontSize: fontTokens.fontSize[300], }, { name: 'большой', size: 'large', - height: lightTheme.theme.Button.Common.buttonHeightLG, - iconSize: lightTheme.typography.Size['text-2xl'], - fontSize: lightTheme.typography.Size['text-xl'], + height: semanticTokens.dimension.size[1300], + iconSize: fontTokens.fontSize[600], + fontSize: fontTokens.fontSize[500], }, { name: 'самый большой', size: 'xlarge', - height: lightTheme.theme.Button.Common.buttonHeightXL, + height: semanticTokens.dimension.size[1400], iconSize: 28, - fontSize: lightTheme.typography.Size['text-2xl'], + fontSize: fontTokens.fontSize[600], }, ] @@ -192,12 +194,10 @@ describe('SelectButtonItem', () => { await waitFor(() => { expect(icon).toHaveProp( 'stroke', - lightTheme.theme.Form.SelectButton.selectButtonIconActiveColor + lightComponentTokens.selectbutton.extend.checkedColor ) expect(text).toHaveAnimatedStyle({ - color: toRgba( - lightTheme.theme.Form.SelectButton.selectButtonIconActiveColor - ), + color: toRgba(lightComponentTokens.selectbutton.extend.checkedColor), }) }) @@ -207,12 +207,10 @@ describe('SelectButtonItem', () => { await waitFor(() => { expect(icon).toHaveProp( 'stroke', - lightTheme.theme.Form.SelectButton.selectButtonTextColor + lightTheme.semantic.colorScheme.color.fg.muted ) expect(text).toHaveAnimatedStyle({ - color: toRgba( - lightTheme.theme.Form.SelectButton.selectButtonTextColor - ), + color: toRgba(lightTheme.semantic.colorScheme.color.fg.muted), }) }) }) From a18c50358525e9390cb9969e981e08668147526f Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:48 +0300 Subject: [PATCH 33/40] =?UTF-8?q?feat(Skeleton):=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Skeleton/Skeleton.tsx | 10 ++++++---- .../__tests__/__snapshots__/Skeleton.test.tsx.snap | 12 ++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/components/Skeleton/Skeleton.tsx b/src/components/Skeleton/Skeleton.tsx index 1aa52ffe..3e0813d7 100644 --- a/src/components/Skeleton/Skeleton.tsx +++ b/src/components/Skeleton/Skeleton.tsx @@ -87,14 +87,16 @@ export const Skeleton = memo(({ style, testID, ...rest }) => { ) }) -const styles = StyleSheet.create(({ border, theme }) => ({ +const styles = StyleSheet.create(({ components: { skeleton } }) => ({ container: { - borderRadius: border.Radius['rounded-lg'], + borderRadius: skeleton.root.borderRadius, overflow: 'hidden', - backgroundColor: theme.Misc.Skeleton.skeletonBg, + backgroundColor: skeleton.colorScheme.root.background, }, gradientContainer: { position: 'absolute', height: '100%' }, - gradientColor: { backgroundColor: theme.Misc.Skeleton.skeletonAnimationBg }, + gradientColor: { + backgroundColor: skeleton.colorScheme.root.animationBackground, + }, })) export const SkeletonTestId = { diff --git a/src/components/Skeleton/__tests__/__snapshots__/Skeleton.test.tsx.snap b/src/components/Skeleton/__tests__/__snapshots__/Skeleton.test.tsx.snap index 2da3ca1f..14b2bb9d 100644 --- a/src/components/Skeleton/__tests__/__snapshots__/Skeleton.test.tsx.snap +++ b/src/components/Skeleton/__tests__/__snapshots__/Skeleton.test.tsx.snap @@ -7,7 +7,7 @@ exports[`Skeleton 50% animation 1`] = ` [ { "backgroundColor": "#e2e2e4", - "borderRadius": 7, + "borderRadius": 14, "overflow": "hidden", }, { @@ -100,7 +100,7 @@ exports[`Skeleton 50% animation 1`] = ` 0, 1726145252, 0.5, - 1728053247, + 1727066353, 1, 1726145252, ] @@ -144,7 +144,7 @@ exports[`Skeleton 100% animation 1`] = ` [ { "backgroundColor": "#e2e2e4", - "borderRadius": 7, + "borderRadius": 14, "overflow": "hidden", }, { @@ -237,7 +237,7 @@ exports[`Skeleton 100% animation 1`] = ` 0, 1726145252, 0.5, - 1728053247, + 1727066353, 1, 1726145252, ] @@ -281,7 +281,7 @@ exports[`Skeleton before animation started: before animation started 1`] = ` [ { "backgroundColor": "#e2e2e4", - "borderRadius": 7, + "borderRadius": 14, "overflow": "hidden", }, { @@ -374,7 +374,7 @@ exports[`Skeleton before animation started: before animation started 1`] = ` 0, 1726145252, 0.5, - 1728053247, + 1727066353, 1, 1726145252, ] From fa78e690a84d44f7629dec761f7ab71c26e98b80 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:49 +0300 Subject: [PATCH 34/40] =?UTF-8?q?feat(Slider):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Slider/Slider.tsx | 73 +++--- .../__snapshots__/Slider.test.tsx.snap | 246 +++++++++--------- 2 files changed, 158 insertions(+), 161 deletions(-) diff --git a/src/components/Slider/Slider.tsx b/src/components/Slider/Slider.tsx index 8195b651..60c4a6cb 100644 --- a/src/components/Slider/Slider.tsx +++ b/src/components/Slider/Slider.tsx @@ -252,41 +252,38 @@ export const Slider = memo( } ) -const styles = StyleSheet.create(({ theme, border }) => { - return { - container: { - width: '100%', - justifyContent: 'center', - alignItems: 'center', - }, - track: { - height: theme.Form.Slider.sliderHorizontalHeight, - backgroundColor: theme.Form.Slider.sliderBg, - borderRadius: theme.Form.Slider.sliderHandleBorderRadius, - position: 'relative', - width: '100%', - justifyContent: 'center', - }, - - line: { - height: theme.Form.Slider.sliderHorizontalHeight, - borderRadius: theme.Form.Slider.sliderHandleBorderRadius, - position: 'absolute', - backgroundColor: theme.Form.Slider.sliderRangeBg, - }, - - point: { - width: theme.Form.Slider.sliderHandleWidth, - height: theme.Form.Slider.sliderHandleHeight, - borderRadius: theme.Form.Slider.sliderHandleHeight / 2, - position: 'absolute', - backgroundColor: theme.Form.Slider.sliderHandleBg, - borderWidth: border.Width['border-3'], - borderColor: theme.Form.Slider.sliderHandleBorder, - }, - - disabled: { opacity: 0.6, mixBlendMode: 'luminosity' }, - - hovered: { backgroundColor: theme.Form.Slider.sliderHandleHoverBg }, - } -}) +const styles = StyleSheet.create(({ components, semantic }) => ({ + container: { width: '100%', justifyContent: 'center', alignItems: 'center' }, + track: { + height: components.slider.track.size, + backgroundColor: components.slider.track.background, + borderRadius: components.slider.track.borderRadius, + position: 'relative', + width: '100%', + justifyContent: 'center', + }, + + line: { + height: components.slider.track.size, + borderRadius: components.slider.track.borderRadius, + position: 'absolute', + backgroundColor: components.slider.range.background, + }, + + point: { + width: components.slider.handle.width, + height: components.slider.handle.height, + borderRadius: components.slider.handle.borderRadius, + position: 'absolute', + backgroundColor: components.slider.colorScheme.handle.content.background, + borderWidth: semantic.dimension.borderWidth[300], + borderColor: components.slider.handle.background, + }, + + disabled: { + opacity: semantic.effects.opacity[60], + mixBlendMode: 'luminosity', + }, + + hovered: { backgroundColor: components.slider.handle.hoverBackground }, +})) diff --git a/src/components/Slider/__tests__/__snapshots__/Slider.test.tsx.snap b/src/components/Slider/__tests__/__snapshots__/Slider.test.tsx.snap index 0a400845..9079a675 100644 --- a/src/components/Slider/__tests__/__snapshots__/Slider.test.tsx.snap +++ b/src/components/Slider/__tests__/__snapshots__/Slider.test.tsx.snap @@ -19,7 +19,7 @@ exports[`Slider snapshots default 1`] = ` { "backgroundColor": "#e2e2e4", "borderRadius": 14, - "height": 3.5, + "height": 4, "justifyContent": "center", "position": "relative", "width": "100%", @@ -37,7 +37,7 @@ exports[`Slider snapshots default 1`] = ` { "value": { "left": 0, - "width": 8.75, + "width": 10, }, } } @@ -47,7 +47,7 @@ exports[`Slider snapshots default 1`] = ` { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, @@ -59,13 +59,13 @@ exports[`Slider snapshots default 1`] = ` { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, { "left": 0, - "width": 8.75, + "width": 10, }, ] } @@ -94,11 +94,11 @@ exports[`Slider snapshots default 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, ], @@ -110,11 +110,11 @@ exports[`Slider snapshots default 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, { @@ -150,7 +150,7 @@ exports[`Slider snapshots disabled = false, range = false 1`] = ` { "backgroundColor": "#e2e2e4", "borderRadius": 14, - "height": 3.5, + "height": 4, "justifyContent": "center", "position": "relative", "width": "100%", @@ -168,7 +168,7 @@ exports[`Slider snapshots disabled = false, range = false 1`] = ` { "value": { "left": 0, - "width": 8.75, + "width": 10, }, } } @@ -178,7 +178,7 @@ exports[`Slider snapshots disabled = false, range = false 1`] = ` { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, @@ -190,13 +190,13 @@ exports[`Slider snapshots disabled = false, range = false 1`] = ` { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, { "left": 0, - "width": 8.75, + "width": 10, }, ] } @@ -225,11 +225,11 @@ exports[`Slider snapshots disabled = false, range = false 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, ], @@ -241,11 +241,11 @@ exports[`Slider snapshots disabled = false, range = false 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, { @@ -281,7 +281,7 @@ exports[`Slider snapshots disabled = false, range = true 1`] = ` { "backgroundColor": "#e2e2e4", "borderRadius": 14, - "height": 3.5, + "height": 4, "justifyContent": "center", "position": "relative", "width": "100%", @@ -298,7 +298,7 @@ exports[`Slider snapshots disabled = false, range = true 1`] = ` jestAnimatedStyle={ { "value": { - "left": 8.75, + "left": 10, "width": 0, }, } @@ -309,7 +309,7 @@ exports[`Slider snapshots disabled = false, range = true 1`] = ` { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, @@ -321,12 +321,12 @@ exports[`Slider snapshots disabled = false, range = true 1`] = ` { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, { - "left": 8.75, + "left": 10, "width": 0, }, ] @@ -356,11 +356,11 @@ exports[`Slider snapshots disabled = false, range = true 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, ], @@ -372,11 +372,11 @@ exports[`Slider snapshots disabled = false, range = true 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, { @@ -413,11 +413,11 @@ exports[`Slider snapshots disabled = false, range = true 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, ], @@ -429,11 +429,11 @@ exports[`Slider snapshots disabled = false, range = true 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, { @@ -469,7 +469,7 @@ exports[`Slider snapshots disabled = false, range = true, maxPointerValueInit = { "backgroundColor": "#e2e2e4", "borderRadius": 14, - "height": 3.5, + "height": 4, "justifyContent": "center", "position": "relative", "width": "100%", @@ -486,7 +486,7 @@ exports[`Slider snapshots disabled = false, range = true, maxPointerValueInit = jestAnimatedStyle={ { "value": { - "left": 8.75, + "left": 10, "width": 0, }, } @@ -497,7 +497,7 @@ exports[`Slider snapshots disabled = false, range = true, maxPointerValueInit = { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, @@ -509,12 +509,12 @@ exports[`Slider snapshots disabled = false, range = true, maxPointerValueInit = { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, { - "left": 8.75, + "left": 10, "width": 0, }, ] @@ -544,11 +544,11 @@ exports[`Slider snapshots disabled = false, range = true, maxPointerValueInit = { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, ], @@ -560,11 +560,11 @@ exports[`Slider snapshots disabled = false, range = true, maxPointerValueInit = { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, { @@ -601,11 +601,11 @@ exports[`Slider snapshots disabled = false, range = true, maxPointerValueInit = { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, ], @@ -617,11 +617,11 @@ exports[`Slider snapshots disabled = false, range = true, maxPointerValueInit = { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, { @@ -660,7 +660,7 @@ exports[`Slider snapshots disabled = true, range = false 1`] = ` { "backgroundColor": "#e2e2e4", "borderRadius": 14, - "height": 3.5, + "height": 4, "justifyContent": "center", "position": "relative", "width": "100%", @@ -678,7 +678,7 @@ exports[`Slider snapshots disabled = true, range = false 1`] = ` { "value": { "left": 0, - "width": 8.75, + "width": 10, }, } } @@ -688,7 +688,7 @@ exports[`Slider snapshots disabled = true, range = false 1`] = ` { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, @@ -700,13 +700,13 @@ exports[`Slider snapshots disabled = true, range = false 1`] = ` { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, { "left": 0, - "width": 8.75, + "width": 10, }, ] } @@ -735,11 +735,11 @@ exports[`Slider snapshots disabled = true, range = false 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, ], @@ -751,11 +751,11 @@ exports[`Slider snapshots disabled = true, range = false 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, { @@ -794,7 +794,7 @@ exports[`Slider snapshots disabled = true, range = true 1`] = ` { "backgroundColor": "#e2e2e4", "borderRadius": 14, - "height": 3.5, + "height": 4, "justifyContent": "center", "position": "relative", "width": "100%", @@ -811,7 +811,7 @@ exports[`Slider snapshots disabled = true, range = true 1`] = ` jestAnimatedStyle={ { "value": { - "left": 8.75, + "left": 10, "width": 0, }, } @@ -822,7 +822,7 @@ exports[`Slider snapshots disabled = true, range = true 1`] = ` { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, @@ -834,12 +834,12 @@ exports[`Slider snapshots disabled = true, range = true 1`] = ` { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, { - "left": 8.75, + "left": 10, "width": 0, }, ] @@ -869,11 +869,11 @@ exports[`Slider snapshots disabled = true, range = true 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, ], @@ -885,11 +885,11 @@ exports[`Slider snapshots disabled = true, range = true 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, { @@ -926,11 +926,11 @@ exports[`Slider snapshots disabled = true, range = true 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, ], @@ -942,11 +942,11 @@ exports[`Slider snapshots disabled = true, range = true 1`] = ` { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, { @@ -985,7 +985,7 @@ exports[`Slider snapshots disabled = true, range = true, maxPointerValueInit = 8 { "backgroundColor": "#e2e2e4", "borderRadius": 14, - "height": 3.5, + "height": 4, "justifyContent": "center", "position": "relative", "width": "100%", @@ -1002,7 +1002,7 @@ exports[`Slider snapshots disabled = true, range = true, maxPointerValueInit = 8 jestAnimatedStyle={ { "value": { - "left": 8.75, + "left": 10, "width": 0, }, } @@ -1013,7 +1013,7 @@ exports[`Slider snapshots disabled = true, range = true, maxPointerValueInit = 8 { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, @@ -1025,12 +1025,12 @@ exports[`Slider snapshots disabled = true, range = true, maxPointerValueInit = 8 { "backgroundColor": "#2b2e33", "borderRadius": 14, - "height": 3.5, + "height": 4, "position": "absolute", }, false, { - "left": 8.75, + "left": 10, "width": 0, }, ] @@ -1060,11 +1060,11 @@ exports[`Slider snapshots disabled = true, range = true, maxPointerValueInit = 8 { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, ], @@ -1076,11 +1076,11 @@ exports[`Slider snapshots disabled = true, range = true, maxPointerValueInit = 8 { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, { @@ -1117,11 +1117,11 @@ exports[`Slider snapshots disabled = true, range = true, maxPointerValueInit = 8 { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, ], @@ -1133,11 +1133,11 @@ exports[`Slider snapshots disabled = true, range = true, maxPointerValueInit = 8 { "backgroundColor": "#ffffff", "borderColor": "#2b2e33", - "borderRadius": 8.75, - "borderWidth": 3, - "height": 17.5, + "borderRadius": 1600, + "borderWidth": 4, + "height": 20, "position": "absolute", - "width": 17.5, + "width": 20, }, false, { From 98e8631f98f747cdbaa65fdcbf75b1387acb87eb Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:49 +0300 Subject: [PATCH 35/40] =?UTF-8?q?feat(Tabs):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Tabs/TabItem/TabItem.tsx | 59 +-- src/components/Tabs/Tabs.tsx | 12 +- .../__snapshots__/Tabs.test.tsx.snap | 466 +++++++++--------- 3 files changed, 270 insertions(+), 267 deletions(-) diff --git a/src/components/Tabs/TabItem/TabItem.tsx b/src/components/Tabs/TabItem/TabItem.tsx index 71168592..7f65a7c9 100644 --- a/src/components/Tabs/TabItem/TabItem.tsx +++ b/src/components/Tabs/TabItem/TabItem.tsx @@ -56,15 +56,17 @@ export const TabItem = memo( ({ - color: disabled - ? theme.Button.Disabled.disabledButtonTextColor - : pressed - ? theme.Panel.TabView.tabviewHeaderHoverTextColor - : active - ? theme.Panel.TabView.tabviewHeaderActiveTextColor - : theme.Panel.TabView.tabviewHeaderTextColor, - })} + uniProps={({ components, semantic }) => { + return { + color: disabled + ? semantic.colorScheme.color.fg.muted + : pressed + ? components.tabs.tab.hoverColor + : active + ? components.tabs.tab.activeColor + : components.tabs.tab.color, + } + }} /> ) : null} ( } ) -const styles = StyleSheet.create(({ theme, typography, fonts }) => ({ +const styles = StyleSheet.create(({ components, semantic, fonts }) => ({ container: { alignItems: 'center', flexDirection: 'row', - height: - theme.Misc.Badge.badgeHeight + - theme.Panel.TabView.tabviewHeaderPaddingTopBottom * 2, - gap: theme.General.inlineSpacing, - paddingHorizontal: theme.Panel.TabView.tabviewHeaderPaddingLeftRight, - paddingVertical: theme.Panel.TabView.tabviewHeaderPaddingTopBottom, + height: semantic.dimension.size[700] + components.tabs.tab.padding * 2, + gap: components.tabs.tab.gap, + paddingHorizontal: components.tabs.tab.padding, + paddingVertical: components.tabs.tab.padding, - backgroundColor: theme.Panel.TabView.tabviewHeaderBg, + backgroundColor: components.tabs.colorScheme.tab.background, }, pressedContainer: { - backgroundColor: theme.Panel.TabView.tabviewHeaderHoverBg, + backgroundColor: components.tabs.colorScheme.tab.hoverBackground, }, activeContainer: { - backgroundColor: theme.Panel.TabView.tabviewHeaderActiveBg, + backgroundColor: components.tabs.colorScheme.tab.activeBackground, + }, + disabledContainer: { + opacity: semantic.effects.opacity[60], + mixBlendMode: 'luminosity', }, - disabledContainer: { opacity: 0.6, mixBlendMode: 'luminosity' }, icon: { - width: theme.Menu.Item.menuitemSubmenuIconFontSize, - height: theme.Menu.Item.menuitemSubmenuIconFontSize, + width: semantic.dimension.size[600], + height: semantic.dimension.size[600], }, text: { - fontFamily: fonts.primary, - fontSize: typography.Size['text-base'], + fontFamily: fonts.fontFamily.heading, + fontSize: fonts.fontSize[300], verticalAlign: 'middle', includeFontPadding: false, - color: theme.Panel.TabView.tabviewHeaderTextColor, + color: components.tabs.tab.color, }, - pressedText: { color: theme.Panel.TabView.tabviewHeaderHoverTextColor }, - activeText: { color: theme.Panel.TabView.tabviewHeaderActiveTextColor }, - disabledText: { color: theme.Button.Disabled.disabledButtonTextColor }, + pressedText: { color: components.tabs.tab.hoverColor }, + activeText: { color: components.tabs.tab.activeColor }, + disabledText: { color: semantic.colorScheme.color.fg.muted }, })) export enum TestId { diff --git a/src/components/Tabs/Tabs.tsx b/src/components/Tabs/Tabs.tsx index 497546b6..3c94a134 100644 --- a/src/components/Tabs/Tabs.tsx +++ b/src/components/Tabs/Tabs.tsx @@ -91,19 +91,19 @@ export const Tabs = memo( } ) -const styles = StyleSheet.create(({ theme, border }) => ({ +const styles = StyleSheet.create(({ components, semantic }) => ({ container: { flexDirection: 'row', - gap: theme.Panel.TabView.tabviewHeaderSpacing, + gap: components.tabs.tab.margin, - borderBottomWidth: border.Width.border, - borderColor: theme.Panel.TabView.tabviewNavBorderColor, + borderBottomWidth: semantic.dimension.borderWidth[100], + borderColor: components.tabs.tablist.borderColor, }, line: { position: 'absolute', bottom: 0, - height: border.Width['border-2'], + height: semantic.dimension.borderWidth[200], - backgroundColor: theme.Panel.TabView.tabviewHeaderActiveBorderColor, + backgroundColor: components.tabs.activeBar.background, }, })) diff --git a/src/components/Tabs/__tests__/__snapshots__/Tabs.test.tsx.snap b/src/components/Tabs/__tests__/__snapshots__/Tabs.test.tsx.snap index 70574bf1..e4a3b881 100644 --- a/src/components/Tabs/__tests__/__snapshots__/Tabs.test.tsx.snap +++ b/src/components/Tabs/__tests__/__snapshots__/Tabs.test.tsx.snap @@ -39,16 +39,16 @@ exports[`TabItem component tests active: label 1`] = ` [ { "alignItems": "center", - "backgroundColor": "rgba(255, 255, 255, 0.0001)", + "backgroundColor": "transparent", "flexDirection": "row", - "gap": 7, - "height": 49, - "paddingHorizontal": 0, + "gap": 8, + "height": 52, + "paddingHorizontal": 14, "paddingVertical": 14, }, false, { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", + "backgroundColor": "transparent", }, undefined, ] @@ -61,12 +61,12 @@ exports[`TabItem component tests active: label 1`] = ` { "color": "#85888e", "fontFamily": "TT Fellows", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, "verticalAlign": "middle", }, { - "color": "#000000", + "color": "#2b2e33", }, false, undefined, @@ -118,16 +118,16 @@ exports[`TabItem component tests active: label, badge 1`] = ` [ { "alignItems": "center", - "backgroundColor": "rgba(255, 255, 255, 0.0001)", + "backgroundColor": "transparent", "flexDirection": "row", - "gap": 7, - "height": 49, - "paddingHorizontal": 0, + "gap": 8, + "height": 52, + "paddingHorizontal": 14, "paddingVertical": 14, }, false, { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", + "backgroundColor": "transparent", }, undefined, ] @@ -140,12 +140,12 @@ exports[`TabItem component tests active: label, badge 1`] = ` { "color": "#85888e", "fontFamily": "TT Fellows", - "fontSize": 14, + "fontSize": 16, "includeFontPadding": false, "verticalAlign": "middle", }, { - "color": "#000000", + "color": "#2b2e33", }, false, undefined, @@ -171,10 +171,10 @@ exports[`TabItem component tests active: label, badge 1`] = ` "backgroundColor": "#44e858", }, { - "borderRadius": 100, - "height": 21, + "borderRadius": 1600, + "height": 24, "justifyContent": "center", - "paddingHorizontal": 7, + "paddingHorizontal": 8, }, ] } @@ -184,9 +184,9 @@ exports[`TabItem component tests active: label, badge 1`] = ` style={ [ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", }, @@ -219,9 +219,9 @@ exports[`TabItem component tests active: label, badge 1`] = ` onLayout={[Function]} style={ { - "color": "#000000", + "color": "#2b2e33", "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", } @@ -275,16 +275,16 @@ exports[`TabItem component tests active: label, icon 1`] = ` [ { "alignItems": "center", - "backgroundColor": "rgba(255, 255, 255, 0.0001)", + "backgroundColor": "transparent", "flexDirection": "row", - "gap": 7, - "height": 49, - "paddingHorizontal": 0, + "gap": 8, + "height": 52, + "paddingHorizontal": 14, "paddingVertical": 14, }, false, { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", + "backgroundColor": "transparent", }, undefined, ] @@ -292,15 +292,15 @@ exports[`TabItem component tests active: label, icon 1`] = ` > @@ -2160,16 +2160,16 @@ exports[`Tabs component tests disabled 1`] = ` [ { "alignItems": "center", - "backgroundColor": "rgba(255, 255, 255, 0.0001)", + "backgroundColor": "transparent", "flexDirection": "row", - "gap": 7, - "height": 49, - "paddingHorizontal": 0, + "gap": 8, + "height": 52, + "paddingHorizontal": 14, "paddingVertical": 14, }, false, { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", + "backgroundColor": "transparent", }, { "mixBlendMode": "luminosity", @@ -2180,11 +2180,11 @@ exports[`Tabs component tests disabled 1`] = ` > @@ -2632,16 +2632,16 @@ exports[`Tabs component tests normal 1`] = ` [ { "alignItems": "center", - "backgroundColor": "rgba(255, 255, 255, 0.0001)", + "backgroundColor": "transparent", "flexDirection": "row", - "gap": 7, - "height": 49, - "paddingHorizontal": 0, + "gap": 8, + "height": 52, + "paddingHorizontal": 14, "paddingVertical": 14, }, false, { - "backgroundColor": "rgba(255, 255, 255, 0.0001)", + "backgroundColor": "transparent", }, false, ] @@ -2649,15 +2649,15 @@ exports[`Tabs component tests normal 1`] = ` > Date: Tue, 4 Aug 2026 17:05:50 +0300 Subject: [PATCH 36/40] =?UTF-8?q?feat(Tag):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Tag/Tag.tsx | 117 ++++++++-------- .../__tests__/__snapshots__/Tag.test.tsx.snap | 128 +++++++++--------- 2 files changed, 120 insertions(+), 125 deletions(-) diff --git a/src/components/Tag/Tag.tsx b/src/components/Tag/Tag.tsx index d1437ee9..67cb3231 100644 --- a/src/components/Tag/Tag.tsx +++ b/src/components/Tag/Tag.tsx @@ -10,7 +10,7 @@ import { import { StyleSheet } from 'react-native-unistyles' -import type { ThemeType } from '../../theme/types' +import type { ComponentTokens } from '../../theme/tokens/index' import { type SvgSource, SvgUniversal } from '../../utils/SvgUniversal' export interface TagProps @@ -42,13 +42,13 @@ export interface TagProps type TagSeverity = NonNullable -const tagIconColor: Record string> = { - basic: (t) => t.Misc.Badge.badgeTextColor, - info: (t) => t.Misc.Badge.badgeInfoTextColor, - success: (t) => t.Misc.Badge.badgeSuccessTextColor, - warning: (t) => t.Misc.Badge.badgeWarningTextColor, - danger: (t) => t.Misc.Badge.badgeDangerTextColor, - secondary: (t) => t.Misc.Badge.badgeTextColor, +const tagIconColor: Record string> = { + basic: (t) => t.tag.colorScheme.primary.color, + info: (t) => t.tag.colorScheme.info.color, + success: (t) => t.tag.colorScheme.success.color, + warning: (t) => t.tag.colorScheme.warn.color, + danger: (t) => t.tag.colorScheme.danger.color, + secondary: (t) => t.tag.colorScheme.secondary.color, } /** @@ -79,9 +79,9 @@ export const Tag = memo( {...tagStyles.icon} source={Icon} testID={TagTestId.icon} - uniProps={({ theme }) => ({ - color: tagIconColor[severity](theme), - })} + uniProps={({ components }) => { + return { color: tagIconColor[severity](components) } + }} /> ) : null} ( } ) -const tagStyles = StyleSheet.create( - ({ theme, border, spacing, typography, fonts }) => ({ - container: { - alignSelf: 'flex-start', - flexDirection: 'row', - alignItems: 'center', - gap: spacing.Gap['gap-1'], - paddingHorizontal: theme.Misc.Tag.tagPadding, - height: theme.Misc.Tag.tagHeight, - borderRadius: border.Radius['rounded-lg'], - variants: { - severity: { - basic: { backgroundColor: theme.Misc.Badge.badgeBg }, - info: { - backgroundColor: theme.Button.Severity.Info.Basic.infoButtonBg, - }, - success: { - backgroundColor: - theme.Button.Severity.Success.Basic.successButtonBg, - }, - warning: { - backgroundColor: - theme.Button.Severity.Warning.Basic.warningButtonBg, - }, - danger: { - backgroundColor: theme.Button.Severity.Danger.Basic.dangerButtonBg, - }, - secondary: { backgroundColor: theme.Surface['surface-border'] }, +const tagStyles = StyleSheet.create(({ components, fonts }) => ({ + container: { + alignSelf: 'flex-start', + flexDirection: 'row', + alignItems: 'center', + gap: components.tag.root.gap, + paddingHorizontal: components.tag.root.paddingLeft, + paddingVertical: components.tag.root.paddingTop, + borderRadius: components.tag.root.borderRadius, + variants: { + severity: { + basic: { + backgroundColor: components.tag.colorScheme.primary.background, + }, + info: { backgroundColor: components.tag.colorScheme.info.background }, + success: { + backgroundColor: components.tag.colorScheme.success.background, + }, + warning: { + backgroundColor: components.tag.colorScheme.warn.background, + }, + danger: { + backgroundColor: components.tag.colorScheme.danger.background, + }, + secondary: { + backgroundColor: components.tag.colorScheme.secondary.background, }, }, }, - roundedContainer: { borderRadius: border.Radius['rounded-full'] }, - icon: { - width: theme.Misc.Tag.tagFontSize, - height: theme.Misc.Tag.tagFontSize, - }, - text: { - flexShrink: 1, - fontSize: typography.Size['text-xs'], - includeFontPadding: false, - verticalAlign: 'middle', - fontFamily: fonts.primary, - variants: { - severity: { - basic: { color: theme.Misc.Badge.badgeTextColor }, - info: { color: theme.Misc.Badge.badgeInfoTextColor }, - success: { color: theme.Misc.Badge.badgeSuccessTextColor }, - warning: { color: theme.Misc.Badge.badgeWarningTextColor }, - danger: { color: theme.Misc.Badge.badgeDangerTextColor }, - secondary: { color: theme.Misc.Badge.badgeTextColor }, - }, + }, + roundedContainer: { borderRadius: components.tag.root.roundedBorderRadius }, + icon: { width: components.tag.icon.size, height: components.tag.icon.size }, + text: { + flexShrink: 1, + fontSize: components.tag.root.fontSize, + includeFontPadding: false, + verticalAlign: 'middle', + fontFamily: fonts.fontFamily.heading, + variants: { + severity: { + basic: { color: components.tag.colorScheme.primary.color }, + info: { color: components.tag.colorScheme.info.color }, + success: { color: components.tag.colorScheme.success.color }, + warning: { color: components.tag.colorScheme.warn.color }, + danger: { color: components.tag.colorScheme.danger.color }, + secondary: { color: components.tag.colorScheme.secondary.color }, }, }, - }) -) + }, +})) export const TagTestId = { root: 'Tag', diff --git a/src/components/Tag/__tests__/__snapshots__/Tag.test.tsx.snap b/src/components/Tag/__tests__/__snapshots__/Tag.test.tsx.snap index d41f7d70..ff2517c9 100644 --- a/src/components/Tag/__tests__/__snapshots__/Tag.test.tsx.snap +++ b/src/components/Tag/__tests__/__snapshots__/Tag.test.tsx.snap @@ -11,11 +11,11 @@ exports[`Tag snapshot: default 1`] = ` "alignItems": "center", "alignSelf": "flex-start", "backgroundColor": "#44e858", - "borderRadius": 7, + "borderRadius": 8, "flexDirection": "row", - "gap": 3.5, - "height": 21, - "paddingHorizontal": 7, + "gap": 4, + "paddingHorizontal": 8, + "paddingVertical": 4, }, undefined, ] @@ -26,10 +26,10 @@ exports[`Tag snapshot: default 1`] = ` numberOfLines={1} style={ { - "color": "#000000", + "color": "#2b2e33", "flexShrink": 1, "fontFamily": "TT Fellows", - "fontSize": 10.5, + "fontSize": 12, "includeFontPadding": false, "verticalAlign": "middle", } @@ -53,14 +53,14 @@ exports[`Tag snapshot: severity = basic, rounded = true, with Icon 1`] = ` "alignItems": "center", "alignSelf": "flex-start", "backgroundColor": "#44e858", - "borderRadius": 7, + "borderRadius": 8, "flexDirection": "row", - "gap": 3.5, - "height": 21, - "paddingHorizontal": 7, + "gap": 4, + "paddingHorizontal": 8, + "paddingVertical": 4, }, { - "borderRadius": 100, + "borderRadius": 1600, }, ] } @@ -68,15 +68,15 @@ exports[`Tag snapshot: severity = basic, rounded = true, with Icon 1`] = ` > Date: Tue, 4 Aug 2026 17:05:50 +0300 Subject: [PATCH 37/40] =?UTF-8?q?feat(Timer):=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Timer/Timer.tsx | 4 ++-- src/components/Timer/TimerFlip.tsx | 10 +++++----- .../__tests__/__snapshots__/Timer.test.tsx.snap | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/components/Timer/Timer.tsx b/src/components/Timer/Timer.tsx index 02699374..be194889 100644 --- a/src/components/Timer/Timer.tsx +++ b/src/components/Timer/Timer.tsx @@ -96,7 +96,7 @@ export const Timer = memo(({ countFrom, onFinish }) => { ) }) -const styles = StyleSheet.create(({ typography }) => ({ +const styles = StyleSheet.create(({ semantic }) => ({ container: { overflow: 'hidden', width: COUNTER_SIZE, @@ -111,7 +111,7 @@ const styles = StyleSheet.create(({ typography }) => ({ width: COUNTER_SIZE, height: COUNTER_SIZE, }, - circle: { color: typography.Color.Surface['text-surface-0'] }, + circle: { color: semantic.colorScheme.color.fg.active }, })) export enum TestId { diff --git a/src/components/Timer/TimerFlip.tsx b/src/components/Timer/TimerFlip.tsx index 88c72ad9..de57079b 100644 --- a/src/components/Timer/TimerFlip.tsx +++ b/src/components/Timer/TimerFlip.tsx @@ -64,7 +64,7 @@ export const TimerFlip = memo(({ value, duration = 300 }) => { ) }) -const styles = StyleSheet.create(({ typography, fonts }) => ({ +const styles = StyleSheet.create(({ semantic, fonts }) => ({ container: { overflow: 'hidden', width: COUNTER_SIZE, @@ -81,11 +81,11 @@ const styles = StyleSheet.create(({ typography, fonts }) => ({ position: 'absolute', }, text: { - fontSize: typography.Size['text-base'], - fontWeight: 700, + fontSize: fonts.fontSize[300], + fontWeight: fonts.fontWeight.bold, includeFontPadding: false, verticalAlign: 'middle', - color: typography.Color.Surface['text-surface-0'], - fontFamily: fonts.secondary, + color: semantic.colorScheme.color.fg.active, + fontFamily: fonts.fontFamily.base, }, })) diff --git a/src/components/Timer/__tests__/__snapshots__/Timer.test.tsx.snap b/src/components/Timer/__tests__/__snapshots__/Timer.test.tsx.snap index f5235f08..b7bbf37d 100644 --- a/src/components/Timer/__tests__/__snapshots__/Timer.test.tsx.snap +++ b/src/components/Timer/__tests__/__snapshots__/Timer.test.tsx.snap @@ -158,7 +158,7 @@ exports[`Timer should reset timer on changing countFrom prop: after 1 s 1`] = ` { "color": "#181a1f", "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "fontWeight": 700, "includeFontPadding": false, "verticalAlign": "middle", @@ -223,7 +223,7 @@ exports[`Timer should reset timer on changing countFrom prop: after 1 s 1`] = ` { "color": "#181a1f", "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "fontWeight": 700, "includeFontPadding": false, "verticalAlign": "middle", @@ -395,7 +395,7 @@ exports[`Timer should reset timer on changing countFrom prop: after reset 1`] = { "color": "#181a1f", "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "fontWeight": 700, "includeFontPadding": false, "verticalAlign": "middle", @@ -460,7 +460,7 @@ exports[`Timer should reset timer on changing countFrom prop: after reset 1`] = { "color": "#181a1f", "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "fontWeight": 700, "includeFontPadding": false, "verticalAlign": "middle", @@ -632,7 +632,7 @@ exports[`Timer snapshot: before start 1`] = ` { "color": "#181a1f", "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "fontWeight": 700, "includeFontPadding": false, "verticalAlign": "middle", @@ -697,7 +697,7 @@ exports[`Timer snapshot: before start 1`] = ` { "color": "#181a1f", "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "fontWeight": 700, "includeFontPadding": false, "verticalAlign": "middle", @@ -869,7 +869,7 @@ exports[`Timer snapshot: on finish 1`] = ` { "color": "#181a1f", "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "fontWeight": 700, "includeFontPadding": false, "verticalAlign": "middle", @@ -934,7 +934,7 @@ exports[`Timer snapshot: on finish 1`] = ` { "color": "#181a1f", "fontFamily": "Noto Sans", - "fontSize": 14, + "fontSize": 16, "fontWeight": 700, "includeFontPadding": false, "verticalAlign": "middle", From a5d3f43f98c7076b82b6baedcb03856f70479584 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 4 Aug 2026 17:05:51 +0300 Subject: [PATCH 38/40] =?UTF-8?q?feat(ToggleButton):=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ToggleButton/ToggleButton.tsx | 314 +++++++++--------- .../__snapshots__/ToggleButton.test.tsx.snap | 176 +++++----- 2 files changed, 247 insertions(+), 243 deletions(-) diff --git a/src/components/ToggleButton/ToggleButton.tsx b/src/components/ToggleButton/ToggleButton.tsx index b8e0e140..cabf375c 100644 --- a/src/components/ToggleButton/ToggleButton.tsx +++ b/src/components/ToggleButton/ToggleButton.tsx @@ -119,182 +119,186 @@ export const ToggleButton = memo( } ) -const toggleStyles = StyleSheet.create( - ({ theme, spacing, border, fonts, typography }) => ({ - container: { - alignSelf: 'flex-start', - borderRadius: border.Radius['rounded-full'], - borderWidth: border.Width.border, - overflow: 'hidden', - variants: { - checked: { - true: { - borderColor: theme.Form.ToggleButton.toggleButtonActiveBorderColor, - }, - false: { - borderColor: theme.Form.ToggleButton.toggleButtonBorderColor, - }, +const toggleStyles = StyleSheet.create(({ components, semantic, fonts }) => ({ + container: { + alignSelf: 'flex-start', + borderRadius: components.togglebutton.root.borderRadius, + borderWidth: semantic.dimension.borderWidth[100], + overflow: 'hidden', + variants: { + checked: { + true: { + borderColor: + components.togglebutton.colorScheme.root.checkedBorderColor, }, - pressed: { - true: { borderColor: theme.Form.ToggleButton.toggleButtonHoverBg }, - false: {}, - }, - disabled: { - true: { - borderColor: theme.Button.Disabled.disabledButtonBorderColor, - opacity: 0.6, - }, - false: {}, + false: { + borderColor: components.togglebutton.colorScheme.root.borderColor, }, }, - compoundVariants: [ - { - checked: 'true', - pressed: 'true', - styles: { - borderColor: - theme.Form.ToggleButton.toggleButtonActiveHoverBorderColor, - }, + pressed: { + true: { borderColor: components.togglebutton.extend.hoverBorderColor }, + false: {}, + }, + disabled: { + true: { + borderColor: + components.togglebutton.colorScheme.root.disabledBorderColor, + opacity: semantic.effects.opacity[60], }, - ], + false: {}, + }, }, - contentContainer: { - flexDirection: 'row', - alignItems: 'center', - alignSelf: 'flex-start', - borderRadius: border.Radius['rounded-full'], - paddingVertical: theme.Button.Common.buttonPaddingTopBottom, - paddingHorizontal: spacing.Padding['p-6'], - gap: spacing.Gap['gap-3'], - variants: { - size: { - xlarge: { minHeight: theme.Button.Common.buttonHeightXL }, - large: { minHeight: theme.Button.Common.buttonHeightLG }, - base: { - minHeight: theme.Button.Common.buttonHeight, - paddingHorizontal: theme.Button.Common.buttonPaddingLeftRight, - gap: theme.General.inlineSpacing, - }, - small: { - minHeight: theme.Button.Common.buttonHeightSM, - paddingHorizontal: spacing.Padding['p-3'], - gap: theme.General.inlineSpacing, - }, - }, - checked: { - true: { - backgroundColor: theme.Form.ToggleButton.toggleButtonActiveBg, - }, - false: { backgroundColor: theme.Form.ToggleButton.toggleButtonBg }, - }, - pressed: { - true: { - backgroundColor: theme.Form.ToggleButton.toggleButtonHoverBg, - }, - false: {}, - }, - disabled: { - true: { backgroundColor: theme.Button.Disabled.disabledButtonBg }, - false: {}, + compoundVariants: [ + { + checked: 'true', + pressed: 'true', + styles: { + borderColor: components.togglebutton.extend.checkedHoverBorderColor, }, }, - compoundVariants: [ - { - checked: 'true', - pressed: 'true', - styles: { - backgroundColor: theme.Form.ToggleButton.toggleButtonActiveHoverBg, - }, + ], + }, + contentContainer: { + flexDirection: 'row', + alignItems: 'center', + alignSelf: 'flex-start', + borderRadius: components.togglebutton.root.borderRadius, + paddingVertical: components.togglebutton.root.paddingTop, + paddingHorizontal: semantic.dimension.space[600], + gap: components.togglebutton.extend.ext.gap, + variants: { + size: { + xlarge: { minHeight: semantic.dimension.size[1400] }, + large: { minHeight: semantic.dimension.size[1300] }, + base: { + minHeight: semantic.dimension.size[1100], + paddingHorizontal: components.togglebutton.root.paddingLeft, + gap: components.togglebutton.root.gap, }, - ], - }, - iconOnly: { - aspectRatio: 1, - paddingHorizontal: 0, - paddingVertical: 0, - justifyContent: 'center', - }, - icon: { - variants: { - size: { - xlarge: { - width: typography.Size['text-4xl'], - height: typography.Size['text-4xl'], - }, - large: { - width: typography.Size['text-2xl'], - height: typography.Size['text-2xl'], - }, - base: { - width: typography.Size['text-xl'], - height: typography.Size['text-xl'], - }, - small: { - width: typography.Size['text-base'], - height: typography.Size['text-base'], - }, + small: { + minHeight: semantic.dimension.size[800], + paddingHorizontal: components.togglebutton.root.sm.paddingRight, + gap: components.togglebutton.root.gap, }, - checked: { - true: { color: theme.Form.ToggleButton.toggleButtonActiveTextColor }, - false: { color: theme.Form.ToggleButton.toggleButtonTextColor }, + }, + checked: { + true: { + backgroundColor: + components.togglebutton.colorScheme.root.checkedBackground, }, - pressed: { - true: { color: theme.Form.ToggleButton.toggleButtonHoverTextColor }, - false: {}, + false: { + backgroundColor: components.togglebutton.colorScheme.root.background, }, - disabled: { - true: { color: theme.Button.Disabled.disabledButtonTextColor }, - false: {}, + }, + pressed: { + true: { + backgroundColor: + components.togglebutton.colorScheme.root.hoverBackground, }, + false: {}, }, - compoundVariants: [ - { - checked: 'true', - pressed: 'true', - styles: { - color: theme.Form.ToggleButton.toggleButtonTextActiveHoverColor, - }, + disabled: { + true: { + backgroundColor: + components.togglebutton.colorScheme.root.disabledBackground, }, - ], + false: {}, + }, }, - label: { - flexShrink: 1, - fontFamily: fonts.primary, - fontWeight: '600', - includeFontPadding: false, - verticalAlign: 'middle', - variants: { - size: { - xlarge: { fontSize: typography.Size['text-2xl'] }, - large: { fontSize: typography.Size['text-xl'] }, - base: { fontSize: typography.Size['text-base'] }, - small: { fontSize: typography.Size['text-sm'] }, + compoundVariants: [ + { + checked: 'true', + pressed: 'true', + styles: { + backgroundColor: + components.togglebutton.extend.checkedHoverBackground, }, - checked: { - true: { color: theme.Form.ToggleButton.toggleButtonActiveTextColor }, - false: { color: theme.Form.ToggleButton.toggleButtonTextColor }, + }, + ], + }, + iconOnly: { + aspectRatio: 1, + paddingHorizontal: semantic.dimension.space.none, + paddingVertical: semantic.dimension.space.none, + justifyContent: 'center', + }, + icon: { + variants: { + size: { + xlarge: { + // Токена iconSize.xlg в дизайн-системе нет — размер взят semantic-ролью. + width: semantic.dimension.size[1000], + height: semantic.dimension.size[1000], }, - pressed: { - true: { color: theme.Form.ToggleButton.toggleButtonHoverTextColor }, - false: {}, + large: { + width: components.togglebutton.extend.iconSize.lg, + height: components.togglebutton.extend.iconSize.lg, }, - disabled: { - true: { color: theme.Button.Disabled.disabledButtonTextColor }, - false: {}, + base: { + width: components.togglebutton.extend.iconSize.md, + height: components.togglebutton.extend.iconSize.md, }, - }, - compoundVariants: [ - { - checked: 'true', - pressed: 'true', - styles: { - color: theme.Form.ToggleButton.toggleButtonTextActiveHoverColor, - }, + small: { + width: components.togglebutton.extend.iconSize.sm, + height: components.togglebutton.extend.iconSize.sm, }, - ], + }, + checked: { + true: { color: components.togglebutton.colorScheme.root.checkedColor }, + false: { color: components.togglebutton.colorScheme.root.color }, + }, + pressed: { + true: { color: components.togglebutton.colorScheme.root.hoverColor }, + false: {}, + }, + disabled: { + true: { color: components.togglebutton.colorScheme.root.disabledColor }, + false: {}, + }, }, - }) -) + compoundVariants: [ + { + checked: 'true', + pressed: 'true', + styles: { color: components.togglebutton.extend.checkedHoverColor }, + }, + ], + }, + label: { + flexShrink: 1, + fontFamily: fonts.fontFamily.heading, + fontWeight: fonts.fontWeight.demibold, + includeFontPadding: false, + verticalAlign: 'middle', + variants: { + size: { + xlarge: { fontSize: fonts.fontSize[600] }, + large: { fontSize: fonts.fontSize[500] }, + base: { fontSize: fonts.fontSize[300] }, + small: { fontSize: fonts.fontSize[100] }, + }, + checked: { + true: { color: components.togglebutton.colorScheme.root.checkedColor }, + false: { color: components.togglebutton.colorScheme.root.color }, + }, + pressed: { + true: { color: components.togglebutton.colorScheme.root.hoverColor }, + false: {}, + }, + disabled: { + true: { color: components.togglebutton.colorScheme.root.disabledColor }, + false: {}, + }, + }, + compoundVariants: [ + { + checked: 'true', + pressed: 'true', + styles: { color: components.togglebutton.extend.checkedHoverColor }, + }, + ], + }, +})) export const ToggleButtonTestId = { root: 'ToggleButton', diff --git a/src/components/ToggleButton/__tests__/__snapshots__/ToggleButton.test.tsx.snap b/src/components/ToggleButton/__tests__/__snapshots__/ToggleButton.test.tsx.snap index 213d712b..6f1ddbaa 100644 --- a/src/components/ToggleButton/__tests__/__snapshots__/ToggleButton.test.tsx.snap +++ b/src/components/ToggleButton/__tests__/__snapshots__/ToggleButton.test.tsx.snap @@ -10,8 +10,8 @@ exports[`ToggleButton snapshots checked = false, disabled = false, iconOnly = fa [ { "alignSelf": "flex-start", - "borderColor": "rgba(255, 255, 255, 0.0001)", - "borderRadius": 100, + "borderColor": "#e2e2e4", + "borderRadius": 1600, "borderWidth": 1, "overflow": "hidden", }, @@ -27,12 +27,12 @@ exports[`ToggleButton snapshots checked = false, disabled = false, iconOnly = fa "alignItems": "center", "alignSelf": "flex-start", "backgroundColor": "#e2e2e4", - "borderRadius": 100, + "borderRadius": 1600, "flexDirection": "row", - "gap": 7, + "gap": 8, "minHeight": 28, - "paddingHorizontal": 10.5, - "paddingVertical": 0, + "paddingHorizontal": 14, + "paddingVertical": 8, }, false, ] @@ -41,15 +41,15 @@ exports[`ToggleButton snapshots checked = false, disabled = false, iconOnly = fa > Date: Tue, 4 Aug 2026 17:05:51 +0300 Subject: [PATCH 39/40] =?UTF-8?q?feat(Typography):=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Typography/Anchor.tsx | 36 +- src/components/Typography/Body.tsx | 31 +- src/components/Typography/Caption.tsx | 45 +- src/components/Typography/Service.tsx | 56 +- src/components/Typography/Subtitle.tsx | 20 +- src/components/Typography/Title.tsx | 28 +- .../__snapshots__/Anchor.test.tsx.snap | 132 +-- .../__snapshots__/Body.test.tsx.snap | 422 ++++---- .../__snapshots__/Caption.test.tsx.snap | 192 ++-- .../__snapshots__/Service.test.tsx.snap | 952 +++++++++--------- .../__snapshots__/Subtitle.test.tsx.snap | 76 +- .../__snapshots__/Title.test.tsx.snap | 24 +- 12 files changed, 1016 insertions(+), 998 deletions(-) diff --git a/src/components/Typography/Anchor.tsx b/src/components/Typography/Anchor.tsx index 475176e6..f8e79e26 100644 --- a/src/components/Typography/Anchor.tsx +++ b/src/components/Typography/Anchor.tsx @@ -68,10 +68,10 @@ export const Anchor = memo( }, [noWrapper, testID]) const iconSize = base ? styles.iconBase : styles.icon - const iconUniProps = ({ typography: t }: ThemeType) => ({ + const iconUniProps = ({ semantic }: ThemeType) => ({ color: visited - ? t.Color.Service['text-help'] - : t.Color.Service['text-info'], + ? semantic.colorScheme.color.fg.status.help.default + : semantic.colorScheme.color.fg.status.info.default, }) return ( @@ -133,35 +133,35 @@ export const Anchor = memo( } ) -const styles = StyleSheet.create(({ spacing, typography, fonts }) => ({ +const styles = StyleSheet.create(({ semantic, fonts }) => ({ container: { flexDirection: 'row', alignItems: 'center' }, text: { flexShrink: 1, - fontSize: typography.Size['text-sm'], + fontSize: fonts.fontSize[200], includeFontPadding: false, verticalAlign: 'middle', - color: typography.Color.Service['text-info'], - fontFamily: fonts.secondary, - lineHeight: 15, - letterSpacing: -0.25, + color: semantic.colorScheme.color.fg.status.info.default, + fontFamily: fonts.fontFamily.base, + lineHeight: fonts.lineHeight[300], + letterSpacing: fonts.letterSpacing[200], }, underlined: { textDecorationLine: 'underline' }, base: { - fontSize: typography.Size['text-base'], + fontSize: fonts.fontSize[300], lineHeight: undefined, - letterSpacing: 0, + letterSpacing: fonts.letterSpacing[500], }, - visited: { color: typography.Color.Service['text-help'] }, + visited: { color: semantic.colorScheme.color.fg.status.help.default }, icon: { - width: typography.Size['text-base'], - height: typography.Size['text-base'], + width: semantic.dimension.size[450], + height: semantic.dimension.size[450], }, iconBase: { - width: typography.Size['text-xl'], - height: typography.Size['text-xl'], + width: semantic.dimension.size[600], + height: semantic.dimension.size[600], }, - leftIconContainer: { paddingRight: spacing.Padding['p-2'] }, - rightIconContainer: { paddingLeft: spacing.Padding['p-2'] }, + leftIconContainer: { paddingRight: semantic.dimension.space[200] }, + rightIconContainer: { paddingLeft: semantic.dimension.space[200] }, })) export const AnchorTestId = { diff --git a/src/components/Typography/Body.tsx b/src/components/Typography/Body.tsx index f223873e..c44d11ed 100644 --- a/src/components/Typography/Body.tsx +++ b/src/components/Typography/Body.tsx @@ -36,21 +36,26 @@ export const Body = ({ ) } -const styles = StyleSheet.create(({ theme, typography, fonts }) => ({ +// Осознанный обход слоя components: цвет текста — семантическая роль, и своего +// токена у Typography нет (компонент отсутствует в tokens.json). +const styles = StyleSheet.create(({ semantic, fonts }) => ({ text: { - fontSize: typography.Size['text-base'], + fontSize: fonts.fontSize[300], includeFontPadding: false, verticalAlign: 'middle', - fontFamily: fonts.secondary, - lineHeight: 20, + fontFamily: fonts.fontFamily.base, + lineHeight: fonts.lineHeight[450], }, - regular: { fontWeight: 400 }, - bold: { fontWeight: 700, letterSpacing: -0.5 }, - default: { color: theme.General.textColor }, - primary: { color: theme.General.primaryColor }, - secondary: { color: theme.General.textSecondaryColor }, - base: { fontSize: typography.Size['text-sm'], lineHeight: 18 }, - paragraph: { lineHeight: 24 }, - paragraphBase: { lineHeight: 21 }, - disabled: { opacity: 0.6 }, + regular: { fontWeight: fonts.fontWeight.regular }, + bold: { + fontWeight: fonts.fontWeight.bold, + letterSpacing: fonts.letterSpacing[400], + }, + default: { color: semantic.colorScheme.color.fg.default }, + primary: { color: semantic.colorScheme.color.fg.brand.default }, + secondary: { color: semantic.colorScheme.color.fg.muted }, + base: { fontSize: fonts.fontSize[200], lineHeight: fonts.lineHeight[400] }, + paragraph: { lineHeight: fonts.lineHeight[600] }, + paragraphBase: { lineHeight: fonts.lineHeight[500] }, + disabled: { opacity: semantic.effects.opacity[60] }, })) diff --git a/src/components/Typography/Caption.tsx b/src/components/Typography/Caption.tsx index 7795843a..c71c7c2b 100644 --- a/src/components/Typography/Caption.tsx +++ b/src/components/Typography/Caption.tsx @@ -39,13 +39,15 @@ export const Caption = ({ {...styles.icon} source={Icon} testID={CaptionTestId.icon} - uniProps={({ theme }) => ({ - color: { - default: theme.General.textColor, - primary: theme.General.primaryColor, - secondary: theme.General.textSecondaryColor, - }[color], - })} + uniProps={({ semantic }) => { + return { + color: { + default: semantic.colorScheme.color.fg.default, + primary: semantic.colorScheme.color.fg.brand.default, + secondary: semantic.colorScheme.color.fg.muted, + }[color], + } + }} /> {text} @@ -57,23 +59,28 @@ export const Caption = ({ const CaptionTestId = { text: 'CaptionText', icon: 'CaptionIcon' } -const styles = StyleSheet.create(({ theme, spacing, typography, fonts }) => ({ +// Осознанный обход слоя components: цвет текста — семантическая роль, и своего +// токена у Typography нет (компонент отсутствует в tokens.json). +const styles = StyleSheet.create(({ semantic, fonts }) => ({ text: { - fontSize: typography.Size['text-sm'], + fontSize: fonts.fontSize[200], includeFontPadding: false, verticalAlign: 'middle', - fontFamily: fonts.secondary, - lineHeight: 15, - letterSpacing: -0.25, + fontFamily: fonts.fontFamily.base, + lineHeight: fonts.lineHeight[300], + letterSpacing: fonts.letterSpacing[200], }, textWithIcon: { flexShrink: 1 }, - default: { color: theme.General.textColor }, - primary: { color: theme.General.primaryColor }, - secondary: { color: theme.General.textSecondaryColor }, - disabled: { opacity: 0.6 }, - withIconContainer: { flexDirection: 'row', gap: spacing.Gap['gap-1'] }, + default: { color: semantic.colorScheme.color.fg.default }, + primary: { color: semantic.colorScheme.color.fg.brand.default }, + secondary: { color: semantic.colorScheme.color.fg.muted }, + disabled: { opacity: semantic.effects.opacity[60] }, + withIconContainer: { + flexDirection: 'row', + gap: semantic.dimension.space[100], + }, icon: { - width: typography.Size['text-base'], - height: typography.Size['text-base'], + width: semantic.dimension.size[450], + height: semantic.dimension.size[450], }, })) diff --git a/src/components/Typography/Service.tsx b/src/components/Typography/Service.tsx index 78ea369e..442dc22d 100644 --- a/src/components/Typography/Service.tsx +++ b/src/components/Typography/Service.tsx @@ -69,15 +69,17 @@ export const Service = ({ ({ - color: { - danger: t.Color.Service['text-danger'], - warning: t.Color.Service['text-warning'], - success: t.Color.Service['text-success'], - info: t.Color.Service['text-info'], - help: t.Color.Service['text-help'], - }[variant], - })} + uniProps={({ semantic }) => { + return { + color: { + danger: semantic.colorScheme.color.fg.status.danger.default, + warning: semantic.colorScheme.color.fg.status.warning.default, + success: semantic.colorScheme.color.fg.status.success.default, + info: semantic.colorScheme.color.fg.status.info.default, + help: semantic.colorScheme.color.fg.status.help.default, + }[variant], + } + }} /> ) : null} @@ -85,34 +87,34 @@ export const Service = ({ ) } -const styles = StyleSheet.create(({ typography, spacing, fonts }) => ({ +const styles = StyleSheet.create(({ semantic, fonts }) => ({ iconBase: { - width: typography.Size['text-xl'], - height: typography.Size['text-xl'], + width: semantic.dimension.size[600], + height: semantic.dimension.size[600], }, icon: { - width: typography.Size['text-base'], - height: typography.Size['text-base'], + width: semantic.dimension.size[450], + height: semantic.dimension.size[450], }, - containerBase: { flexDirection: 'row', gap: spacing.Gap['gap-2'] }, - container: { flexDirection: 'row', gap: spacing.Gap['gap-1'] }, + containerBase: { flexDirection: 'row', gap: semantic.dimension.space[200] }, + container: { flexDirection: 'row', gap: semantic.dimension.space[100] }, textCommon: { includeFontPadding: false, verticalAlign: 'middle', flexShrink: 1, - fontWeight: 400, - fontSize: typography.Size['text-sm'], - fontFamily: fonts.secondary, - lineHeight: 15, - letterSpacing: -0.25, + fontWeight: fonts.fontWeight.regular, + fontSize: fonts.fontSize[200], + fontFamily: fonts.fontFamily.base, + lineHeight: fonts.lineHeight[300], + letterSpacing: fonts.letterSpacing[200], }, - textBase: { lineHeight: undefined, fontSize: typography.Size['text-base'] }, + textBase: { lineHeight: undefined, fontSize: fonts.fontSize[300] }, - warning: { color: typography.Color.Service['text-warning'] }, - success: { color: typography.Color.Service['text-success'] }, - info: { color: typography.Color.Service['text-info'] }, - help: { color: typography.Color.Service['text-help'] }, - danger: { color: typography.Color.Service['text-danger'] }, + warning: { color: semantic.colorScheme.color.fg.status.warning.default }, + success: { color: semantic.colorScheme.color.fg.status.success.default }, + info: { color: semantic.colorScheme.color.fg.status.info.default }, + help: { color: semantic.colorScheme.color.fg.status.help.default }, + danger: { color: semantic.colorScheme.color.fg.status.danger.default }, })) diff --git a/src/components/Typography/Subtitle.tsx b/src/components/Typography/Subtitle.tsx index 99ff640b..bfacf93c 100644 --- a/src/components/Typography/Subtitle.tsx +++ b/src/components/Typography/Subtitle.tsx @@ -30,16 +30,18 @@ export const Subtitle = memo( ) ) -const styles = StyleSheet.create(({ theme, typography, fonts }) => ({ +// Осознанный обход слоя components: цвет текста — семантическая роль, и своего +// токена у Typography нет (компонент отсутствует в tokens.json). +const styles = StyleSheet.create(({ semantic, fonts }) => ({ text: { - fontSize: typography.Size['text-xs'], - fontWeight: 700, + fontSize: fonts.fontSize[100], + fontWeight: fonts.fontWeight.bold, textTransform: 'uppercase', - fontFamily: fonts.secondary, - lineHeight: 15, + fontFamily: fonts.fontFamily.base, + lineHeight: fonts.lineHeight[300], }, - base: { lineHeight: 18, fontSize: typography.Size['text-sm'] }, - default: { color: theme.General.textColor }, - primary: { color: theme.General.primaryColor }, - secondary: { color: theme.General.textSecondaryColor }, + base: { lineHeight: fonts.lineHeight[400], fontSize: fonts.fontSize[200] }, + default: { color: semantic.colorScheme.color.fg.default }, + primary: { color: semantic.colorScheme.color.fg.brand.default }, + secondary: { color: semantic.colorScheme.color.fg.muted }, })) diff --git a/src/components/Typography/Title.tsx b/src/components/Typography/Title.tsx index de6dd6d0..97946d4b 100644 --- a/src/components/Typography/Title.tsx +++ b/src/components/Typography/Title.tsx @@ -10,21 +10,23 @@ export const Title = ({ level, style, ...other }: TitleProps) => ( ) -const styles = StyleSheet.create(({ theme, typography, fonts }) => ({ +// Осознанный обход слоя components: цвет текста — семантическая роль, и своего +// токена у Typography нет (компонент отсутствует в tokens.json). +const styles = StyleSheet.create(({ semantic, fonts }) => ({ text: { - color: theme.General.textColor, - fontFamily: fonts.primary, - fontWeight: 700, + color: semantic.colorScheme.color.fg.default, + fontFamily: fonts.fontFamily.heading, + fontWeight: fonts.fontWeight.bold, includeFontPadding: false, verticalAlign: 'middle', }, - d1: { fontSize: typography.Size['text-5xl'] }, - d2: { fontSize: typography.Size['text-4xl'] }, - d3: { fontSize: typography.Size['text-3xl'] }, - h1: { fontSize: typography.Size['text-2xl'] }, - h2: { fontSize: typography.Size['text-xl'] }, - h3: { fontSize: typography.Size['text-lg'] }, - h4: { fontSize: typography.Size['text-base'] }, - h5: { fontSize: typography.Size['text-sm'] }, - h6: { fontSize: typography.Size['text-xs'] }, + d1: { fontSize: fonts.fontSize[750] }, + d2: { fontSize: fonts.fontSize[700] }, + d3: { fontSize: fonts.fontSize[650] }, + h1: { fontSize: fonts.fontSize[600] }, + h2: { fontSize: fonts.fontSize[500] }, + h3: { fontSize: fonts.fontSize[400] }, + h4: { fontSize: fonts.fontSize[300] }, + h5: { fontSize: fonts.fontSize[100] }, + h6: { fontSize: fonts.fontSize[100] }, })) diff --git a/src/components/Typography/__tests__/__snapshots__/Anchor.test.tsx.snap b/src/components/Typography/__tests__/__snapshots__/Anchor.test.tsx.snap index 53bf9367..1d37bed1 100644 --- a/src/components/Typography/__tests__/__snapshots__/Anchor.test.tsx.snap +++ b/src/components/Typography/__tests__/__snapshots__/Anchor.test.tsx.snap @@ -17,13 +17,13 @@ exports[`Body component tests default props 1`] = ` style={ [ { - "color": "#1e76cd", + "color": "#4496e8", "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, false, @@ -82,22 +82,22 @@ exports[`Body component tests левая иконка, base, visited, testID = C onStartShouldSetResponder={[Function]} style={ { - "paddingRight": 7, + "paddingRight": 8, } } testID="AnchorLeftPressable" > @@ -15,16 +15,16 @@ exports[`Service component tests base = false, showIcon = false, variant = dange { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, false, { - "color": "#db3424", + "color": "#e85244", }, ] } @@ -39,7 +39,7 @@ exports[`Service component tests base = false, showIcon = false, variant = dange style={ { "flexDirection": "row", - "gap": 3.5, + "gap": 4, } } > @@ -49,16 +49,16 @@ exports[`Service component tests base = false, showIcon = false, variant = dange { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, false, { - "color": "#db3424", + "color": "#e85244", }, ] } @@ -73,7 +73,7 @@ exports[`Service component tests base = false, showIcon = false, variant = help style={ { "flexDirection": "row", - "gap": 3.5, + "gap": 4, } } > @@ -83,16 +83,16 @@ exports[`Service component tests base = false, showIcon = false, variant = help { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, false, { - "color": "#9457ea", + "color": "#a855f7", }, ] } @@ -107,7 +107,7 @@ exports[`Service component tests base = false, showIcon = false, variant = help style={ { "flexDirection": "row", - "gap": 3.5, + "gap": 4, } } > @@ -117,16 +117,16 @@ exports[`Service component tests base = false, showIcon = false, variant = help { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, false, { - "color": "#9457ea", + "color": "#a855f7", }, ] } @@ -141,7 +141,7 @@ exports[`Service component tests base = false, showIcon = false, variant = info style={ { "flexDirection": "row", - "gap": 3.5, + "gap": 4, } } > @@ -151,16 +151,16 @@ exports[`Service component tests base = false, showIcon = false, variant = info { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, false, { - "color": "#1e76cd", + "color": "#4496e8", }, ] } @@ -175,7 +175,7 @@ exports[`Service component tests base = false, showIcon = false, variant = info style={ { "flexDirection": "row", - "gap": 3.5, + "gap": 4, } } > @@ -185,16 +185,16 @@ exports[`Service component tests base = false, showIcon = false, variant = info { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, false, { - "color": "#1e76cd", + "color": "#4496e8", }, ] } @@ -209,7 +209,7 @@ exports[`Service component tests base = false, showIcon = false, variant = succe style={ { "flexDirection": "row", - "gap": 3.5, + "gap": 4, } } > @@ -219,16 +219,16 @@ exports[`Service component tests base = false, showIcon = false, variant = succe { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, false, { - "color": "#168322", + "color": "#44e858", }, ] } @@ -243,7 +243,7 @@ exports[`Service component tests base = false, showIcon = false, variant = succe style={ { "flexDirection": "row", - "gap": 3.5, + "gap": 4, } } > @@ -253,16 +253,16 @@ exports[`Service component tests base = false, showIcon = false, variant = succe { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, false, { - "color": "#168322", + "color": "#44e858", }, ] } @@ -277,7 +277,7 @@ exports[`Service component tests base = false, showIcon = false, variant = warni style={ { "flexDirection": "row", - "gap": 3.5, + "gap": 4, } } > @@ -287,16 +287,16 @@ exports[`Service component tests base = false, showIcon = false, variant = warni { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, false, { - "color": "#dc9710", + "color": "#f5b83d", }, ] } @@ -311,7 +311,7 @@ exports[`Service component tests base = false, showIcon = false, variant = warni style={ { "flexDirection": "row", - "gap": 3.5, + "gap": 4, } } > @@ -321,16 +321,16 @@ exports[`Service component tests base = false, showIcon = false, variant = warni { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, false, { - "color": "#dc9710", + "color": "#f5b83d", }, ] } @@ -345,21 +345,21 @@ exports[`Service component tests base = false, showIcon = true, variant = danger style={ { "flexDirection": "row", - "gap": 3.5, + "gap": 4, } } > @@ -2359,19 +2359,19 @@ exports[`Service component tests base = true, showIcon = false, variant = danger { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { - "fontSize": 14, + "fontSize": 16, "lineHeight": undefined, }, { - "color": "#db3424", + "color": "#e85244", }, ] } @@ -2386,7 +2386,7 @@ exports[`Service component tests base = true, showIcon = false, variant = danger style={ { "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -2396,19 +2396,19 @@ exports[`Service component tests base = true, showIcon = false, variant = danger { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { - "fontSize": 14, + "fontSize": 16, "lineHeight": undefined, }, { - "color": "#db3424", + "color": "#e85244", }, ] } @@ -2423,7 +2423,7 @@ exports[`Service component tests base = true, showIcon = false, variant = help 1 style={ { "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -2433,19 +2433,19 @@ exports[`Service component tests base = true, showIcon = false, variant = help 1 { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { - "fontSize": 14, + "fontSize": 16, "lineHeight": undefined, }, { - "color": "#9457ea", + "color": "#a855f7", }, ] } @@ -2460,7 +2460,7 @@ exports[`Service component tests base = true, showIcon = false, variant = help 2 style={ { "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -2470,19 +2470,19 @@ exports[`Service component tests base = true, showIcon = false, variant = help 2 { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { - "fontSize": 14, + "fontSize": 16, "lineHeight": undefined, }, { - "color": "#9457ea", + "color": "#a855f7", }, ] } @@ -2497,7 +2497,7 @@ exports[`Service component tests base = true, showIcon = false, variant = info 1 style={ { "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -2507,19 +2507,19 @@ exports[`Service component tests base = true, showIcon = false, variant = info 1 { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { - "fontSize": 14, + "fontSize": 16, "lineHeight": undefined, }, { - "color": "#1e76cd", + "color": "#4496e8", }, ] } @@ -2534,7 +2534,7 @@ exports[`Service component tests base = true, showIcon = false, variant = info 2 style={ { "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -2544,19 +2544,19 @@ exports[`Service component tests base = true, showIcon = false, variant = info 2 { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { - "fontSize": 14, + "fontSize": 16, "lineHeight": undefined, }, { - "color": "#1e76cd", + "color": "#4496e8", }, ] } @@ -2571,7 +2571,7 @@ exports[`Service component tests base = true, showIcon = false, variant = succes style={ { "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -2581,19 +2581,19 @@ exports[`Service component tests base = true, showIcon = false, variant = succes { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { - "fontSize": 14, + "fontSize": 16, "lineHeight": undefined, }, { - "color": "#168322", + "color": "#44e858", }, ] } @@ -2608,7 +2608,7 @@ exports[`Service component tests base = true, showIcon = false, variant = succes style={ { "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -2618,19 +2618,19 @@ exports[`Service component tests base = true, showIcon = false, variant = succes { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { - "fontSize": 14, + "fontSize": 16, "lineHeight": undefined, }, { - "color": "#168322", + "color": "#44e858", }, ] } @@ -2645,7 +2645,7 @@ exports[`Service component tests base = true, showIcon = false, variant = warnin style={ { "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -2655,19 +2655,19 @@ exports[`Service component tests base = true, showIcon = false, variant = warnin { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { - "fontSize": 14, + "fontSize": 16, "lineHeight": undefined, }, { - "color": "#dc9710", + "color": "#f5b83d", }, ] } @@ -2682,7 +2682,7 @@ exports[`Service component tests base = true, showIcon = false, variant = warnin style={ { "flexDirection": "row", - "gap": 7, + "gap": 8, } } > @@ -2692,19 +2692,19 @@ exports[`Service component tests base = true, showIcon = false, variant = warnin { "flexShrink": 1, "fontFamily": "Noto Sans", - "fontSize": 12.25, + "fontSize": 14, "fontWeight": 400, "includeFontPadding": false, - "letterSpacing": -0.25, - "lineHeight": 15, + "letterSpacing": -0.32, + "lineHeight": 18, "verticalAlign": "middle", }, { - "fontSize": 14, + "fontSize": 16, "lineHeight": undefined, }, { - "color": "#dc9710", + "color": "#f5b83d", }, ] } @@ -2719,21 +2719,21 @@ exports[`Service component tests base = true, showIcon = true, variant = danger style={ { "flexDirection": "row", - "gap": 7, + "gap": 8, } } > Date: Tue, 4 Aug 2026 18:24:35 +0300 Subject: [PATCH 40/40] =?UTF-8?q?refactor(theme):=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D1=81=D0=BB=D0=BE=D0=B9=20leg?= =?UTF-8?q?acy-=D1=81=D0=BE=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=B8=D0=BC?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MIGRATION.md | 4 +- README.md | 21 ++- src/hooks/useFonts.ts | 7 +- src/theme/ThemeContext.tsx | 66 ++------- src/theme/__tests__/ThemeContext.test.tsx | 114 +++++++++------ .../__tests__/easing.test.ts} | 2 +- .../{tokenAdapters.ts => adapters/easing.ts} | 0 src/theme/adapters/index.ts | 1 + src/theme/commonTheme.ts | 23 ---- src/theme/darkTheme.ts | 15 +- src/theme/index.ts | 5 +- .../InputSize/base.json | 0 .../InputSize/index.ts | 0 .../InputSize/large.json | 0 .../InputSize/xlarge.json | 0 .../ModalSize/index.ts | 0 .../ModalSize/lg.json | 0 .../ModalSize/md.json | 0 .../ModalSize/sm.json | 0 .../ModalSize/xl.json | 0 src/theme/legacyTokens/README.md | 13 ++ .../{assets => legacyTokens}/background.json | 0 .../{assets => legacyTokens}/border.json | 0 .../{assets => legacyTokens}/customCommon.ts | 0 .../{assets => legacyTokens}/customDark.ts | 0 .../{assets => legacyTokens}/customLight.ts | 0 .../{assets => legacyTokens}/effects.json | 0 .../{assets => legacyTokens}/global.json | 0 src/theme/legacyTokens/index.ts | 130 ++++++++++++++++++ .../primaryColors.json | 0 src/theme/{assets => legacyTokens}/shadow.ts | 0 .../{assets => legacyTokens}/sizing.json | 0 .../{assets => legacyTokens}/spacing.json | 0 .../{assets => legacyTokens}/themeDark.json | 0 .../{assets => legacyTokens}/themeLight.json | 0 .../{assets => legacyTokens}/typography.json | 0 src/theme/lightTheme.ts | 15 +- src/theme/themes.ts | 29 ++++ src/theme/tokens/README.md | 12 +- src/theme/types.ts | 60 +++----- 40 files changed, 302 insertions(+), 215 deletions(-) rename src/theme/{__tests__/tokenAdapters.test.ts => adapters/__tests__/easing.test.ts} (87%) rename src/theme/{tokenAdapters.ts => adapters/easing.ts} (100%) create mode 100644 src/theme/adapters/index.ts delete mode 100644 src/theme/commonTheme.ts rename src/theme/{assets => legacyTokens}/InputSize/base.json (100%) rename src/theme/{assets => legacyTokens}/InputSize/index.ts (100%) rename src/theme/{assets => legacyTokens}/InputSize/large.json (100%) rename src/theme/{assets => legacyTokens}/InputSize/xlarge.json (100%) rename src/theme/{assets => legacyTokens}/ModalSize/index.ts (100%) rename src/theme/{assets => legacyTokens}/ModalSize/lg.json (100%) rename src/theme/{assets => legacyTokens}/ModalSize/md.json (100%) rename src/theme/{assets => legacyTokens}/ModalSize/sm.json (100%) rename src/theme/{assets => legacyTokens}/ModalSize/xl.json (100%) create mode 100644 src/theme/legacyTokens/README.md rename src/theme/{assets => legacyTokens}/background.json (100%) rename src/theme/{assets => legacyTokens}/border.json (100%) rename src/theme/{assets => legacyTokens}/customCommon.ts (100%) rename src/theme/{assets => legacyTokens}/customDark.ts (100%) rename src/theme/{assets => legacyTokens}/customLight.ts (100%) rename src/theme/{assets => legacyTokens}/effects.json (100%) rename src/theme/{assets => legacyTokens}/global.json (100%) create mode 100644 src/theme/legacyTokens/index.ts rename src/theme/{assets => legacyTokens}/primaryColors.json (100%) rename src/theme/{assets => legacyTokens}/shadow.ts (100%) rename src/theme/{assets => legacyTokens}/sizing.json (100%) rename src/theme/{assets => legacyTokens}/spacing.json (100%) rename src/theme/{assets => legacyTokens}/themeDark.json (100%) rename src/theme/{assets => legacyTokens}/themeLight.json (100%) rename src/theme/{assets => legacyTokens}/typography.json (100%) create mode 100644 src/theme/themes.ts diff --git a/MIGRATION.md b/MIGRATION.md index 074c690b..de792443 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -18,7 +18,7 @@ import { export const Root = () => ( @@ -45,7 +45,7 @@ const fonts = useFonts() import { StyleSheet } from 'react-native-unistyles' const styles = StyleSheet.create(({ fonts }) => ({ - title: { fontFamily: fonts.primary }, + title: { fontFamily: fonts.fontFamily.heading }, })) ``` diff --git a/README.md b/README.md index b95d6112..bf4be666 100644 --- a/README.md +++ b/README.md @@ -36,26 +36,25 @@ npm i @cdek-it/react-native-ui-kit UI kit использует следующие виды шрифтов. -| Тип шрифта | Используемые начертания | Рекомендуемый шрифт | Рекомендуемый аналог | -| ----------- | ---------------------------------------------- | ------------------- | -------------------- | -| `primary` | – regular
– demibold
– demibold italic | TT Fellows | Noto Sans | -| `secondary` | – regular
– bold | Noto Sans | — | +| Тип шрифта | Используемые начертания | Рекомендуемый шрифт | Рекомендуемый аналог | +| ---------- | ---------------------------------------------- | ------------------- | -------------------- | +| `heading` | – regular
– demibold
– demibold italic | TT Fellows | Noto Sans | +| `base` | – regular
– bold | Noto Sans | — | Исходники шрифтов не поставляются вместе с пакетом, их требуется подключать -отдельно. После подключения шрифтов в проект, необходимо указать их в -`ThemeContextProvider`. +отдельно под именами, указанными в токенах. ```tsx - + ``` После этого шрифты доступны через `useUnistyles().theme.fonts` или прямо в `StyleSheet.create(({ fonts }) => ...)`. -`ThemeContextProvider` настраивает активную тему и шрифты для `unistyles`. -`ThemeContext` остается пустым и всегда имеет значение `null`. +`ThemeContextProvider` только настраивает темы и шрифты для `unistyles`. +`ThemeContext` остается пустым и всегда имеет значение `null`. Deprecated-формат +`fonts={{ primary, secondary }}` временно сохраняется для обратной +совместимости. ### Пример подключения шрифтов с помощью expo-fonts через плагин diff --git a/src/hooks/useFonts.ts b/src/hooks/useFonts.ts index e83308db..348ee283 100644 --- a/src/hooks/useFonts.ts +++ b/src/hooks/useFonts.ts @@ -1,10 +1,9 @@ import { useUnistyles } from 'react-native-unistyles' -import type { FontsConfig } from '../theme' +import type { ThemeType } from '../theme/types' -export const useFonts = (): FontsConfig => { +export const useFonts = (): ThemeType['fonts'] => { const { theme } = useUnistyles() - const { primary, secondary } = theme.fonts - return { primary, secondary } + return theme.fonts } diff --git a/src/theme/ThemeContext.tsx b/src/theme/ThemeContext.tsx index f20afb5b..f528907e 100644 --- a/src/theme/ThemeContext.tsx +++ b/src/theme/ThemeContext.tsx @@ -4,56 +4,19 @@ import { StyleSheet, UnistylesRuntime } from 'react-native-unistyles' import { SkeletonContextProvider } from '../utils/SkeletonContext' -import { darkTheme } from './darkTheme' -import { lightTheme } from './lightTheme' -import { - componentTokens, - fontTokens, - semanticTokens, - type ComponentTokens, - type SemanticTokens, -} from './tokens' -import { - type FontsConfig, - type FontTokens, - type ThemeType, - ThemeVariant, -} from './types' - -type InternalTheme = Omit & { - components: ComponentTokens - fonts: FontsConfig & FontTokens - semantic: ThemeType['semantic'] & SemanticTokens -} - -const createInternalTheme = ( - theme: ThemeType, - components: ComponentTokens -): InternalTheme => ({ - ...theme, - components, - fonts: { - ...fontTokens, - ...theme.fonts, - fontFamily: { base: theme.fonts.secondary, heading: theme.fonts.primary }, - }, - semantic: { ...semanticTokens, ...theme.semantic }, -}) - -const internalThemes = { - light: createInternalTheme(lightTheme, componentTokens.light), - dark: createInternalTheme(darkTheme, componentTokens.dark), -} +import { applyFontConfig, type FontsConfig } from './legacyTokens' +import { darkTheme, lightTheme } from './themes' +import { ThemeVariant } from './types' StyleSheet.configure({ settings: { initialTheme: 'light' }, - themes: internalThemes, + themes: { light: lightTheme, dark: darkTheme }, }) declare module 'react-native-unistyles' { export interface UnistylesThemes { - light: (typeof internalThemes)['light'] - dark: (typeof internalThemes)['dark'] + light: typeof lightTheme + dark: typeof darkTheme } } @@ -79,17 +42,12 @@ export const ThemeContextProvider = ({ UnistylesRuntime.setTheme(THEME_NAME_MAP[initialTheme]) if (fonts) { - const updateFonts = (theme: InternalTheme): InternalTheme => ({ - ...theme, - fonts: { - ...theme.fonts, - ...fonts, - fontFamily: { base: fonts.secondary, heading: fonts.primary }, - }, - }) - - UnistylesRuntime.updateTheme('light', updateFonts) - UnistylesRuntime.updateTheme('dark', updateFonts) + UnistylesRuntime.updateTheme('light', (theme) => + applyFontConfig(theme, fonts) + ) + UnistylesRuntime.updateTheme('dark', (theme) => + applyFontConfig(theme, fonts) + ) } // eslint-disable-next-line react-hooks/exhaustive-deps -- initial* props применяем только на mount }, []) diff --git a/src/theme/__tests__/ThemeContext.test.tsx b/src/theme/__tests__/ThemeContext.test.tsx index 2edec632..c65f0d92 100644 --- a/src/theme/__tests__/ThemeContext.test.tsx +++ b/src/theme/__tests__/ThemeContext.test.tsx @@ -4,15 +4,10 @@ import { Text } from 'react-native' import { UnistylesRuntime } from 'react-native-unistyles' import { ThemeContextProvider } from '../ThemeContext' -import { darkTheme } from '../darkTheme' -import { lightTheme } from '../lightTheme' +import { darkTheme, lightTheme } from '../themes' import { componentTokens, fontTokens, semanticTokens } from '../tokens' -import darkComponentTokens from '../tokens/components/dark.json' -import lightComponentTokens from '../tokens/components/light.json' import darkSemanticColorSchemeTokens from '../tokens/semantic/colorScheme/dark.json' import lightSemanticColorSchemeTokens from '../tokens/semantic/colorScheme/light.json' -import semanticDimensions from '../tokens/semantic/dimensions.json' -import semanticEffects from '../tokens/semantic/effects.json' import { ThemeVariant } from '../types' describe('ThemeContextProvider', () => { @@ -40,7 +35,7 @@ describe('ThemeContextProvider', () => { expect(UnistylesRuntime.setTheme).toHaveBeenCalledWith('light') }) - test('при передаче fonts обновляет обе темы', () => { + test('при legacy-формате fonts обновляет обе темы', () => { const fonts = { primary: 'Roboto', secondary: 'Inter' } render( @@ -59,14 +54,41 @@ describe('ThemeContextProvider', () => { ) const [, updater] = jest.mocked(UnistylesRuntime.updateTheme).mock.calls[0] - const theme = UnistylesRuntime.getTheme('light') + const theme = lightTheme expect(updater(theme)).toStrictEqual({ ...theme, fonts: { ...theme.fonts, + fontFamily: { + ...theme.fonts.fontFamily, + heading: fonts.primary, + base: fonts.secondary, + }, ...fonts, - fontFamily: { base: fonts.secondary, heading: fonts.primary }, + }, + }) + }) + + test('при актуальном формате fonts обновляет обе темы', () => { + const fonts = { heading: 'Roboto', base: 'Inter' } + + render( + + child + + ) + + const [, updater] = jest.mocked(UnistylesRuntime.updateTheme).mock.calls[0] + const theme = lightTheme + + expect(updater(theme)).toStrictEqual({ + ...theme, + fonts: { + ...theme.fonts, + fontFamily: { ...theme.fonts.fontFamily, ...fonts }, + primary: fonts.heading, + secondary: fonts.base, }, }) }) @@ -81,51 +103,57 @@ describe('ThemeContextProvider', () => { expect(UnistylesRuntime.updateTheme).not.toHaveBeenCalled() }) - test('каждая тема содержит только соответствующую цветовую схему', () => { + test('каждая тема содержит соответствующие semantic-токены', () => { expect(lightTheme.semantic.colorScheme).toBe(lightSemanticColorSchemeTokens) expect(darkTheme.semantic.colorScheme).toBe(darkSemanticColorSchemeTokens) - expect(lightTheme.semantic).not.toHaveProperty('dimension') - expect(lightTheme.semantic).not.toHaveProperty('effects') + expect(lightTheme.semantic.dimension).toBe(semanticTokens.dimension) + expect(lightTheme.semantic.effects).toBe(semanticTokens.effects) }) test('общие semantic-токены не зависят от темы', () => { - expect(semanticTokens.dimension).toBe(semanticDimensions) - expect(semanticTokens.effects).toBe(semanticEffects) + expect(lightTheme.semantic.dimension).toBe(darkTheme.semantic.dimension) + expect(lightTheme.semantic.effects).toBe(darkTheme.semantic.effects) }) - test('component-токены не входят в публичные темы', () => { - expect(lightTheme).not.toHaveProperty('components') - expect(darkTheme).not.toHaveProperty('components') + test('каждая тема содержит соответствующие component-токены', () => { + expect(lightTheme.components).toBe(componentTokens.light) + expect(darkTheme.components).toBe(componentTokens.dark) }) - test('внутренняя карта component-токенов содержит обе темы', () => { - expect(componentTokens.light).toBe(lightComponentTokens) - expect(componentTokens.dark).toBe(darkComponentTokens) + test('каждая тема содержит общие шрифтовые токены', () => { + expect(lightTheme.fonts.fontSize).toBe(fontTokens.fontSize) + expect(darkTheme.fonts.fontSize).toBe(fontTokens.fontSize) }) - test('внутренняя тема Unistyles содержит сгенерированные токены', () => { - const internalLightTheme = UnistylesRuntime.getTheme('light') - const internalDarkTheme = UnistylesRuntime.getTheme('dark') - - expect(internalLightTheme).toMatchObject({ - components: lightComponentTokens, - fonts: fontTokens, - semantic: { - colorScheme: lightSemanticColorSchemeTokens, - dimension: semanticDimensions, - effects: semanticEffects, - }, - }) + test('публичные темы сохраняют legacy-алиасы шрифтов', () => { + expect(lightTheme.fonts).toStrictEqual( + expect.objectContaining({ + primary: fontTokens.fontFamily.heading, + secondary: fontTokens.fontFamily.base, + }) + ) + }) - expect(internalDarkTheme).toMatchObject({ - components: darkComponentTokens, - fonts: fontTokens, - semantic: { - colorScheme: darkSemanticColorSchemeTokens, - dimension: semanticDimensions, - effects: semanticEffects, - }, - }) - expect(internalLightTheme.fonts).toStrictEqual(internalDarkTheme.fonts) + test('публичные темы сохраняют legacy-токены', () => { + const legacyKeys = [ + 'background', + 'border', + 'colors', + 'custom', + 'effects', + 'global', + 'shadow', + 'sizing', + 'spacing', + 'theme', + 'typography', + ] + + expect(Object.keys(lightTheme)).toStrictEqual( + expect.arrayContaining(legacyKeys) + ) + expect(Object.keys(darkTheme)).toStrictEqual( + expect.arrayContaining(legacyKeys) + ) }) }) diff --git a/src/theme/__tests__/tokenAdapters.test.ts b/src/theme/adapters/__tests__/easing.test.ts similarity index 87% rename from src/theme/__tests__/tokenAdapters.test.ts rename to src/theme/adapters/__tests__/easing.test.ts index f11c67b4..c6218172 100644 --- a/src/theme/__tests__/tokenAdapters.test.ts +++ b/src/theme/adapters/__tests__/easing.test.ts @@ -1,4 +1,4 @@ -import { toEasing } from '../tokenAdapters' +import { toEasing } from '../easing' describe('toEasing', () => { test('создаёт Reanimated easing из коэффициентов токена', () => { diff --git a/src/theme/tokenAdapters.ts b/src/theme/adapters/easing.ts similarity index 100% rename from src/theme/tokenAdapters.ts rename to src/theme/adapters/easing.ts diff --git a/src/theme/adapters/index.ts b/src/theme/adapters/index.ts new file mode 100644 index 00000000..3c4cc4cc --- /dev/null +++ b/src/theme/adapters/index.ts @@ -0,0 +1 @@ +export { toEasing, type EasingToken } from './easing' diff --git a/src/theme/commonTheme.ts b/src/theme/commonTheme.ts deleted file mode 100644 index 8add2156..00000000 --- a/src/theme/commonTheme.ts +++ /dev/null @@ -1,23 +0,0 @@ -import background from './assets/background.json' -import border from './assets/border.json' -import { customCommon } from './assets/customCommon' -import effects from './assets/effects.json' -import global from './assets/global.json' -import primaryColors from './assets/primaryColors.json' -import { shadow } from './assets/shadow' -import sizing from './assets/sizing.json' -import spacing from './assets/spacing.json' -import typography from './assets/typography.json' - -export const commonTheme = { - background, - colors: { primary: primaryColors }, - border, - effects, - global, - sizing, - spacing, - typography, - custom: customCommon, - shadow, -} diff --git a/src/theme/darkTheme.ts b/src/theme/darkTheme.ts index bbc330fe..c3419e58 100644 --- a/src/theme/darkTheme.ts +++ b/src/theme/darkTheme.ts @@ -1,14 +1 @@ -import { InputSize } from './assets/InputSize' -import { ModalSize } from './assets/ModalSize' -import { customDark } from './assets/customDark' -import darkThemeAssets from './assets/themeDark.json' -import { commonTheme } from './commonTheme' -import darkSemanticColorSchemeTokens from './tokens/semantic/colorScheme/dark.json' -import type { ThemeType } from './types' - -export const darkTheme: ThemeType = { - semantic: { colorScheme: darkSemanticColorSchemeTokens }, - theme: { ...darkThemeAssets, InputSize, ModalSize, custom: customDark }, - ...commonTheme, - fonts: { primary: 'TT Fellows', secondary: 'Noto Sans' }, -} +export { darkTheme } from './themes' diff --git a/src/theme/index.ts b/src/theme/index.ts index 4266d324..76e8c11c 100644 --- a/src/theme/index.ts +++ b/src/theme/index.ts @@ -1,6 +1,5 @@ -export { darkTheme } from './darkTheme' -export { lightTheme } from './lightTheme' -export { toEasing, type EasingToken } from './tokenAdapters' +export { darkTheme, lightTheme } from './themes' +export { toEasing, type EasingToken } from './adapters' export { semanticTokens, type SemanticTokens } from './tokens' export { ThemeContext, diff --git a/src/theme/assets/InputSize/base.json b/src/theme/legacyTokens/InputSize/base.json similarity index 100% rename from src/theme/assets/InputSize/base.json rename to src/theme/legacyTokens/InputSize/base.json diff --git a/src/theme/assets/InputSize/index.ts b/src/theme/legacyTokens/InputSize/index.ts similarity index 100% rename from src/theme/assets/InputSize/index.ts rename to src/theme/legacyTokens/InputSize/index.ts diff --git a/src/theme/assets/InputSize/large.json b/src/theme/legacyTokens/InputSize/large.json similarity index 100% rename from src/theme/assets/InputSize/large.json rename to src/theme/legacyTokens/InputSize/large.json diff --git a/src/theme/assets/InputSize/xlarge.json b/src/theme/legacyTokens/InputSize/xlarge.json similarity index 100% rename from src/theme/assets/InputSize/xlarge.json rename to src/theme/legacyTokens/InputSize/xlarge.json diff --git a/src/theme/assets/ModalSize/index.ts b/src/theme/legacyTokens/ModalSize/index.ts similarity index 100% rename from src/theme/assets/ModalSize/index.ts rename to src/theme/legacyTokens/ModalSize/index.ts diff --git a/src/theme/assets/ModalSize/lg.json b/src/theme/legacyTokens/ModalSize/lg.json similarity index 100% rename from src/theme/assets/ModalSize/lg.json rename to src/theme/legacyTokens/ModalSize/lg.json diff --git a/src/theme/assets/ModalSize/md.json b/src/theme/legacyTokens/ModalSize/md.json similarity index 100% rename from src/theme/assets/ModalSize/md.json rename to src/theme/legacyTokens/ModalSize/md.json diff --git a/src/theme/assets/ModalSize/sm.json b/src/theme/legacyTokens/ModalSize/sm.json similarity index 100% rename from src/theme/assets/ModalSize/sm.json rename to src/theme/legacyTokens/ModalSize/sm.json diff --git a/src/theme/assets/ModalSize/xl.json b/src/theme/legacyTokens/ModalSize/xl.json similarity index 100% rename from src/theme/assets/ModalSize/xl.json rename to src/theme/legacyTokens/ModalSize/xl.json diff --git a/src/theme/legacyTokens/README.md b/src/theme/legacyTokens/README.md new file mode 100644 index 00000000..f163ad42 --- /dev/null +++ b/src/theme/legacyTokens/README.md @@ -0,0 +1,13 @@ +# Legacy-токены + +Эти токены сохраняются только для обратной совместимости публичных `lightTheme`, +`darkTheme` и `ThemeType`. Компоненты библиотеки используют `components`, +`semantic` и сгенерированную структуру `fonts`. + +Единственная точка подключения legacy-токенов — `index.ts`. Компоненты не должны +импортировать отдельные файлы из этой директории. Удалить этот слой можно в +следующей мажорной версии. + +К этому же слою относятся deprecated-алиасы `fonts.primary` и `fonts.secondary`, +а также их преобразование в `fonts.fontFamily.heading` и +`fonts.fontFamily.base`. diff --git a/src/theme/assets/background.json b/src/theme/legacyTokens/background.json similarity index 100% rename from src/theme/assets/background.json rename to src/theme/legacyTokens/background.json diff --git a/src/theme/assets/border.json b/src/theme/legacyTokens/border.json similarity index 100% rename from src/theme/assets/border.json rename to src/theme/legacyTokens/border.json diff --git a/src/theme/assets/customCommon.ts b/src/theme/legacyTokens/customCommon.ts similarity index 100% rename from src/theme/assets/customCommon.ts rename to src/theme/legacyTokens/customCommon.ts diff --git a/src/theme/assets/customDark.ts b/src/theme/legacyTokens/customDark.ts similarity index 100% rename from src/theme/assets/customDark.ts rename to src/theme/legacyTokens/customDark.ts diff --git a/src/theme/assets/customLight.ts b/src/theme/legacyTokens/customLight.ts similarity index 100% rename from src/theme/assets/customLight.ts rename to src/theme/legacyTokens/customLight.ts diff --git a/src/theme/assets/effects.json b/src/theme/legacyTokens/effects.json similarity index 100% rename from src/theme/assets/effects.json rename to src/theme/legacyTokens/effects.json diff --git a/src/theme/assets/global.json b/src/theme/legacyTokens/global.json similarity index 100% rename from src/theme/assets/global.json rename to src/theme/legacyTokens/global.json diff --git a/src/theme/legacyTokens/index.ts b/src/theme/legacyTokens/index.ts new file mode 100644 index 00000000..991912d0 --- /dev/null +++ b/src/theme/legacyTokens/index.ts @@ -0,0 +1,130 @@ +import { InputSize } from './InputSize' +import { ModalSize } from './ModalSize' +import background from './background.json' +import border from './border.json' +import { customCommon } from './customCommon' +import { customDark } from './customDark' +import { customLight } from './customLight' +import effects from './effects.json' +import global from './global.json' +import primaryColors from './primaryColors.json' +import { shadow } from './shadow' +import sizing from './sizing.json' +import spacing from './spacing.json' +import darkTheme from './themeDark.json' +import lightTheme from './themeLight.json' +import typography from './typography.json' + +interface FontFamilyTokens { + base: string + heading: string +} + +export interface LegacyFontAliases { + /** @deprecated Используйте `fonts.fontFamily.heading`. */ + primary: string + /** @deprecated Используйте `fonts.fontFamily.base`. */ + secondary: string +} + +export type FontsConfig = FontFamilyTokens | LegacyFontAliases + +export interface FontsConfigType { + fonts: FontsConfig +} + +export interface LegacyTheme { + /** @deprecated Используйте `semantic` или `components`. */ + background: typeof background + /** @deprecated Используйте `semantic` или `components`. */ + colors: { primary: typeof primaryColors } + /** @deprecated Используйте `semantic` или `components`. */ + border: typeof border + /** @deprecated Используйте `semantic.effects`. */ + effects: typeof effects + /** @deprecated Используйте `semantic`, `components` или `fonts`. */ + global: typeof global + /** @deprecated Используйте `semantic` или `components`. */ + sizing: typeof sizing + /** @deprecated Используйте `semantic` или `components`. */ + spacing: typeof spacing + /** @deprecated Используйте `semantic` или `components`. */ + theme: typeof lightTheme & { + custom: typeof customLight + InputSize: typeof InputSize + ModalSize: typeof ModalSize + } + /** @deprecated Используйте `fonts`. */ + typography: typeof typography + /** @deprecated Используйте `semantic` или `components`. */ + custom: typeof customCommon + /** @deprecated Используйте `semantic.effects`. */ + shadow: typeof shadow +} + +const commonLegacyTokens: Omit = { + background, + colors: { primary: primaryColors }, + border, + effects, + global, + sizing, + spacing, + typography, + custom: customCommon, + shadow, +} + +const legacyThemes = { + light: { + theme: { ...lightTheme, InputSize, ModalSize, custom: customLight }, + ...commonLegacyTokens, + }, + dark: { + theme: { ...darkTheme, InputSize, ModalSize, custom: customDark }, + ...commonLegacyTokens, + }, +} satisfies Record<'light' | 'dark', LegacyTheme> + +const toFontFamilyTokens = (fonts: FontsConfig): FontFamilyTokens => { + if (!('primary' in fonts)) { + return fonts + } + + const aliases = fonts as Record<'primary' | 'secondary', string> + + return { base: aliases.secondary, heading: aliases.primary } +} + +const toLegacyFontAliases = ({ + base, + heading, +}: FontFamilyTokens): LegacyFontAliases => ({ + primary: heading, + secondary: base, +}) + +export const applyFontConfig = < + T extends { fonts: { fontFamily: FontFamilyTokens } }, +>( + theme: T, + fonts: FontsConfig +) => { + const fontFamily = { ...theme.fonts.fontFamily, ...toFontFamilyTokens(fonts) } + + return { + ...theme, + fonts: { ...theme.fonts, fontFamily, ...toLegacyFontAliases(fontFamily) }, + } +} + +export const withLegacyTokens = < + T extends { fonts: { fontFamily: FontFamilyTokens } }, +>( + theme: T, + colorScheme: keyof typeof legacyThemes +) => ({ + ...theme, + ...legacyThemes[colorScheme], + fonts: { ...theme.fonts, ...toLegacyFontAliases(theme.fonts.fontFamily) }, +}) diff --git a/src/theme/assets/primaryColors.json b/src/theme/legacyTokens/primaryColors.json similarity index 100% rename from src/theme/assets/primaryColors.json rename to src/theme/legacyTokens/primaryColors.json diff --git a/src/theme/assets/shadow.ts b/src/theme/legacyTokens/shadow.ts similarity index 100% rename from src/theme/assets/shadow.ts rename to src/theme/legacyTokens/shadow.ts diff --git a/src/theme/assets/sizing.json b/src/theme/legacyTokens/sizing.json similarity index 100% rename from src/theme/assets/sizing.json rename to src/theme/legacyTokens/sizing.json diff --git a/src/theme/assets/spacing.json b/src/theme/legacyTokens/spacing.json similarity index 100% rename from src/theme/assets/spacing.json rename to src/theme/legacyTokens/spacing.json diff --git a/src/theme/assets/themeDark.json b/src/theme/legacyTokens/themeDark.json similarity index 100% rename from src/theme/assets/themeDark.json rename to src/theme/legacyTokens/themeDark.json diff --git a/src/theme/assets/themeLight.json b/src/theme/legacyTokens/themeLight.json similarity index 100% rename from src/theme/assets/themeLight.json rename to src/theme/legacyTokens/themeLight.json diff --git a/src/theme/assets/typography.json b/src/theme/legacyTokens/typography.json similarity index 100% rename from src/theme/assets/typography.json rename to src/theme/legacyTokens/typography.json diff --git a/src/theme/lightTheme.ts b/src/theme/lightTheme.ts index e3c80bfb..a39341e9 100644 --- a/src/theme/lightTheme.ts +++ b/src/theme/lightTheme.ts @@ -1,14 +1 @@ -import { InputSize } from './assets/InputSize' -import { ModalSize } from './assets/ModalSize' -import { customLight } from './assets/customLight' -import lightThemeAssets from './assets/themeLight.json' -import { commonTheme } from './commonTheme' -import lightSemanticColorSchemeTokens from './tokens/semantic/colorScheme/light.json' -import type { ThemeType } from './types' - -export const lightTheme: ThemeType = { - semantic: { colorScheme: lightSemanticColorSchemeTokens }, - theme: { ...lightThemeAssets, InputSize, ModalSize, custom: customLight }, - ...commonTheme, - fonts: { primary: 'TT Fellows', secondary: 'Noto Sans' }, -} +export { lightTheme } from './themes' diff --git a/src/theme/themes.ts b/src/theme/themes.ts new file mode 100644 index 00000000..9f55ed97 --- /dev/null +++ b/src/theme/themes.ts @@ -0,0 +1,29 @@ +import { withLegacyTokens } from './legacyTokens' +import { componentTokens, fontTokens, semanticTokens } from './tokens' +import darkSemanticColorSchemeTokens from './tokens/semantic/colorScheme/dark.json' +import lightSemanticColorSchemeTokens from './tokens/semantic/colorScheme/light.json' +import type { RuntimeTheme, ThemeType } from './types' + +const createRuntimeTheme = ( + colorScheme: RuntimeTheme['semantic']['colorScheme'], + components: RuntimeTheme['components'] +): RuntimeTheme => ({ + semantic: { colorScheme, ...semanticTokens }, + components, + fonts: fontTokens, +}) + +const runtimeThemes = { + light: createRuntimeTheme( + lightSemanticColorSchemeTokens, + componentTokens.light + ), + dark: createRuntimeTheme(darkSemanticColorSchemeTokens, componentTokens.dark), +} + +export const lightTheme: ThemeType = withLegacyTokens( + runtimeThemes.light, + 'light' +) + +export const darkTheme: ThemeType = withLegacyTokens(runtimeThemes.dark, 'dark') diff --git a/src/theme/tokens/README.md b/src/theme/tokens/README.md index c4c6c42c..f7dd2729 100644 --- a/src/theme/tokens/README.md +++ b/src/theme/tokens/README.md @@ -1,11 +1,11 @@ # Сгенерированные токены -В публичный `ThemeType.semantic` подключается только выбранный `colorScheme`. -Общие `dimension`, `effects` и `fonts` добавляются во внутреннюю тему Unistyles и -не зависят от цветовой схемы. В неё же добавляются соответствующие светлой или -тёмной теме `components`. В публичные темы и экспорты component- и font-токены -не входят. Всё генерируется из `design-tokens/input/tokens.json` и не -редактируется вручную. +В `ThemeType`, `lightTheme` и `darkTheme` входят выбранный +`semantic.colorScheme`, общие `semantic.dimension`, `semantic.effects`, `fonts` +и соответствующие теме `components`. Отдельно из пакета экспортируются только +общие `semanticTokens`; карты component- и font-токенов остаются внутренними. +Всё генерируется из `design-tokens/input/tokens.json` и не редактируется +вручную. Подробности: [генератор токенов](../../../scripts/token-generator/README.md). diff --git a/src/theme/types.ts b/src/theme/types.ts index c0b3ad20..0402a101 100644 --- a/src/theme/types.ts +++ b/src/theme/types.ts @@ -1,59 +1,39 @@ import type { TextStyle } from 'react-native' -import type { InputSize } from './assets/InputSize' -import type { ModalSize } from './assets/ModalSize' -import type background from './assets/background.json' -import type border from './assets/border.json' -import type { customCommon } from './assets/customCommon' -import type { customLight } from './assets/customLight' -import type effects from './assets/effects.json' -import type global from './assets/global.json' -import type primaryColors from './assets/primaryColors.json' -import type { shadow } from './assets/shadow' -import type sizing from './assets/sizing.json' -import type spacing from './assets/spacing.json' -import type lightTheme from './assets/themeLight.json' -import type typography from './assets/typography.json' +import type { LegacyFontAliases, LegacyTheme } from './legacyTokens' +import type lightComponentTokens from './tokens/components/light.json' import type fontTokens from './tokens/fonts.json' import type lightSemanticColorSchemeTokens from './tokens/semantic/colorScheme/light.json' +import type semanticDimensions from './tokens/semantic/dimensions.json' +import type semanticEffects from './tokens/semantic/effects.json' -export interface ThemeType { - background: typeof background - colors: { primary: typeof primaryColors } - border: typeof border - effects: typeof effects - global: typeof global - sizing: typeof sizing - spacing: typeof spacing - semantic: { colorScheme: typeof lightSemanticColorSchemeTokens } - theme: typeof lightTheme & { - custom: typeof customLight - InputSize: typeof InputSize - ModalSize: typeof ModalSize +export interface RuntimeTheme { + semantic: { + colorScheme: typeof lightSemanticColorSchemeTokens + dimension: typeof semanticDimensions + effects: typeof semanticEffects } - typography: typeof typography - custom: typeof customCommon - shadow: typeof shadow - fonts: FontsConfig + components: typeof lightComponentTokens + fonts: FontTokens } +export type ThemeType = RuntimeTheme & + LegacyTheme & { fonts: FontTokens & LegacyFontAliases } + export enum ThemeVariant { Light = 'Light', Dark = 'Dark', } -export interface FontsConfig { - primary: string - secondary: string -} - -export interface FontsConfigType { - fonts: FontsConfig -} - export type FontTokens = Omit & { fontWeight: Record< keyof typeof fontTokens.fontWeight, TextStyle['fontWeight'] > } + +export type { + FontsConfig, + FontsConfigType, + LegacyFontAliases, +} from './legacyTokens'