ApollionProvider
Purpose
The ApollionProvider supplies standardized color, spacing, density, and
surface (positive/negative) to all child components
via the styled-components ThemeProvider.
As of v4.0.0 the provider is the only entry point — there is no more
legacy ThemeProvider nor a defaultTheme separate from createTheme.
All configuration enters here.
Implementation
Creating a theme is optional — without props, the ApollionProvider uses
Apollion's default theme.
import { ApollionProvider } from '@apollion-dsi/core/themes';
render(
<ApollionProvider>
<App />
</ApollionProvider>,
document.getElementById('#root'),
);With a custom theme
import { ApollionProvider, createTheme } from '@apollion-dsi/core/themes';
const theme = createTheme({ colors: { main: '#003750' /* ... */ } });
<ApollionProvider theme={theme}>
<App />
</ApollionProvider>;Details: see createTheme.
With density
Apply a different density for dashboards, marketing pages, or any scenario that calls for tighter or airier paddings/gaps.
compact
normal
spacious
import { ApollionProvider } from '@apollion-dsi/core/themes';
<ApollionProvider dimension="compact"> {/* tighter — dashboards */}
<App />
</ApollionProvider>
<ApollionProvider dimension="normal"> {/* default — general */}
<App />
</ApollionProvider>
<ApollionProvider dimension="spacious"> {/* looser — marketing */}
<App />
</ApollionProvider>The prop is declarative at the provider boundary — no hook and no imperative getter. See Dimensions.
Dark mode — the engine owns it
Pass a single colors config and the provider derives both themes itself
— light as given, dark via the canonical seed swap (baseLight↔baseDark,
deepLight↔deepDark; brand/feedback slots stay fixed) plus the mode-aware
surface ladder. Declare the mode preference (defaultMode="system" follows
prefers-color-scheme), optionally persist it, and the engine writes
data-apollion-mode + color-scheme on <html>: every color is a
light-dark() pair, so the flip is an attribute change — no re-render, no
flash. The accessibility presets are an independent axis (a11y) that
composes with either mode. Full contract: Dark Mode Engine.
Current mode: light
Same brand palette; base contrast flips between light/dark.import { ApollionProvider } from '@apollion-dsi/core/themes';
const colors = {
main: '#003750',
/* brand/feedback slots… — the contrast anchors default to the stock ladder seeds */
};
<ApollionProvider colors={colors} defaultMode="system" persist="localStorage" a11y={null}>
<App />
</ApollionProvider>;Manual light/dark pair (escape hatch)
For a non-canonical dark theme (a hand-tuned dark palette that is not just
the contrast swap), build the two themes yourself and pass them as
lightTheme/darkTheme — they take precedence over colors. The
toDarkColors helper is still available if you only want to swap the contrast
axes explicitly.
import { ApollionProvider, createTheme } from '@apollion-dsi/core/themes';
import { toDarkColors } from '@apollion-dsi/core/themes/colors';
const lightTheme = createTheme({ colors });
const darkTheme = createTheme({ colors: toDarkColors(colors) });
<ApollionProvider lightTheme={lightTheme} darkTheme={darkTheme} defaultMode="system">
<App />
</ApollionProvider>;With surface inversion
<ApollionProvider surface="negative">
<App />
</ApollionProvider>For subtrees, prefer <SurfaceProvider surface="negative"> (more
common — "dark card on light page"). See
Surface Inversion.
ApollionProvider API
| Property | Type | Default | Description |
|---|---|---|---|
| theme | Theme (optional) | createTheme() | Pre-built theme via createTheme(). When absent + dimension provided, the theme is built on-the-fly. |
| colors | ColorsInput (optional) | — | Single light-mode color config; the engine derives light + dark (canonical swap) itself. Ignored when theme/lightTheme/darkTheme is passed. |
| dimension | 'compact' | 'normal' | 'spacious' (optional) | 'normal' | Density applied to paddings/gaps. See Dimensions. |
| surface | 'positive' | 'negative' (optional) | 'positive' | Inverts the foundation if 'negative'. For subtrees prefer <SurfaceProvider>. |
| lightTheme / darkTheme | Theme (optional) | — | Pre-built pair for a non-canonical dark theme (escape hatch); wins over colors. Resolved via useSystemPreference or toggleTheme. |
| mode | 'light' | 'dark' | 'system' (optional) | — | Controlled mode preference; 'system' follows prefers-color-scheme. The parent is the source of truth (setMode only fires onModeChange). |
| defaultMode | 'light' | 'dark' | 'system' (optional) | 'light' | Uncontrolled initial preference; restored from persist when stored. |
| initialMode | 'light' | 'dark' (optional) | — | SSR contract: what the server rendered (e.g. readModeFromCookie). Server and first client render agree; the preference is applied before paint. |
| persist | false | 'localStorage' | 'cookie' | ModeStorage | false | Persist mode (under storageKey) and a11y (under `${storageKey}-a11y`). Pair with <ApollionModeScript /> for a no-flash first paint. |
| storageKey | string (optional) | 'apollion-mode' | Storage key of the preference. |
| syncDocument | boolean (optional) | true | Writes data-apollion-mode, data-apollion-a11y and style.colorScheme on <html> — the switch every light-dark() pair resolves from. |
| attribute | string (optional) | 'data-apollion-mode' | Attribute name written by syncDocument. |
| a11y | null | 'grayscale' | 'high-contrast' | 'colorblind' (optional) | — | Controlled accessibility preset — orthogonal to the mode; the preset remaps the seeds, the engine still derives light + dark. |
| defaultA11y | same as a11y (optional) | null | Uncontrolled initial preset; restored from persist. |
| onModeChange / onA11yChange | callbacks (optional) | — | Fired by setMode / setA11y with the new preference / preset. |
| useSystemPreference | boolean (optional) | false | Deprecated (5.7.0) — alias of defaultMode="system". |
| themeMode / onThemeModeChange | 'light' | 'dark' / callback (optional) | — | Deprecated (5.7.0) — controlled mode without 'system'; the callback receives the resolved mode. |