@react-awesome-query-builder/antd
Version:
User-friendly query builder for React. AntDesign widgets
182 lines (159 loc) • 6.88 kB
text/typescript
// https://ant.design/docs/react/customize-theme
import { Utils, RenderSize, Config, ThemeMode, CssVars } from "@react-awesome-query-builder/ui";
import { theme as antdTheme, ConfigProviderProps, GlobalToken } from "antd";
import omitBy from "lodash/omitBy";
import pickBy from "lodash/pickBy";
type Algorithm = typeof antdTheme["darkAlgorithm"] | typeof antdTheme["defaultAlgorithm"];
type ThemeConfig = ConfigProviderProps["theme"];
// type Theme = ReturnType<typeof antdTheme.useToken>["theme"];
// type SeedToken = Parameters<typeof antdTheme["defaultAlgorithm"]>[0];
// type MapToken = ReturnType<typeof antdTheme["defaultAlgorithm"]>;
const { logger, isTruthy } = Utils.OtherUtils;
const { setColorOpacity, generateCssVarsForLevels, chroma, isDarkColor, isColor } = Utils.ColorUtils;
const buildAlgorithms = (darkMode: boolean, compactMode: boolean) => {
const algorithms: Algorithm[] = [
darkMode && antdTheme.darkAlgorithm,
compactMode && antdTheme.compactAlgorithm,
// (!compactMode && !darkMode && antdTheme.defaultAlgorithm),
].filter(isTruthy);
// const palette = algorithms.reduce(
// (tkns, algo, i) => i === 0 ? algo(tkns) : algo({} as SeedToken, tkns as MapToken),
// antdTheme.defaultSeed
// ) as MapToken;
return { algorithms };
};
const detectTokenThemeMode = (token: GlobalToken | undefined): ThemeMode | undefined => {
if (!token) {
return undefined;
}
return isDarkColor(token.colorBgBase) ? "dark" : "light";
};
// // Not accurate!
// const filterOutColorTokens = (token: GlobalToken) => {
// return omitBy(token, (_tokenValue: string, tokenName: keyof GlobalToken) => {
// return tokenName.startsWith("colorText")
// || tokenName.startsWith("colorBg")
// || tokenName.startsWith("colorFill")
// || tokenName.startsWith("colorBorder")
// || tokenName as string === "_tokenKey"
// ;
// }) as GlobalToken;
// };
const filterBasicTokens = (token: GlobalToken) => {
return pickBy(token, (tokenValue: string | number | boolean, tokenName: keyof GlobalToken) => {
return (
// preserve primary color!
tokenName === "colorPrimary"
// seed color tokens - seems fine to reuse
|| [
"colorInfo",
"colorSuccess",
"colorWarning",
"colorError",
"colorLink",
].includes(tokenName)
// non-color tokens
|| tokenName.startsWith("boxShadow")
|| tokenName.startsWith("font")
|| tokenName.startsWith("lineType")
|| tokenName.startsWith("motion")
|| typeof tokenValue !== "string"
);
}) as GlobalToken;
};
const filterTokens = (token: GlobalToken) => {
// return filterOutColorTokens(token);
return filterBasicTokens(token);
};
export const mergeThemes = (themeMode: ThemeMode | undefined, existingToken: GlobalToken | undefined, themeConfig: ThemeConfig | undefined, algorithms: Algorithm[]) => {
const tokenThemeMode = detectTokenThemeMode(existingToken);
const canInheritToken = !themeMode || !existingToken || themeMode == tokenThemeMode;
const filteredExistingToken = existingToken ? filterTokens(existingToken) : undefined;
const mergedTheme: ThemeConfig = {
...(algorithms.length ? { algorithm: algorithms } : {}),
...(existingToken ? { token: filteredExistingToken } : {}),
inherit: canInheritToken,
...(themeConfig ? themeConfig : {}),
};
// logger.log("mergeThemes - antd", {
// canInheritToken,
// themeMode,
// existingToken,
// filteredExistingToken,
// themeConfig,
// mergedTheme,
// });
return mergedTheme;
};
const generateCssVars = (token: GlobalToken, config: Config) => {
// logger.log("generateCssVars - antd token", token);
const darkMode = isDarkColor(token.colorBgBase)!;
const renderSize = config.settings.renderSize;
const useThickLeftBorderOnHoverItem = config.settings.designSettings?.useThickLeftBorderOnHoverItem ?? false;
const useShadowOnHoverItem = config.settings.designSettings?.useShadowOnHoverItem ?? false;
let sizedBorderRadius;
switch (renderSize) {
case "large":
sizedBorderRadius = token?.borderRadiusLG ?? token?.borderRadius;
break;
case "small":
sizedBorderRadius = token?.borderRadiusSM ?? token?.borderRadius;
break;
case "medium":
default:
sizedBorderRadius = token?.borderRadius;
break;
}
let cssVars: CssVars = {
"--main-background": token.colorBgContainer,
"--rule-background": token.colorBgElevated,
// "--group-background": darkMode ? token.colorBgMask : token.colorBgLayout,
// "--rulegroup-background": darkMode ? token.colorBgSpotlight : token.colorBgLayout,
// "--rulegroupext-background": darkMode ? token.colorBgSpotlight : token.colorBgLayout,
// "--switch-background": darkMode ? token.colorBgMask : token.colorFillQuaternary,
// "--case-background": darkMode ? token.colorBgMask : token.colorFillTertiary,
// level-based background colors
...generateCssVarsForLevels(darkMode, "--group-background", token.colorBgContainer),
...generateCssVarsForLevels(darkMode, "--rulegroup-background", token.colorBgContainer),
...generateCssVarsForLevels(darkMode, "--rulegroupext-background", token.colorBgContainer),
...generateCssVarsForLevels(darkMode, "--switch-background", token.colorBgContainer),
...generateCssVarsForLevels(darkMode, "--case-background", token.colorBgContainer),
"--rule-border-color": token.colorBorderSecondary,
"--group-border-color": token.colorBorder,
"--rulegroup-border-color": token.colorBorder,
"--rulegroupext-border-color": token.colorBorder,
"--switch-border-color": token.colorBorderSecondary,
"--case-border-color": token.colorBorder,
"--treeline-color": darkMode ? token.colorPrimaryHover : token.colorPrimaryHover,
"--treeline-switch-color": darkMode ? token.colorInfo : token.colorInfo,
"--treeline-disabled-color": token.colorFillSecondary,
"--main-text-color": token.colorText,
"--main-font-family": token.fontFamily,
"--main-font-size": token.fontSize + "px",
"--item-radius": sizedBorderRadius + "px",
"--conjunctions-radius": sizedBorderRadius + "px",
} as Record<string, string>;
if (useThickLeftBorderOnHoverItem) {
cssVars = {
...cssVars,
"--rule-border-left-width-hover": "2px",
"--group-border-left-width-hover": "2px",
"--rulegroup-border-left-width-hover": "2px",
"--rulegroupext-border-left-width-hover": "2px",
};
}
if(useShadowOnHoverItem) {
cssVars = {
...cssVars,
"--rule-shadow-hover": token.boxShadowTertiary,
"--group-shadow-hover": token.boxShadowTertiary,
"--rulegroup-shadow-hover": token.boxShadowTertiary,
"--rulegroupext-shadow-hover": token.boxShadowTertiary,
};
}
return cssVars;
};
export {
buildAlgorithms,
generateCssVars,
};