156 lines
4.7 KiB
TypeScript
156 lines
4.7 KiB
TypeScript
export const PATTERN_BACKGROUND_OPACITY = 0.05;
|
|
export const PATTERN_VECTOR_OPACITY = 0.1;
|
|
export const PRIMARY_LIGHT_OPACITY = 0.15;
|
|
|
|
export type BgType = "pattern" | "custom" | "color";
|
|
|
|
export type RestaurantBackgroundSettings = {
|
|
bgType?: BgType | string | null;
|
|
bgUrl?: string | null;
|
|
bgBlur?: number | string | null;
|
|
bgOpacity?: number | string | null;
|
|
bgOverlay?: string | null;
|
|
menuColor?: string | null;
|
|
isPattern?: boolean;
|
|
};
|
|
|
|
export const normalizeBgNumber = (value: unknown): number | null => {
|
|
if (value == null || value === "") return null;
|
|
const parsed = typeof value === "string" ? Number(value) : value;
|
|
if (typeof parsed !== "number" || Number.isNaN(parsed)) return null;
|
|
return parsed;
|
|
};
|
|
|
|
export const hexToRgba = (hex: string, alpha: number): string => {
|
|
const normalized = hex.replace("#", "");
|
|
if (normalized.length !== 6) {
|
|
return `rgba(0, 0, 0, ${alpha})`;
|
|
}
|
|
|
|
const r = parseInt(normalized.slice(0, 2), 16);
|
|
const g = parseInt(normalized.slice(2, 4), 16);
|
|
const b = parseInt(normalized.slice(4, 6), 16);
|
|
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
};
|
|
|
|
const isUnsetBgValue = (value: unknown): boolean =>
|
|
value == null || value === "" || value === 0;
|
|
|
|
const isCustomImageBackgroundLegacy = (
|
|
settings: RestaurantBackgroundSettings,
|
|
): boolean => {
|
|
if (!settings.bgUrl) return false;
|
|
|
|
return (
|
|
!isUnsetBgValue(settings.bgBlur) ||
|
|
!isUnsetBgValue(settings.bgOpacity) ||
|
|
!isUnsetBgValue(settings.bgOverlay)
|
|
);
|
|
};
|
|
|
|
export const resolveBgType = (
|
|
settings: RestaurantBackgroundSettings,
|
|
): BgType => {
|
|
if (settings.bgType === null) return "color";
|
|
|
|
const normalized = settings.bgType?.toLowerCase();
|
|
if (
|
|
normalized === "pattern" ||
|
|
normalized === "custom" ||
|
|
normalized === "color"
|
|
) {
|
|
return normalized;
|
|
}
|
|
|
|
if (settings.isPattern === true) return "pattern";
|
|
if (settings.isPattern === false && settings.bgUrl && isCustomImageBackgroundLegacy(settings)) {
|
|
return "custom";
|
|
}
|
|
if (settings.isPattern === false) return "color";
|
|
if (isCustomImageBackgroundLegacy(settings)) return "custom";
|
|
if (settings.bgUrl) return "pattern";
|
|
|
|
return "color";
|
|
};
|
|
|
|
export const isCustomImageBackground = (
|
|
settings: RestaurantBackgroundSettings,
|
|
): boolean => resolveBgType(settings) === "custom";
|
|
|
|
export const isPatternBackground = (
|
|
settings: RestaurantBackgroundSettings,
|
|
): boolean => resolveBgType(settings) === "pattern";
|
|
|
|
export const isColorBackground = (
|
|
settings: RestaurantBackgroundSettings,
|
|
): boolean => resolveBgType(settings) === "color";
|
|
|
|
export const colorizeSvg = (
|
|
svg: string,
|
|
color: string,
|
|
vectorOpacity: number = PATTERN_VECTOR_OPACITY,
|
|
): string => {
|
|
let result = svg.replace(/fill="(?!black|none)[^"]+"/g, `fill="${color}"`);
|
|
result = result.replace(
|
|
/fill-opacity="[^"]+"/g,
|
|
`fill-opacity="${vectorOpacity}"`,
|
|
);
|
|
result = result.replace(
|
|
/(<(?:path|circle|rect|ellipse|polygon)[^>]*fill="(?!black|none)[^"]+")(?![^>]*fill-opacity)/g,
|
|
`$1 fill-opacity="${vectorOpacity}"`,
|
|
);
|
|
return result;
|
|
};
|
|
|
|
export const applyColorBackgroundCssVariables = (menuColor: string) => {
|
|
const root = document.documentElement;
|
|
root.removeAttribute("data-pattern-bg");
|
|
root.removeAttribute("data-image-bg");
|
|
root.style.removeProperty("--bg-pattern-base");
|
|
root.style.removeProperty("--bg-pattern-vector");
|
|
root.style.setProperty(
|
|
"--background",
|
|
hexToRgba(menuColor, PATTERN_BACKGROUND_OPACITY),
|
|
);
|
|
root.style.setProperty(
|
|
"--primary-light",
|
|
hexToRgba(menuColor, PRIMARY_LIGHT_OPACITY),
|
|
);
|
|
};
|
|
|
|
export const applyPatternCssVariables = (menuColor: string) => {
|
|
const root = document.documentElement;
|
|
const baseTint = hexToRgba(menuColor, PATTERN_BACKGROUND_OPACITY);
|
|
|
|
root.setAttribute("data-pattern-bg", "true");
|
|
root.style.setProperty("--bg-pattern-base", baseTint);
|
|
root.style.setProperty(
|
|
"--bg-pattern-vector",
|
|
hexToRgba(menuColor, PATTERN_VECTOR_OPACITY),
|
|
);
|
|
root.style.setProperty(
|
|
"--primary-light",
|
|
hexToRgba(menuColor, PRIMARY_LIGHT_OPACITY),
|
|
);
|
|
root.style.setProperty("--background", baseTint);
|
|
};
|
|
|
|
export const clearPatternCssVariables = () => {
|
|
const root = document.documentElement;
|
|
root.removeAttribute("data-pattern-bg");
|
|
root.style.removeProperty("--bg-pattern-base");
|
|
root.style.removeProperty("--bg-pattern-vector");
|
|
root.style.removeProperty("--primary-light");
|
|
root.style.removeProperty("--background");
|
|
};
|
|
|
|
export const applyCustomImageCssVariables = () => {
|
|
const root = document.documentElement;
|
|
root.setAttribute("data-image-bg", "true");
|
|
root.removeAttribute("data-pattern-bg");
|
|
};
|
|
|
|
export const clearCustomImageCssVariables = () => {
|
|
document.documentElement.removeAttribute("data-image-bg");
|
|
};
|