mirror of
https://github.com/penpot/penpot.git
synced 2026-05-30 20:28:07 +00:00
* 🐛 Fix DTCG token import discriminator and group-level $type inheritance Closes #8342. The DTCG Community Group Final Report (W3C, 2025-10-28) specifies: "The presence of a $value property definitively identifies an object as a token." "A token's type can be specified by the optional $type property [...] Furthermore, the $type property on a group applies to all tokens nested within that group." Two bugs in `common/src/app/common/types/tokens_lib.cljc` violate the spec and silently break import of any third-party DTCG file that uses group-level type inheritance: 1. `flatten-nested-tokens-json` used `(not (contains? v "$type"))` as the group-vs-token discriminator. A group node carrying only a `$type` (to set a default for child tokens) was misidentified as a token, then immediately discarded because it had no `$value`. 2. `schema:dtcg-node` declared both `$type` and `$value` as required, so even after the discriminator was fixed any leaf token that relied on group-level type inheritance failed `dtcg-node?` validation and never reached the parser. The combined effect: importing a spec-compliant DTCG file that expressed types at the group level produced a TokensLib with no tokens at all, because every leaf was discarded as "unknown type". Penpot-exported files were unaffected because Penpot always emits both `$type` and `$value` on every token and never attaches `$type` to a group, so the existing tests covered only the inline-type shape. - `schema:dtcg-node`: mark `$type` optional. - `flatten-nested-tokens-json`: use `$value` as the discriminator (anything without `$value` is a group), accept an optional `inherited-type` accumulator that carries the nearest enclosing group `$type` down through recursion, and resolve a token's type from its own `$type` first, falling back to the inherited type. A token's own `$type` always wins over the inherited one (per spec). Added `parse-dtcg-group-type-inheritance` covering both cases: - group `$type` is inherited by tokens that don't declare their own (`colors.red`, `colors.blue`, `space.small`) - token `$type` overrides the inherited group `$type` (`colors.danger`, `space.large`) Existing DTCG round-trip tests continue to pass because they all declare `$type` at the token level, which the new code still honours. CHANGES.md entry added under the 2.17.0 Bugs-fixed section. * 📚 Do not update CHANGES.md We are changing the procedures to not update the changelog on each PR. Instead, we use github tracking to check what issues come in a release, and update the changelog automatically in a batch. Signed-off-by: Andrés Moya <hirunatan@hammo.org> --------- Signed-off-by: Andrés Moya <hirunatan@hammo.org> Co-authored-by: MilosM348 <milos.milic001@outlook.com>