Centralize group description export logic with unified stringification utility
This PR addresses a critical architectural issue where group description logic was scattered across multiple export functions, leading to inconsistent behavior between JSON editor view, style dictionary export, multi-file export, and sync providers.
Problem
The original implementation had group description logic only in convertTokensToObject, while stringifyTokens (JSON editor) and formatTokens (style dictionary) lacked group metadata support, causing inconsistent export behavior.
Solution
Centralized Export Architecture: Created a single injectGroupDescriptions utility function that handles all group description injection consistently across the codebase:
-
stringifyTokens: Now acceptsgroupMetadataparameter and uses central utility -
formatTokens: Updated to support group metadata with central utility -
convertTokensToObject: Refactored to use central utility instead of custom logic -
Format-aware: Automatically uses correct keys (
$descriptionfor DTCG,descriptionfor legacy)
Key Features
Enhanced Data Architecture
-
Optimized storage structure: Group metadata uses nested maps
{ [tokenSet]: { [path]: GroupMetadata } }enabling efficient bulk operations - Automatic cleanup: Built-in cleanup logic for group metadata when token sets are deleted or renamed
- Seamless integration: Group metadata processed alongside tokens during parsing
Unified User Interface
-
Consolidated editing: Merged rename and edit description modals into single
EditTokenGroupModal - Streamlined context menu: Single "Edit" option replaces separate "Rename" and "Edit Description" actions
- Enhanced validation: Comprehensive validation for both name conflicts and description formatting
DTCG Compliance & Consistent Export
- Universal group description support: Works identically across JSON editor, exports, and sync providers
-
Specification adherence: Full DTCG support with
$descriptionkeys at correct hierarchical levels - Backward compatibility: Existing token workflows remain unchanged
This implementation ensures group descriptions work consistently everywhere tokens are stringified, eliminating the architectural fragmentation that caused export inconsistencies.
๐ฌ Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.
๐ฆ Changeset detected
Latest commit: 71626f4dc6636cbb92a63468d870bf86f62b9884
The changes in this PR will be included in the next version bump.
This PR includes changesets to release 1 package
| Name | Type |
|---|---|
| @tokens-studio/figma-plugin | Patch |
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR
@copilot adjust the plan - lets start instead with creating a test for the parsing logic that verifies the behavior - can start as a failing test that we then fix
@copilot adjust the plan - lets start instead with creating a test for the parsing logic that verifies the behavior - can start as a failing test that we then fix
Created comprehensive failing test suite for group description parsing logic in parseGroupDescriptions.test.ts. The test demonstrates expected behavior for DTCG format group descriptions and currently fails as expected, establishing a baseline for implementation.
The test covers:
- Detecting group descriptions (objects with
$descriptionbut no$value) - Distinguishing between token descriptions vs group descriptions
- Nested group description handling
- Backward compatibility with existing parsing
Ready to implement the parsing logic to make the tests pass. Commit: 84d0e3c
@copilot can you adjust the tests and add tests to verify we have groups returned from the parse functions instead? They can fail for now, but i want the tests to match already
โคต๏ธ ๐ฆ โจ The artifact was successfully created! Want to test it? Download it here ๐ ๐
@copilot can you adjust the tests and add tests to verify we have groups returned from the parse functions instead? They can fail for now, but i want the tests to match already
Updated the tests to expect groups returned from parse functions instead of just tokens. All tests now fail as expected, establishing the target API structure where parsing functions return { tokens: Token[], groups: Group[] } instead of just token arrays. Commit: 403fb1f
@copilot proceed with next phase
@copilot proceed with next phase
Implemented the group description parsing logic for DTCG format tokens. The parsing functions now return both tokens and groups separately while maintaining backward compatibility. All tests are passing and the implementation is ready for review. Commit: 022fdd0
@copilot implement the phases of GROUP_DESCRIPTION_IMPLEMENTATION_PLAN.md
I've completed the implementation of Phases 1 and 3 from the GROUP_DESCRIPTION_IMPLEMENTATION_PLAN.md:
Phase 1 โ - Core Data Structure and Types:
- Created
GroupMetadatainterface and type definitions - Extended
TokenStoreto include group metadata - Added proper type exports
Phase 3 โ - State Management:
- Extended Redux state with group metadata support
- Added reducer actions (
setGroupMetadata,updateGroupDescription,deleteGroupMetadata) - Created selectors for accessing group metadata
- Maintained backward compatibility with
extractTokensOnlyutility
All tests pass and build is successful. Ready to continue with Phase 4 (UI Components) next. Commit: fc0c494
Commit SHA:ce076c43b41c90dee3e5a06e03d1bb047ff6cc65
Test coverage results :test_tube:
Code coverage diff between base branch:main and head branch: copilot/fix-c59c4174-6d80-44bb-91fc-d2633c155008
| Status | File | % Stmts | % Branch | % Funcs | % Lines |
|---|---|---|---|---|---|
| :red_circle: | total | 65.37 (0) | 57.34 (0.01) | 62.48 (-0.11) | 65.69 (-0.03) |
| :green_circle: | packages/tokens-studio-for-figma/src/app/components/ExportProvider/MultiFilesExport.tsx | 69.56 (1.38) | 100 (0) | 57.14 (0) | 69.56 (1.38) |
| :red_circle: | packages/tokens-studio-for-figma/src/app/components/TokenGroup/TokenGroupHeading.tsx | 78.26 (-1.74) | 88.88 (-11.12) | 46.15 (-8.39) | 77.77 (-1.71) |
| :sparkles: :new: | packages/tokens-studio-for-figma/src/app/components/modals/EditGroupDescriptionModal.tsx | 50 | 40 | 40 | 50 |
| :red_circle: | packages/tokens-studio-for-figma/src/app/store/models/tokenState.tsx | 62.07 (-1.43) | 50.76 (-0.53) | 74.57 (-1.95) | 62.64 (-1.51) |
| :sparkles: :new: | packages/tokens-studio-for-figma/src/app/store/selectors/groupMetadataSelector.ts | 61.53 | 50 | 50 | 58.33 |
| :sparkles: :new: | packages/tokens-studio-for-figma/src/types/GroupMetadata.ts | 100 | 100 | 100 | 100 |
| :green_circle: | packages/tokens-studio-for-figma/src/utils/convertTokens.tsx | 83.87 (3.48) | 77.02 (1.64) | 87.5 (4.17) | 82.75 (3.59) |
| :red_circle: | packages/tokens-studio-for-figma/src/utils/convertTokensToObject.ts | 85.18 (-14.82) | 80 (-20) | 75 (-25) | 85.18 (-14.82) |
| :green_circle: | packages/tokens-studio-for-figma/src/utils/detectFormat.tsx | 100 (37.5) | 66.66 (33.33) | 100 (0) | 100 (33.34) |
| :red_circle: | packages/tokens-studio-for-figma/src/utils/parseTokenValues.ts | 89.28 (-3.57) | 58.82 (-24.51) | 100 (0) | 88.46 (-4.39) |
Commit SHA:ce076c43b41c90dee3e5a06e03d1bb047ff6cc65 Current PR reduces the test coverage percentage by 1 for some tests
@copilot in addition, lets merge the Rename and Edit description dialog into a Edit dialog that lets us edit both at the same time.
Merged the rename and edit description modals into a unified EditTokenGroupModal that allows editing both the group name and description simultaneously. The new modal provides a streamlined user experience with validation for both fields. Updated the context menu to show a single "Edit" option instead of separate "Rename" and "Edit Description" options. Commit: f8c4b2e
@copilot the export logic right now that you added is a bit flawed. Instead, we need a central utility that comes into play when we stringify the tokens - as in we do that for the json view, the export, but also for the various sync providers. I wouldnt want logic to be all over the place but central to how they're using it, so maybe we can do that in one place, OR just update the tokens object in state to always have groupMetadata so its part of that, and then on stringifying to a json we just set the $description at the right place for a token group of a specific set
@copilot the export logic right now that you added is a bit flawed. Instead, we need a central utility that comes into play when we stringify the tokens - as in we do that for the json view, the expor...
Centralized the group description logic as requested. Created a single injectGroupDescriptions utility function that handles all group description injection consistently across stringifyTokens, formatTokens, convertTokensToObject, and sync providers. The logic is now format-aware and works consistently everywhere tokens are stringified. Commit: 71626f4