mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-07 21:41:46 +08:00
72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import { rgba, lighten, darken } from 'polished';
|
|
import { window } from 'global';
|
|
|
|
import { logger } from '@storybook/client-logger';
|
|
|
|
export const mkColor = (color: string) => ({ color });
|
|
|
|
// Check if it is a string. This is for the sake of warning users
|
|
// and the successive guarding logics that use String methods.
|
|
const isColorString = (color: string) => {
|
|
if (typeof color !== 'string') {
|
|
logger.warn(
|
|
`Color passed to theme object should be a string. Instead ` +
|
|
`${color}(${typeof color}) was passed.`
|
|
);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
// Passing arguments that can't be converted to RGB such as linear-gradient
|
|
// to library polished's functions such as lighten or darken throws the error
|
|
// that crashes the entire storybook. It needs to be guarded when arguments
|
|
// of those functions are from user input.
|
|
const isValidColorForPolished = (color: string) => {
|
|
return !/(gradient|var|calc)/.test(color);
|
|
};
|
|
|
|
const applyPolished = (type: string, color: string) => {
|
|
if (type === 'darken') {
|
|
return rgba(`${darken(1, color)}`, 0.95);
|
|
}
|
|
|
|
if (type === 'lighten') {
|
|
return rgba(`${lighten(1, color)}`, 0.95);
|
|
}
|
|
|
|
return color;
|
|
};
|
|
|
|
const colorFactory = (type: string) => (color: string) => {
|
|
if (!isColorString(color)) {
|
|
return color;
|
|
}
|
|
|
|
if (!isValidColorForPolished(color)) {
|
|
return color;
|
|
}
|
|
|
|
// Guard anything that is not working with polished.
|
|
try {
|
|
return applyPolished(type, color);
|
|
} catch (error) {
|
|
return color;
|
|
}
|
|
};
|
|
|
|
export const lightenColor = colorFactory('lighten');
|
|
export const darkenColor = colorFactory('darken');
|
|
|
|
// The default color scheme is light so unless the preferred color
|
|
// scheme is set to dark we always want to use the light theme
|
|
export const getPreferredColorScheme = () => {
|
|
if (!window || !window.matchMedia) return 'light';
|
|
|
|
const isDarkThemePreferred = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
if (isDarkThemePreferred) return 'dark';
|
|
|
|
return 'light';
|
|
};
|