Hello all,
As you probably know, switching from one design system and supporting framework to another (e.g., moving from boostrap 3 to vuetify) is a really difficult and time consuming if not anticipated.
In addition, it is sometime interesting to easily switch to an alternative design system for a specific need (e.g., switch to https://www.systeme-de-design.gouv.fr/ for a development for the french government), preferably by configuration.
To tackle those two challenges, with @ludovic we’d like to propose to build the design system of Cristal as an abstraction over several design systems (see our design page on design systems, we’ll create a proposal to choose the design systems we will support soon).
To make it more concrete, the idea is define a set of UI elements and their parameters that would form the minimal building blocks of Cristal UI (i.e., a design system API).
Then, those element will be mapper to concrete UI elements from a design system - including mapping the parameters.
For instance, say we define a CritalButton
with parameters label and level (primary, secondary, tersary), the table below presents how the mapping would operate:
Abstract Component | API | dsfr (https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/bouton ) | Bootstrap 5 (https://getbootstrap.com/docs/5.3/components/buttons/) | vuetify (https://vuetifyjs.com/en/components/buttons/) |
---|---|---|---|---|
Button (primary) | <CristalButton level='primary'/> Label </CristalButton>
| <button class="fr-btn"> Label </button> | <button type="button" class="btn btn-primary"> Label </button> | <button class='v-btn v-btn--elevated v-theme--light bg-primary v-btn--density-default v-btn--size-default v-btn--variant-elevated'> Label </button> |
Button (seconday) | <CristalButton level='secondary'/> Label </CristalButton>
| <button class="fr-btn fr-btn--secondary fr-btn--tertiary"> Label </button> | <button type="button" class="btn btn-secondary"> Secondary </button> | <button class='v-btn v-theme--light text-primary v-btn--density-default v-btn--size-default v-btn--variant-tonal'> Label </button> |
Button (tersary) | <CristalButton level='tersary'/> Label </CristalButton> | <button class="fr-btn"> Label </button> | <button type="button" class="btn btn-light"> Label </button> | <button class='v-btn v-theme--light text-primary v-btn--density-default v-btn--size-default v-btn--variant-outlined'> Label </button> |
We have identified some important point of difficulty, that are not to be overlooked before agreeing on the approach:
- the indirection probably has a performance cost that we did not estimate
- the indirection also has a conceptual cost as we’ll need to define an maintain the mapping between the API and the implementations
- we will only be able to support the minimal common features of the design systems we will support, meaning that a lot of fine tuning proposed by some design systems will not be available (for instance, Boostrap 5 button has a lot of background color choices, but vuetify does not. Consequently, the API will only limit itself to a small set of color variations, and bootstrap subtleties are lost).
Let me know what you think.
Thanks