@atlaskit/tokens
Version:
Design tokens are the single source of truth to name and store design decisions.
146 lines (145 loc) • 5.45 kB
TypeScript
import type { ThemeState } from './theme-state';
/**
* Inputs for the dynamic colour themes. Every colour token is derived from these two colours.
*/
interface DynamicColorInputs {
dynamicForeground: string;
dynamicBackground: string;
}
/**
* Typed inputs for the experimental semantic spacing theme.
*/
type SpacingThemeInputs = {
/**
* Positive gap ramp multiplier. Defaults to 1.
*/
dynamicSpaceGapScale?: number;
/**
* Positive exponent controlling which gap sizes respond most. Defaults to 1.
*/
dynamicSpaceGapCurve?: number;
/**
* Between 0 (curved response) and 1 (uniform scaling). Defaults to 0.
*/
dynamicSpaceGapUniformity?: number;
/**
* Round calculated gaps to the nearest CSS pixel. Defaults to true.
*/
dynamicSpaceGapRound?: boolean;
/**
* Positive inset ramp multiplier. Defaults to 1.
*/
dynamicSpaceInsetScale?: number;
/**
* Positive exponent controlling which inset sizes respond most. Defaults to 1.
*/
dynamicSpaceInsetCurve?: number;
/**
* Between 0 (curved response) and 1 (uniform scaling). Defaults to 0.
*/
dynamicSpaceInsetUniformity?: number;
/**
* Round calculated insets to the nearest CSS pixel. Defaults to true.
*/
dynamicSpaceInsetRound?: boolean;
};
type HeadingSize = 'xxlarge' | 'xlarge' | 'large' | 'medium' | 'small' | 'xsmall' | 'xxsmall';
/**
* Optional unitless multipliers for individual heading sizes, applied on top of `dynamicFontScale`.
* Each defaults to `1`, e.g. `dynamicFontHeadingXxlargeScale: 1.5` makes only `xxlarge` headings
* larger.
*/
type HeadingScaleInputs = {
[Size in HeadingSize as `dynamicFontHeading${Capitalize<Size>}Scale`]?: number;
};
/**
* Optional line-height multipliers for individual heading sizes, applied on top of font, heading
* and global line-height scales without changing font sizes. Each defaults to `1`.
*/
type HeadingLineHeightScaleInputs = {
[Size in HeadingSize as `dynamicFontHeading${Capitalize<Size>}LineHeightScale`]?: number;
};
/**
* The variable contract for custom themes that support runtime overrides.
*
* Add a theme here when it is introduced. Its theme dimensions and required override values are
* then shared by TypeScript consumers.
*/
export interface CustomThemeOverrideRegistry {
'UNSAFE-spacing': {
spacing: SpacingThemeInputs;
};
'UNSAFE-dynamic': {
light: DynamicColorInputs;
};
'UNSAFE-dynamic-dark': {
dark: DynamicColorInputs;
};
'UNSAFE-typography': {
typography: {
/**
* A CSS `font-family` value. Applies to body, heading and brand text; code stays monospace.
*/
dynamicFontFamily: string;
/**
* Unitless multiplier for font sizes and line heights. `1` is the default scale.
*/
dynamicFontScale: number;
/**
* Optional multiplier for line heights, applied on top of font and heading scales without
* changing font sizes. Defaults to `1`.
*/
dynamicFontLineHeightScale?: number;
} & HeadingScaleInputs & HeadingLineHeightScaleInputs;
};
}
type ThemeOverrideKind = Exclude<keyof ThemeState, 'colorMode' | 'contrastMode' | 'UNSAFE_themeOptions'>;
type ThemeNamesForKind<Kind extends ThemeOverrideKind> = {
[ThemeName in keyof CustomThemeOverrideRegistry]: Kind extends keyof CustomThemeOverrideRegistry[ThemeName] ? ThemeName : never;
}[keyof CustomThemeOverrideRegistry];
type CustomThemeWithOverrides<Kind extends ThemeOverrideKind> = {
[ThemeName in ThemeNamesForKind<Kind>]: {
id: ThemeName;
overrides: CustomThemeOverrideRegistry[ThemeName][Kind & keyof CustomThemeOverrideRegistry[ThemeName]];
};
}[ThemeNamesForKind<Kind>];
type ThemeWithoutModes = Omit<ThemeState, 'colorMode' | 'contrastMode'>;
/**
* A theme configuration that can provide typed overrides alongside a custom theme ID.
*
* @example
* ```tsx
* <AppProvider defaultTheme={{
* light: {
* id: 'UNSAFE-dynamic',
* overrides: { dynamicForeground: '#172b4d', dynamicBackground: '#ffffff' },
* },
* dark: {
* id: 'UNSAFE-dynamic-dark',
* overrides: { dynamicForeground: '#ffffff', dynamicBackground: '#1d2125' },
* },
* }}
* />
* ```
*/
export type ThemeWithCustomOverrides = Partial<{
[Kind in keyof ThemeWithoutModes]: Kind extends ThemeOverrideKind ? ThemeWithoutModes[Kind] | CustomThemeWithOverrides<Kind> : ThemeWithoutModes[Kind];
}>;
/**
* Marks a subtree theme element with its provider's scope, so its override styles only match that
* element.
*/
export declare const CUSTOM_THEME_SCOPE_ATTRIBUTE = "data-theme-overrides-scope";
/**
* Separates custom theme override values from the plain theme IDs consumed by the theme runtime.
*
* Pass a `scope` for subtree themes. The override selector then only matches the element carrying
* `CUSTOM_THEME_SCOPE_ATTRIBUTE` with that value, so sibling subtrees using the same custom theme
* with different values don't overwrite each other. Without a scope, the styles target `html` and
* any subtree using the theme.
*/
export declare function getThemeAndOverrides(themeWithOverrides: ThemeWithCustomOverrides | undefined, scope?: string): {
theme: Partial<ThemeWithoutModes>;
inlineStyles: string;
};
export {};