Skip to content

feat: format action for JSON feature values - #8389

Draft
talissoncosta wants to merge 5 commits into
mainfrom
feat/json-value-editor-format
Draft

feat: format action for JSON feature values#8389
talissoncosta wants to merge 5 commits into
mainfrom
feat/json-value-editor-format

Conversation

@talissoncosta

@talissoncosta talissoncosta commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Thanks for submitting a PR! Please check the boxes below:

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

The .json toggle on the value editor only validates and syntax-highlights; the stored value is rendered verbatim. So a pasted, minified JSON blob stays on one unreadable line with no way to indent it.

Adds a Format action next to copy, shown only when the language is JSON and there is a value. It pretty-prints via JSON.stringify(JSON.parse(value), null, 2) and calls the same onChange the editor already uses for typing, so every consumer of ValueEditor (feature value, multivariate variations, segment overrides) gets it for free. Invalid JSON is left untouched with a toast.

Draft: raising for a quick design/product check before finalising.

Open questions for the team:

  • Label/affordance: format text + code icon, or an icon-only button?
  • Scope: JSON only for now. Worth extending to yaml/toml/xml later (each lib can re-serialise)?
  • Any concern about pretty-printing enlarging the stored value string? (Functionally identical for JSON.parse consumers.)

How did you test this code?

Not yet run in a live app — this is a draft for design/product validation. What I have done:

  • eslint --fix passes (the one remaining != warning is pre-existing, on an untouched line).
  • Verified the onChange contract by tracing callers: Highlight already emits a plain string to onChange, and callers run it through Utils.safeParseEventValue, so a formatted string follows the exact same path as typed input.

Suggested manual test before merge:

  1. Paste a minified JSON object into the Edit Feature value editor, switch to the .json tab.
  2. Click Format — value should re-indent with 2 spaces.
  3. Paste invalid JSON and click Format — value left as-is, "Cannot format invalid JSON" toast.
  4. Confirm the action is hidden for non-JSON languages, empty values, and read-only (disabled) editors.

The .json toggle only validates and highlights; the stored value is
rendered verbatim, so pasted minified JSON stays unreadable. Add a
Format action next to copy, shown only when the language is JSON and
there is a value, that pretty-prints via JSON.stringify(parse, 2).

It calls the same onChange the editor already uses for typing, so every
caller (feature value, variations, segment overrides) gets it for free.
Invalid JSON is left untouched with a toast.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flagsmith-frontend-preview Ready Ready Preview Aug 26, 2026 8:53pm
flagsmith-frontend-staging Ready Ready Preview Aug 26, 2026 8:53pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Aug 26, 2026 8:53pm

Request Review

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

ValueEditor adds a format action for non-empty JSON values when editing is enabled. The action pretty-prints valid JSON, reports invalid JSON with a danger toast, and prevents blur commits during activation. Styles control its visibility, interaction state, transitions, and reduced-motion behaviour.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 73f06

The PR adds a JSON-only formatting action that preserves invalid values and uses the existing value-update path. Merge readiness is otherwise unaffected; only a minor stylesheet lint fix remains before normal checks can pass.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The .primary span already sets color: var(--color-text-action); Icon
falls back to currentColor, so the hardcoded #6837fc was redundant and
not theme-aware. Dropping it keeps the same colour and adapts in dark
mode.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the clickable span with BareButton so the action is a real
button: keyboard focusable, focus-visible outline, disabled semantics.
Extend the .select-language selector to style .bare-btn alongside span.

Animate the show/hide with a max-width + opacity transition (collapsing
out of the row when not JSON) instead of popping in, and honour
prefers-reduced-motion.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Only preventDefault is needed, to keep the editor from blurring (which
would fire its onBlur commit). stopPropagation was copied from the tab
spans with no handler here to stop, and can interfere with click-away.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
formatJson emitted onChange unconditionally, and the feature modal flags
the value dirty on any onChange without comparing. So formatting an
already-formatted value showed a spurious pending change. Skip onChange
when the reformatted string is identical.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7998c93b-b070-496b-9dc5-26923834aba7

📥 Commits

Reviewing files that changed from the base of the PR and between caed2bd and 73f0606.

📒 Files selected for processing (2)
  • frontend/web/components/ValueEditor.js
  • frontend/web/styles/3rdParty/_hljs.scss

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

color: var(--color-text-action);
}
}
// Slides and fades in when JSON is selected, collapses out otherwise.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add the required blank line before the new comment.

Stylelint reports scss/double-slash-comment-empty-line-before because the comment on Line 85 follows the closing brace on Line 84 without an empty line. Insert one blank line so the changed stylesheet passes the configured lint rule.

🧰 Tools
🪛 Stylelint (17.14.0)

[error] 85-85: Expected empty line before comment (scss/double-slash-comment-empty-line-before)

(scss/double-slash-comment-empty-line-before)

Source: Linters/SAST tools

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

Labels

feature New feature or request front-end Issue related to the React Front End Dashboard

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant