Opening up
When creating a design system, it's important to make sure that the system is flexible and can be easily extended. This allows the design system to be used in a variety of contexts and applications.
One way to do this is to expose the design system's tokens to the end-user. This allows the user to easily customize the design system to fit their needs.
Exposing theme tokens
Based on your design systems' specifications, theme tokens can vary. Let's use a portion of Material Design's color roles as an example.
Based on the specifications, we need to have a primary color, a secondary color, a tertiary color, and an error color. All of which have a background, and a text color. We can create a theme token for each of these colors. We're going to create the theme file inside of the foundations
directory of our design system.
// foundations/_tokens.scss
:root {
@include sentro.token-config(
$primary: #6200ee,
$on-primary: #ffffff,
$secondary: #03dac6,
$on-secondary: #000000,
$tertiary: #03dac6,
$on-tertiary: #000000,
$error: #b00020,
$on-error: #ffffff
);
}
We can also implement their container variants using token nesting.
// foundations/_tokens.scss
:root {
@include sentro.token-config(
$primary: (
'default': #6200ee,
'container': #caaafc
),
$on-primary: (
'default': #ffffff,
'container': #250062
),
$secondary: (
'default': #03dac6,
'container': #d2fff8
),
$on-secondary: (
'default': #000000,
'container': #004d44
),
$tertiary: (
'default': #03dac6,
'container': #d2fff8
),
$on-tertiary: (
'default': #000000,
'container': #004d44
),
$error: (
'default': #b00020,
'container': #ffcad1
),
$on-error: (
'default': #ffffff,
'container': #8c0009
)
);
}
Now we can start opening this up to the end-user by transferring the values to modifiable variables.
// foundations/_tokens.scss
$primary: (
'default': #6200ee,
'container': #caaafc
) !default;
$on-primary: (
'default': #ffffff,
'container': #250062
) !default;
$secondary: (
'default': #03dac6,
'container': #d2fff8
) !default;
$on-secondary: (
'default': #000000,
'container': #004d44
) !default;
// ...
:root {
@include sentro.token-config(
$primary: $primary,
$on-primary: $on-primary,
$secondary: $secondary,
$on-secondary: $on-secondary,
$tertiary: $tertiary,
$on-tertiary: $on-tertiary,
$error: $error,
$on-error: $on-error
);
}
This way, the end-user can easily override the default values upon import.
// main.scss
@use 'foundations/tokens' with (
$primary: (
'default': #ee6300,
'container': #ffc298
),
$on-primary: (
'default': #ffffff,
'container': #1e0a00
),
$secondary: (
'default': #6200ee,
'container': #caaafc
),
$on-secondary: (
'default': #ffffff,
'container': #250062
),
// ...
);
Exposing component tokens (keys)
In the same way, we can expose component tokens to the end-user. Let's say we have a component that has a fill, an ink, and a border color. We can create a key for each of these properties.
// components/_sdc-component.scss
.sdc-component {
background-color: sentro.key-create('component-fill', 'surface-400');
color: sentro.key-create('component-ink', 'surface-ink');
border: 1px solid sentro.key-create('component-border', 'surface-400');
}
We can then expose these keys to the end-user by transferring the values to modifiable variables.
// components/_sdc-component.scss
$fill: 'surface-400' !default;
$ink: 'surface-ink' !default;
$border: 'surface-400' !default;
.sdc-component {
background-color: sentro.key-create('component-fill', $fill);
color: sentro.key-create('component-ink', $ink);
border: 1px solid sentro.key-create('component-border', $border);
}
The end-user can then override the default values upon import.
// main.scss
@use 'components/sdc-component' with (
$fill: 'surface-200',
$ink: 'accent-600',
$border: 'surface-200'
);