@cloud-ru/ds-theme 1.1.0 → 1.1.1-preview-d50a3da1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -18
- package/dist/cjs/components/ChildThemeProvider/ChildThemeProvider.js +3 -3
- package/dist/cjs/components/RootThemeProvider/RootThemeProvider.d.ts +1 -1
- package/dist/cjs/components/RootThemeProvider/RootThemeProvider.js +4 -4
- package/dist/cjs/constants/appearance.d.ts +26 -15
- package/dist/cjs/constants/appearance.js +27 -16
- package/dist/cjs/hooks/useApplyCustomTheme.d.ts +1 -1
- package/dist/cjs/hooks/useApplyCustomTheme.js +1 -1
- package/dist/cjs/hooks/useThemeClassnames.d.ts +1 -1
- package/dist/cjs/hooks/useThemeClassnames.js +1 -1
- package/dist/cjs/ssr.d.ts +2 -2
- package/dist/cjs/ssr.js +2 -2
- package/dist/cjs/store/globalStore.js +1 -1
- package/dist/cjs/types/appearance.d.ts +8 -5
- package/dist/cjs/utils/customTheme/buildBrandPaletteCss.d.ts +1 -1
- package/dist/cjs/utils/customTheme/buildBrandPaletteCss.js +3 -3
- package/dist/cjs/utils/customTheme/constants.d.ts +13 -13
- package/dist/cjs/utils/customTheme/constants.js +20 -20
- package/dist/cjs/utils/customTheme/generateBrandPalette.d.ts +1 -1
- package/dist/cjs/utils/customTheme/generateBrandPalette.js +1 -1
- package/dist/cjs/utils/getThemeClassnames.d.ts +5 -2
- package/dist/cjs/utils/getThemeClassnames.js +8 -7
- package/dist/cjs/utils/mergeAppearance.js +1 -1
- package/dist/esm/components/ChildThemeProvider/ChildThemeProvider.js +3 -3
- package/dist/esm/components/RootThemeProvider/RootThemeProvider.d.ts +1 -1
- package/dist/esm/components/RootThemeProvider/RootThemeProvider.js +4 -4
- package/dist/esm/constants/appearance.d.ts +26 -15
- package/dist/esm/constants/appearance.js +26 -15
- package/dist/esm/hooks/useApplyCustomTheme.d.ts +1 -1
- package/dist/esm/hooks/useApplyCustomTheme.js +1 -1
- package/dist/esm/hooks/useThemeClassnames.d.ts +1 -1
- package/dist/esm/hooks/useThemeClassnames.js +1 -1
- package/dist/esm/ssr.d.ts +2 -2
- package/dist/esm/ssr.js +1 -1
- package/dist/esm/store/globalStore.js +1 -1
- package/dist/esm/types/appearance.d.ts +8 -5
- package/dist/esm/utils/customTheme/buildBrandPaletteCss.d.ts +1 -1
- package/dist/esm/utils/customTheme/buildBrandPaletteCss.js +3 -3
- package/dist/esm/utils/customTheme/constants.d.ts +13 -13
- package/dist/esm/utils/customTheme/constants.js +20 -20
- package/dist/esm/utils/customTheme/generateBrandPalette.d.ts +1 -1
- package/dist/esm/utils/customTheme/generateBrandPalette.js +1 -1
- package/dist/esm/utils/getThemeClassnames.d.ts +5 -2
- package/dist/esm/utils/getThemeClassnames.js +8 -7
- package/dist/esm/utils/mergeAppearance.js +1 -1
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/components/ChildThemeProvider/ChildThemeProvider.tsx +3 -3
- package/src/components/RootThemeProvider/RootThemeProvider.tsx +4 -4
- package/src/constants/appearance.ts +26 -15
- package/src/hooks/useApplyCustomTheme.ts +1 -1
- package/src/hooks/useThemeClassnames.ts +1 -1
- package/src/ssr.ts +2 -2
- package/src/store/globalStore.ts +1 -1
- package/src/types/appearance.ts +9 -6
- package/src/utils/customTheme/buildBrandPaletteCss.ts +3 -3
- package/src/utils/customTheme/constants.ts +20 -20
- package/src/utils/customTheme/generateBrandPalette.ts +1 -1
- package/src/utils/getThemeClassnames.ts +8 -7
- package/src/utils/mergeAppearance.ts +1 -1
|
@@ -2,19 +2,23 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getThemeClassnameList = getThemeClassnameList;
|
|
4
4
|
exports.getThemeClassnames = getThemeClassnames;
|
|
5
|
+
const appearance_1 = require("../constants/appearance");
|
|
5
6
|
/**
|
|
6
7
|
* Чистая функция: собирает **полный** набор `sn-*` классов из осей оформления списком токенов.
|
|
7
8
|
* Полный набор обязателен на каждой DOM-границе — токены `@cloud-ru/figma-variables` не
|
|
8
9
|
* переопределяются по одной оси через CSS-каскад (см. providers-standard.md). Базовые слои
|
|
9
|
-
* (`sn-base-styles`, `sn-figmaStyles`, `sn-components`)
|
|
10
|
-
* — всегда; `density`/`colorScheme`/`brand
|
|
10
|
+
* (`sn-base-styles`, `sn-figmaStyles`, `sn-components`), материал (`sn-yes`/`sn-no`) и платформа
|
|
11
|
+
* — всегда; `density`/`colorScheme`/`brand` — если заданы.
|
|
12
|
+
*
|
|
13
|
+
* Платформа эмитится всегда (по умолчанию `webDesktop`): плотность ссылается на её переменные и
|
|
14
|
+
* вычисляется на том же элементе, поэтому класс платформы должен стоять рядом с классом плотности.
|
|
11
15
|
*
|
|
12
16
|
* Списочная форма — источник истины для `getThemeClassnames` (строка через `join`) и для
|
|
13
17
|
* `element.classList.add(...)`, которому нужны отдельные токены без промежуточного `split`.
|
|
14
18
|
*/
|
|
15
19
|
function getThemeClassnameList(appearance = {}) {
|
|
16
|
-
const { density, colorScheme, brand,
|
|
17
|
-
const classes = ['sn-base-styles', 'sn-figmaStyles', 'sn-components', acrylic ? 'sn-yes' : 'sn-no'];
|
|
20
|
+
const { density, colorScheme, brand, platform = appearance_1.PLATFORM.WebDesktop, acrylic } = appearance;
|
|
21
|
+
const classes = ['sn-base-styles', 'sn-figmaStyles', 'sn-components', acrylic ? 'sn-yes' : 'sn-no', `sn-${platform}`];
|
|
18
22
|
if (density) {
|
|
19
23
|
classes.push(`sn-${density}`);
|
|
20
24
|
}
|
|
@@ -24,9 +28,6 @@ function getThemeClassnameList(appearance = {}) {
|
|
|
24
28
|
if (brand) {
|
|
25
29
|
classes.push(`sn-${brand}`);
|
|
26
30
|
}
|
|
27
|
-
if (brandRole) {
|
|
28
|
-
classes.push(`sn-${brandRole}`);
|
|
29
|
-
}
|
|
30
31
|
return classes;
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
@@ -10,7 +10,7 @@ function mergeAppearance(parent, overrides) {
|
|
|
10
10
|
return {
|
|
11
11
|
colorScheme: overrides.colorScheme ?? parent.colorScheme,
|
|
12
12
|
brand: overrides.brand ?? parent.brand,
|
|
13
|
-
|
|
13
|
+
platform: overrides.platform ?? parent.platform,
|
|
14
14
|
density: overrides.density ?? parent.density,
|
|
15
15
|
acrylic: overrides.acrylic ?? parent.acrylic,
|
|
16
16
|
};
|
|
@@ -12,11 +12,11 @@ import { ThemeScope } from '../ThemeScope/index.js';
|
|
|
12
12
|
*/
|
|
13
13
|
export function ChildThemeProvider({ value, rootRef, className, children }) {
|
|
14
14
|
const { appearance: parent } = useThemeAppearance();
|
|
15
|
-
const { colorScheme, brand,
|
|
15
|
+
const { colorScheme, brand, platform, density, acrylic } = value;
|
|
16
16
|
const childStore = useMemo(() => staticStore({
|
|
17
|
-
appearance: mergeAppearance(parent, { colorScheme, brand,
|
|
17
|
+
appearance: mergeAppearance(parent, { colorScheme, brand, platform, density, acrylic }),
|
|
18
18
|
setAppearance: undefined,
|
|
19
|
-
}), [parent, colorScheme, brand,
|
|
19
|
+
}), [parent, colorScheme, brand, platform, density, acrylic]);
|
|
20
20
|
return (_jsx(ThemeAppearanceStoreProvider, { store: childStore, children: _jsx(ThemeScope, { rootRef: rootRef, className: className, children: children }) }));
|
|
21
21
|
}
|
|
22
22
|
ChildThemeProvider.displayName = 'ChildThemeProvider';
|
|
@@ -35,7 +35,7 @@ export type RootThemeProviderProps = {
|
|
|
35
35
|
};
|
|
36
36
|
/**
|
|
37
37
|
* Корневой провайдер оформления. Ставится один раз в корне приложения: задаёт контекст осей
|
|
38
|
-
* (`colorScheme`/`brand`/`
|
|
38
|
+
* (`colorScheme`/`brand`/`platform`/`density`/`acrylic`) и эмитит полный набор `sn-*` на корень
|
|
39
39
|
* (`rootRef`) либо на собственный wrapper. Объект контекста — глобальный синглтон (`Symbol.for`),
|
|
40
40
|
* поэтому провайдер работает даже при нескольких версиях пакета в разных микрофронтах, а потребитель
|
|
41
41
|
* читает ближайший провайдер. Локальные переопределения осей в поддереве — через `ChildThemeProvider`.
|
|
@@ -5,7 +5,7 @@ import { ThemeAppearanceStoreProvider, } from '../../context/appearanceContext.j
|
|
|
5
5
|
import { ThemeScope } from '../ThemeScope/index.js';
|
|
6
6
|
/**
|
|
7
7
|
* Корневой провайдер оформления. Ставится один раз в корне приложения: задаёт контекст осей
|
|
8
|
-
* (`colorScheme`/`brand`/`
|
|
8
|
+
* (`colorScheme`/`brand`/`platform`/`density`/`acrylic`) и эмитит полный набор `sn-*` на корень
|
|
9
9
|
* (`rootRef`) либо на собственный wrapper. Объект контекста — глобальный синглтон (`Symbol.for`),
|
|
10
10
|
* поэтому провайдер работает даже при нескольких версиях пакета в разных микрофронтах, а потребитель
|
|
11
11
|
* читает ближайший провайдер. Локальные переопределения осей в поддереве — через `ChildThemeProvider`.
|
|
@@ -14,14 +14,14 @@ import { ThemeScope } from '../ThemeScope/index.js';
|
|
|
14
14
|
* результат передаётся в `value.colorScheme`. Не путать со старым `ThemeProvider` (themeMap/changeTheme).
|
|
15
15
|
*/
|
|
16
16
|
export function RootThemeProvider({ value, store, rootRef, className, brandColor, nonce, children, }) {
|
|
17
|
-
const { colorScheme, brand,
|
|
17
|
+
const { colorScheme, brand, platform, density, acrylic } = value ?? {};
|
|
18
18
|
// Мемо по значениям осей (не по идентичности объекта `value`): иначе литерал `value={{…}}` у
|
|
19
19
|
// потребителя пересоздавал бы стор на каждом рендере. Сеттер в static-режиме не нужен — значением
|
|
20
20
|
// владеет сам потребитель через проп `value`.
|
|
21
21
|
const staticThemeStore = useMemo(() => staticStore({
|
|
22
|
-
appearance: { colorScheme, brand,
|
|
22
|
+
appearance: { colorScheme, brand, platform, density, acrylic },
|
|
23
23
|
setAppearance: undefined,
|
|
24
|
-
}), [colorScheme, brand,
|
|
24
|
+
}), [colorScheme, brand, platform, density, acrylic]);
|
|
25
25
|
return (_jsx(ThemeAppearanceStoreProvider, { store: store ?? staticThemeStore, children: _jsx(ThemeScope, { rootRef: rootRef, className: className, brandColor: brandColor, nonce: nonce, children: children }) }));
|
|
26
26
|
}
|
|
27
27
|
RootThemeProvider.displayName = 'RootThemeProvider';
|
|
@@ -4,20 +4,31 @@ export declare const DENSITY: {
|
|
|
4
4
|
readonly Compact: "compact";
|
|
5
5
|
readonly Spacious: "spacious";
|
|
6
6
|
};
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
readonly
|
|
13
|
-
readonly
|
|
14
|
-
readonly F: "brandF";
|
|
7
|
+
/**
|
|
8
|
+
* Платформа — набор размеров, типографики и отступов, из которого плотность берёт свои значения.
|
|
9
|
+
* Класс `sn-webDesktop` / `sn-webMobile`.
|
|
10
|
+
*/
|
|
11
|
+
export declare const PLATFORM: {
|
|
12
|
+
readonly WebDesktop: "webDesktop";
|
|
13
|
+
readonly WebMobile: "webMobile";
|
|
15
14
|
};
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
readonly
|
|
22
|
-
readonly
|
|
15
|
+
/**
|
|
16
|
+
* Бренд. Класс `sn-<значение>`. Семейства HR-портала и сайта представлены финальными цветовыми
|
|
17
|
+
* вариантами: родительские слои `hrPortal`/`site` нужны только в Figma.
|
|
18
|
+
*/
|
|
19
|
+
export declare const BRAND: {
|
|
20
|
+
readonly CloudConsole: "cloudConsole";
|
|
21
|
+
readonly GigaId: "giga-id";
|
|
22
|
+
readonly Gitverse: "gitverse";
|
|
23
|
+
readonly SnackUI: "snackUI";
|
|
24
|
+
readonly HrBlue: "hrBlue";
|
|
25
|
+
readonly HrGraphite: "hrGraphite";
|
|
26
|
+
readonly HrGreen: "hrGreen";
|
|
27
|
+
readonly HrPurple: "hrPurple";
|
|
28
|
+
readonly HrYellow: "hrYellow";
|
|
29
|
+
readonly SiteBlue: "siteBlue";
|
|
30
|
+
readonly SiteGraphite: "siteGraphite";
|
|
31
|
+
readonly SiteGreen: "siteGreen";
|
|
32
|
+
readonly SitePurple: "sitePurple";
|
|
33
|
+
readonly SiteYellow: "siteYellow";
|
|
23
34
|
};
|
|
@@ -6,20 +6,31 @@ export const DENSITY = {
|
|
|
6
6
|
Compact: 'compact',
|
|
7
7
|
Spacious: 'spacious',
|
|
8
8
|
};
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
F: 'brandF',
|
|
9
|
+
/**
|
|
10
|
+
* Платформа — набор размеров, типографики и отступов, из которого плотность берёт свои значения.
|
|
11
|
+
* Класс `sn-webDesktop` / `sn-webMobile`.
|
|
12
|
+
*/
|
|
13
|
+
export const PLATFORM = {
|
|
14
|
+
WebDesktop: 'webDesktop',
|
|
15
|
+
WebMobile: 'webMobile',
|
|
17
16
|
};
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Бренд. Класс `sn-<значение>`. Семейства HR-портала и сайта представлены финальными цветовыми
|
|
19
|
+
* вариантами: родительские слои `hrPortal`/`site` нужны только в Figma.
|
|
20
|
+
*/
|
|
21
|
+
export const BRAND = {
|
|
22
|
+
CloudConsole: 'cloudConsole',
|
|
23
|
+
GigaId: 'giga-id',
|
|
24
|
+
Gitverse: 'gitverse',
|
|
25
|
+
SnackUI: 'snackUI',
|
|
26
|
+
HrBlue: 'hrBlue',
|
|
27
|
+
HrGraphite: 'hrGraphite',
|
|
28
|
+
HrGreen: 'hrGreen',
|
|
29
|
+
HrPurple: 'hrPurple',
|
|
30
|
+
HrYellow: 'hrYellow',
|
|
31
|
+
SiteBlue: 'siteBlue',
|
|
32
|
+
SiteGraphite: 'siteGraphite',
|
|
33
|
+
SiteGreen: 'siteGreen',
|
|
34
|
+
SitePurple: 'sitePurple',
|
|
35
|
+
SiteYellow: 'siteYellow',
|
|
25
36
|
};
|
|
@@ -14,7 +14,7 @@ export type UseApplyCustomThemeProps = {
|
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
16
|
* Применяет кастомный бренд-цвет: генерирует из `color` бренд-палитру и инжектит `<style>`,
|
|
17
|
-
* переопределяющий её на бренд-классах (`.sn-
|
|
17
|
+
* переопределяющий её на бренд-классах (`.sn-cloudConsole`, `.sn-hrBlue` …), а не inline на одном элементе — поэтому
|
|
18
18
|
* цвет переживает переэмиты `sn-*` вложенными компонентами и доходит до порталов. Семантический слой
|
|
19
19
|
* каскадит из палитры, красятся обе схемы.
|
|
20
20
|
*
|
|
@@ -3,7 +3,7 @@ import { buildBrandPaletteCss } from '../utils/customTheme/index.js';
|
|
|
3
3
|
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect.js';
|
|
4
4
|
/**
|
|
5
5
|
* Применяет кастомный бренд-цвет: генерирует из `color` бренд-палитру и инжектит `<style>`,
|
|
6
|
-
* переопределяющий её на бренд-классах (`.sn-
|
|
6
|
+
* переопределяющий её на бренд-классах (`.sn-cloudConsole`, `.sn-hrBlue` …), а не inline на одном элементе — поэтому
|
|
7
7
|
* цвет переживает переэмиты `sn-*` вложенными компонентами и доходит до порталов. Семантический слой
|
|
8
8
|
* каскадит из палитры, красятся обе схемы.
|
|
9
9
|
*
|
|
@@ -4,7 +4,7 @@ import { ThemeAppearance } from '../types/appearance.js';
|
|
|
4
4
|
* цепочка `ChildThemeProvider`) ⊕ переданные `overrides`. Навешивается на DOM-границу компонента,
|
|
5
5
|
* который хочет переопределить ось (например, мобильная обёртка с `density: 'comfort'`).
|
|
6
6
|
*
|
|
7
|
-
* Поскольку набор включает текущий `colorScheme`/`brand
|
|
7
|
+
* Поскольку набор включает текущий `colorScheme`/`brand` из контекста, такая обёртка —
|
|
8
8
|
* самосогласованный scope и трекает переключение темы. Без провайдера в дереве оформление пустое,
|
|
9
9
|
* и поведение совпадает со старым `getThemeClassnames({ density })`.
|
|
10
10
|
*/
|
|
@@ -5,7 +5,7 @@ import { getThemeClassnames } from '../utils/getThemeClassnames.js';
|
|
|
5
5
|
* цепочка `ChildThemeProvider`) ⊕ переданные `overrides`. Навешивается на DOM-границу компонента,
|
|
6
6
|
* который хочет переопределить ось (например, мобильная обёртка с `density: 'comfort'`).
|
|
7
7
|
*
|
|
8
|
-
* Поскольку набор включает текущий `colorScheme`/`brand
|
|
8
|
+
* Поскольку набор включает текущий `colorScheme`/`brand` из контекста, такая обёртка —
|
|
9
9
|
* самосогласованный scope и трекает переключение темы. Без провайдера в дереве оформление пустое,
|
|
10
10
|
* и поведение совпадает со старым `getThemeClassnames({ density })`.
|
|
11
11
|
*/
|
package/dist/esm/ssr.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { BRAND,
|
|
1
|
+
export { BRAND, DENSITY, PLATFORM } from './constants/appearance.js';
|
|
2
2
|
export { COLOR_SCHEME, THEME_OVERRIDE, THEME_OVERRIDE_STORAGE_KEY } from './constants/colorScheme.js';
|
|
3
|
-
export type { Brand,
|
|
3
|
+
export type { Brand, Density, Platform, ThemeAppearance } from './types/appearance.js';
|
|
4
4
|
export type { ColorScheme, ThemeOverride } from './types/colorScheme.js';
|
|
5
5
|
export { mergeAppearance } from './utils/mergeAppearance.js';
|
|
6
6
|
export { getThemeClassnameList, getThemeClassnames } from './utils/getThemeClassnames.js';
|
package/dist/esm/ssr.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SSR-безопасный субпуть `@cloud-ru/ds-theme/ssr`: только чистые символы (без React-контекста/хуков),
|
|
2
2
|
// чтобы импорт в React Server Components не тянул `createContext`. Зеркало `@cloud-ru/ds-adaptive/ssr`.
|
|
3
|
-
export { BRAND,
|
|
3
|
+
export { BRAND, DENSITY, PLATFORM } from './constants/appearance.js';
|
|
4
4
|
export { COLOR_SCHEME, THEME_OVERRIDE, THEME_OVERRIDE_STORAGE_KEY } from './constants/colorScheme.js';
|
|
5
5
|
export { mergeAppearance } from './utils/mergeAppearance.js';
|
|
6
6
|
export { getThemeClassnameList, getThemeClassnames } from './utils/getThemeClassnames.js';
|
|
@@ -6,7 +6,7 @@ const REGISTRY_KEY = Symbol.for(THEME_KEYS.store);
|
|
|
6
6
|
// между запросами), поэтому серверный рендер всегда отдаёт дефолт; реальные классы на SSR ставит
|
|
7
7
|
// строка на `<html>` (см. providers-standard.md).
|
|
8
8
|
const SERVER_VALUE = { appearance: {}, setAppearance: undefined };
|
|
9
|
-
const APPEARANCE_KEYS = ['colorScheme', 'brand', '
|
|
9
|
+
const APPEARANCE_KEYS = ['colorScheme', 'brand', 'platform', 'density', 'acrylic'];
|
|
10
10
|
function isSameAppearance(a, b) {
|
|
11
11
|
return APPEARANCE_KEYS.every(key => a[key] === b[key]);
|
|
12
12
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BRAND,
|
|
1
|
+
import { BRAND, DENSITY, PLATFORM } from '../constants/appearance.js';
|
|
2
2
|
import { ColorScheme } from './colorScheme.js';
|
|
3
3
|
export type Density = (typeof DENSITY)[keyof typeof DENSITY];
|
|
4
|
+
export type Platform = (typeof PLATFORM)[keyof typeof PLATFORM];
|
|
4
5
|
export type Brand = (typeof BRAND)[keyof typeof BRAND];
|
|
5
|
-
export type BrandRole = (typeof BRAND_ROLE)[keyof typeof BRAND_ROLE];
|
|
6
6
|
/**
|
|
7
7
|
* Набор осей оформления, которые определяют полный набор `sn-*` классов на DOM-границе. Любая
|
|
8
8
|
* незаданная ось наследуется от вышестоящего провайдера (слияние в `ChildThemeProvider`) — но на сам
|
|
@@ -12,10 +12,13 @@ export type BrandRole = (typeof BRAND_ROLE)[keyof typeof BRAND_ROLE];
|
|
|
12
12
|
export type ThemeAppearance = {
|
|
13
13
|
/** Цветовая схема — `sn-light` / `sn-dark`. */
|
|
14
14
|
colorScheme?: ColorScheme;
|
|
15
|
-
/** Бренд — `sn-
|
|
15
|
+
/** Бренд — `sn-cloudConsole` / `sn-hrBlue` … */
|
|
16
16
|
brand?: Brand;
|
|
17
|
-
/**
|
|
18
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Платформа — `sn-webDesktop` / `sn-webMobile`. Без значения — `webDesktop`. Раскладку `@cloud-ru/ds-adaptive`
|
|
19
|
+
* тема не читает: потребитель передаёт согласованные значения и в `AdaptiveProvider`, и сюда.
|
|
20
|
+
*/
|
|
21
|
+
platform?: Platform;
|
|
19
22
|
/** Плотность — `sn-comfort` / `sn-compact` / `sn-spacious`. */
|
|
20
23
|
density?: Density;
|
|
21
24
|
/** Акрил (blur-материал) — `sn-yes` при `true`, иначе `sn-no`. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Собирает текст CSS-правила, переопределяющего бренд-палитру из seed-цвета на бренд-классах.
|
|
3
3
|
*
|
|
4
|
-
* - Без `scope` — глобально (`:is(.sn-
|
|
4
|
+
* - Без `scope` — глобально (`:is(.sn-cloudConsole,…){…}`), для white-label в корне приложения: побеждает
|
|
5
5
|
* по source order на всех бренд-классах страницы, включая порталы.
|
|
6
6
|
* - Со `scope` (CSS-селектор корня поддерева) — ограничивает область потомками и самим корнем; выше
|
|
7
7
|
* токенной специфичности, поэтому порядок не важен.
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { BRAND } from '../../constants/appearance.js';
|
|
2
2
|
import { buildBrandPaletteVars } from './buildBrandPaletteVars.js';
|
|
3
|
-
// Правило нацелено на сами бренд-классы (`.sn-
|
|
3
|
+
// Правило нацелено на сами бренд-классы (`.sn-cloudConsole`, `.sn-hrBlue` …), а не на один элемент inline: компоненты,
|
|
4
4
|
// переэмитящие набор `sn-*` на своих обёртках (Table/Stepper/Alert через `useThemeClassnames`), заново
|
|
5
5
|
// объявляют `--sn-brand-color-primary-*` из класса бренда — inline на предке они перекрыли бы, правило
|
|
6
6
|
// на том же бренд-классе — нет.
|
|
7
7
|
// Один seed переопределяет сразу все бренд-классы (потребитель не знает, в какой бренд-слот завернётся
|
|
8
|
-
// его поддерево). TODO FF-8813: возможность задавать seed индивидуально для каждого
|
|
8
|
+
// его поддерево). TODO FF-8813: возможность задавать seed индивидуально для каждого бренда.
|
|
9
9
|
const BRAND_CLASS_SELECTOR = `:is(${Object.values(BRAND)
|
|
10
10
|
.map(brand => `.sn-${brand}`)
|
|
11
11
|
.join(',')})`;
|
|
12
12
|
/**
|
|
13
13
|
* Собирает текст CSS-правила, переопределяющего бренд-палитру из seed-цвета на бренд-классах.
|
|
14
14
|
*
|
|
15
|
-
* - Без `scope` — глобально (`:is(.sn-
|
|
15
|
+
* - Без `scope` — глобально (`:is(.sn-cloudConsole,…){…}`), для white-label в корне приложения: побеждает
|
|
16
16
|
* по source order на всех бренд-классах страницы, включая порталы.
|
|
17
17
|
* - Со `scope` (CSS-селектор корня поддерева) — ограничивает область потомками и самим корнем; выше
|
|
18
18
|
* токенной специфичности, поэтому порядок не важен.
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
/** Тон акцента (`--sn-brand-color-primary-
|
|
2
|
-
export declare const PRIMARY_ACCENT_TONE = "
|
|
3
|
-
/** Near-white тон для текста на акценте (совпадает с дефолтом `onAccentLight` бренда `
|
|
1
|
+
/** Тон акцента (`--sn-brand-color-primary-50`) — им становится сам seed-цвет. */
|
|
2
|
+
export declare const PRIMARY_ACCENT_TONE = "50";
|
|
3
|
+
/** Near-white тон для текста на акценте (совпадает с дефолтом `onAccentLight` бренда `cloudConsole`). */
|
|
4
4
|
export declare const NEAR_WHITE_TONE = "99";
|
|
5
|
-
/** Near-dark тон для текста на акценте (совпадает с дефолтом `onAccentDark` бренда `
|
|
6
|
-
export declare const NEAR_DARK_TONE = "
|
|
5
|
+
/** Near-dark тон для текста на акценте (совпадает с дефолтом `onAccentDark` бренда `cloudConsole`). */
|
|
6
|
+
export declare const NEAR_DARK_TONE = "05";
|
|
7
7
|
/** Все числовые тоны палитры `--sn-brand-color-primary-<tone>`. */
|
|
8
|
-
export declare const BRAND_PRIMARY_TONES: readonly ["
|
|
8
|
+
export declare const BRAND_PRIMARY_TONES: readonly ["05", "10", "20", "30", "40", "50", "60", "70", "80", "90", "95", "99"];
|
|
9
9
|
export type BrandPrimaryTone = (typeof BRAND_PRIMARY_TONES)[number];
|
|
10
|
-
/** Опорные hex тонов бренда `
|
|
10
|
+
/** Опорные hex тонов бренда `cloudConsole` — источник `L`/`C` для генерации по любому seed-цвету. */
|
|
11
11
|
export declare const BASE_BRAND_PALETTE: Record<BrandPrimaryTone, string>;
|
|
12
12
|
/** Префикс CSS-переменных бренд-палитры. */
|
|
13
13
|
export declare const BRAND_PRIMARY_VAR_PREFIX = "--sn-brand-color-primary-";
|
|
14
|
-
/** Alpha-суффикс для `--sn-brand-color-primary-transparent` (
|
|
15
|
-
export declare const TRANSPARENT_ALPHA_SUFFIX = "
|
|
14
|
+
/** Alpha-суффикс для `--sn-brand-color-primary-transparent` (дефолт `#389f741a` бренда cloudConsole). */
|
|
15
|
+
export declare const TRANSPARENT_ALPHA_SUFFIX = "1a";
|
|
16
16
|
/**
|
|
17
17
|
* Тинты акцента для activated-состояний (`--sn-brand-color-state-activated-*-background`) — это
|
|
18
|
-
* акцентный тон с alpha. Суффиксы
|
|
18
|
+
* акцентный тон с alpha. Суффиксы — дефолты cloudConsole (`#389f741a/33/4d`). Без них
|
|
19
19
|
* activated-заливки (выбранная строка таблицы, active-состояния) не следуют за кастомным бренд-цветом.
|
|
20
20
|
*/
|
|
21
21
|
export declare const ACTIVATED_ALPHA_SUFFIX: {
|
|
22
|
-
readonly default: "
|
|
23
|
-
readonly hovered: "
|
|
24
|
-
readonly pressed: "
|
|
22
|
+
readonly default: "1a";
|
|
23
|
+
readonly hovered: "33";
|
|
24
|
+
readonly pressed: "4d";
|
|
25
25
|
};
|
|
26
26
|
/** Имена CSS-переменных activated-заливок. */
|
|
27
27
|
export declare const BRAND_ACTIVATED_VAR: {
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
// Опорная палитра и тон-константы для генерации кастомного бренд-цвета. Тоновый набор и дефолтные
|
|
2
|
-
// hex совпадают с `--sn-brand-color-primary-<tone>` бренда `
|
|
2
|
+
// hex совпадают с `--sn-brand-color-primary-<tone>` бренда `cloudConsole` из `@cloud-ru/figma-variables`:
|
|
3
3
|
// генератор держит `L`/`C` этих тонов и поворачивает hue к seed-цвету потребителя.
|
|
4
|
-
/** Тон акцента (`--sn-brand-color-primary-
|
|
5
|
-
export const PRIMARY_ACCENT_TONE = '
|
|
6
|
-
/** Near-white тон для текста на акценте (совпадает с дефолтом `onAccentLight` бренда `
|
|
4
|
+
/** Тон акцента (`--sn-brand-color-primary-50`) — им становится сам seed-цвет. */
|
|
5
|
+
export const PRIMARY_ACCENT_TONE = '50';
|
|
6
|
+
/** Near-white тон для текста на акценте (совпадает с дефолтом `onAccentLight` бренда `cloudConsole`). */
|
|
7
7
|
export const NEAR_WHITE_TONE = '99';
|
|
8
|
-
/** Near-dark тон для текста на акценте (совпадает с дефолтом `onAccentDark` бренда `
|
|
9
|
-
export const NEAR_DARK_TONE = '
|
|
8
|
+
/** Near-dark тон для текста на акценте (совпадает с дефолтом `onAccentDark` бренда `cloudConsole`). */
|
|
9
|
+
export const NEAR_DARK_TONE = '05';
|
|
10
10
|
/** Все числовые тоны палитры `--sn-brand-color-primary-<tone>`. */
|
|
11
|
-
export const BRAND_PRIMARY_TONES = ['
|
|
12
|
-
/** Опорные hex тонов бренда `
|
|
11
|
+
export const BRAND_PRIMARY_TONES = ['05', '10', '20', '30', '40', '50', '60', '70', '80', '90', '95', '99'];
|
|
12
|
+
/** Опорные hex тонов бренда `cloudConsole` — источник `L`/`C` для генерации по любому seed-цвету. */
|
|
13
13
|
export const BASE_BRAND_PALETTE = {
|
|
14
|
-
'
|
|
14
|
+
'05': '#21372f',
|
|
15
15
|
'10': '#243e35',
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'
|
|
16
|
+
'20': '#2b483c',
|
|
17
|
+
'30': '#2c5e49',
|
|
18
|
+
'40': '#22775b',
|
|
19
|
+
'50': '#389f74',
|
|
20
20
|
'60': '#5ebb91',
|
|
21
|
-
'
|
|
21
|
+
'70': '#85ceaa',
|
|
22
22
|
'80': '#caeadb',
|
|
23
23
|
'90': '#edf7f1',
|
|
24
24
|
'95': '#f5fdf8',
|
|
@@ -26,17 +26,17 @@ export const BASE_BRAND_PALETTE = {
|
|
|
26
26
|
};
|
|
27
27
|
/** Префикс CSS-переменных бренд-палитры. */
|
|
28
28
|
export const BRAND_PRIMARY_VAR_PREFIX = '--sn-brand-color-primary-';
|
|
29
|
-
/** Alpha-суффикс для `--sn-brand-color-primary-transparent` (
|
|
30
|
-
export const TRANSPARENT_ALPHA_SUFFIX = '
|
|
29
|
+
/** Alpha-суффикс для `--sn-brand-color-primary-transparent` (дефолт `#389f741a` бренда cloudConsole). */
|
|
30
|
+
export const TRANSPARENT_ALPHA_SUFFIX = '1a';
|
|
31
31
|
/**
|
|
32
32
|
* Тинты акцента для activated-состояний (`--sn-brand-color-state-activated-*-background`) — это
|
|
33
|
-
* акцентный тон с alpha. Суффиксы
|
|
33
|
+
* акцентный тон с alpha. Суффиксы — дефолты cloudConsole (`#389f741a/33/4d`). Без них
|
|
34
34
|
* activated-заливки (выбранная строка таблицы, active-состояния) не следуют за кастомным бренд-цветом.
|
|
35
35
|
*/
|
|
36
36
|
export const ACTIVATED_ALPHA_SUFFIX = {
|
|
37
|
-
default: '
|
|
38
|
-
hovered: '
|
|
39
|
-
pressed: '
|
|
37
|
+
default: '1a',
|
|
38
|
+
hovered: '33',
|
|
39
|
+
pressed: '4d',
|
|
40
40
|
};
|
|
41
41
|
/** Имена CSS-переменных activated-заливок. */
|
|
42
42
|
export const BRAND_ACTIVATED_VAR = {
|
|
@@ -3,7 +3,7 @@ import { BrandPrimaryTone } from './constants.js';
|
|
|
3
3
|
export type BrandPalette = Record<BrandPrimaryTone, string>;
|
|
4
4
|
/**
|
|
5
5
|
* Строит бренд-палитру из одного seed-цвета: берёт `L`/`C` каждого опорного тона `BASE_BRAND_PALETTE`
|
|
6
|
-
* и поворачивает hue к hue seed-цвета (OKLCH). Тон акцента (`
|
|
6
|
+
* и поворачивает hue к hue seed-цвета (OKLCH). Тон акцента (`50`) становится самим seed-цветом.
|
|
7
7
|
* Так один цвет потребителя перекрашивает всю шкалу `--sn-brand-color-primary-<tone>`, сохраняя
|
|
8
8
|
* светлоту/насыщенность DS-палитры. Невалидный hex → `null`.
|
|
9
9
|
*/
|
|
@@ -2,7 +2,7 @@ import { hex2color, lch2color } from './color/index.js';
|
|
|
2
2
|
import { BASE_BRAND_PALETTE, BRAND_PRIMARY_TONES, PRIMARY_ACCENT_TONE } from './constants.js';
|
|
3
3
|
/**
|
|
4
4
|
* Строит бренд-палитру из одного seed-цвета: берёт `L`/`C` каждого опорного тона `BASE_BRAND_PALETTE`
|
|
5
|
-
* и поворачивает hue к hue seed-цвета (OKLCH). Тон акцента (`
|
|
5
|
+
* и поворачивает hue к hue seed-цвета (OKLCH). Тон акцента (`50`) становится самим seed-цветом.
|
|
6
6
|
* Так один цвет потребителя перекрашивает всю шкалу `--sn-brand-color-primary-<tone>`, сохраняя
|
|
7
7
|
* светлоту/насыщенность DS-палитры. Невалидный hex → `null`.
|
|
8
8
|
*/
|
|
@@ -3,8 +3,11 @@ import { ThemeAppearance } from '../types/appearance.js';
|
|
|
3
3
|
* Чистая функция: собирает **полный** набор `sn-*` классов из осей оформления списком токенов.
|
|
4
4
|
* Полный набор обязателен на каждой DOM-границе — токены `@cloud-ru/figma-variables` не
|
|
5
5
|
* переопределяются по одной оси через CSS-каскад (см. providers-standard.md). Базовые слои
|
|
6
|
-
* (`sn-base-styles`, `sn-figmaStyles`, `sn-components`)
|
|
7
|
-
* — всегда; `density`/`colorScheme`/`brand
|
|
6
|
+
* (`sn-base-styles`, `sn-figmaStyles`, `sn-components`), материал (`sn-yes`/`sn-no`) и платформа
|
|
7
|
+
* — всегда; `density`/`colorScheme`/`brand` — если заданы.
|
|
8
|
+
*
|
|
9
|
+
* Платформа эмитится всегда (по умолчанию `webDesktop`): плотность ссылается на её переменные и
|
|
10
|
+
* вычисляется на том же элементе, поэтому класс платформы должен стоять рядом с классом плотности.
|
|
8
11
|
*
|
|
9
12
|
* Списочная форма — источник истины для `getThemeClassnames` (строка через `join`) и для
|
|
10
13
|
* `element.classList.add(...)`, которому нужны отдельные токены без промежуточного `split`.
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
+
import { PLATFORM } from '../constants/appearance.js';
|
|
1
2
|
/**
|
|
2
3
|
* Чистая функция: собирает **полный** набор `sn-*` классов из осей оформления списком токенов.
|
|
3
4
|
* Полный набор обязателен на каждой DOM-границе — токены `@cloud-ru/figma-variables` не
|
|
4
5
|
* переопределяются по одной оси через CSS-каскад (см. providers-standard.md). Базовые слои
|
|
5
|
-
* (`sn-base-styles`, `sn-figmaStyles`, `sn-components`)
|
|
6
|
-
* — всегда; `density`/`colorScheme`/`brand
|
|
6
|
+
* (`sn-base-styles`, `sn-figmaStyles`, `sn-components`), материал (`sn-yes`/`sn-no`) и платформа
|
|
7
|
+
* — всегда; `density`/`colorScheme`/`brand` — если заданы.
|
|
8
|
+
*
|
|
9
|
+
* Платформа эмитится всегда (по умолчанию `webDesktop`): плотность ссылается на её переменные и
|
|
10
|
+
* вычисляется на том же элементе, поэтому класс платформы должен стоять рядом с классом плотности.
|
|
7
11
|
*
|
|
8
12
|
* Списочная форма — источник истины для `getThemeClassnames` (строка через `join`) и для
|
|
9
13
|
* `element.classList.add(...)`, которому нужны отдельные токены без промежуточного `split`.
|
|
10
14
|
*/
|
|
11
15
|
export function getThemeClassnameList(appearance = {}) {
|
|
12
|
-
const { density, colorScheme, brand,
|
|
13
|
-
const classes = ['sn-base-styles', 'sn-figmaStyles', 'sn-components', acrylic ? 'sn-yes' : 'sn-no'];
|
|
16
|
+
const { density, colorScheme, brand, platform = PLATFORM.WebDesktop, acrylic } = appearance;
|
|
17
|
+
const classes = ['sn-base-styles', 'sn-figmaStyles', 'sn-components', acrylic ? 'sn-yes' : 'sn-no', `sn-${platform}`];
|
|
14
18
|
if (density) {
|
|
15
19
|
classes.push(`sn-${density}`);
|
|
16
20
|
}
|
|
@@ -20,9 +24,6 @@ export function getThemeClassnameList(appearance = {}) {
|
|
|
20
24
|
if (brand) {
|
|
21
25
|
classes.push(`sn-${brand}`);
|
|
22
26
|
}
|
|
23
|
-
if (brandRole) {
|
|
24
|
-
classes.push(`sn-${brandRole}`);
|
|
25
|
-
}
|
|
26
27
|
return classes;
|
|
27
28
|
}
|
|
28
29
|
/**
|
|
@@ -7,7 +7,7 @@ export function mergeAppearance(parent, overrides) {
|
|
|
7
7
|
return {
|
|
8
8
|
colorScheme: overrides.colorScheme ?? parent.colorScheme,
|
|
9
9
|
brand: overrides.brand ?? parent.brand,
|
|
10
|
-
|
|
10
|
+
platform: overrides.platform ?? parent.platform,
|
|
11
11
|
density: overrides.density ?? parent.density,
|
|
12
12
|
acrylic: overrides.acrylic ?? parent.acrylic,
|
|
13
13
|
};
|