Update the tokens

One of the benefits to work directly with the SDK is that you can update the tokens value on the fly to match exactly your needs. Before explaining you how to do it, it's important that you note that updating tokens won't run a remote update in your repository.

All the updates will be performed locally on the loaded SDTF, but that's it, there's no side effects

Importing the updaters

Before even updating the tokens, we need to import the updaters that will help us to perform the updates. Everything is grouped inside the updaters object:

import { updaters } from '@specifyapp/sdk/next'

Update the colors

If you need to have your colors to be converted to a specific format, you can use the prebuilt color updater:

import { updaters } from '@specifyapp/sdk/next'

sdtfClient.update(updaters.color({ toFormat: 'hex' }, { where: { token: '^color-' }}))

You can refer to the spec to see all the available colors.

Update the token's name casing

If you need to have your token's name to be formatted in a specify way: camelCase, snakeCase, etc... You can use the changeCase updater:

import { updaters } from '@specifyapp/sdk/next'

sdtfClient.update(updaters.changeCase({ toFormat: 'kebabCase' }, { where: { token: '.*' }}))

You can refer to the spec to see all the available casing.

Update the dimensions

If you need to have your dimensions to be converted to a specific format, you can use the prebuilt dimension updater:

import { updaters } from '@specifyapp/sdk/next'

sdtfClient.update(updaters.dimension(
  { toFormat: 'rem', baseValue: { rem: 12 } }, 
  { where: { token: '^spacing-' }}
)

You can refer to the spec to see all the available units.

Executing multiple updates

The update method actually takes as much parameter as you want, so you can do the following:

import { updaters } from '@specifyapp/sdk/next'

sdtfClient.update(
  updaters.dimension(
    { toFormat: 'rem', baseValue: { rem: 12 } }, 
    { where: { token: '^spcacing-' }}
   ),
   updaters.nameCase({ toFormat: 'kebabCase' }, { where: { token: '.*' }}),
   updaters.color({ toFormat: 'hex' }, { where: { token: '^color-' }})
)

Avoid query repetition

If you want to perform multiple updates with the same query, it can quickly become quite verbose. To avoid it, you can use the withQuery method:

import { updaters } from '@specifyapp/sdk/next'

sdtfClient
  .withQuery({ where: { token: '*' }})
  .update(
    updaters.dimension(
      { toFormat: 'rem', baseValue: { rem: 12 } }, 
    ),
    updaters.nameCase({ toFormat: 'kebabCase' }),
    updaters.color({ toFormat: 'hex' })
   )

Creating your custom updater

An updater is in reality a function that looks like this:

import type { SDTFQuery, SDTFEngine } from '@specifyapp/specify-design-token-format'

function myUpdater(
  options?: {}
  applyTo?: SDTFQuery,
): Updater {
  return (engine: SDTFEngine, applyToInner?: SDTFQuery) => {
    const query = applyTo ?? applyToInner;

    // Do the conversion
    ...
  };
}

So if you want to create a custom updater, feel free to copy/paste the above function and implement it the way you want. You can refer to the SDTF Engine to understand how to perform updates on the SDTF.

If you're wondering why there's 2 applyTo, it's because the first one is the one that you're passing when calling the function, and the second one is passed if the updater is called with withQuery.

Once implemented, you can use it the same way we're using the updaters above:

sdtfClient.update(myUpdater())

The above implementation works for a reusable updater, but if you exactly know what you want, you can do the following as well:

import type { SDTFEngine } from '@specifyapp/specify-design-token-format'

function myUpdater(engine: SDTFEngine) {
    // Do something
}

sdtf.update(myUpdater)

Last updated