-
Notifications
You must be signed in to change notification settings - Fork 23
Open
Description
Goals
Гибкая система, что не мешает вносить изменения в конфигурации компонентов централизованно и управляемо.
Проблемы:
- большое количество шаблонного кода в конфигурациях;
- очень много вхождений для правок конфигураций;
- бывает что теряются часть конфигураций;
Например:
Для Accordion view["default"] в пакетах на базе sdds-serv имеется абсолютно одинаковый набор свойств.
POC
Общая конфигурация компонент Button
import { buttonTokens as tokens } from '@salutejs/plasma-new-hope';
const generateFontConfig = (size = 'm', weight = 'normal') => {
return {
[tokens.buttonFontFamily]: `var(--plasma-typo-body-${size}-font-family)`,
[tokens.buttonFontSize]: `var(--plasma-typo-body-${size}-font-size)`,
[tokens.buttonFontStyle]: `var(--plasma-typo-body-${size}-font-style)`,
[tokens.buttonFontWeight]: `var(--plasma-typo-body-${size}-${weight}-font-weight)`,
[tokens.buttonLetterSpacing]: `var(--plasma-typo-body-${size}-letter-spacing)`,
[tokens.buttonLineHeight]: `var(--plasma-typo-body-${size}-line-height)`,
};
};
export const ButtonBaseConfig = {
defaults: {
view: 'default',
focused: 'true',
size: 'm',
},
variations: {
view: {
default: {
[tokens.buttonColor]: 'var(--inverse-text-primary)',
[tokens.buttonValueColor]: 'var(--inverse-text-secondary)',
[tokens.buttonBackgroundColor]: 'var(--surface-solid-default)',
[tokens.buttonColorHover]: 'var(--inverse-text-primary)',
[tokens.buttonBackgroundColorHover]: 'var(--surface-solid-default-hover)',
[tokens.buttonColorActive]: 'var(--inverse-text-primary)',
[tokens.buttonBackgroundColorActive]: 'var(--surface-solid-default-active)',
[tokens.buttonLoadingBackgroundColor]: `var(${tokens.buttonBackgroundColor})`,
},
accent: {
[tokens.buttonColor]: 'var(--on-dark-text-primary)',
[tokens.buttonValueColor]: 'var(--on-dark-text-secondary)',
[tokens.buttonBackgroundColor]: 'var(--surface-accent)',
[tokens.buttonColorHover]: 'var(--on-dark-text-primary)',
[tokens.buttonBackgroundColorHover]: 'var(--surface-accent-hover)',
[tokens.buttonColorActive]: 'var(--on-dark-text-primary)',
[tokens.buttonBackgroundColorActive]: 'var(--surface-accent-active)',
[tokens.buttonLoadingBackgroundColor]: 'var(--surface-solid-default-active)',
[tokens.buttonLoadingBackgroundColor]: `var(${tokens.buttonBackgroundColor})`,
},
},
size: {
m: {
[tokens.buttonHeight]: '3rem',
[tokens.buttonWidth]: '11.25rem',
[tokens.buttonPadding]: '1.25rem',
[tokens.buttonRadius]: '0.75rem',
[tokens.buttonSpinnerSize]: '1.375rem',
[tokens.buttonSpinnerColor]: 'inherit',
[tokens.buttonLeftContentMargin]: '0 0.375rem 0 -0.125rem',
[tokens.buttonRightContentMargin]: '0 -0.125rem 0 0.375rem',
[tokens.buttonValueMargin]: '0 0 0 0.25rem',
...generateFontConfig('m', 'bold'),
},
s: {
[tokens.buttonHeight]: '2.5rem',
[tokens.buttonWidth]: '11.25rem',
[tokens.buttonPadding]: '1rem',
[tokens.buttonRadius]: '0.625rem',
[tokens.buttonSpinnerSize]: '1.375rem',
[tokens.buttonSpinnerColor]: 'inherit',
[tokens.buttonLeftContentMargin]: '0 0.25rem 0 -0.125rem',
[tokens.buttonRightContentMargin]: '0 -0.125rem 0 0.25rem',
[tokens.buttonValueMargin]: '0 0 0 0.25rem',
...generateFontConfig('m', 'bold'),
},
},
focused: {
true: {
[tokens.buttonFocusColor]: 'var(--surface-accent)',
},
},
stretching: {
auto: {},
filled: {},
fixed: {},
},
},
};Абстрактный класс компонента
class AbstractConfig {
public variations = {};
public defaults = {};
getVariationsKeys(variation) {
return Object.keys(this.variations[variation]);
}
getVariationProp(variations, path) {
const [variation, prop] = path.split('.');
if (!variations[variation] || !variations[variation][prop]) {
return {};
}
return variations[variation][prop];
}
generateVariation(config) {
const data = Object.values(tokens)
.filter((key) => !!config[key])
.reduce((acc, key) => {
acc += `${key}: ${config[key]}; \n`;
return acc;
}, '');
return css`
${data};
`;
}
createVariation({ baseConfig, libConfig, variation }) {
return Object.keys(baseConfig.variations[variation]).reduce((acc, key) => {
const path = `${variation}.${key}`;
return {
...acc,
[key]: this.generateVariation({
...this.getVariationProp(baseConfig.variations, path),
...this.getVariationProp(libConfig.variations, path),
}),
};
}, {});
}
}Класс компонента Button
export class ButtonBase extends AbstractConfig {
constructor(baseConfig, libConfig) {
super();
this.defaults = { ...baseConfig.defaults, ...libConfig.defaults };
// INFO: Merge configs
this.variations = {
view: this.createVariation({
baseConfig,
libConfig,
variation: 'view',
}),
size: this.createVariation({
baseConfig,
libConfig,
variation: 'size',
}),
focused: this.createVariation({
baseConfig,
libConfig,
variation: 'focused',
}),
};
}
}Создание экземпляра конфигурации
import { buttonTokens as tokens } from '@salutejs/plasma-new-hope/styled-components';
import { ButtonBase } from '...';
import { ButtonBaseConfig } from '...';
export const config = new ButtonBase(ButtonBaseConfig, {
defaults: {
view: 'accent',
focused: 'true',
size: 's',
},
variations: {
view: {
default: {
[tokens.buttonBackgroundColor]: 'var(--surface-accent)',
},
},
}
});Metadata
Metadata
Assignees
Labels
No labels