figma-plugin icon indicating copy to clipboard operation
figma-plugin copied to clipboard

Centralize group description export logic with unified stringification utility

Open Copilot opened this issue 6 months ago โ€ข 14 comments

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 accepts groupMetadata parameter 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 ($description for DTCG, description for 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 $description keys 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.

Copilot avatar Aug 27 '25 19:08 Copilot

๐Ÿฆ‹ 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

changeset-bot[bot] avatar Aug 27 '25 19:08 changeset-bot[bot]

@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

six7 avatar Aug 27 '25 19:08 six7

@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 $description but 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 avatar Aug 27 '25 19:08 Copilot

@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

six7 avatar Aug 27 '25 20:08 six7

โคต๏ธ ๐Ÿ“ฆ โœจ The artifact was successfully created! Want to test it? Download it here ๐Ÿ‘€ ๐ŸŽ

github-actions[bot] avatar Aug 27 '25 20:08 github-actions[bot]

@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 avatar Aug 27 '25 20:08 Copilot

@copilot proceed with next phase

six7 avatar Aug 28 '25 19:08 six7

@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 avatar Aug 28 '25 20:08 Copilot

@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 GroupMetadata interface and type definitions
  • Extended TokenStore to 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 extractTokensOnly utility

All tests pass and build is successful. Ready to continue with Phase 4 (UI Components) next. Commit: fc0c494

Copilot avatar Aug 28 '25 20:08 Copilot

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)

github-actions[bot] avatar Aug 29 '25 05:08 github-actions[bot]

Commit SHA:ce076c43b41c90dee3e5a06e03d1bb047ff6cc65 Current PR reduces the test coverage percentage by 1 for some tests

github-actions[bot] avatar Aug 29 '25 05:08 github-actions[bot]

@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 avatar Aug 29 '25 06:08 Copilot

@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

six7 avatar Aug 29 '25 06:08 six7

@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

Copilot avatar Aug 29 '25 07:08 Copilot