Skip to content

FE: Add dark mode view to storybook#43469

Merged
RachelElysia merged 2 commits intomainfrom
storybook-dark-light
Apr 14, 2026
Merged

FE: Add dark mode view to storybook#43469
RachelElysia merged 2 commits intomainfrom
storybook-dark-light

Conversation

@RachelElysia
Copy link
Copy Markdown
Member

@RachelElysia RachelElysia commented Apr 13, 2026

Issue

Closes #43468

Description

  • Add dark mode toggle to storybook

Screenrecording

Screen.Recording.2026-04-13.at.12.49.13.PM.mov

Testing

  • QA'd all new/changed functionality manually

Summary by CodeRabbit

  • New Features

    • Added a Storybook theme toolbar to toggle light/dark with automatic runtime theming.
  • Bug Fixes

    • Dropdown button icons now inherit color correctly and adapt to theme.
  • Chores

    • Cleaned up story configurations and removed legacy background overrides.
    • Added consistent story layout wrapper for improved rendering.
    • Removed an obsolete variant option from dropdown story controls.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.90%. Comparing base (1318102) to head (16cca83).
⚠️ Report is 35 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #43469   +/-   ##
=======================================
  Coverage   66.90%   66.90%           
=======================================
  Files        2599     2599           
  Lines      208184   208184           
  Branches     9334     9334           
=======================================
  Hits       139276   139276           
  Misses      56250    56250           
  Partials    12658    12658           
Flag Coverage Δ
frontend 54.75% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@RachelElysia RachelElysia marked this pull request as ready for review April 13, 2026 18:10
@RachelElysia RachelElysia requested a review from a team as a code owner April 13, 2026 18:10
Copilot AI review requested due to automatic review settings April 13, 2026 18:10
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Add dark mode toggle to Storybook with global theme support

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add dark/light mode toggle to Storybook with global theme support
• Implement theme decorator applying dark mode styles dynamically
• Remove redundant background parameters from story files
• Fix dropdown button icon color inheritance for dark mode
Diagram
flowchart LR
  A["Storybook Preview Config"] -->|"Add globalTypes"| B["Theme Toggle UI"]
  A -->|"Add withTheme Decorator"| C["Apply Dark Mode Styles"]
  C -->|"Toggle dark-mode class"| D["Body Element"]
  C -->|"Set background/color"| D
  E["Story Files"] -->|"Remove backgrounds"| F["Use Global Decorator"]
  G["DropdownButton Styles"] -->|"Add currentColor"| H["Icon Adapts to Dark Mode"]
Loading

Grey Divider

File Changes

1. .storybook/preview.js ✨ Enhancement +40/-0

Add dark mode toggle and theme decorator

• Add globalTypes configuration with theme toggle (light/dark)
• Implement applyTheme function to apply dark mode styles to body
• Create withTheme decorator using React hooks for theme switching
• Export decorator to apply theme globally across all stories

.storybook/preview.js


2. frontend/components/buttons/DropdownButton/_styles.scss 🐞 Bug fix +6/-0

Fix icon color inheritance for dark mode

• Add CSS rule to make dropdown button icon stroke inherit text color
• Enables icon color adaptation in dark mode

frontend/components/buttons/DropdownButton/_styles.scss


3. frontend/components/LiveQuery/TargetChipSelector/TargetChipSelector.stories.tsx Miscellaneous +0/-9

Remove redundant background parameters

• Remove hardcoded background parameters configuration
• Rely on global theme decorator instead

frontend/components/LiveQuery/TargetChipSelector/TargetChipSelector.stories.tsx


View more (3)
4. frontend/components/TabNav/TabNav.stories.tsx Miscellaneous +0/-15

Remove redundant background parameters

• Remove hardcoded background parameters configuration
• Rely on global theme decorator instead

frontend/components/TabNav/TabNav.stories.tsx


5. frontend/components/TeamsDropdown/TeamsDropdown.stories.tsx ✨ Enhancement +8/-0

Add React import and layout decorator

• Add React import statement
• Add decorator with min-height wrapper for dropdown layout

frontend/components/TeamsDropdown/TeamsDropdown.stories.tsx


6. frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx Miscellaneous +1/-13

Remove backgrounds and update variant options

• Remove hardcoded background parameters configuration
• Update variant options (remove "success", rename "text-link" to "link")
• Rely on global theme decorator instead

frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Apr 13, 2026

Code Review by Qodo

🐞 Bugs (3)   📘 Rule violations (0)   📎 Requirement gaps (0)
🐞\ ≡ Correctness (1) ☼ Reliability (1) ⚙ Maintainability (1)

Grey Divider


Action required

1. Invalid variant in story 🐞
Description
DropdownButton Storybook controls include variant "link", but the underlying Button component does
not support it (it supports "text-link"), so selecting it will produce an unstyled button--link
class. This makes the Storybook story misleading and can hide regressions for the real supported
variants.
Code

frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx[R31-37]

    variant: {
      options: [
        "default",
-        "success",
        "alert",
        "pill",
-        "text-link",
+        "link",
        "text-icon",
Evidence
The story passes variant directly into DropdownButton, which passes it through to Button; Button’s
variant type/styles include text-link but not link, and there are no styles for button--link.

frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx[30-44]
frontend/components/buttons/DropdownButton/DropdownButton.jsx[95-110]
frontend/components/buttons/Button/Button.tsx[7-21]
frontend/components/buttons/Button/_styles.scss[220-255]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`DropdownButton.stories.tsx` exposes a `variant` control value `"link"`, but the actual Button variants support `"text-link"` (not `"link"`). Selecting `"link"` yields a `button--link` class with no corresponding styles.

### Issue Context
`DropdownButton.jsx` forwards `variant` directly to `<Button variant={variant}>`, so Storybook controls must match Button’s real variant API.

### Fix Focus Areas
- frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx[31-43]
- frontend/components/buttons/Button/Button.tsx[7-21]
- frontend/components/buttons/Button/_styles.scss[220-255]

### Suggested fix
Replace `"link"` with `"text-link"` in the `argTypes.variant.options` list (and any other story args/controls that reference `"link"`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Theme toggle misses theme event 🐞
Description
.storybook/preview.js toggles the dark-mode class but does not dispatch the app’s
fleet-theme-change event or update the theme localStorage key, so components that derive theme
from those signals won’t update when the Storybook toolbar theme changes. This can cause Storybook
dark mode to diverge from real app behavior (e.g., components listening for the event).
Code

.storybook/preview.js[R18-26]

+const applyTheme = (isDark) => {
+  document.body.classList.toggle("dark-mode", isDark);
+  document.body.style.backgroundColor = isDark ? "#181a1f" : "";
+  document.body.style.color = isDark ? "#e2e4ea" : "";
+
+  document.querySelectorAll(".docs-story").forEach((el) => {
+    el.style.backgroundColor = isDark ? "#181a1f" : "";
+  });
+};
Evidence
The app’s canonical toggleDarkMode updates localStorage and dispatches fleet-theme-change; at
least one component (SiteTopNav) initializes from isDarkMode() and listens for that event to
update state. Storybook’s applyTheme does neither, so those components won’t react to the toolbar
toggle.

.storybook/preview.js[18-26]
frontend/utilities/theme.ts[1-26]
frontend/components/top_nav/SiteTopNav/SiteTopNav.tsx[128-159]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Storybook’s theme toggle only sets `body.dark-mode` (and some inline styles). It does not update the `fleet-dark-mode` localStorage key or dispatch the `fleet-theme-change` event, so components that rely on those signals won’t update in Storybook when toggling the toolbar.

### Issue Context
The application’s canonical theme implementation is in `frontend/utilities/theme.ts` (`toggleDarkMode` / `initTheme`). Some components (e.g., `SiteTopNav`) initialize theme state from `isDarkMode()` and subscribe to `fleet-theme-change`.

### Fix Focus Areas
- .storybook/preview.js[18-36]
- frontend/utilities/theme.ts[1-26]
- frontend/components/top_nav/SiteTopNav/SiteTopNav.tsx[128-159]

### Suggested fix
In `.storybook/preview.js`, when applying the theme:
- set `localStorage.setItem('fleet-dark-mode', String(isDark))` (or call into a shared helper), and
- dispatch `window.dispatchEvent(new CustomEvent('fleet-theme-change', { detail: { dark: isDark } }))`.
Optionally add/remove `body.theme-transition` to match app behavior if desired.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

3. Hardcoded body text color 🐞
Description
.storybook/preview.js hard-codes document.body.style.color in dark mode, overriding the app’s
default body text color derived from theme CSS variables. This can change inherited text colors and
make Storybook dark mode visually diverge from the actual app palette.
Code

.storybook/preview.js[R19-22]

+  document.body.classList.toggle("dark-mode", isDark);
+  document.body.style.backgroundColor = isDark ? "#181a1f" : "";
+  document.body.style.color = isDark ? "#e2e4ea" : "";
+
Evidence
Global styles set body text color using $ui-fleet-black-75, which is overridden in dark mode to a
specific value; the Storybook inline style forces a different hex (#e2e4ea) and will override the
CSS-driven value due to inline style precedence.

.storybook/preview.js[19-22]
frontend/styles/global/_global.scss[9-18]
frontend/styles/var/colors.scss[97-110]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Storybook sets `document.body.style.color` (and background) to hard-coded hex values. Inline styles override the CSS-variable-based theming and can drift from the app’s canonical palette.

### Issue Context
The app defines body color/background in `frontend/styles/global/_global.scss` using themed variables, with dark-mode overrides in `frontend/styles/var/colors.scss`.

### Fix Focus Areas
- .storybook/preview.js[18-26]
- frontend/styles/global/_global.scss[9-18]
- frontend/styles/var/colors.scss[97-110]

### Suggested fix
Remove the inline `document.body.style.color` (and possibly `backgroundColor`) assignments and rely solely on toggling `body.dark-mode`. If Storybook docs/canvas needs a background override, prefer using CSS that references existing CSS variables (e.g., `background-color: var(--core-fleet-white)`) rather than hard-coded hex values.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines 31 to 37
variant: {
options: [
"default",
"success",
"alert",
"pill",
"text-link",
"link",
"text-icon",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Invalid variant in story 🐞 Bug ≡ Correctness

DropdownButton Storybook controls include variant "link", but the underlying Button component does
not support it (it supports "text-link"), so selecting it will produce an unstyled button--link
class. This makes the Storybook story misleading and can hide regressions for the real supported
variants.
Agent Prompt
### Issue description
`DropdownButton.stories.tsx` exposes a `variant` control value `"link"`, but the actual Button variants support `"text-link"` (not `"link"`). Selecting `"link"` yields a `button--link` class with no corresponding styles.

### Issue Context
`DropdownButton.jsx` forwards `variant` directly to `<Button variant={variant}>`, so Storybook controls must match Button’s real variant API.

### Fix Focus Areas
- frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx[31-43]
- frontend/components/buttons/Button/Button.tsx[7-21]
- frontend/components/buttons/Button/_styles.scss[220-255]

### Suggested fix
Replace `"link"` with `"text-link"` in the `argTypes.variant.options` list (and any other story args/controls that reference `"link"`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

variant="link" not supported (Qodo + Copilot)

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 13, 2026

Walkthrough

Added Storybook-wide theming: a theme global toolbar control (light/dark) and a decorator that applies body.dark-mode, sets body background/text colors, and updates .docs-story backgrounds at runtime. Removed per-story parameters.backgrounds entries from multiple stories. One story file gained a wrapper decorator to ensure minimum height. DropdownButton variant options were adjusted and its SCSS updated so icon SVG paths use stroke: currentColor.

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete against the template. It lacks changes files, validation details, testing checklist items, and other required sections from the template. Add changes file entry, complete the testing checklist items, and follow the template structure more comprehensively.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'FE: Add dark mode view to storybook' directly describes the main objective of adding a dark mode toggle to Storybook.
Linked Issues check ✅ Passed The PR implementation successfully addresses all objectives from issue #43468: adds dark/light toggle to Storybook toolbar, applies the production CSS class body.dark-mode, enables component preview in dark mode, and is verifiable via yarn storybook.
Out of Scope Changes check ✅ Passed All changes are directly related to adding dark mode to Storybook. The DropdownButton variant removal and icon styling changes are implementation details necessary to support the feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch storybook-dark-light

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx (1)

31-43: ⚠️ Potential issue | 🟡 Minor

link is not a supported button variant.

Line 36 no longer matches frontend/components/buttons/Button/Button.tsx:8-21, which still exposes "text-link" rather than "link". With this option in argTypes, Storybook can generate a variant value that DropdownButton/Button doesn’t understand.

Suggested fix
       options: [
         "default",
         "alert",
         "pill",
-        "link",
+        "text-link",
         "text-icon",
         "icon",
         "inverse",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx` around
lines 31 - 43, The Storybook argTypes for DropdownButton lists an unsupported
variant "link"; update the variant options in DropdownButton.stories.tsx to
match the actual Button variants (replace "link" with "text-link") so the
generated variant values align with the Button implementation (see Button.tsx's
exposed variants).
🧹 Nitpick comments (1)
.storybook/preview.js (1)

18-25: Prefer class-driven styling over hard-coded hex values.

The dark-mode class already gives Storybook the same theming hook as the app. The inline colors on document.body and .docs-story add a second source of truth that can drift the next time the production theme changes. I’d keep the JS limited to toggling the class and move any Storybook-only backdrop tweaks into CSS keyed off body.dark-mode.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.storybook/preview.js around lines 18 - 25, The applyTheme function is
applying inline hex colors (document.body.style.backgroundColor,
document.body.style.color, and per-element .docs-story backgroundColor) which
duplicates the theme; remove those inline style assignments and keep only
document.body.classList.toggle("dark-mode", isDark) and the
document.querySelectorAll(".docs-story").forEach call should no longer set
styles in JS; instead add Storybook-only CSS rules (e.g., in
.storybook/preview.css or a global decorator) that target body.dark-mode and
body.dark-mode .docs-story to define background and text colors so the dark
theme is driven by classes not hard-coded hex values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/components/buttons/DropdownButton/_styles.scss`:
- Around line 75-76: The selector .dropdown-button .icon doesn't match the caret
because DropdownButton.jsx renders <Icon /> directly inside <Button> (see the
JSX around the caret rendering), so change the selector to target the actual SVG
markup (e.g. target the svg/path produced by <Icon /> such as .dropdown-button
svg path or .dropdown-button > svg path) and fix the keyword casing to lowercase
(use currentcolor) so Stylelint passes and the dark-mode stroke override applies
to the chevron.

---

Outside diff comments:
In `@frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx`:
- Around line 31-43: The Storybook argTypes for DropdownButton lists an
unsupported variant "link"; update the variant options in
DropdownButton.stories.tsx to match the actual Button variants (replace "link"
with "text-link") so the generated variant values align with the Button
implementation (see Button.tsx's exposed variants).

---

Nitpick comments:
In @.storybook/preview.js:
- Around line 18-25: The applyTheme function is applying inline hex colors
(document.body.style.backgroundColor, document.body.style.color, and per-element
.docs-story backgroundColor) which duplicates the theme; remove those inline
style assignments and keep only document.body.classList.toggle("dark-mode",
isDark) and the document.querySelectorAll(".docs-story").forEach call should no
longer set styles in JS; instead add Storybook-only CSS rules (e.g., in
.storybook/preview.css or a global decorator) that target body.dark-mode and
body.dark-mode .docs-story to define background and text colors so the dark
theme is driven by classes not hard-coded hex values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 09b0516d-c2b2-4623-8420-b5d788427430

📥 Commits

Reviewing files that changed from the base of the PR and between 98e08ad and 4284fb0.

📒 Files selected for processing (6)
  • .storybook/preview.js
  • frontend/components/LiveQuery/TargetChipSelector/TargetChipSelector.stories.tsx
  • frontend/components/TabNav/TabNav.stories.tsx
  • frontend/components/TeamsDropdown/TeamsDropdown.stories.tsx
  • frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx
  • frontend/components/buttons/DropdownButton/_styles.scss
💤 Files with no reviewable changes (2)
  • frontend/components/LiveQuery/TargetChipSelector/TargetChipSelector.stories.tsx
  • frontend/components/TabNav/TabNav.stories.tsx

Comment on lines +75 to +76
.dropdown-button .icon svg path {
stroke: currentColor;
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.

⚠️ Potential issue | 🟠 Major

Target the actual chevron markup here.

frontend/components/buttons/DropdownButton/DropdownButton.jsx:101-109 renders <Icon /> directly inside <Button>, so Line 75’s .icon selector never matches the caret. That means the new dark-mode override won’t affect the icon, and Line 76 also still fails Stylelint because the keyword casing is wrong.

Suggested fix
-.dropdown-button .icon svg path {
-  stroke: currentColor;
+.dropdown-button svg path {
+  stroke: currentcolor;
 }
📝 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
.dropdown-button .icon svg path {
stroke: currentColor;
.dropdown-button svg path {
stroke: currentcolor;
🧰 Tools
🪛 Stylelint (17.6.0)

[error] 76-76: Expected "currentColor" to be "currentcolor" (value-keyword-case)

(value-keyword-case)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/components/buttons/DropdownButton/_styles.scss` around lines 75 -
76, The selector .dropdown-button .icon doesn't match the caret because
DropdownButton.jsx renders <Icon /> directly inside <Button> (see the JSX around
the caret rendering), so change the selector to target the actual SVG markup
(e.g. target the svg/path produced by <Icon /> such as .dropdown-button svg path
or .dropdown-button > svg path) and fix the keyword casing to lowercase (use
currentcolor) so Stylelint passes and the dark-mode stroke override applies to
the chevron.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a global dark/light mode toggle to Storybook so components can be previewed under the same body.dark-mode theming approach used by the app.

Changes:

  • Adds a Storybook toolbar control (globalTypes.theme) and a global decorator to toggle body.dark-mode.
  • Removes per-story background overrides from several stories to rely on the global theme toggle.
  • Tweaks DropdownButton chevron styling to better adapt in dark mode.

Reviewed changes

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

Show a summary per file
File Description
.storybook/preview.js Introduces the global theme toolbar toggle and applies the dark-mode class via a decorator.
frontend/components/buttons/DropdownButton/_styles.scss Overrides dropdown chevron stroke to follow text color for dark mode compatibility.
frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx Updates story controls/options and removes Storybook background parameters.
frontend/components/TeamsDropdown/TeamsDropdown.stories.tsx Adds a decorator wrapper to ensure adequate height for rendering.
frontend/components/TabNav/TabNav.stories.tsx Removes per-story background parameters in favor of global theming.
frontend/components/LiveQuery/TargetChipSelector/TargetChipSelector.stories.tsx Removes per-story background parameters in favor of global theming.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .storybook/preview.js
Comment on lines +28 to +33
const withTheme = (Story, context) => {
const isDark = context.globals.theme === "dark";

useEffect(() => {
applyTheme(isDark);
}, [isDark]);
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

withTheme calls useEffect, but the function name is lowercase. With plugin:react-hooks/recommended enabled, this violates react-hooks/rules-of-hooks (hooks must be called from a React component or custom hook). Rename the decorator to an uppercase component name (e.g., WithTheme) or move the effect into a properly named custom hook, so lint/build doesn’t fail.

Copilot uses AI. Check for mistakes.
Comment thread .storybook/preview.js Outdated
Comment on lines +20 to +25
document.body.style.backgroundColor = isDark ? "#181a1f" : "";
document.body.style.color = isDark ? "#e2e4ea" : "";

document.querySelectorAll(".docs-story").forEach((el) => {
el.style.backgroundColor = isDark ? "#181a1f" : "";
});
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

applyTheme hard-codes background/text colors via inline styles. Since the app’s theming is already driven by CSS custom properties that switch on body.dark-mode, these inline overrides can drift from production colors and can accidentally override token-based styling. Prefer toggling only the dark-mode class and handling any Storybook-specific docs/canvas background tweaks in CSS (e.g., a Storybook-only stylesheet using the same tokens).

Suggested change
document.body.style.backgroundColor = isDark ? "#181a1f" : "";
document.body.style.color = isDark ? "#e2e4ea" : "";
document.querySelectorAll(".docs-story").forEach((el) => {
el.style.backgroundColor = isDark ? "#181a1f" : "";
});

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Replaced with variables, thanks!

@RachelElysia RachelElysia marked this pull request as draft April 13, 2026 19:44
@RachelElysia
Copy link
Copy Markdown
Member Author

RachelElysia commented Apr 14, 2026

  1. Theme event / localStorage missing
    Not an issue -- this is purely a Storybook visual toggle and the dark-mode class is what drives styles not what was set on the actual app
  2. applyTheme + useEffect
    Not an issue - applyTheme isn't a hook — it's a plain function. The useEffect is called in withTheme which is a React component (Storybook decorator).
  3. Icon component and .icon selector on DropdownButton
    The Icon component renders with class icon (that's the baseClass). So .dropdown-button .icon svg path does match — Icon wraps in a
    . CodeRabbit is wrong here, no action needed.
    --
    Summary: None of these are blocking. The variant="link" is already resolved via Fleet UI: Improve internal links/buttons #43470, the hook rules-of-hooks flag is a false positive, and the .icon selector concern is incorrect. The hard-coded colors and missing event dispatch are cosmetic Storybook-only concerns that I replaced with the same variables as used in our app.

@RachelElysia RachelElysia marked this pull request as ready for review April 14, 2026 19:39
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
frontend/components/buttons/DropdownButton/_styles.scss (1)

75-76: ⚠️ Potential issue | 🟡 Minor

Fix CSS keyword casing.

Upon re-examination of the Icon component structure (which wraps the SVG in a div with class icon), the selector .dropdown-button .icon svg path appears correct and should match the chevron markup. However, the CSS keyword casing needs correction.

🎨 Proposed fix
-.dropdown-button .icon svg path {
-  stroke: currentColor;
+.dropdown-button .icon svg path {
+  stroke: currentcolor;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/components/buttons/DropdownButton/_styles.scss` around lines 75 -
76, The CSS uses the wrong casing for the color keyword in the selector
.dropdown-button .icon svg path; update the declaration so the stroke uses the
correct CSS keyword casing (currentColor) instead of the lowercase variant to
ensure the SVG chevron inherits the icon color.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@frontend/components/buttons/DropdownButton/_styles.scss`:
- Around line 75-76: The CSS uses the wrong casing for the color keyword in the
selector .dropdown-button .icon svg path; update the declaration so the stroke
uses the correct CSS keyword casing (currentColor) instead of the lowercase
variant to ensure the SVG chevron inherits the icon color.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8a8e1e2d-63ac-4970-a0bb-22f376c3b026

📥 Commits

Reviewing files that changed from the base of the PR and between 4284fb0 and 16cca83.

📒 Files selected for processing (6)
  • .storybook/preview.js
  • frontend/components/LiveQuery/TargetChipSelector/TargetChipSelector.stories.tsx
  • frontend/components/TabNav/TabNav.stories.tsx
  • frontend/components/TeamsDropdown/TeamsDropdown.stories.tsx
  • frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx
  • frontend/components/buttons/DropdownButton/_styles.scss
💤 Files with no reviewable changes (3)
  • frontend/components/LiveQuery/TargetChipSelector/TargetChipSelector.stories.tsx
  • frontend/components/TabNav/TabNav.stories.tsx
  • frontend/components/buttons/DropdownButton/DropdownButton.stories.tsx
✅ Files skipped from review due to trivial changes (2)
  • frontend/components/TeamsDropdown/TeamsDropdown.stories.tsx
  • .storybook/preview.js

@RachelElysia RachelElysia merged commit f3976c9 into main Apr 14, 2026
19 checks passed
@RachelElysia RachelElysia deleted the storybook-dark-light branch April 14, 2026 20:31
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.

FE: Add dark mode to Storybook

4 participants