Skip to content

Add support for dark theme #87

Description

@Arthurk12

Is your feature request related to a problem? Please describe.
bigbluebutton/bigbluebutton#25763 (merged into v4.1.x-develop) replaces DarkReader with a native CSS dark theme: data-theme="dark" on <html>, plus public/stylesheets/theme-dark.css, which redefines CSS custom properties under :root[data-theme='dark']. Until now, plugins didn't have to think about dark mode, because DarkReader inverted the whole rendered document, plugin DOM included. Once 4.1 ships, plugins stop getting that inversion and render with light colors on a dark client, unless their styles react to the theme. Plugins don't get React context from the client, so each plugin has to be dark-aware on its own.

Current state of this library:

  1. Library components are only partly covered, and by accident. src/stylesheets/palette.ts resolves every color as var(--<token>, <light fallback>). theme-dark.css overrides some of those tokens (--color-background-white, --color-light-gray, --color-text-default, --color-neutral-3, --color-neutral-2, --default-border, --color-blue-aux, --color-overlay, --color-gray), but not others, and those keep their light values in dark mode. Some examples: --color-neutral-white, --color-neutral-4, --color-hover-light, --color-hover-dark, --color-background-blue, --color-brand-aux, --color-text-light, --color-icon-default, --color-icon-white, --color-border-focus-ring, --color-shadow-default.
  2. The dark values live in the wrong repo. The only dark values for this library's tokens are in a "BBButton Library" section of the client's theme-dark.css. Adding a token or component here means a coordinated change in the core, and the library can't be checked in dark mode on its own (Storybook has no dark theme).
  3. Plugin-owned UI gets no help at all. Plugins also have their own styled-components (containers, cards, lists, text). With no dark palette exported here, every plugin will hand-roll its own [data-theme='dark'] overrides and hex values. That means duplicated work, inconsistent colors across plugins, and a bug for every plugin that doesn't do it before 4.1.
  4. Theme detection is inconsistent. Toggle/styles.ts uses theme.applyStyles('dark', …) (MUI color scheme). That depends on the host's MUI theme, not on data-theme on <html>, so it doesn't follow the new client mechanism.

Describe the solution you'd like
The library should own a light + dark palette that follows the core's data-theme contract, so dark mode is solved once for every plugin:

  • Dark values for every token in palette.ts, applied under [data-theme='dark']. The library would ship this as a stylesheet or a global style/injector that plugins mount once.
  • Keep the host-override chain. Each dark token should still resolve the client's variable first (e.g. var(--color-background-white, <lib dark default>)), so the client, or a custom-branded deployment, can still restyle both themes.
  • Split tokens by role like the core (surface / text / border) wherever one light color maps to different dark colors depending on how it's used, and rewrite the components to use the role-specific token.
  • Document the palette as the way plugins style their own UI. colors is already exported (package root and @bigbluebutton/bbb-ui-components-react/colors) but undocumented; plugins that build on it get dark mode for free.
  • Replace ad-hoc dark handling (theme.applyStyles('dark', …) in Toggle) with the token-based approach, so there's only one source of truth.
  • Add a Storybook dark-mode toggle (set data-theme="dark" on the preview <html>) so every component can be checked in both themes.

Acceptance criteria:

  • Every color token exported by the library has a dark value that applies when <html data-theme="dark"> is set, without needing DarkReader or client-side overrides.
  • Host CSS variables still take precedence in both themes.
  • All components render correctly in dark mode in Storybook.
  • Palette usage for plugins is documented in the README.
  • No component depends on the MUI color scheme to detect dark mode.

Describe alternatives you've considered

  • Each plugin handles dark mode itself ([data-theme='dark'] overrides or listening to darkmodechange): duplicated effort, colors drift between plugins, and every plugin that doesn't do it before 4.1 regresses.
  • Keep the library's dark values in the core's theme-dark.css (as it is today): it couples library releases to core changes, leaves plugin-owned UI uncovered, and makes dark mode impossible to check in this repo.

Affected component(s)
All components (shared palette in src/stylesheets/palette.ts / colors.ts); BBBToggle in particular because of its MUI-based dark handling.

Proposed API / Usage Example

import { colors } from '@bigbluebutton/bbb-ui-components-react/colors';

// Plugin-owned styles follow the client theme automatically
const Card = styled.div`
  background: ${colors.background.white};
  color: ${colors.text.default};
  border: 1px solid ${colors.border.default};
`;

Screenshots or mockups
N/A

Additional context

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions