Skip to content

fix(features): darken placeholder text and move copy inside the value editor field - #8446

Merged
talissoncosta merged 3 commits into
mainfrom
feat/input-placeholder-and-value-copy-8441
Sep 4, 2026
Merged

fix(features): darken placeholder text and move copy inside the value editor field#8446
talissoncosta merged 3 commits into
mainfrom
feat/input-placeholder-and-value-copy-8441

Conversation

@talissoncosta

@talissoncosta talissoncosta commented Sep 2, 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

Closes #8441
Closes #8442

Both from the same design.

  • Placeholder contrast. Every placeholder resolves to --color-text-tertiary, which was Neutrals/300 in light mode: 2.26:1 on white. Now Neutrals/500, measured at 5.22:1. Dark mode already passed. The same token also fixes two hint texts that were failing for the same reason. react-select's placeholder was the last one reading raw SCSS instead of the token, so it moves across too.
  • Copy moves inside the input, out of the .txt/.json/.xml/.toml/.yaml row. It is a real <button> with an aria-label now, so it is keyboard reachable.
  • Info icon was 12px and sat 2px above the label text. It is 16px and centred, per the design.

Screenshots

Light Dark
Before image image
After image image

How did you test this code?

New Storybook story (Components/Forms/ValueEditor) covering the empty, filled, multiline, JSON, invalid JSON, code-medium and disabled states, snapshotted by Chromatic in both themes.

Contrast measured in the browser rather than calculated: computed color against computed background-color on the rendered placeholder.

Manually through Create feature → Value, MV variation values, segment overrides and the SAML metadata field.

Worth a look

  • FieldLabel is shared, so the icon change touches every form label in the app. The flex sits on FieldLabel's own element rather than .control-label, since nine hand-written labels elsewhere use that class and have no icon to align.
  • Copy stays hidden on read-only editors. That was never a decision, it fell out of copy living in the row that gets hidden. Three of the eight call sites are permanently read-only, which is arguably where it is most useful.
  • The design shows the placeholder as enter a value; we render Enter a value... from Highlight's hardcoded default. Left alone as a copy change for @dragos-bubu to confirm.

@vercel

vercel Bot commented Sep 2, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
flagsmith-frontend-preview Ready Ready Preview Sep 4, 2026 12:59pm UTC
flagsmith-frontend-staging Ready Ready Preview Sep 4, 2026 12:59pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
docs Ignored Ignored Preview Sep 4, 2026 12:59pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: c72848fe-b55e-4da6-bdc2-16af39b1d0a4

📥 Commits

Reviewing files that changed from the base of the PR and between 201b683 and f9a428e.

📒 Files selected for processing (1)
  • frontend/common/theme/tokens.json

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


📝 Walkthrough

Walkthrough

The change updates light-theme tertiary text tokens and react-select placeholder styling. It refactors ValueEditor validation icons and copy controls, adds copy-button styling, and removes the ConfigProvider wrapper. It updates FieldLabel, adds Storybook stories for multiple ValueEditor states, and registers a global toast stub for Storybook.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: 🟡 Moderate · up to f9a42

This change improves ValueEditor copy interaction, placeholder contrast, and component stories, but the new story may not compile and may expose inaccessible label relationships. Resolve these issues before merging.


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.

@github-actions github-actions Bot added the front-end Issue related to the React Front End Dashboard label Sep 2, 2026
@talissoncosta talissoncosta changed the title Input type text: placeholder contrast and copy affordance fix(a11y): placeholder contrast and copy affordance on the value input Sep 4, 2026
@talissoncosta
talissoncosta force-pushed the feat/input-placeholder-and-value-copy-8441 branch from ca926e8 to e86fc77 Compare September 4, 2026 11:52
@github-actions github-actions Bot added the fix label Sep 4, 2026
@talissoncosta
talissoncosta marked this pull request as ready for review September 4, 2026 12:04
@talissoncosta
talissoncosta requested a review from a team as a code owner September 4, 2026 12:04
@talissoncosta
talissoncosta requested review from kyle-ssg and removed request for a team September 4, 2026 12:04
@github-actions github-actions Bot added fix and removed fix labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Docker builds report

Image Build Status Security report
ghcr.io/flagsmith/flagsmith-api-test:pr-8446 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-e2e:pr-8446 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith:pr-8446 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-api:pr-8446 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-private-cloud:pr-8446 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-frontend:pr-8446 Finished ✅ Results

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor
❌ private-cloud · depot-ubuntu-latest-16 — run #20172 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

failed  3 failed

Details

stats  3 tests across 3 suites
duration  22.3 seconds
commit  bb4e89c
info  📦 Artifacts: View test results and HTML report
🔄 Run: #20172 (attempt 1)

Failed tests

firefox › tests/change-request-test.pw.ts › Change Request Tests › Change requests can be created, approved, and published with four-eyes approval @enterprise
firefox › tests/roles-test.pw.ts › Roles Tests › Roles can be created with project and environment permissions @enterprise
firefox › tests/sso-test.pw.ts › SCIM Tests › SCIM configuration can be created, regenerated, and deleted @enterprise

🗂️ Previous results
✅ oss · depot-ubuntu-latest-arm-16 — run #20172 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  45.3 seconds
commit  bb4e89c
info  🔄 Run: #20172 (attempt 1)

✅ oss · depot-ubuntu-latest-16 — run #20172 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  41.9 seconds
commit  bb4e89c
info  🔄 Run: #20172 (attempt 1)

✅ private-cloud · depot-ubuntu-latest-arm-16 — run #20174 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  37.3 seconds
commit  f9a428e
info  🔄 Run: #20174 (attempt 1)

✅ private-cloud · depot-ubuntu-latest-16 — run #20174 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  4 passed

Details

stats  4 tests across 4 suites
duration  32.9 seconds
commit  f9a428e
info  🔄 Run: #20174 (attempt 1)

✅ oss · depot-ubuntu-latest-arm-16 — run #20174 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  48.6 seconds
commit  f9a428e
info  🔄 Run: #20174 (attempt 1)

✅ oss · depot-ubuntu-latest-16 — run #20174 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  41.2 seconds
commit  f9a428e
info  🔄 Run: #20174 (attempt 1)

✅ private-cloud · depot-ubuntu-latest-arm-16 — run #20173 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  38.4 seconds
commit  201b683
info  🔄 Run: #20173 (attempt 1)

✅ private-cloud · depot-ubuntu-latest-16 — run #20173 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  35.9 seconds
commit  201b683
info  🔄 Run: #20173 (attempt 1)

✅ oss · depot-ubuntu-latest-arm-16 — run #20173 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  46.1 seconds
commit  201b683
info  🔄 Run: #20173 (attempt 1)

✅ oss · depot-ubuntu-latest-16 — run #20173 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  41.4 seconds
commit  201b683
info  🔄 Run: #20173 (attempt 1)

✅ private-cloud · depot-ubuntu-latest-arm-16 — run #20171 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  1 minute, 12 seconds
commit  7c79b87
info  🔄 Run: #20171 (attempt 1)

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Visual Regression

15 screenshots compared. See report for details.
View full report

@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: 3


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: ff3bebd2-8a7a-4e31-8d11-e0050466b8a4

📥 Commits

Reviewing files that changed from the base of the PR and between cc4c7b9 and e86fc77.

⛔ Files ignored due to path filters (1)
  • frontend/documentation/TokenReference.generated.stories.tsx is excluded by !**/*.generated.*
📒 Files selected for processing (9)
  • frontend/.storybook/preview.js
  • frontend/common/theme/tokens.json
  • frontend/common/theme/tokens.ts
  • frontend/documentation/components/ValueEditor.stories.tsx
  • frontend/web/components/ValueEditor.js
  • frontend/web/styles/3rdParty/_hljs.scss
  • frontend/web/styles/3rdParty/_react-select.scss
  • frontend/web/styles/_tokens.scss
  • frontend/web/styles/_variables.scss
💤 Files with no reviewable changes (1)
  • frontend/web/styles/_variables.scss

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

Comment thread frontend/documentation/components/ValueEditor.stories.tsx
Comment thread frontend/documentation/components/ValueEditor.stories.tsx Outdated
Comment thread frontend/web/components/ValueEditor.js

@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: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: 5211892c-06bb-485e-a892-cd9574dd6352

📥 Commits

Reviewing files that changed from the base of the PR and between e86fc77 and a7d2438.

📒 Files selected for processing (1)
  • frontend/documentation/components/ValueEditor.stories.tsx

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

Comment thread frontend/documentation/components/ValueEditor.stories.tsx
Comment thread frontend/documentation/components/ValueEditor.stories.tsx
talissoncosta and others added 3 commits September 4, 2026 09:57
Placeholders across inputs, textareas and the value editor all resolve to
--color-text-tertiary. In light mode that was Neutrals/300 (#9da4ae), which
is 2.26:1 on surface-default, well under the 4.5:1 AA threshold.

Repoint the light value to Neutrals/500 (#656d7b), measured at 5.22:1. Dark
mode already passed and is unchanged.

Also switch the react-select placeholder onto the same token: it was the one
placeholder still reading the raw SCSS variable, fixed for both themes. That
leaves $input-placeholder-color(-dark) unused, so remove them.

Closes #8441

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copy was the last item of the .txt/.json/.xml/.toml/.yaml row that floats
above the editor, which conflated picking a format with copying the value.
It now sits inside the input, right aligned, per the design.

While moving it, make it a real control: BareButton with an aria-label
instead of a <span onMouseDown>, so it is focusable and reachable by
keyboard and screen reader. Its colour comes from --color-icon-action on
hover rather than a hardcoded purple.

Copy stayed hidden on disabled editors and under onlyOneLang only because
it lived in the row those hide. That behaviour is preserved here so the
change stays visual, but it is worth revisiting: three of the eight call
sites are permanently disabled read-only values, which is where copy is
most useful.

Drop the ConfigProvider wrapper. ValueEditor reads none of isLoading,
error, getValue or hasFeature, and on the E2E path they were spread onto
the textarea as unknown DOM attributes. It also crashed the component
outside app boot, which is what the new story surfaced.

Swap the validation icons from ionicons to our own Icon. Storybook stubs
IonIcon as a grey circle, so the new story was showing a placeholder where
a warning triangle belongs. Both ids stay: saveFeatureWithValidation reads
the error one off the DOM.

Add a Storybook story covering the empty, filled, multiline, JSON, invalid
JSON, code-medium, disabled and single-language states, snapshotted by
Chromatic in both themes.

Closes #8442

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The design puts the info icon at 20x20 beside the label; ours asked for 12,
and since info-outlined draws its circle across 20 of a 24 viewBox that
rendered a 10px target. It is 16 now.

It also sat 2px above the text. .control-label is display: block, so the
tooltip's inline-flex wrapper took part in inline layout, and an
inline-flex box whose only child is a replaced element baselines on its
bottom margin edge rather than its content. The svg { vertical-align:
bottom } rule alongside it cannot correct that: vertical-align is ignored
on flex items.

Laying the label out as a centred flex row puts the icon dead on the text
centre. vertical-align: middle was the other candidate and overshoots by
1.3px, aligning to half the x-height rather than the cap centre.

That goes on FieldLabel's own element, not on .control-label. Nine
hand-written labels across six other files carry that class, none of them
with an icon to align, so they keep display: block and this touches only
what FieldLabel renders. The stylesheet is unchanged.

Checked against block: the label keeps its full width, and a long label
still wraps to the same height.

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

Copy link
Copy Markdown
Contributor Author

@themis-blindfold review

@talissoncosta talissoncosta changed the title fix(a11y): placeholder contrast and copy affordance on the value input fix(features): darken placeholder text and move copy inside the value field Sep 4, 2026
@themis-blindfold

Copy link
Copy Markdown
Contributor

⚖️ Themis review: ✅ Ship it

The placeholder token now meets the requested light-theme contrast target, the copy control is a keyboard-accessible button inside the value editor, and the shared label icon aligns with the design. Completed frontend, unit, end-to-end, Chromatic, lint, and security checks are green.

Area Score
🎯 Correctness 5/5
🧪 Test coverage 4/5
📐 Code quality 5/5
🚀 Product impact 4/5

⚖️ Acknowledged

  • Storybook framework-type import — thread resolved by @talissoncosta
  • Editor labels are not associated with their contenteditable controls — thread resolved by @talissoncosta
  • Same-tree BareButton import style — thread resolved by @talissoncosta
  • Story metadata typing awaits the component's TypeScript migration — thread resolved by @talissoncosta
  • Story wrapper props typing awaits the exported component props — thread resolved by @talissoncosta
📝 Walkthrough
  • Semantic theme tokens - raises light-mode tertiary text from neutral 300 to neutral 500 and regenerates the TypeScript, SCSS, and token reference outputs.
  • Value editor - replaces the language-row copy affordance with an in-editor semantic button, including focus and hover treatment and content clearance.
  • Field labels - uses centred flex layout and a 16px information icon across the shared label component.
  • Storybook - adds value-editor states across both themes for visual regression coverage.
🧪 How to verify
  1. In the ValueEditor Storybook page, check empty, long multiline, JSON, code-medium, disabled, and XML-only states in light and dark themes.
  2. In Create feature, tab to the copy button, activate it with Enter and Space, and confirm the current value is copied.
  3. Check variation values, segment overrides, and SAML metadata fields for unchanged editing and validation behaviour.
  4. Run cd frontend && npm run test:unit.
    Automate: add a Storybook interaction test that activates the copy button with the keyboard and asserts the clipboard feedback path.

Product take: Solid accessibility and usability improvement in a high-frequency editor, with a small, contained visual footprint.

🧭 Assumptions & unverified claims

No unverified assumptions or claims.

The copy button has finally found its home · reviewed at f9a428e

@talissoncosta talissoncosta changed the title fix(features): darken placeholder text and move copy inside the value field fix(features): darken placeholder text and move copy inside the value editor field Sep 4, 2026

@Zaimwa9 Zaimwa9 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@talissoncosta
talissoncosta merged commit 2f1a915 into main Sep 4, 2026
31 checks passed
@talissoncosta
talissoncosta deleted the feat/input-placeholder-and-value-copy-8441 branch September 4, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix front-end Issue related to the React Front End Dashboard

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create feature / Value - Input type text enhacement Accessibility feature - Input type text: placeholder

3 participants