Skip to content

fix(IconButton): Make icon buttons readable in dark mode - #8805

Open
talissoncosta wants to merge 11 commits into
mainfrom
refactor/icon-button
Open

talissoncosta wants to merge 11 commits into
mainfrom
refactor/icon-button

Conversation

@talissoncosta

@talissoncosta talissoncosta commented Oct 17, 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

In dark mode, the kebab button's icon was nearly invisible and its menu blended into the card. Both came from hardcoded light colours, and the same grey (#656D7B) was copied into most icon-only buttons.

  • Every btn-with-icon and theme='icon' button now uses IconButton, so icons follow the theme. Each button has an aria-label naming its row, and the kebab exposes aria-expanded.
  • Removes the icon theme from Button and the .btn-with-icon / .btn-icon styles.
  • The action menu uses surface, border and shadow tokens.
  • IconButton: icons are centred in their slot, and secondary uses a grey icon with its own active state. The two IconButtons already on main (FeatureRow back arrow, PrerequisitesTable) are ghost, so only the centring reaches them.

Reviewing this

Review by commit. The first two hold the decisions; the third is the same swap repeated.

Before After
btn-with-icon, default (44px) secondary, large (44px)
btn-with-icon, small (40px): metrics table, user actions secondary, medium (36px)
Kebab menus (32px) secondary, medium (36px)
Warehouse card (xSmall, 32px) secondary, small (28px)
theme='icon' (32px) ghost, small (28px)
CopyField secondary, large (44px)
Release pipeline "Add stage" outline, small, round

Buttons that had a box keep one (secondary); buttons that had none stay boxless (ghost). Hover no longer turns the icon purple. It darkens the box and the icon instead.

How did you test this code?

Typecheck and lint show no new errors. Manual QA in light and dark mode, ticked as checked:

  • Kebab on the features list, a segment override card and the members table.
  • Kebab on the segments list.
  • Delete button in the Cohorts tab.
  • Other table rows with a delete button: roles, groups, invites, webhooks, custom fields, SAML, trust relationships, SDK keys, health providers.
  • Experiments metrics table: edit and delete sit side by side.
  • Copy buttons next to a feature name (feature modal, compare pages).
  • CopyField next to an API key.
  • Delete button on a segment rule condition.
  • Release pipelines "Add stage" and the theme toggle.
  • Segment override with only remove permission: "Remove Override" is a secondary button.
  • Dropdown on the feature save button and the experiment header: the menu has the same border as the kebab menus in dark mode.

talissoncosta and others added 3 commits October 17, 2026 13:10
…w the theme

The icons hardcoded a grey fill that disappeared on dark surfaces, and the
action menu matched the card behind it. The menu now uses surface, border
and shadow tokens.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…y variant

A 16px icon in a medium button sat in the top-left corner of its 20px slot.
Secondary drew a pure white icon on dark and shared one style between hover
and active.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…con theme

Every btn-with-icon and theme='icon' button now uses IconButton, so icons
follow the theme instead of a hardcoded grey, and each gets an aria-label.
Removes the icon theme and the .btn-with-icon/.btn-icon styles.

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

vercel Bot commented Oct 17, 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 Oct 17, 2026 5:18pm UTC
flagsmith-frontend-staging Ready Ready Preview Oct 17, 2026 5:18pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
docs Ignored Ignored Preview Oct 17, 2026 5:18pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

📝 Walkthrough

Icon-only controls across the frontend now use IconButton instead of form Button controls. The changes set variants, sizes, and accessible labels while retaining the described handlers and actions. Shared styles for the old icon-button classes and the Button icon theme are removed. ActionButton now receives menu-open state and exposes it through aria-expanded.

Priority: ➖ Normal

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

Merge Risk: 🔵 Low · up to 80758

A saved-override edge case can make its actions button harder for assistive-technology users to identify. This is a localized accessibility issue, so the merge risk is low.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

…ts to it

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nd keep Remove Override secondary

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…secondary variant

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

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

Co-Authored-By: Claude Opus 5.5 (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: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 452da31b-7992-4882-a653-7fa972099c21
📥 Commits

Reviewing files that changed from the base of the PR and between e40b88b and d291d4b.

📒 Files selected for processing: 47
  • frontend/documentation/components/Button.stories.tsx
  • frontend/web/components/ActionButton.tsx
  • frontend/web/components/CompareEnvironments/CompareEnvironments.tsx
  • frontend/web/components/CompareIdentities.tsx
  • frontend/web/components/CopyField.tsx
  • frontend/web/components/ExternalResourcesTable.tsx
  • frontend/web/components/GithubRepositoriesTable.tsx
  • frontend/web/components/IdentityTraits.tsx
  • frontend/web/components/ManagementAPIKeys.js
  • frontend/web/components/RolesTable.tsx
  • frontend/web/components/SegmentOverrideActions.tsx
  • frontend/web/components/ThemeToggle/ThemeToggle.tsx
  • frontend/web/components/UserAction.tsx
  • frontend/web/components/UserGroupList.tsx
  • frontend/web/components/base/IconButton/IconButton.scss
  • frontend/web/components/base/forms/Button.tsx
  • frontend/web/components/experiments/AudienceSegmentList/AudienceSegmentList.tsx
  • frontend/web/components/experiments/MetricsTable/MetricsTable.scss
  • frontend/web/components/experiments/MetricsTable/MetricsTable.tsx
  • frontend/web/components/feature-override/FeatureOverrideRow.tsx
  • frontend/web/components/feature-summary/FeatureAction.tsx
  • frontend/web/components/feature-summary/FeatureName.tsx
  • frontend/web/components/feature-summary/FeatureRow.tsx
  • frontend/web/components/metadata/ContentTypesMetadataFieldTable.tsx
  • frontend/web/components/metadata/MetadataPage.tsx
  • frontend/web/components/modals/AuditLogWebhooks.tsx
  • frontend/web/components/modals/CreateGroup.tsx
  • frontend/web/components/modals/InviteUsers.tsx
  • frontend/web/components/modals/create-feature/tabs/IdentityOverridesTab.tsx
  • frontend/web/components/pages/GitHubSetupPage.tsx
  • frontend/web/components/pages/IdentitiesPage.tsx
  • frontend/web/components/pages/SegmentPage.tsx
  • frontend/web/components/pages/UsersAndPermissionsPage.tsx
  • frontend/web/components/pages/environment-settings/EnvironmentSettingsPage.tsx
  • frontend/web/components/pages/environment-settings/tabs/cohort-sync-tab/CohortSyncTab.tsx
  • frontend/web/components/pages/environment-settings/tabs/warehouse-tab/WarehouseConnectionCard.tsx
  • frontend/web/components/pages/organisation-settings/tabs/sso/saml/SAMLAttributeMappingTable.tsx
  • frontend/web/components/pages/organisation-settings/tabs/sso/saml/index.tsx
  • frontend/web/components/pages/organisation-settings/tabs/trust-relationships/TrustRelationshipModal/TrustRelationshipModal.tsx
  • frontend/web/components/pages/organisation-settings/tabs/trust-relationships/TrustRelationships/TrustRelationships.tsx
  • frontend/web/components/pages/project-settings/tabs/EditHealthProvider.tsx
  • frontend/web/components/pages/sdk-keys/components/ServerSideKeyRow.tsx
  • frontend/web/components/release-pipelines/StageArrow.tsx
  • frontend/web/components/segments/Rule/components/RuleConditionRow.tsx
  • frontend/web/components/segments/SegmentRow/components/SegmentAction.tsx
  • frontend/web/styles/project/_FeaturesPage.scss
  • frontend/web/styles/project/_buttons.scss
💤 Files with no reviewable changes: 4
  • frontend/web/components/base/forms/Button.tsx
  • frontend/web/components/experiments/MetricsTable/MetricsTable.scss
  • frontend/web/styles/project/_buttons.scss
  • frontend/documentation/components/Button.stories.tsx

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

Comment thread frontend/web/components/ActionButton.tsx Outdated
Comment thread frontend/web/components/UserAction.tsx Outdated
…'s light one

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…le in E2E

The kebab and user actions now say which feature, segment or user they act
on, so the E2E helpers select them by accessible name and data-test goes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@talissoncosta talissoncosta changed the title refactor(Button): Move icon-only buttons to IconButton and drop the icon theme fix(IconButton): Make icon buttons readable in dark mode Oct 19, 2026
@talissoncosta
talissoncosta marked this pull request as ready for review October 19, 2026 09:51
@talissoncosta
talissoncosta requested a review from a team as a code owner October 19, 2026 09:51
@talissoncosta
talissoncosta requested review from kyle-ssg and removed request for a team October 19, 2026 09:51
@github-actions github-actions Bot removed the refactor label Oct 19, 2026
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Docker builds report

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

@github-actions github-actions Bot added the fix label Oct 19, 2026
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor
✅ private-cloud · depot-ubuntu-latest-arm-16 — run #22575 (attempt 1)

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

passed  2 passed

Details

stats  2 tests across 2 suites
duration  38 seconds
commit  807584f
info  🔄 Run: #22575 (attempt 1)

🗂️ Previous results
✅ private-cloud · depot-ubuntu-latest-16 — run #22575 (attempt 1)

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

passed  5 passed

Details

stats  5 tests across 5 suites
duration  33.9 seconds
commit  807584f
info  🔄 Run: #22575 (attempt 1)

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

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

passed  1 passed

Details

stats  1 test across 1 suite
duration  38 seconds
commit  807584f
info  🔄 Run: #22575 (attempt 1)

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

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

passed  1 passed

Details

stats  1 test across 1 suite
duration  31.5 seconds
commit  807584f
info  🔄 Run: #22575 (attempt 1)

@github-actions

Copy link
Copy Markdown
Contributor

Visual Regression

24 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: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: a1fb3823-c913-49df-952a-02b9474011f0
📥 Commits

Reviewing files that changed from the base of the PR and between d291d4b and 807584f.

📒 Files selected for processing: 13
  • frontend/e2e/helpers/e2e-helpers.playwright.ts
  • frontend/web/components/ActionButton.tsx
  • frontend/web/components/EditPermissions.tsx
  • frontend/web/components/SegmentOverrideActions.tsx
  • frontend/web/components/SegmentOverrides.js
  • frontend/web/components/UserAction.tsx
  • frontend/web/components/base/forms/ButtonDropdown.tsx
  • frontend/web/components/feature-summary/FeatureAction.tsx
  • frontend/web/components/feature-summary/FeatureRow.tsx
  • frontend/web/components/segments/SegmentRow/SegmentRow.tsx
  • frontend/web/components/segments/SegmentRow/components/SegmentAction.tsx
  • frontend/web/components/users-permissions/OrganisationUsersTable/components/OrganisationUsersTableRow.tsx
  • frontend/web/styles/project/_FeaturesPage.scss
💤 Files with no reviewable changes: 1
  • frontend/web/styles/project/_FeaturesPage.scss

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

>
{({ permission }) => (
<SegmentOverrideActions
segmentName={name || v.segment_name}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

set -eu
printf '%s\n' '--- diff ---'
git diff --unified=80 e40b88bed0c95d1c0338aead3e3c44c59f01cab2 807584f7d8b353827e452909b4d0c50f3273a940 -- frontend/web/components/SegmentOverrides.js
printf '%s\n' '--- definitions and references ---'
rg -n -F --glob 'frontend/web/components/SegmentOverrides.js' -e 'getOverrideLabel' -e 'SegmentOverrideActions' -e 'segmentName=' frontend/web/components/SegmentOverrides.js
printf '%s\n' '--- relevant file ---'
nl -ba frontend/web/components/SegmentOverrides.js | sed -n '1,280p'

Repository: Flagsmith/flagsmith

Length of output: 18849


🏁 Script executed:

set -eu
printf '%s\n' '--- action component ---'
nl -ba frontend/web/components/SegmentOverrideActions.js
printf '%s\n' '--- SegmentOverrideInner references and surrounding callers ---'
rg -n -F --glob 'frontend/web/**' -e '<SegmentOverrideInner' -e 'SegmentOverrideInner' -e 'segment_name' -e 'name=' frontend/web/components frontend/web | sed -n '1,240p'
printf '%s\n' '--- exact caller regions ---'
rg -n -F --glob 'frontend/web/**' '<SegmentOverrides' frontend/web | sed -n '1,120p'

Repository: Flagsmith/flagsmith

Length of output: 263


🏁 Script executed:

set -eu
printf '%s\n' '--- import candidates ---'
find frontend/web/components -maxdepth 3 \( -iname 'SegmentOverrideActions*' -o -iname '*ActionButton*' \) -print
printf '%s\n' '--- resolved component references ---'
rg -n -F --glob 'frontend/web/**' -e 'segmentName' -e 'ActionButton' -e '<SegmentOverrideInner' -e 'SegmentOverrideInner' frontend/web/components frontend/web || test "$?" -eq 1

Repository: Flagsmith/flagsmith

Length of output: 6183


🏁 Script executed:

set -eu
printf '%s\n' '--- SegmentOverrideActions.tsx ---'
nl -ba frontend/web/components/SegmentOverrideActions.tsx | sed -n '1,150p'
printf '%s\n' '--- ActionButton.tsx ---'
nl -ba frontend/web/components/ActionButton.tsx | sed -n '1,90p'
printf '%s\n' '--- SegmentOverrideInner call sites ---'
nl -ba frontend/web/components/SegmentOverrides.js | sed -n '330,490p'
printf '%s\n' '--- relevant prop construction ---'
rg -n -F --glob 'frontend/web/**' -e 'segmentOverrides' -e 'segment_overrides' -e '<SegmentOverrides' -e 'name:' frontend/web/components frontend/web | sed -n '1,260p'

Repository: Flagsmith/flagsmith

Length of output: 42524


🏁 Script executed:

set -eu
nl -ba frontend/web/components/SegmentOverrides.js | sed -n '490,680p'
printf '%s\n' '--- all SegmentOverrideListInner call sites ---'
rg -n -F --glob 'frontend/web/**' -e 'SegmentOverrideListInner' -e 'SegmentOverrideList' -e '<SegmentOverrides' frontend/web/components frontend/web | sed -n '1,160p'

Repository: Flagsmith/flagsmith

Length of output: 8692


🏁 Script executed:

set -eu
printf '%s\n' '--- wrapper render ---'
nl -ba frontend/web/components/SegmentOverrides.js | sed -n '680,790p'
printf '%s\n' '--- SegmentOverridesTab caller ---'
nl -ba frontend/web/components/modals/create-feature/tabs/SegmentOverridesTab.tsx | sed -n '180,260p'
printf '%s\n' '--- SegmentOverrides imports and props ---'
rg -n -F --glob 'frontend/web/components/modals/create-feature/tabs/SegmentOverridesTab.tsx' -e 'value=' -e 'segment_name' -e 'segmentOverrides' -e 'segment_overrides' -e 'name=' frontend/web/components/modals/create-feature/tabs/SegmentOverridesTab.tsx

Repository: Flagsmith/flagsmith

Length of output: 8755


🏁 Script executed:

set -eu
printf '%s\n' '--- SegmentOverrideValue declarations/imports ---'
rg -n -F --glob 'frontend/web/**' -e 'SegmentOverrideValue' frontend/web common api | sed -n '1,180p'
printf '%s\n' '--- segment override data references ---'
rg -n -F --glob 'frontend/web/**' -e 'segment_overrides' -e 'segmentOverrides' frontend/web/components/modals/create-feature frontend/web/common frontend/web | sed -n '1,220p'

Repository: Flagsmith/flagsmith

Length of output: 6565


🏁 Script executed:

set -eu
nl -ba frontend/web/components/modals/create-feature/tabs/SegmentOverridesTab.tsx | sed -n '1,105p'
printf '%s\n' '--- feature initial data and segment updates ---'
nl -ba frontend/web/components/modals/create-feature/index.tsx | sed -n '380,420p;590,625p;675,700p'

Repository: Flagsmith/flagsmith

Length of output: 9227


Use the complete override label for segmentName.

If a saved override contains name but omits segment_name, the normal caller provides no row-level name. The current action label therefore becomes More actions for undefined. Use the existing fallback helper.

Suggested fix
--- "a/frontend/web/components/SegmentOverrides.js"
+++ "b/frontend/web/components/SegmentOverrides.js"
@@ -212,7 +212,7 @@
                 >
                   {({ permission }) => (
                     <SegmentOverrideActions
-                      segmentName={name || v.segment_name}
+                      segmentName={getOverrideLabel(v)}
                       hideViewSegment={hideViewSegment}
                       canCompare={canCompare}
                       onCompare={onCompare}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
segmentName={name || v.segment_name}
segmentName={getOverrideLabel(v)}

This branch was successfully deployed

2 active deployments
Preview – flagsmith-frontend-staging — 807584f7 Deployed Oct 17, 2026 by vercel[bot]
Preview – flagsmith-frontend-preview — 807584f7 Deployed Oct 17, 2026 by vercel[bot]
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.

1 participant