我正在尝试为我的样式组件实现一种可选的样式覆盖。
目前我有这个:
这是一个函数,将会将我改变的样式与主题中的默认样式合并。
const mergeComponentTheme = <T extends object>(mode: ThemeMode, defaultTheme: T, overridingTheme?: CustomComponentStyle<T>): T => {
return Object.keys(defaultTheme).reduce<T>((previousValue, currentValue) => {
const property = currentValue as keyof T;
const themeMode = mode as keyof typeof overridingTheme;
const value = (overridingTheme && overridingTheme[themeMode][property]) || defaultTheme[property];
return { ...previousValue, [currentValue]: value };
}, {} as T);
};
这是我目前的使用方式。
const Button = styled.button<CustomStyled<ButtonTheme>>`
${({ theme, customStyle }) => {
const componentStyle = mergeComponentTheme<ButtonTheme>(theme.mode, theme.current.button, customStyle);
return css`
background-color: ${componentStyle.backgroundColor};
color: ${componentStyle.foregroundColor};
padding: ${componentStyle.padding};
margin: ${componentStyle.margin};
border-radius: ${componentStyle.borderRadius};
filter: drop-shadow(0 0 2px ${componentStyle.dropShadowColor});
transition: all 0.2s ease-in-out;
&:hover {
background-color: ${componentStyle.backgroundColorHover};
cursor: pointer;
}
`;
}}
`;
这些是示例中使用的所有类型。
type CustomStyled<T> = {
customStyle?: CustomComponentStyle<T>;
};
type CustomComponentStyle<T> = {
light?: Partial<T>;
dark?: Partial<T>;
};
enum ThemeMode {
LIGHT = 'light',
DARK = 'dark',
}
interface ButtonTheme extends GenericTheme {
borderRadius: Radius;
}
type GenericTheme = {
backgroundColor: Color;
foregroundColor: Color;
backgroundColorHover: Color;
foregroundColorHover: Color;
dropShadowColor: Color;
margin: Space;
padding: Space;
};
有没有更简洁的方法来做到这一点。我愿意听取建议。
不过,几乎忘了问题的标题。所以我的主要问题是,如果我从themeMode常量中删除这部分as keyof typeof overridingTheme;,overridingTheme[themeMode]会说即使在检查之后它可能是未定义的。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
尝试: