Skip to content

Gradient token support for studio users#3918

Open
akshay-gupta7 wants to merge 13 commits into
mainfrom
akshay/gradient-export
Open

Gradient token support for studio users#3918
akshay-gupta7 wants to merge 13 commits into
mainfrom
akshay/gradient-export

Conversation

@akshay-gupta7

@akshay-gupta7 akshay-gupta7 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Why does this PR exist?

Closes #0000

Adds display and export support for gradient tokens synced from Tokens Studio via Studio OAuth (REST API). Gradient tokens were already a known type in the plugin but had no mapping or rendering for the OAuth sync path — they showed blank pills, [object Object] in tooltips, broke the edit form, and could not be exported as Figma paint styles.

What does this pull request do?

Type system & ingestion

  • Adds TokenTypes.GRADIENT to the TokenTypes enum and maps the incoming 'gradient' type string from the Studio REST API via normalizeTokenType
  • Adds TokenGradientValue type and SingleGradientToken to the token type system
  • Handles gradient stop colors that arrive from the Studio API as color objects { colorSpace, components, hex?, alpha? } rather than plain hex strings — resolveStopColor extracts a usable CSS color from them (prefers hex, otherwise computes rgb()/rgba() from components)

Rendering

  • Adds gradientTokenToCss and gradientTokenSummary utilities for converting gradient objects to CSS strings and human-readable summaries
  • Renders gradient token pills using var(--backgroundColor) on the ::before swatch, matching the color token pill pattern, with StyledTokenButton GRADIENT variant styles
  • Simplifies the token tooltip to show a summary line only (radial, 180°, 3 stops) instead of per-stop color rows

Edit form

  • Adds a full GradientTokenForm (kind selector, stop list, draggable GradientStopBar, geometry inputs) with alias-mode toggle
  • Adds a tokenTypesWithFigmaSection constant so gradient tokens show the Figma scopes section without being included in tokenTypesToCreateVariable (gradient tokens cannot be Figma Variables)
  • Adds gradient scopes (ALL_FILLS, FRAME_FILL, SHAPE_FILL, TEXT_FILL, STROKE_COLOR, EFFECT_COLOR) to TOKEN_TYPE_TO_SCOPES_MAP
  • Fixes the Figma section auto-expanding on open by ignoring empty [] scope arrays when deciding whether to show the expanded state
  • Validates gradient values on save (structured value requires ≥ 2 stops with non-empty colors)
  • Draft-string local state on numeric inputs so clearing / typing -/. doesn't snap to 0; positions are clamped to [0, 1]
  • Stop list keyed by stop identity so per-item state (e.g. color picker) follows the stop when the list reorders
  • handleRemoveStop decrements the selection index when removing a stop above it
  • GradientStopBar drag uses setPointerCapture + pointercancel so releasing outside the plugin iframe cleans up correctly

Export as paint styles

  • Extends updateStyles/updateColorStyles filter to include TokenTypes.GRADIENT when stylesGradient is enabled
  • setColorValuesOnTarget routes gradient-type tokens (including alias-of-gradient) through the gradient paint builder rather than the solid path
  • paintStyleMatchesColorToken accepts string | TokenGradientValue, collapses linear/radial branches, and handles GRADIENT_ANGULAR / GRADIENT_DIAMOND
  • convertConicGradient regex widened to accept negative and leading-decimal angles
  • getReferenceTokensFromGradient split is paren-aware so rgb()/rgba() stop colors no longer misalign variable references with gradientStops
  • Rename/delete token dialogs offer the connected style option for gradient tokens (added TokenTypes.GRADIENT to the choice arrays)

Robustness

  • isSingleGradientToken null-checks before the in operator so a malformed token with value: null doesn't crash the tooltip
  • updateAliasesInState gets a gradient-aware branch that only updates stop.color reference strings, so renaming an unrelated token no longer stringifies stops/center/start/end via toString()

Testing this change

  1. Connect the plugin to a Tokens Studio project via Studio OAuth
  2. Create a gradient token in Studio (linear, radial, or conic) with multiple stops
  3. Pull tokens into the plugin — the token should appear under the Gradient group
  4. Verify the pill shows the gradient preview (not a blank/white circle)
  5. Hover the token — tooltip should show e.g. radial, 180°, 3 stops with no color swatches
  6. Open the edit form — the Figma section should be collapsed (+ icon), not auto-expanded
  7. Expand the Figma section — fill-related scopes should be available
  8. Enable Styles → Gradient in export settings and run Create Styles — a paint style should be created for each gradient token
  9. Rename a gradient token that has a connected style — the "Rename style" option should be offered
  10. Delete a gradient token with a connected style — the "Delete associated style" option should be offered

Additional Notes (if any)

Gradient tokens have variableType: null in the Studio schema — they are intentionally excluded from Figma Variable creation. The Figma scopes section is shown for metadata purposes only (e.g. for style application), not for variable creation.

Stop color objects are a DTCG-compatible format ({ colorSpace, components, alpha? }). The resolveStopColor helper prefers the hex shortcut if present, otherwise computes rgb()/rgba() from the components array (0–1 floats).

Known limitation — follow-up ticket: the form exposes editable geometry fields (per-stop midpoint, center, radius, size, linear start/end) that the CSS-string export path currently ignores; kind: 'diamond' also falls back to linear-gradient(45deg, ...) because CSS has no diamond equivalent. Fixing these properly means routing export through a direct TokenGradientValue → GradientPaint builder rather than the CSS round-trip.

Screenshot 2026-07-11 at 1 46 10 AM Screenshot 2026-07-11 at 1 46 28 AM

@changeset-bot

changeset-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b2b9846

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@akshay-gupta7
akshay-gupta7 marked this pull request as draft July 9, 2026 10:47
@anathaniel-TS

Copy link
Copy Markdown

🛡️ Hyma Compliance Check

No compliance-relevant changes detected

25 file(s) scanned · 0 findings

This PR adds a new "gradient" token type (UI form, tooltip rendering, Figma paint-style matching, type definitions). All changes are local data-model/UI logic for the plugin — no new external API calls, no sync-provider or OAuth changes, no new personal-data storage, and no secrets/credentials introduced.

ℹ️ This check is informational.
🛡️ Hyma Compliance Check · automated

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Commit SHA:2c5181c92205449dab51bc2b3e866e49c33755e3

Test coverage results 🧪

Code coverage diff between base branch:main and head branch: akshay/gradient-export 
Status File % Stmts % Branch % Funcs % Lines
🔴 total 59.09 (-0.74) 50.93 (-0.83) 56.95 (-0.89) 59.71 (-0.62)
🔴 packages/tokens-studio-for-figma/src/app/components/EditTokenForm.tsx 45.27 (-2.81) 31 (-2.9) 40 (-1.5) 47.32 (-2.24)
✨ 🆕 packages/tokens-studio-for-figma/src/app/components/GradientStopBar.tsx 8.19 0 0 9.25
✨ 🆕 packages/tokens-studio-for-figma/src/app/components/GradientTokenForm.tsx 5.12 0 0 6.15
🔴 packages/tokens-studio-for-figma/src/app/components/TokenListing.tsx 90.32 (-5.68) 73.68 (-2.79) 100 (0) 100 (0)
🟢 packages/tokens-studio-for-figma/src/app/components/Tokens.tsx 74.32 (0.71) 32.5 (5.48) 61.9 (1.9) 73.23 (1.18)
🔴 packages/tokens-studio-for-figma/src/app/components/TokenButton/TokenButtonContent.tsx 55.55 (-24.45) 38.46 (-7.69) 100 (0) 55.55 (-24.45)
✨ 🆕 packages/tokens-studio-for-figma/src/app/components/TokenTooltip/SingleGradientValueDisplay.tsx 12.5 0 0 16.66
🔴 packages/tokens-studio-for-figma/src/app/components/TokenTooltip/TokenTooltipContentValue.tsx 96.29 (-3.71) 97.36 (-2.64) 100 (0) 96.15 (-3.85)
🔴 packages/tokens-studio-for-figma/src/app/hooks/usePropertiesForType.ts 90 (-4.73) 92.3 (-3.7) 100 (0) 90 (-4.73)
🟢 packages/tokens-studio-for-figma/src/app/store/useTokens.tsx 56.25 (0) 37.5 (0.16) 60.29 (0) 56.96 (0)
🔴 packages/tokens-studio-for-figma/src/app/store/utils/updateAliasesInState.ts 68.18 (-14.67) 50 (-20) 85.71 (-14.29) 75.67 (-14.33)
🔴 packages/tokens-studio-for-figma/src/plugin/node.ts 85.45 (-0.66) 71.73 (-1.2) 82.35 (0) 85.98 (-0.68)
🔴 packages/tokens-studio-for-figma/src/plugin/setColorValuesOnTarget.ts 90.27 (-2.37) 86.31 (-1.04) 100 (0) 90.9 (-2.64)
🔴 packages/tokens-studio-for-figma/src/plugin/updateStyles.ts 86 (-1.5) 77.58 (-3.9) 90.9 (0) 88.09 (0.29)
🔴 packages/tokens-studio-for-figma/src/plugin/figmaUtils/styleMatchers/paintStyleMatchesColorToken.ts 88.23 (-11.77) 85 (-8.33) 100 (0) 100 (0)
✨ 🆕 packages/tokens-studio-for-figma/src/types/tokens/SingleGradientToken.ts 100 100 100 100
✨ 🆕 packages/tokens-studio-for-figma/src/types/values/TokenGradientValue.ts 100 100 100 100
🔴 packages/tokens-studio-for-figma/src/utils/color/getReferenceTokensFromGradient.ts 89.28 (-2.38) 85 (-5) 100 (0) 96 (4.34)
✨ 🆕 packages/tokens-studio-for-figma/src/utils/color/gradientTokenToCss.ts 97.05 82.22 100 96.42
✨ 🆕 packages/tokens-studio-for-figma/src/utils/is/isSingleGradientToken.ts 50 13.33 50 62.5

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

⤵️ 📦 ✨ The artifact was successfully created! Want to test it? Download it here 👀 🎁

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds end-to-end support for gradient tokens coming from the Tokens Studio OAuth (REST) sync path, so they can be displayed, previewed, edited, and applied similarly to existing color tokens (while remaining excluded from Figma Variable creation).

Changes:

  • Introduces TokenTypes.GRADIENT across the token type system (types, guards, schema defs) and enables rendering/preview via gradientTokenToCss + a simplified tooltip summary.
  • Extends style application and value mapping to handle gradient token values (including structured gradient objects) when creating/applying paint styles and node fills/strokes.
  • Adds a dedicated gradient token edit form UI (stop editor + draggable stop bar) and shows gradient-related Figma scope metadata.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/tokens-studio-for-figma/src/utils/trimValue.ts Preserves structured gradient values while still trimming alias strings.
packages/tokens-studio-for-figma/src/utils/trimValue.test.ts Adds tests for gradient trim/pass-through behavior.
packages/tokens-studio-for-figma/src/utils/is/isSingleGradientToken.ts Adds type guard for gradient tokens (object or alias string).
packages/tokens-studio-for-figma/src/utils/is/index.ts Re-exports the new gradient type guard.
packages/tokens-studio-for-figma/src/utils/color/index.ts Exposes gradient-to-CSS utilities from the color utils barrel.
packages/tokens-studio-for-figma/src/utils/color/gradientTokenToCss.ts Converts structured gradient objects (incl. REST color objects) into CSS gradients and summaries.
packages/tokens-studio-for-figma/src/utils/color/gradientTokenToCss.test.ts Adds unit tests for gradient CSS/summary helpers.
packages/tokens-studio-for-figma/src/types/values/TokenGradientValue.ts Introduces the gradient value/stops type.
packages/tokens-studio-for-figma/src/types/values/index.ts Re-exports TokenGradientValue.
packages/tokens-studio-for-figma/src/types/tokens/SingleToken.ts Extends SingleToken union to include gradient tokens.
packages/tokens-studio-for-figma/src/types/tokens/SingleGradientToken.ts Adds the SingleGradientToken type.
packages/tokens-studio-for-figma/src/types/tokens/index.ts Re-exports SingleGradientToken.
packages/tokens-studio-for-figma/src/types/tokens/EditTokenObject.ts Allows gradient tokens in the edit-token object union.
packages/tokens-studio-for-figma/src/plugin/updateStyles.ts Includes gradient tokens in the style creation/update pipeline (gated by settings).
packages/tokens-studio-for-figma/src/plugin/setColorValuesOnTarget.ts Allows applying structured gradient values by converting them to CSS strings before gradient parsing.
packages/tokens-studio-for-figma/src/plugin/node.ts Flattens resolved gradient token values to CSS strings when mapping values for plugin operations.
packages/tokens-studio-for-figma/src/plugin/figmaUtils/styleMatchers/paintStyleMatchesColorToken.ts Normalizes gradient values when comparing tokens to paint styles.
packages/tokens-studio-for-figma/src/constants/VariableTypes.ts Adds tokenTypesWithFigmaSection so gradients show metadata without enabling variables.
packages/tokens-studio-for-figma/src/constants/TokenTypes.ts Adds GRADIENT to the TokenTypes enum.
packages/tokens-studio-for-figma/src/constants/FigmaVariableMetaData.ts Adds gradient-related scopes to TOKEN_TYPE_TO_SCOPES_MAP.
packages/tokens-studio-for-figma/src/config/tokenType.defs.json Adds a “gradient” token type definition for UI/schema metadata.
packages/tokens-studio-for-figma/src/app/store/useTokens.tsx Treats GRADIENT similarly to gradient-valued COLOR when deciding style creation.
packages/tokens-studio-for-figma/src/app/hooks/usePropertiesForType.ts Adds fill/border properties for gradient tokens.
packages/tokens-studio-for-figma/src/app/components/TokenTooltip/TokenTooltipContentValue.tsx Routes gradient tokens to a new tooltip value display.
packages/tokens-studio-for-figma/src/app/components/TokenTooltip/SingleGradientValueDisplay.tsx Renders a summary tooltip line for gradients.
packages/tokens-studio-for-figma/src/app/components/Tokens.tsx Hides “create gradient token” UI unless the storage provider supports it (still displays existing ones).
packages/tokens-studio-for-figma/src/app/components/TokenListing.tsx Initializes default values for new gradient tokens.
packages/tokens-studio-for-figma/src/app/components/TokenButton/TokenButtonContent.tsx Adds gradient swatch rendering in token pills (CSS var background).
packages/tokens-studio-for-figma/src/app/components/TokenButton/StyledTokenButton.tsx Adds GRADIENT styling variants for pill rendering in LIST/GRID modes.
packages/tokens-studio-for-figma/src/app/components/GradientTokenForm.tsx Adds a full gradient editor form (kind/geometry/stops/alias mode).
packages/tokens-studio-for-figma/src/app/components/GradientStopBar.tsx Adds interactive stop bar UI (drag-to-reposition + click-to-add).
packages/tokens-studio-for-figma/src/app/components/FigmaVariableForm.tsx Shows the Figma metadata section for gradient tokens via tokenTypesWithFigmaSection.
packages/tokens-studio-for-figma/src/app/components/EditTokenForm.tsx Integrates GradientTokenForm into the edit form switch.

Comment thread packages/tokens-studio-for-figma/src/plugin/updateStyles.ts
@akshay-gupta7

akshay-gupta7 commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

claude review :

Local max-effort review — 15 findings

Ran a multi-agent review (10 finder angles → 13 verifiers → gap sweep) over the branch. All 15 findings below survived verification. Ranked most-severe first; CONFIRMED = trigger and wrong output identified, PLAUSIBLE = mechanism real, trigger uncertain.


🔴 Critical — data corruption / broken exports

1. Rename any token → every gradient token is corruptedCONFIRMED
src/app/store/utils/updateAliasesInState.ts:37

The composite-object branch flattens each top-level value property via v.toString(). For a gradient value, stops.toString() yields "[object Object],[object Object]" and start/end/center become "[object Object]". Written back unconditionally.

Trigger: rename color.primary → color.brand while any gradient token exists → every gradient token in state is permanently destroyed.


2. Gradient-of-alias exports as a black solid paintCONFIRMED
src/plugin/setColorValuesOnTarget.ts:130

resolvedValue is the raw alias string, so both branches at line 103 fail. In the else branch, valueToApply is the resolved gradient object, but line 130 only checks isGradient(valueToApply) (string startsWith, false for objects), so convertToFigmaColor('') runs.

Trigger: gradient token B = {gradient.A}, export styles → B is a black SolidPaint.
Fix: if (isGradient(valueToApply) || isGradientTokenValue(valueToApply)).


3. rgba() stops misalign variable referencesCONFIRMED
src/plugin/setColorValuesOnTarget.ts:49 (via getReferenceTokensFromGradient)

resolveStopColor emits rgb()/rgba() for object stops; getReferenceTokensFromGradient splits on , and only pushes entries containing #/{, so an rgb(255, 0, 0) stop contributes zero entries — indices no longer align with gradientStops.

Trigger: createStylesWithVariableReferences on + a gradient with [rgba stop, {color.blue} stop] → the brand variable binds to stop 0 (the rgba one).


4. Conic gradients never match their own styleCONFIRMED
src/plugin/figmaUtils/styleMatchers/paintStyleMatchesColorToken.ts:29

Matcher only handles SOLID, GRADIENT_LINEAR, GRADIENT_RADIAL. Conic tokens flatten to conic-gradient(...) which convertStringToFigmaGradient produces as GRADIENT_ANGULAR. GRADIENT_DIAMOND also unhandled. Secondary: the SOLID branch feeds a linear-gradient(...) string into convertToFigmaColor.

Trigger: conic gradient exported once, then re-checked → never matches; raw paints re-applied every time.


🟠 High — silent behavioural drift

5. Form geometry fields are inert; diamond exports as linearCONFIRMED
src/utils/color/gradientTokenToCss.ts:35

gradientTokenToCss consumes only angle/shape/startAngle + stops. Editable midpoint, center, radius, size, start/end are stored but ignored by preview, export, and style matching. Diamond falls to the default → linear-gradient(45deg, ...).

Trigger: edit Center X/Y or create a diamond gradient → exported paint ignores the geometry / is a 45° linear, no warning.


6. Null-valued gradient crashes the tooltipCONFIRMED
src/utils/is/isSingleGradientToken.ts:17

typeof null === 'object' passes; tokenValueKey in token[tokenValueKey] then throws TypeError. Same in isSingleGradientTokenInJSON.

Trigger: malformed remote JSON with { type: 'gradient', value: null } is hovered → TokenTooltipContentValue crashes the React tree.


7. Renamed/deleted gradient tokens leak paint stylesCONFIRMED (both)
src/app/components/EditTokenForm.tsx:514 + src/app/store/useManageTokens.tsx:138

Rename dialog offers Rename style only for [COLOR, TYPOGRAPHY, BOX_SHADOW]; delete dialog offers Delete associated style to the same list. Gradient tokens now create paint styles, so:

  • rename → old-name style orphans, $figmaStyleReferences desyncs, next export creates a duplicate
  • delete → connected paint style remains in the file

Fix: add TokenTypes.GRADIENT to both arrays.


8. Negative conic startAngle silently becomes 0CONFIRMED
src/utils/color/gradientTokenToCss.ts:44

Emits from -45deg; convertConicGradient's regex /from\s+(\d+(?:\.\d+)?)deg/ doesn't match negatives, so startAngle stays 0.

Trigger: type -45 into Start Angle → preview shows -45°, exported paint is 0°.


9. Chained-alias mode toggle overwrites token with defaultPLAUSIBLE
src/app/components/GradientTokenForm.tsx:273

handleMode restores from selectedToken?.rawValue. When A → gradient.b where gradient.b is itself an alias, rawValue isn't a gradient object → form silently swaps in DEFAULT_GRADIENT_VALUE; saving overwrites.

Fix: use selectedToken.value (resolved) instead.


🟡 Medium — UX / robustness

10. No validation on gradient savePLAUSIBLE
src/app/components/EditTokenForm.tsx:105

isValid falls to internalEditToken?.value && …; a gradient object is always truthy, so cleared stop colors, garbage strings, or out-of-range numbers save silently.

Trigger: clear a stop's color to '' and Save → later flattens to linear-gradient(180deg, 0%, …) which the export parser can't handle.


11. GradientNumberInput snaps to 0 and doesn't clampCONFIRMED (coercion) / PLAUSIBLE (API throw)
src/app/components/GradientTokenForm.tsx:117

Number(v) || 0 on every change: clearing the field or typing -/. collapses to 0. No clamping: position 50 reaches Figma's ColorStop (valid range 0–1).


12. Stop list keyed by index — picker sticks; selection shiftsCONFIRMED (both)
src/app/components/GradientTokenForm.tsx:504

key={seed(index)} is position-derived; GradientStopItem's colorPickerOpen sticks to the position. Separately, handleRemoveStop only clamps selectedStopIndex — removing a stop below the selection silently moves the selection to a different stop.

Trigger: open picker on stop 2, remove stop 1 → picker on wrong stop; select stop 3, remove stop 1 → selection is now on the old stop 4.


13. Drag doesn't recover if pointer leaves the iframePLAUSIBLE
src/app/components/GradientStopBar.tsx:137

Document pointermove/pointerup with no setPointerCapture or pointercancel. Release outside the (narrow) plugin window → no pointerup fires inside the iframe.

Trigger: re-entering the iframe makes the stop follow the cursor with no button pressed; the ending click lands on the track and adds a spurious stop.


14. Aliases resolving to objects render [object Object]CONFIRMED
src/app/components/GradientTokenForm.tsx:286

String(aliasValue) after getAliasValue; aliases resolving to Studio color objects or other gradients yield '[object Object]' — invalid CSS — and the '#888888' fallback never fires.

Trigger: stop color '{gradient.primary}' → swatch, stop bar, and preview render transparent.

@akshay-gupta7 akshay-gupta7 self-assigned this Jul 10, 2026
@akshay-gupta7

Copy link
Copy Markdown
Contributor Author

Gradient token review — fix status

Commit: fix: address code review findings for gradient token support

✅ Fixed in this commit (12 of 15 findings)

Critical

  • 1 Rename any token → every gradient token corruptedsrc/app/store/utils/updateAliasesInState.ts
    Added a gradient-aware branch before the generic composite path. Only stop.color strings are updated for references; nested stops/start/end/center are no longer flattened via toString().

  • 2 Gradient-of-alias exports as black solid paintsrc/plugin/setColorValuesOnTarget.ts:130
    Solid fallback now also checks isGradientTokenValue(valueToApply), so alias-of-gradient resolves to a gradient paint instead of convertToFigmaColor('').

  • 3 rgba() stops misalign variable referencessrc/utils/color/getReferenceTokensFromGradient.ts
    Rewrote splitter to be paren-aware and to push one entry per stop-like fragment (empty when no reference). rgb/rgba stop colors no longer shatter the index alignment.

  • 4 Conic gradients never match their own stylesrc/plugin/figmaUtils/styleMatchers/paintStyleMatchesColorToken.ts
    Collapsed the LINEAR/RADIAL branches and added GRADIENT_ANGULAR and GRADIENT_DIAMOND; SOLID branch short-circuits when the token value is a gradient string.

High

  • 6 Null-valued gradient crashes tooltipsrc/utils/is/isSingleGradientToken.ts
    Added value !== null check before the in operator; same fix in isSingleGradientTokenInJSON.

  • 7 Renamed/deleted gradients leak paint stylessrc/app/components/EditTokenForm.tsx:514 + src/app/store/useManageTokens.tsx:138
    Added TokenTypes.GRADIENT to both style-choice arrays.

  • 8 Negative conic startAngle silently becomes 0src/plugin/figmaTransforms/gradients.ts:336
    Widened convertConicGradient's regex to accept negative and leading-decimal angles.

  • 9 Chained-alias mode toggle overwrites token with defaultsrc/app/components/GradientTokenForm.tsx
    handleMode now prefers selectedToken.value (resolved) over rawValue.

Medium

  • 10 No validation on gradient savesrc/app/components/EditTokenForm.tsx:105
    Gradient tokens now validate: alias strings pass, structured values require ≥ 2 stops with non-empty colors.

  • 11 GradientNumberInput snaps to 0 and doesn't clampsrc/app/components/GradientTokenForm.tsx
    Local draft string preserves empty / - / . mid-edit; only parseable values commit. Optional min/max props; handleStopNumberChange / handleStopPositionDrag clamp position to [0, 1].

  • 12 Stop list keyed by index; selection shifts on removalsrc/app/components/GradientTokenForm.tsx
    Stop list now keyed by the stop object identity (seed(stop)), so per-item state follows the stop. handleRemoveStop decrements selectedStopIndex when the removed stop is below it.

  • 13 Drag doesn't recover if pointer leaves the iframesrc/app/components/GradientStopBar.tsx
    Added setPointerCapture on drag start and a pointercancel listener; cleanup releases the capture.

  • 14 Aliases resolving to objects render [object Object]src/app/components/GradientTokenForm.tsx
    stopCssColors accepts the alias only when getAliasValue returns a non-empty string; otherwise falls back to '#888888'.

🟡 Remaining — needs deeper refactor (follow-up ticket)

5 Form geometry fields are inert; diamond exports as linear

src/utils/color/gradientTokenToCss.ts — the following editable form fields are stored but ignored by preview, export, and style matching:

  • midpoint (per stop)
  • center (radial, conic, diamond)
  • radius (radial)
  • size (diamond)
  • start / end (linear)

Additionally, kind: 'diamond' falls through to linear-gradient(45deg, ...), so the exported Figma paint is GRADIENT_LINEAR even though Figma natively supports GRADIENT_DIAMOND.

Why deferred: the current export path is TokenGradientValue → CSS string → convertStringToFigmaGradient → GradientPaint. Full geometry support needs a direct TokenGradientValue → GradientPaint builder (no CSS round-trip), plus a matching path in paintStyleMatchesColorToken. That's a self-contained refactor worth its own PR.

Impact until fixed: users editing geometry fields see no effect in exports; diamond tokens export as 45° linear gradients without warning; two tokens differing only in these fields collide against the same paint style.

Test status

  • 45 unit tests across the 5 touched modules pass
  • ESLint clean on all changed source files
  • TypeScript source has no new errors (only pre-existing test-file assertion typing noise)

@akshay-gupta7 akshay-gupta7 changed the title Gradient token Gradient token support for studio users Jul 10, 2026
@akshay-gupta7
akshay-gupta7 marked this pull request as ready for review July 10, 2026 21:39
@akshay-gupta7
akshay-gupta7 requested a review from six7 July 10, 2026 21:41
@anathaniel-TS

Copy link
Copy Markdown

🛡️ Hyma Compliance Check

No compliance-relevant changes detected

30 file(s) scanned · 0 findings

ℹ️ This check is informational.
🛡️ Hyma Compliance Check · automated

1 similar comment
@anathaniel-TS

Copy link
Copy Markdown

🛡️ Hyma Compliance Check

No compliance-relevant changes detected

30 file(s) scanned · 0 findings

ℹ️ This check is informational.
🛡️ Hyma Compliance Check · automated

@anathaniel-TS

Copy link
Copy Markdown

🛡️ Hyma Compliance Check

No compliance-relevant changes detected

30 file(s) scanned · 0 findings

ℹ️ This check is informational.
🛡️ Hyma Compliance Check · automated

2 similar comments
@anathaniel-TS

Copy link
Copy Markdown

🛡️ Hyma Compliance Check

No compliance-relevant changes detected

30 file(s) scanned · 0 findings

ℹ️ This check is informational.
🛡️ Hyma Compliance Check · automated

@anathaniel-TS

Copy link
Copy Markdown

🛡️ Hyma Compliance Check

No compliance-relevant changes detected

30 file(s) scanned · 0 findings

ℹ️ This check is informational.
🛡️ Hyma Compliance Check · automated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants