include
the same token does not do a "deep merge"? #1425
Description
Style Dictionary takes all the files it finds in the include and source arrays and performs a deep merge on them.
I do not know if what I'm seeing is a bug, or a misunderstanding of what "deep merge" means to StyleDictionary...
I assumed "deep merge" meant that metadata fields, like $extensions
or $description
, that were NOT overridden would still be in the output... IOW, "inherited" by the files later in the precedence order.
However, this does not seem to be the case if the same token, stored in two separate files, is listed in the include
config...
/* default.tokens.json */
{
"colors": {
"primary": {
"$value": "#ff0000",
"$type": "color",
"$description: "The primary color."
"$extensions": {
"com.foo": true
}
}
}
}
/* overrides.tokens.json */
{
"colors": {
"primary": {
"$value": "#0000ff",
"$type": "color"
}
}
}
/* config.json */
{
"include": [
"default.tokens.json",
"overrides.tokens.json
],
"platforms": {
"json": {
"files": [
{
"destination": "tokens.json",
"format": "json"
}
]
}
}
}
/* output.tokens.json */
{
"colors": {
"primary": {
"$value": "#0000ff",
"$type": "color",
"filePath": "overrides.tokens.json",
"isSource": true,
"original": {
"$value": "#0000ff",
"$type": "color"
},
"name": "primary",
"attributes": {},
"path": [
"colors",
"primary"
]
}
}
}
/* Expected output.tokens.json */
{
"colors": {
"primary": {
"$value": "#0000ff",
"$type": "color",
"$description": "The primary color.",
"$extensions": {
"com.foo": true
},
"filePath": "overrides.tokens.json",
"isSource": true,
"original": {
"$value": "#0000ff",
"$type": "color",
"$description": "The primary color.",
"$extensions": {
"com.foo": true
}
},
"name": "primary",
"attributes": {},
"path": [
"colors",
"primary"
]
}
}
}
However, if I move the overrides.tokens.json
to source
, instead of include
, the output is what I would expect.
/* config.json */
{
"include": [
"default.tokens.json"
],
"source": [
"overrides.tokens.json"
],
...
}
This seems perhaps to be the intended usage of source
; however, the problem arises when you have multiple overrides for the same token in source
, for example when trying to generate "derivative" themes, or dark modes, because a glut of "red herring" Collision warnings are generated.
/* config.json */
{
"include": [
"default.tokens.json"
],
"source": [
"overrides.tokens.json",
"dark.tokens.json"
],
...
}
/* dark.tokens.json */
{
"colors": {
"primary": {
"$value": "#ffffff",
"$type": "color"
}
}
}
Token collisions detected (4):
Collision detected at: colors.primary! Original value: #0000ff, New value: #ffffff
Collision detected at: colors.primary! Original value: color, New value: color
Collision detected at: colors.primary! Original value: dark.tokens.json, New value: dark.tokens.json
Collision detected at: colors.primary! Original value: true, New value: true
Before I go silencing ALL collision warnings (some of which might actually be wanted source
config?
- Tangentially related logging-level issue: Suppress filtered out reference warnings at the
getReferences()
level? #1287