Skip to content

Commit 7ec79a7

Browse files
committed
add css resolver to docs
1 parent 5473ba5 commit 7ec79a7

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

web/docs/panel/extensions/concepts/theming.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,59 @@ Anything Mantine already models: `colors` (including a custom 10-shade palette),
5858
Setting a component's `defaultProps` in the theme is usually a cleaner way to restyle a whole class of component than a props interceptor. If all you want is "every `Button` defaults to `variant='light'`", the theme is the simpler tool. Reach for an interceptor only when the change depends on the incoming props.
5959
:::
6060

61+
## The CSS Variables Resolver
62+
63+
The theme object and a static `app.css` sit at two extremes: the theme is fully theme-aware but only reaches what Mantine models, while `app.css` reaches any variable but is static - it can't see your palette or react to it. The resolver is the bridge. `initializeMantineCssResolver()` hands you the resolved theme and lets you compute CSS variables from it, so your values stay in lockstep with the palette, `primaryColor`, and the active color scheme.
64+
65+
Override it on your `Extension` class. Most extensions don't need it, so the default returns `null` (contribute nothing):
66+
67+
```ts
68+
import { Extension, ExtensionContext } from 'shared';
69+
import type { CSSVariablesResolver } from '@mantine/core';
70+
71+
class MyExtension extends Extension {
72+
public initializeMantineCssResolver(ctx: ExtensionContext): CSSVariablesResolver | null {
73+
return (theme) => {
74+
const brand = theme.colors[theme.primaryColor];
75+
76+
return {
77+
variables: {},
78+
dark: {
79+
'--chart-series-1-border': brand[4],
80+
'--chart-series-1-fill': brand[8],
81+
},
82+
light: {
83+
'--chart-series-1-border': brand[6],
84+
'--chart-series-1-fill': brand[2],
85+
},
86+
};
87+
};
88+
}
89+
}
90+
91+
export default new MyExtension();
92+
```
93+
94+
A resolver returns three buckets:
95+
96+
- **`variables`** - emitted regardless of color scheme.
97+
- **`light`** - emitted under the light scheme only.
98+
- **`dark`** - emitted under the dark scheme only.
99+
100+
The Panel feeds the result into the top-level `MantineProvider`'s `cssVariablesResolver`, which renders the variables into a `<style>` tag scoped by scheme. Because the values come from `theme`, a later extension that changes `primaryColor` in `initializeMantineTheme()` automatically reshades everything your resolver derived from it - no second edit on your side.
101+
102+
### How resolvers combine
103+
104+
Like `initializeMantineTheme()`, this runs once per installed extension at load. Each resolver is called with the **already-merged** theme - every extension's `initializeMantineTheme()` override is folded in first - so you derive from the final palette, not your own slice of it. The Panel then merges the returned buckets in installation order, per variable: two extensions writing different variables both take effect; two writing the same one is last-writer-wins. Returning `null` opts out cleanly and adds nothing to the merge.
105+
106+
::: info
107+
The resolver sees the merged theme but runs separately from it. If your variable is purely theme-derived and Mantine already models the target (a palette shade, a spacing value), set it in `initializeMantineTheme()` instead - the resolver is for variables Mantine *doesn't* model but that you still want computed from the theme, like the chart colors above.
108+
:::
109+
110+
::: info
111+
Reach for the resolver over `app.css` only when the value has to track the theme. A fixed `--chart-grid-color: #2a2a2a` belongs in `app.css`; a chart series color derived from `theme.colors[theme.primaryColor]` belongs here, so it follows palette changes and both schemes for free.
112+
:::
113+
61114
## CSS Variables and Tailwind Tokens
62115

63116
Below the theme object sits a layer of raw CSS custom properties. The Panel resolves Mantine's theme into `--mantine-color-*` variables on `:root`, scoped by color scheme through the `[data-mantine-color-scheme="dark"]` / `[data-mantine-color-scheme="light"]` attributes. It also defines its own tokens - the font stack, server-status colors, chart colors - in its `app.css`.

web/docs/panel/extensions/file-structure.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ class Dev0x7d8TestExtension extends Extension {
6969
return {};
7070
}
7171

72+
// Your extension can also provide a resolver for css variables, this runs when the page is loaded
73+
public initializeMantineCssResolver(ctx: ExtensionContext): CSSVariablesResolver | null {
74+
return null;
75+
}
76+
7277
/**
7378
* Your extension call processor, this can be called by other extensions to interact with yours,
7479
* if the call does not apply to your extension, simply return `ctx.skip()` to continue the matching process.

0 commit comments

Comments
 (0)