4.17.0 • Published 2 months ago

vienna.ui-theme v4.17.0

Weekly downloads
23
License
NO LICENSE
Repository
-
Last release
2 months ago

Изменение внешнего вида компонентов

Raiffeisenbank Design System

Основные определения

Архитектура внешнего вида компонент строится на трех сущностях: токены, пресеты и темы. Разберем их поподробней.

Токены

Токены – это атомарная сущность, переменные с одним конкретным, неделимым значением. Для веба токен конвертируется в значение, которое может принимать css-свойство. Токены Дизайн-системы сгруппированы в смысловые группы и собраны в один json объект.

Например, так выглядит группа размерных токенов, каждый из размеров является отдельным токеном.

{
    "layout": {
        "size": {
            "xxxs": "8px",
            "xxs": "12px",
            "xs": "24px",
            "s": "32px",
            "m": "36px",
            "l": "40px",
            "xl": "48px",
            "xxl": "52px"
        }
    }

Следует обратить внимание, что имена токенов несемантичны, они или полностью абстрактны, как в токенах цветов, или описывают значение токена, но они никак не определяют, как будет использоваться данный токен. Это позволяет использовать их в любом контексте.

Токены хранятся в пакете vienna.tokens, их можно импортировать как json-объект из tokens.json или как js-модуль из tokens.js.

Пресеты

Пресеты – это дополнительный уровень абстракции между компонентом и настройками его отображения. Пресет - это именованный блок css-кода, который используется компонентом, как единое целое.

Например:

Button.styles.tsx

const presets = getPresets('button', {
    base: null,
    design: 'design',
    loading: null,
});

export const Box = styled.button`
    ${presets.base}
    ${presets.design}

    ${({ isLoading }) =>
        isLoading &&
        css`
            ${presets.loading}
        `}
`;

Как видно из примера, компонент абстрагирован от конкретных значений пресета, его логика компонента никак не зависит от этого значения. Пресет используется, как фрагмент css, который вставляется в конкретный участок css-кода компонента. Таким образом, изменяя значение пресетов, мы можем управлять css-кодом компонента и соответсвенно его внешним видом.

Тема

Тема – это то, что связывает пресеты и токены между собой. Она определяет конкретные значения пресетов компонента. Тему дизайн-системы можно представить, как совокупность тем всех её компонентов. Технически тема – это json объект, который содержит все пресеты для всех компонентов и использует токены для определения значений этих пресетов.

Например, для приведенных выше пресетов кнопки дефолтная тема будет выглядеть так:

"button": {
    "base": {
        "border-radius": "8px",
        "border-color": "transparent",
        "font-family": "ALS Hauss, Helvetica, 'Helvetica New', Arial, sans-serif",
        "font-weight": "500",
        "text-decoration": "none",
        "transition": "background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease"
    },
    "design": {
        "accent": {
            "color": "#2B2D33",
            "background-color": "#FEE600"
        },
        "primary": {
            "color": "#FFFFFF",
            "background-color": "#2B2D33"
        },

    },
    "loading": {
        "cursor": "default",
        "color": "transparent",
        "transition": "none"
    },
}

Дефолтная тема дизайн-системы хранится в пакете vienna.ui-theme. Как и токены ее можно импортировать как json-объект (presets.json) и как js-модуль (presets.js).

Theme Provider

Таким образом, изменение внешнего вида компонента сводится к нахождению нужного пресета и переопределению его значения. Для этого мы используем встроенный инструмент styled components, называющийся ThemeProvider.

ThemeProvider построен на использовании context API, так, что, переданная ему тема, будет доступна всем вложенным компонентам, независимо от уровня вложенности. При использовании ThemeProvider всем дочерним компонентам приходит дополнительный атрибут theme. При попытке компонента получить каждый пресет, он вначале ищется в теме, переданной в ThemeProvider и, если данного пресета в этой теме нет, используется значение из дефолтной темы ДС.

В ThemeProvider можно обернуть как приложение целиком, и таким образом переопределить внешний вид всех инстансов компонетов дизайн-системы, так и только участок кода (отдельную страницу или участок кода на ней) и переопределить компоненты только в ограниченном контексте.

Например, для кнопки выше:

import { ThemeProvider } from 'vienna-ui';
const theme = {
    button: {
        design: {
            accent: {
                color: 'white',
                backgroundColor: 'blue',
            },
        },
    },
};

return (
    <ThemeProvider theme={theme}>
        <Button design='accent'>Test</Button>
    </ThemeProvider>
);

Теперь все акцентные кнопки внутри ThemeProvider будут белым цветом текста на синем фоне.

Пресет в теме, переданной в ThemeProvider переписывает дефолтный пресет целиком. Для примера выше, важно переписать, как значение color, так и backgroundColor. Если передать пресет, например, только с 'color', значение цвета фона для данной кнопки будет потеряно.

Пресет custom

В дополнение к стандартным пресетам, экспортируемым темой, компонент использует custom пресеты. Данные пресеты отсутствуют в дефолтной теме ДС, поэтому значения этих пресетов в компонентах по умолчанию пустое. Но указав его значение в ThemeProvider можно переписать все дефолтные стили компонента. Custom пресеты в стилях компонента всегда идут самыми последними, это позволяет значениям этих пресетов переписать все css-свойства заданые выше.

Например, для нашего примера с кнопкой:

import { ThemeProvider } from 'vienna-ui';
const theme = {
    button: {
        custom: {
            fontWeight: 'bold',
        },
    },
};

return (
    <ThemeProvider theme={theme}>
        <Button design='accent'>Test</Button>
    </ThemeProvider>
);

После этого все кнопки, объявленные внутри ThemeProvider, будут с толстым начертанием текста. Custom-пресеты – это самый простой способ переопределить внешний вид компонента.

4.17.0

2 months ago

4.8.0

4 months ago

1.4.3

2 years ago

1.4.2

2 years ago

1.4.1

2 years ago

1.4.0

2 years ago

1.3.0

3 years ago

1.2.0

3 years ago

1.2.1

3 years ago

1.1.1

3 years ago

1.1.0

3 years ago

1.0.2

3 years ago

1.0.1

4 years ago

1.0.0

4 years ago