feat(Theme): handle contextual tokens#1066
Conversation
| } | ||
|
|
||
| const getDeviceContext = (deviceName: DeviceType | undefined = undefined): DeviceContextProps => { | ||
| function getDeviceContext(deviceName: DeviceType): DeviceContextProps { |
There was a problem hiding this comment.
Les modifs dans ce fichier sont essentiellement pour limiter les changements de state si les valeurs n'ont pas changé, et ainsi limiter les recompilations du thème
|
Storybook for this build: https://ds.equisoft.io/pr-1066/ |
|
Webapp for this build: https://ds.equisoft.io/pr-1066/webapp/ |
| export type TokenName = string; | ||
| export type TokenValue = string; | ||
|
|
||
| export type TokenContext = 'mobile' | 'tablet'; |
There was a problem hiding this comment.
Je pense on devrait ajouter desktop aussi. Je pense pas que les theme sont necessairement desktop first. Et meme si on ne l'utilise pas vraiment, au moins la possibilite serait la pareil.
'my-token': 'red'
'my-token:desktop': 'blue'
// vs
'my-token': 'blue'
'my-token:tablet': 'red'
'my-token:mobile': 'red'
|
En plus des petites corrections suggérées par Savut, j'ai retiré tous les changements qui touchaient aux add-ons du storybook. Comme le scope grandissait, on pourra le faire dans un PR à part. Comme les tokens contextuels ne sont pas encore utilisés dans les components, la problématique d'avoir plusieurs |
meriouma
left a comment
There was a problem hiding this comment.
LGTM. Quelques petites questions, mais belle job!
| // Context values should be added in order of importance. Later values will be applied over earlier values. | ||
| function getTokenContext( | ||
| deviceContext: DeviceContextProps, | ||
| // @ts-ignore Future use |
There was a problem hiding this comment.
Tu pourrais toujours switcher à @ts-expect-error pour être certain de pas l'oublier, mais les chances sont faibles.
| component: {} as ResolvedTokenMap<ComponentToken>, | ||
| }; | ||
| Object.entries(theme.alias).forEach(([contextualTokenName, tokenValue]) => { | ||
| const [tokenName, tokenContext] = contextualTokenName.split(':') as [AliasToken, TokenContext]; |
There was a problem hiding this comment.
On peut avoir plusieurs contextes actifs, mais est-ce qu'on peut avoir plusieurs contextes dans un même token? Si oui je suis pas certain que c'est bien géré ici?
There was a problem hiding this comment.
Mon idée c'était juste un contexte par token. Et aussi, le type ContextualToken utilise un template string qui valide que le nom du token contient un contexte valide, je ne crois pas que ça fonctionnerait si on permet un nombre arbitraire de contextes.
Ceci dit, si on a beaucoup de breakpoints, ça réduirait probablement le nombre de tokens. Je sais pas trop..!
| ...customizedTheme, | ||
| component: {} as ResolvedTokenMap<ComponentToken>, | ||
| }; | ||
| Object.entries(theme.alias).forEach(([contextualTokenName, tokenValue]) => { |
There was a problem hiding this comment.
Peut-être?
| Object.entries(theme.alias).forEach(([contextualTokenName, tokenValue]) => { | |
| Object.entries(theme.alias).forEach(([maybeContextualTokenName, tokenValue]) => { |
| }; | ||
|
|
||
| export const equisoftTheme = buildTheme(equisoftThemeCustomization); | ||
| export const equisoftThemeCustomization: ThemeCustomization = {}; |
There was a problem hiding this comment.
Je me demande si ce layer sert encore à quelque chose vs faire themeCustomization = {} dans le ThemeWrapper, ou mettre le fallback à {} directement dans la signature de buildTheme? 🤔
There was a problem hiding this comment.
Hmm, mais ça va peut-être fucker ceux qui importaient le equisoftTheme. Faudrait qu'ils passent explicitement undefined si on veut pas nécessairement exporter ça. Hmmmmmmm.
There was a problem hiding this comment.
Mon idée c'était de rendre explicite le fait que le thème par défaut est bien le thème Equisoft, et non un thème "vide".
De plus, dans des discussions antérieures sur les tokens, on avait déterminé que le thème Equisoft divergeait un peu du mapping des autres thèmes et qu'il serait préférable qu'il ait des overrides par-dessus le mapping par défaut, ce qui éliminerait des overrides systématiques dans les autres thèmes. Ça ne s'est pas encore concrétisé mais je crois que c'est toujours d'actualité.
Tout ça pour dire que je le laisserais comme ça! 😛
| @@ -1,4 +1,4 @@ | |||
| export * from './equisoft'; | |||
| export * from './tokens'; | |||
| export * from './tokens/tokens'; | |||
There was a problem hiding this comment.
Y'en a déjà un mais je pense que je ne voulais pas exporter toute la liste des tokens et les mappings par défaut. Mais j'imagine que ça serait pas ben grave de le faire non plus...
| import { decorateWith, Decorator } from './decorator'; | ||
|
|
||
| export const DeviceContextDecorator: Decorator = decorateWith(DeviceContextProvider); | ||
| export const DeviceContextDecorator: Decorator = decorateWith(DesignSystem); |
There was a problem hiding this comment.
Il sert à quoi en fait ce décorateur? Vu que le décorateur à la racine c'est le DS dans le preview 🤔
There was a problem hiding this comment.
Il sert pu. Je crois qu'on avait mal compris comment les décorateurs s'appliquaient dans Storybook, ou encore que quelque chose a changé depuis de leur côté.
Dans tous les cas, je retire ça et je fais un cleanup des stories dans un jira à part. Pour l'instant, ça ne cause pas de problème de le laisser comme ça.

DS-1277
Modification du système de compilation du thème pour gérer les tokens contextuels, qui permettent de spécifier une valeur alternative pour un token lorsqu'on se retrouve dans un contexte donné. Ces tokens sont de la forme
token-name:contextet sont permis dans les alias tokens uniquement.Ex:
Actuellement, les contextes pris en charge sont seulement les types d'appareils:
mobileettablet. Dans le futur, ce système pourra être bonifié avec certaines préférences utilisateur passées par le client: densité, contraste, animations, etc.Pour que le système soit dynamique, le thème doit être recompilé chaque fois qu'il y a un changement dans le contexte. La fonction de compilation a été optimisée et garde en cache la dernière copie du thème compilé, ce qui permet d'éviter de multiples compilation si plusieurs tags
<DesignSystem>sont utilisés côte-à-côte dans la même page.Finalement, la documentation existante pour les thèmes dans le Storybook n'était pas compatible (chaque story est déjà wrapped dans un tag
DesignSystem, c'est incohérent d'en ajouter un autre manuellement). Pour y remédier, j'ai ajouté un add-on qui permet d'appliquer le thème sur l'ensemble du Storybook, et qui fournit les bonnes valeurs au contexte racine.