123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- /* eslint-disable @typescript-eslint/no-var-requires */
- const { template, camelCase, cloneDeep } = require('lodash')
- const variablesTemplate = template(`import { css } from '@emotion/react'
- export const variables = css\`
- :root {
- <%= cssVariables %>
- }\`
- export const theme = {
- <%= themeVariables %>
- }
- export const cVar = (key: keyof typeof theme, returnValue?: boolean) => {
- if (returnValue) return theme[key].value
- return theme[key].variable
- }
- `)
- module.exports = {
- source: [`./src/styles/tokens/**/*.json`],
- parsers: [
- {
- pattern: /\.json$/,
- parse: ({ contents }) => {
- // style dictionary requires adding ".value" suffix to all referenced value, e.g. "value": "{core.neutral.default.900}" should be e.g. "value": "{core.neutral.default.900.value}"
- // this parser should fix it, although it just a workaround
- // we could remove this when they do something about it https://github.com/amzn/style-dictionary/issues/721
- const parsed = contents.replace(/}"|\.value}"/g, `.value}"`)
- return JSON.parse(parsed)
- },
- },
- // creates filterEffects design tokens, which are needed to use for `filter: drop-shadow()`
- {
- pattern: /\.json$/,
- parse: ({ contents }) => {
- const obj = JSON.parse(contents)
- if (obj.effect) {
- const deepCopy = cloneDeep(obj)
- deepCopy.filterEffect = deepCopy.effect
- delete deepCopy.effect
- return { ...obj, ...deepCopy }
- }
- },
- },
- ],
- transform: {
- removeDefaultFromName: {
- type: 'name',
- transformer: (token) => token.name.replace(/-default|-regular/g, ''),
- },
- easingTransform: {
- type: 'value',
- matcher: (token) => token.attributes.type === 'easing',
- // [1, 2, 3, 4] will become 1, 2, 3, 4
- transformer: (token) => `cubic-bezier(${token.value.toString().replace(/\[|\]/g, '')})`,
- },
- transitionTransform: {
- type: 'value',
- transitive: true,
- matcher: (token) => token.attributes.type === 'transition',
- transformer: (token) => `${token.value.timing} ${token.value.easing}`,
- },
- typographyValueTransform: {
- type: 'value',
- transitive: true,
- matcher: (token) => token.attributes.type === 'textStyles',
- transformer: (token) =>
- `${token.value.fontWeight} ${token.value.fontSize}/${token.value.lineHeight} ${token.value.fontFamily}`,
- },
- typographyNameTransform: {
- type: 'name',
- matcher: (token) => token.attributes.type === 'textStyles',
- transformer: (token) => token.name.replace(/-heading|-text|-styles/g, ''),
- },
- effectsTransform: {
- type: 'value',
- transitive: true,
- matcher: (token) => token.attributes.category === 'effect',
- transformer: (token) => {
- const isDivider = token.attributes.type === 'dividers'
- return `${isDivider ? 'inset' : ''} ${token.value.x} ${token.value.y} ${token.value.blur} ${
- token.value.spread
- } ${token.value.color}`
- },
- },
- filterEffectsTransform: {
- type: 'value',
- transitive: true,
- matcher: (token) => token.attributes.category === 'filterEffect',
- transformer: (token) => `drop-shadow(${token.value.x} ${token.value.y} ${token.value.blur} ${token.value.color})`,
- },
- },
- format: {
- customFormat: ({ dictionary }) => {
- // create new tokens for letter-spacing
- const allTokens = dictionary.allTokens
- const letterSpacingTokens = allTokens
- .filter((token) => token.attributes.type === 'textStyles')
- .map((token) => ({
- ...token,
- value: token.original.value.letterSpacing || 0,
- name: `${token.name}-letter-spacing`,
- }))
- // create new tokens for text-transform
- const textTransformTokens = allTokens
- .filter((token) => token.attributes.type === 'textStyles')
- .map((token) => ({
- ...token,
- value: token.original.value.textTransform || 'none',
- name: `${token.name}-text-transform`,
- }))
- const convertedTokens = [...allTokens, ...letterSpacingTokens, ...textTransformTokens]
- return variablesTemplate({
- cssVariables: convertedTokens
- .map((token) => {
- let keyValuePair = `--${token.name}: ${token.value};`
- if (dictionary.usesReference(token.original.value)) {
- const refs = dictionary.getReferences(token.original.value)
- refs.forEach((ref) => {
- const [key, value] = keyValuePair.split(':')
- const modifiedValue = value.replace(ref.value, `var(--${ref.name})`)
- keyValuePair = `${key}:${modifiedValue}`
- })
- }
- return keyValuePair
- })
- .join('\n'),
- themeVariables: convertedTokens
- .map((token) => `${camelCase(token.name)}: { variable: 'var(--${token.name})', value: '${token.value}' },`)
- .join('\n'),
- })
- },
- },
- platforms: {
- ts: {
- transforms: [
- `attribute/cti`,
- `name/cti/kebab`,
- 'removeDefaultFromName',
- 'typographyValueTransform',
- 'typographyNameTransform',
- 'easingTransform',
- 'transitionTransform',
- 'effectsTransform',
- 'filterEffectsTransform',
- ],
- buildPath: 'src/styles/generated/',
- files: [
- {
- destination: 'variables.ts',
- format: 'customFormat',
- filter: (token) => token.type !== 'typedef',
- options: {
- outputReferences: true,
- },
- },
- ],
- },
- },
- }
|