Hvis du ikke er kjent med designtokens, er de ganske enkelt representasjoner av designspesifikasjoner i kode.
Med "representasjoner" menes det at de er nøkkelverdi-par som representerer designspesifikasjoner.
Generelt sett er det to typer designtokens:
-
«Enkle» tokens – representasjoner av gyldige verdier av designsystemet. Disse symbolene dekker vanligvis fargene, typografien, avstanden osv. til designsystemet (dvs.
color-red-500
,font-bold
osv.). -
«Komponent»-tokens – Representasjoner av designspesifikasjonene for en komponent/element (dvs.
component-button-background-color
).
Med en design-tokens-pipeline kan du skrive ut design-tokens i JSON-format, og deretter oversette disse "rå"/JSON-designtokenene til formaterte tokens (JavaScript-moduler, CSS-variabler, SASS-variabler, osv.).
Med den bakgrunnen i tankene, se for deg at et designsystem hadde "enkle" designsymboler som definerer gyldige farger.
Her er JSON-representasjonen:
{
"color": {
"red-50": "#FFC3C2",
"red-100": "#FFAFAD",
// ...etc
}
}
Tenk deg nå at en pipeline for designtokens formaterer JSON til følgende JavaScript-moduler:
export colorRed50 = "#FFC3C2";
export colorRed100 = "#FFAFAD";
// ...etc
Og la oss si at disse tokens kan konsumeres i en applikasjon via en npm-pakke:
// SomeComponent.jsx
import * as tokens from "@some/design-system/tokens";
function SomeComponent() {
const style = { color: tokens.colorRed50 };
return <div style={style}>Some Component</div>
}
Nå, gitt et slikt oppsett, hvordan kan vi programmatisk lage gradienter når vi får to fargesymboler?
Her er én måte:
// SomeComponent.jsx
import * as tokens from "@some/design-system/tokens";
function SomeComponent() {
const style = {
background: `
linear-gradient(
45deg,
${tokens.colorRed50},
${tokens.colorRed100}
)
`,
};
return <div style={style}>Some Component</div>
}
Ok, men er det en måte vi kan refaktorisere dette på?
Vel, vi kan lage en hjelpefunksjon som returnerer gradienten når du gir from
og to
verdier:
// get-gradient.js
export default function getGradient(from, to) {
return `linear-gradient(45deg, ${from}, ${to})`;
}
// SomeComponent.jsx
import * as tokens from "@some/design-system/tokens";
import getGradient from './get-gradient.js';
function SomeComponent() {
const style = {
background: getGradient(
tokens.colorRed50,
tokens.colorRed100,
),
};
return <div style={style}>Some Component</div>
}
Denne refaktoren lagrer ikke i kodelinjer, men den garanterer at gradienter vil bli opprettet på samme måte så lenge de opprettes gjennom getGradient
hjelpefunksjon.
Hva om vi refaktorerte ett skritt videre og lot gradienten brukes på en hvilken som helst underordnet komponent via en innpakningskomponent?
// Gradient.jsx
import { Children, cloneElement } from 'react';
function getGradient(from, to) {
return `linear-gradient(45deg, ${from}, ${to})`;
}
export default function Gradient({ children, from, to }) {
return Children.map(children, (child) => {
return cloneElement(child, {
style: {
...child.props.style,
background: getGradient(from, to),
},
});
});
}
// SomeComponent.jsx
import * as tokens from "@some/design-system/tokens";
import AnotherComponent from './AnotherCompoent.jsx';
import Gradient from './Gradient.jsx';
function SomeComponent() {
return (
<Gradient from={tokens.colorRed50} to={tokens.colorRed100}>
<AnotherComponent />
</Gradient>
);
}
Ved å bruke Children
og cloneElement
, Gradient
komponenten kloner det underordnede elementet og bruker gradienten.
🎊 Fantastisk! Nå har vi et mønster for å bruke en gradient via en wrapper-komponent i React!