// 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["theme"]; // type SeedToken = Parameters[0]; // type MapToken = ReturnType; 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; 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, };