blob: 29d073dcfcf8300d96e9c5ff43d57ce9d7c0eca7 [file] [log] [blame]
// gentheme generates the token values for a CSS theme.
//
import {
argbFromHex,
hexFromArgb,
MaterialDynamicColors,
Hct,
SchemeTonalSpot,
DynamicScheme,
TonalPalette,
sanitizeDegreesDouble,
} from '@material/material-color-utilities';
// Create our own Scheme.
//
// This is essentially a copy of the Material Color Utilities SchemaTonalSpot,
// which is the default Material You theme on Android 12 and 13, but with the
// addition of a secondary color that also has a Chroma of 36, just like the
// primary color.
class MySchemeTonalSpot extends DynamicScheme {
constructor(
sourceColorHct: Hct,
secondaryColorHct: Hct,
isDark: boolean,
contrastLevel: number
) {
super({
sourceColorArgb: sourceColorHct.toInt(),
variant: 2, // Variant.TONAL_SPOT,
contrastLevel,
isDark,
primaryPalette: TonalPalette.fromHueAndChroma(sourceColorHct.hue, 36.0),
secondaryPalette: TonalPalette.fromHueAndChroma(
secondaryColorHct.hue,
36.0
),
tertiaryPalette: TonalPalette.fromHueAndChroma(
sanitizeDegreesDouble(sourceColorHct.hue + 60.0),
24.0
),
neutralPalette: TonalPalette.fromHueAndChroma(sourceColorHct.hue, 6.0),
neutralVariantPalette: TonalPalette.fromHueAndChroma(
sourceColorHct.hue,
8.0
),
});
}
}
/** Generates a theme as a CSS string that defines CSS variables with all the
* colors used in the Skia Infra theme starting from two colors that are passed
* in as hex string values, e.g. "#009900".
*
* See //infra-sk/theme.scss for how the tokens are used.
*/
export const gentheme = (primary: string, secondary: string): string => {
const primarySeed = argbFromHex(primary);
const secondarySeed = argbFromHex(secondary);
const darkScheme = new MySchemeTonalSpot(
Hct.fromInt(primarySeed),
Hct.fromInt(secondarySeed),
true,
0.4
);
const lightScheme = new MySchemeTonalSpot(
Hct.fromInt(primarySeed),
Hct.fromInt(secondarySeed),
false,
0.4
);
// prettier-ignore
const tokensFromDynamicScheme = (selectors: string, scheme: SchemeTonalSpot) => `${selectors} {
--background: ${hexFromArgb(MaterialDynamicColors.background.getArgb(scheme))};
--disabled: ${hexFromArgb(MaterialDynamicColors.surfaceVariant.getArgb(scheme))};
--error: ${hexFromArgb(MaterialDynamicColors.error.getArgb(scheme))};
--error-container: ${hexFromArgb(MaterialDynamicColors.errorContainer.getArgb(scheme))};
--on-error-container: ${hexFromArgb(MaterialDynamicColors.onErrorContainer.getArgb(scheme))};
--on-background: ${hexFromArgb(MaterialDynamicColors.onBackground.getArgb(scheme))};
--on-disabled: ${hexFromArgb(MaterialDynamicColors.onSurfaceVariant.getArgb(scheme))};
--on-error: ${hexFromArgb(MaterialDynamicColors.onError.getArgb(scheme))};
--on-primary: ${hexFromArgb(MaterialDynamicColors.onPrimary.getArgb(scheme))};
--on-secondary: ${hexFromArgb(MaterialDynamicColors.onSecondary.getArgb(scheme))};
--on-surface: ${hexFromArgb(MaterialDynamicColors.onSurface.getArgb(scheme))};
--primary: ${hexFromArgb(MaterialDynamicColors.primary.getArgb(scheme))};
--secondary: ${hexFromArgb(MaterialDynamicColors.secondary.getArgb(scheme))};
--surface: ${hexFromArgb(MaterialDynamicColors.surfaceContainer.getArgb(scheme))};
--surface-1dp: ${hexFromArgb(MaterialDynamicColors.surfaceContainerHigh.getArgb(scheme))};
--surface-2dp: ${hexFromArgb(MaterialDynamicColors.surfaceContainerHighest.getArgb(scheme))};
--outline: ${hexFromArgb(MaterialDynamicColors.outline.getArgb(scheme))};
--primary-highlight: ${hexFromArgb(MaterialDynamicColors.primaryContainer.getArgb(scheme))};
--on-primary-highlight: ${hexFromArgb(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme))};
--secondary-highlight: ${hexFromArgb(MaterialDynamicColors.secondaryContainer.getArgb(scheme))};
--on-hightlight: ${hexFromArgb(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme))};
--on-secondary-highlight: ${hexFromArgb(MaterialDynamicColors.onSecondaryContainer.getArgb(scheme))};
--primary-variant: ${hexFromArgb(MaterialDynamicColors.primaryContainer.getArgb(scheme))};
--on-primary-variant: ${hexFromArgb(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme))};
--surface-1dp: ${hexFromArgb(MaterialDynamicColors.surfaceContainerHigh.getArgb(scheme))};
--surface-2dp: ${hexFromArgb(MaterialDynamicColors.surfaceContainerHighest.getArgb(scheme))};
}`;
// Format as CSS and not SCSS so that the output can be used directly in the
// theme-chooser-sk demo page.
return `/* prettier-ignore */
${tokensFromDynamicScheme('.body-sk', lightScheme)}
/* prettier-ignore */
${tokensFromDynamicScheme('.body-sk.darkmode,.body-sk .darkmode', darkScheme)}`;
};