UNPKG

12.8 kBTypeScriptView Raw
1import { OverridableStringUnion } from '@mui/types';
2import { SxConfig, SxProps, CSSObject, ApplyStyles } from '@mui/system';
3import { ExtractTypographyTokens } from '@mui/system/cssVars';
4import { ThemeOptions, Theme } from './createThemeNoVars';
5import { Palette, PaletteOptions } from './createPalette';
6import { Shadows } from './shadows';
7import { ZIndex } from './zIndex';
8import { Components } from './components';
9
10/**
11 * default MD color-schemes
12 */
13export type DefaultColorScheme = 'light' | 'dark';
14
15/**
16 * The application can add more color-scheme by extending this interface via module augmentation
17 *
18 * Ex.
19 * declare module @mui/material/styles {
20 * interface ColorSchemeOverrides {
21 * foo: true;
22 * }
23 * }
24 *
25 * // SupportedColorScheme = 'light' | 'dark' | 'foo';
26 */
27export interface ColorSchemeOverrides {}
28export type ExtendedColorScheme = OverridableStringUnion<never, ColorSchemeOverrides>;
29
30/**
31 * All color-schemes that the application has
32 */
33export type SupportedColorScheme = DefaultColorScheme | ExtendedColorScheme;
34
35export interface Opacity {
36 inputPlaceholder: number;
37 inputUnderline: number;
38 switchTrackDisabled: number;
39 switchTrack: number;
40}
41
42export type Overlays = [
43 string | undefined,
44 string | undefined,
45 string | undefined,
46 string | undefined,
47 string | undefined,
48 string | undefined,
49 string | undefined,
50 string | undefined,
51 string | undefined,
52 string | undefined,
53 string | undefined,
54 string | undefined,
55 string | undefined,
56 string | undefined,
57 string | undefined,
58 string | undefined,
59 string | undefined,
60 string | undefined,
61 string | undefined,
62 string | undefined,
63 string | undefined,
64 string | undefined,
65 string | undefined,
66 string | undefined,
67 string | undefined,
68];
69
70export interface PaletteBackgroundChannel {
71 defaultChannel: string;
72 paperChannel: string;
73}
74
75export interface PaletteCommonChannel {
76 background: string;
77 backgroundChannel: string;
78 onBackground: string;
79 onBackgroundChannel: string;
80}
81
82export interface PaletteColorChannel {
83 mainChannel: string;
84 lightChannel: string;
85 darkChannel: string;
86 contrastTextChannel: string;
87}
88
89export interface PaletteActionChannel {
90 activeChannel: string;
91 selectedChannel: string;
92}
93
94export interface PaletteTextChannel {
95 primaryChannel: string;
96 secondaryChannel: string;
97}
98
99export interface PaletteAlert {
100 errorColor: string;
101 infoColor: string;
102 successColor: string;
103 warningColor: string;
104 errorFilledBg: string;
105 infoFilledBg: string;
106 successFilledBg: string;
107 warningFilledBg: string;
108 errorFilledColor: string;
109 infoFilledColor: string;
110 successFilledColor: string;
111 warningFilledColor: string;
112 errorStandardBg: string;
113 infoStandardBg: string;
114 successStandardBg: string;
115 warningStandardBg: string;
116 errorIconColor: string;
117 infoIconColor: string;
118 successIconColor: string;
119 warningIconColor: string;
120}
121
122export interface PaletteAppBar {
123 defaultBg: string;
124 darkBg: string;
125 darkColor: string;
126}
127
128export interface PaletteAvatar {
129 defaultBg: string;
130}
131
132export interface PaletteButton {
133 inheritContainedBg: string;
134 inheritContainedHoverBg: string;
135}
136
137export interface PaletteChip {
138 defaultBorder: string;
139 defaultAvatarColor: string;
140 defaultIconColor: string;
141}
142
143export interface PaletteFilledInput {
144 bg: string;
145 hoverBg: string;
146 disabledBg: string;
147}
148
149export interface PaletteLinearProgress {
150 primaryBg: string;
151 secondaryBg: string;
152 errorBg: string;
153 infoBg: string;
154 successBg: string;
155 warningBg: string;
156}
157
158export interface PaletteSkeleton {
159 bg: string;
160}
161
162export interface PaletteSlider {
163 primaryTrack: string;
164 secondaryTrack: string;
165 errorTrack: string;
166 infoTrack: string;
167 successTrack: string;
168 warningTrack: string;
169}
170
171export interface PaletteSnackbarContent {
172 bg: string;
173 color: string;
174}
175
176export interface PaletteSpeedDialAction {
177 fabHoverBg: string;
178}
179
180export interface PaletteStepConnector {
181 border: string;
182}
183
184export interface PaletteStepContent {
185 border: string;
186}
187
188export interface PaletteSwitch {
189 defaultColor: string;
190 defaultDisabledColor: string;
191 primaryDisabledColor: string;
192 secondaryDisabledColor: string;
193 errorDisabledColor: string;
194 infoDisabledColor: string;
195 successDisabledColor: string;
196 warningDisabledColor: string;
197}
198
199export interface PaletteTableCell {
200 border: string;
201}
202
203export interface PaletteTooltip {
204 bg: string;
205}
206
207// The Palette should be sync with `../themeCssVarsAugmentation/index.d.ts`
208export interface ColorSystemOptions {
209 palette?: PaletteOptions & {
210 background?: Partial<PaletteBackgroundChannel>;
211 common?: Partial<PaletteCommonChannel>;
212 primary?: Partial<PaletteColorChannel>;
213 secondary?: Partial<PaletteColorChannel>;
214 error?: Partial<PaletteColorChannel>;
215 info?: Partial<PaletteColorChannel>;
216 success?: Partial<PaletteColorChannel>;
217 text?: Partial<PaletteTextChannel>;
218 dividerChannel?: Partial<string>;
219 action?: Partial<PaletteActionChannel>;
220 Alert?: Partial<PaletteAlert>;
221 AppBar?: Partial<PaletteAppBar>;
222 Avatar?: Partial<PaletteAvatar>;
223 Button?: Partial<PaletteButton>;
224 Chip?: Partial<PaletteChip>;
225 FilledInput?: Partial<PaletteFilledInput>;
226 LinearProgress?: Partial<PaletteLinearProgress>;
227 Skeleton?: Partial<PaletteSkeleton>;
228 Slider?: Partial<PaletteSlider>;
229 SnackbarContent?: Partial<PaletteSnackbarContent>;
230 SpeedDialAction?: Partial<PaletteSpeedDialAction>;
231 StepConnector?: Partial<PaletteStepConnector>;
232 StepContent?: Partial<PaletteStepContent>;
233 Switch?: Partial<PaletteSwitch>;
234 TableCell?: Partial<PaletteTableCell>;
235 Tooltip?: Partial<PaletteTooltip>;
236 };
237 opacity?: Partial<Opacity>;
238 overlays?: Overlays;
239}
240
241export interface CssVarsPalette {
242 common: PaletteCommonChannel;
243 primary: PaletteColorChannel;
244 secondary: PaletteColorChannel;
245 error: PaletteColorChannel;
246 info: PaletteColorChannel;
247 success: PaletteColorChannel;
248 warning: PaletteColorChannel;
249 text: PaletteTextChannel;
250 background: PaletteBackgroundChannel;
251 dividerChannel: string;
252 action: PaletteActionChannel;
253 Alert: PaletteAlert;
254 AppBar: PaletteAppBar;
255 Avatar: PaletteAvatar;
256 Button: PaletteButton;
257 Chip: PaletteChip;
258 FilledInput: PaletteFilledInput;
259 LinearProgress: PaletteLinearProgress;
260 Skeleton: PaletteSkeleton;
261 Slider: PaletteSlider;
262 SnackbarContent: PaletteSnackbarContent;
263 SpeedDialAction: PaletteSpeedDialAction;
264 StepConnector: PaletteStepConnector;
265 StepContent: PaletteStepContent;
266 Switch: PaletteSwitch;
267 TableCell: PaletteTableCell;
268 Tooltip: PaletteTooltip;
269}
270
271export interface ColorSystem {
272 palette: Palette & CssVarsPalette;
273 opacity: Opacity;
274 overlays: Overlays;
275}
276
277export interface CssVarsThemeOptions extends Omit<ThemeOptions, 'palette' | 'components'> {
278 /**
279 * @default 'light'
280 */
281 defaultColorScheme?: SupportedColorScheme;
282 /**
283 * Prefix of the generated CSS variables
284 * @default 'mui'
285 */
286 cssVarPrefix?: string;
287 /**
288 * Theme components
289 */
290 components?: Components<Omit<Theme, 'components' | 'palette'> & CssVarsTheme>;
291 /**
292 * Color schemes configuration
293 */
294 colorSchemes?: Partial<Record<DefaultColorScheme, boolean | ColorSystemOptions>> &
295 (ExtendedColorScheme extends string ? Record<ExtendedColorScheme, ColorSystemOptions> : {});
296 /**
297 * The strategy to generate CSS variables
298 *
299 * @example 'media'
300 * Generate CSS variables using [prefers-color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme)
301 *
302 * @example '.mode-%s'
303 * Generate CSS variables within a class .mode-light, .mode-dark
304 *
305 * @example '[data-mode-%s]'
306 * Generate CSS variables within a data attribute [data-mode-light], [data-mode-dark]
307 */
308 colorSchemeSelector?: 'media' | 'class' | 'data' | string;
309 /**
310 * The selector to generate the global CSS variables (non-color-scheme related)
311 * @default ':root'
312 * @example ':host' // (for shadow DOM)
313 * @see https://mui.com/material-ui/customization/shadow-dom/#3-css-theme-variables-optional
314 */
315 rootSelector?: string;
316 /**
317 * If `true`, the CSS color-scheme will not be set.
318 * https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme
319 * @default false
320 */
321 disableCssColorScheme?: boolean;
322 /**
323 * A function to determine if the key, value should be attached as CSS Variable
324 * `keys` is an array that represents the object path keys.
325 * Ex, if the theme is { foo: { bar: 'var(--test)' } }
326 * then, keys = ['foo', 'bar']
327 * value = 'var(--test)'
328 */
329 shouldSkipGeneratingVar?: (keys: string[], value: string | number) => boolean;
330}
331
332// should not include keys defined in `shouldSkipGeneratingVar` and have value typeof function
333export interface ThemeVars {
334 font: ExtractTypographyTokens<Theme['typography']>;
335 palette: Omit<
336 ColorSystem['palette'],
337 | 'colorScheme'
338 | 'mode'
339 | 'contrastThreshold'
340 | 'tonalOffset'
341 | 'getContrastText'
342 | 'augmentColor'
343 >;
344 opacity: Opacity;
345 overlays: Overlays;
346 shadows: Shadows;
347 shape: Theme['shape'];
348 spacing: string;
349 zIndex: ZIndex;
350}
351
352type Split<T, K extends keyof T = keyof T> = K extends string | number
353 ? { [k in K]: Exclude<T[K], undefined> }
354 : never;
355
356type ConcatDeep<T> =
357 T extends Record<string | number, infer V>
358 ? keyof T extends string | number
359 ? V extends string | number
360 ? keyof T
361 : keyof V extends string | number
362 ? `${keyof T}-${ConcatDeep<Split<V>>}`
363 : never
364 : never
365 : never;
366
367/**
368 * Does not work for these cases:
369 * - { borderRadius: string | number } // the value can't be a union
370 * - { shadows: [string, string, ..., string] } // the value can't be an array
371 */
372type NormalizeVars<T> = ConcatDeep<Split<T>>;
373
374// shut off automatic exporting for the Generics above
375export {};
376
377export interface ThemeCssVarOverrides {}
378
379export type ThemeCssVar = OverridableStringUnion<
380 | NormalizeVars<Omit<ThemeVars, 'overlays' | 'shadows' | 'shape'>>
381 | 'shape-borderRadius'
382 | 'shadows-0'
383 | 'shadows-1'
384 | 'shadows-2'
385 | 'shadows-3'
386 | 'shadows-4'
387 | 'shadows-5'
388 | 'shadows-6'
389 | 'shadows-7'
390 | 'shadows-8'
391 | 'shadows-9'
392 | 'shadows-10'
393 | 'shadows-11'
394 | 'shadows-12'
395 | 'shadows-13'
396 | 'shadows-14'
397 | 'shadows-15'
398 | 'shadows-16'
399 | 'shadows-17'
400 | 'shadows-18'
401 | 'shadows-19'
402 | 'shadows-20'
403 | 'shadows-21'
404 | 'shadows-22'
405 | 'shadows-23'
406 | 'shadows-24'
407 | 'overlays-0'
408 | 'overlays-1'
409 | 'overlays-2'
410 | 'overlays-3'
411 | 'overlays-4'
412 | 'overlays-5'
413 | 'overlays-6'
414 | 'overlays-7'
415 | 'overlays-8'
416 | 'overlays-9'
417 | 'overlays-10'
418 | 'overlays-11'
419 | 'overlays-12'
420 | 'overlays-13'
421 | 'overlays-14'
422 | 'overlays-15'
423 | 'overlays-16'
424 | 'overlays-17'
425 | 'overlays-18'
426 | 'overlays-19'
427 | 'overlays-20'
428 | 'overlays-21'
429 | 'overlays-22'
430 | 'overlays-23'
431 | 'overlays-24',
432 ThemeCssVarOverrides
433>;
434
435/**
436 * Theme properties generated by extendTheme and CssVarsProvider
437 */
438export interface CssVarsTheme extends ColorSystem {
439 colorSchemes: Partial<Record<SupportedColorScheme, ColorSystem>>;
440 rootSelector: string;
441 colorSchemeSelector: 'media' | 'class' | 'data' | string;
442 cssVarPrefix: string;
443 defaultColorScheme: SupportedColorScheme;
444 vars: ThemeVars;
445 getCssVar: (field: ThemeCssVar, ...vars: ThemeCssVar[]) => string;
446 getColorSchemeSelector: (colorScheme: SupportedColorScheme) => string;
447 generateThemeVars: () => ThemeVars;
448 generateStyleSheets: () => Array<Record<string, any>>;
449 generateSpacing: () => Theme['spacing'];
450
451 // Default theme tokens
452 spacing: Theme['spacing'];
453 breakpoints: Theme['breakpoints'];
454 shape: Theme['shape'];
455 typography: Theme['typography'];
456 transitions: Theme['transitions'];
457 shadows: Theme['shadows'];
458 mixins: Theme['mixins'];
459 zIndex: Theme['zIndex'];
460 direction: Theme['direction'];
461 /**
462 * A function to determine if the key, value should be attached as CSS Variable
463 * `keys` is an array that represents the object path keys.
464 * Ex, if the theme is { foo: { bar: 'var(--test)' } }
465 * then, keys = ['foo', 'bar']
466 * value = 'var(--test)'
467 */
468 shouldSkipGeneratingVar: (keys: string[], value: string | number) => boolean;
469 unstable_sxConfig: SxConfig;
470 unstable_sx: (props: SxProps<CssVarsTheme>) => CSSObject;
471 applyStyles: ApplyStyles<SupportedColorScheme>;
472}
473
474/**
475 * Generate a theme base on the options received.
476 * @param options Takes an incomplete theme object and adds the missing parts.
477 * @param args Deep merge the arguments with the about to be returned theme.
478 * @returns A complete, ready-to-use theme object.
479 */
480export default function createThemeWithVars(
481 options?: CssVarsThemeOptions,
482 ...args: object[]
483): Omit<Theme, 'applyStyles'> & CssVarsTheme;