Join the Webstudio community

Updated 6 months ago

Change token with js

At a glance

The community members are discussing whether it is possible to edit a token with JavaScript to change the border radius on multiple objects at once. Some suggest directly setting the styles with JavaScript, while others note that tokens can compile to multiple classes, making it difficult to manage. Potential solutions discussed include exposing token-class mappings in client-side JavaScript, using data attributes and custom CSS states, and leveraging CSS variables. However, there is no clear consensus on the best approach, as each solution has its own challenges, such as maintaining compatibility if tokens are renamed or removed in the builder.

Hey is it possible to edit a token with javascript? I need to change the border radius on many objects at once
O
N
B
28 comments
Why not just set the styles you want with js?
Thats the process I was going through already but thought if this was possible it would be faster since I already have a token on all of them
It's def. something to think about. Since token can compile to multiple classes, it's not a 1:1 relationship but there could be a way to get, add and remove them from client js
There could be an API

const class = api.tokenToClass('someName')
element.classList.add(class);

Biggest problem I see is if you rename it in the builder, your client js stops working. There is no way to know.

So we need a better idea here. @TrySound mb you got one
Same problem exists in wf with classes and it's pretty bad
if we could solve it in a really good way, it would be a massive win.
I think the only way to do this well is to expose it somehow explicitely in in client js and make sure its impossible to delete or rename the token without knowing where its being used.
There is nothing to solve until we get native support for css mixins + ability to access them with js
even then, its going to be the same problem
Maybe one way to do it is to have an expression syntax inside custom js that allows access to tokens:

Plain Text
`const tokenClasses = ${system.tokens.myToken};` // 'a b c'
Plain Text
const class = api.tokenToClass('someName')
element.classList.add(class);

as you said there is no 1:1 relationship
tokens are merged build time, duplicated/overwritten styles are removed
there is no token representation in published site
The way is to use native and known solutions. Class, data attribute + html embed with custom css
Tokens are completely static which give us a freedom to do optimizations.
see the code above, it doesn't break anything or limits us
as I said there is no token in published site
Originally it could a b c d and what is left could be just a
there is no way to restore the information about token styles
there is ofcourse another way, instead of accessing and adding/removing tokens/classes, you add/remove attributes and predefine custom states using attribute selector, so this way you can freely manipulate attributes with client js while tokens target the right state
one thing is true is that we would have to expose all token-classes mappings to client js and this way increase client js bundle, because we can't know if the access can happen dynamically, so we would have to have all tokens-classes on he client.
this is the most realistic solution then
basically predefine all states in css, toggle the states using attributes
but we really need custom attribute selectors for this
also btw css variables
especially in cases where you need to change it on multiple elements at once, variable is handier as it can be defined once
here conditionals would be great again
btw if we just support css variables as values, setting one or. a few variables would solva that particular case, the usage has to have a default and when the value is set it will be taken
this is actually an even better solution when it comes to changing some value on many objects at once
and @TrySound is already working on css variables, so I guess this is actually going to be possible soon
wait, this also has the same problem, slightly less unexpected though - using variable names from client js will also break if they change in the builder but user forgets to update them in js

a slightly better story here is that variables are kinda expected to be used outside of css as well, maybe we can somehow make user user knows which once are used in client js
Add a reply
Sign up and join the conversation on Discord