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:
- 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.
- 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).
- 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.
- 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:
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
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>, pluspublic/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:
src/stylesheets/palette.tsresolves every color asvar(--<token>, <light fallback>).theme-dark.cssoverrides 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.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).[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.Toggle/styles.tsusestheme.applyStyles('dark', …)(MUI color scheme). That depends on the host's MUI theme, not ondata-themeon<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-themecontract, so dark mode is solved once for every plugin:palette.ts, applied under[data-theme='dark']. The library would ship this as a stylesheet or a global style/injector that plugins mount once.var(--color-background-white, <lib dark default>)), so the client, or a custom-branded deployment, can still restyle both themes.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.colorsis already exported (package root and@bigbluebutton/bbb-ui-components-react/colors) but undocumented; plugins that build on it get dark mode for free.theme.applyStyles('dark', …)in Toggle) with the token-based approach, so there's only one source of truth.data-theme="dark"on the preview<html>) so every component can be checked in both themes.Acceptance criteria:
<html data-theme="dark">is set, without needing DarkReader or client-side overrides.Describe alternatives you've considered
[data-theme='dark']overrides or listening todarkmodechange): duplicated effort, colors drift between plugins, and every plugin that doesn't do it before 4.1 regresses.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
Screenshots or mockups
N/A
Additional context
bigbluebutton-html5/public/stylesheets/theme-dark.css(v4.1.x-develop)theme-dark.cssin the core can be dropped or slimmed down (follow-up there).