@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
435 lines (433 loc) • 12.9 kB
JavaScript
import { DEFAULT_APPEARANCE_CONFIG as p } from "./defaults.js";
import { DEFAULT_BRANDING_CONFIG as I, DEFAULT_COMPONENT_APPEARANCE as O, DEFAULT_LAYOUT_CONFIG as B } from "./defaults.js";
var b = Object.defineProperty, y = (a, r, e) => r in a ? b(a, r, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[r] = e, c = (a, r, e) => y(a, typeof r != "symbol" ? r + "" : r, e);
const u = {
flat: {
className: "bg-default-100 hover:bg-default-200 focus:bg-default-100",
style: {
backgroundColor: "hsl(var(--color-default-100))",
border: "none",
borderRadius: "var(--border-radius-md)"
}
},
bordered: {
className: "border-2 border-default-200 hover:border-default-300 focus:border-primary",
style: {
backgroundColor: "transparent",
border: "2px solid hsl(var(--color-default-200))",
borderRadius: "var(--border-radius-md)"
}
},
underlined: {
className: "border-b-2 border-default-300 hover:border-default-400 focus:border-primary",
style: {
backgroundColor: "transparent",
border: "none",
borderBottom: "2px solid hsl(var(--color-default-300))",
borderRadius: "0"
}
},
faded: {
className: "bg-default-50 hover:bg-default-100 focus:bg-default-100 border border-default-200",
style: {
backgroundColor: "hsl(var(--color-default-50))",
border: "1px solid hsl(var(--color-default-200))",
borderRadius: "var(--border-radius-md)"
}
}
}, g = {
solid: {
className: "bg-primary text-primary-foreground hover:bg-primary-600 focus:bg-primary-700",
style: {
backgroundColor: "hsl(var(--color-primary))",
color: "hsl(var(--color-primary-foreground))",
border: "none"
}
},
bordered: {
className: "border-2 border-primary text-primary hover:bg-primary hover:text-primary-foreground",
style: {
backgroundColor: "transparent",
color: "hsl(var(--color-primary))",
border: "2px solid hsl(var(--color-primary))"
}
},
light: {
className: "bg-primary-100 text-primary-700 hover:bg-primary-200",
style: {
backgroundColor: "hsl(var(--color-primary-100))",
color: "hsl(var(--color-primary-700))",
border: "none"
}
},
flat: {
className: "bg-default-100 text-default-700 hover:bg-default-200",
style: {
backgroundColor: "hsl(var(--color-default-100))",
color: "hsl(var(--color-default-700))",
border: "none"
}
},
faded: {
className: "bg-default-50 text-default-700 hover:bg-default-100 border border-default-200",
style: {
backgroundColor: "hsl(var(--color-default-50))",
color: "hsl(var(--color-default-700))",
border: "1px solid hsl(var(--color-default-200))"
}
},
shadow: {
className: "bg-primary text-primary-foreground hover:bg-primary-600 shadow-lg hover:shadow-xl",
style: {
backgroundColor: "hsl(var(--color-primary))",
color: "hsl(var(--color-primary-foreground))",
border: "none",
boxShadow: "var(--shadow-lg)"
}
},
ghost: {
className: "text-primary hover:bg-primary-100 hover:text-primary-700",
style: {
backgroundColor: "transparent",
color: "hsl(var(--color-primary))",
border: "none"
}
}
}, h = {
shadow: {
className: "bg-card text-card-foreground shadow-md",
style: {
backgroundColor: "hsl(var(--color-card))",
color: "hsl(var(--color-card-foreground))",
boxShadow: "var(--shadow-md)"
}
},
bordered: {
className: "bg-card text-card-foreground border border-border",
style: {
backgroundColor: "hsl(var(--color-card))",
color: "hsl(var(--color-card-foreground))",
border: "1px solid hsl(var(--color-border))"
}
},
flat: {
className: "bg-default-50 text-default-900",
style: {
backgroundColor: "hsl(var(--color-default-50))",
color: "hsl(var(--color-default-900))"
}
}
}, x = {
sm: {
padding: "var(--spacing-sm)",
fontSize: "var(--font-size-sm)",
height: "32px",
minHeight: "32px"
},
md: {
padding: "var(--spacing-md)",
fontSize: "var(--font-size-base)",
height: "40px",
minHeight: "40px"
},
lg: {
padding: "var(--spacing-lg)",
fontSize: "var(--font-size-lg)",
height: "48px",
minHeight: "48px"
}
}, C = {
xs: { width: "320px", maxWidth: "90vw" },
sm: { width: "400px", maxWidth: "90vw" },
md: { width: "512px", maxWidth: "90vw" },
lg: { width: "640px", maxWidth: "90vw" },
xl: { width: "768px", maxWidth: "90vw" },
"2xl": { width: "896px", maxWidth: "95vw" },
"3xl": { width: "1024px", maxWidth: "95vw" },
"4xl": { width: "1280px", maxWidth: "95vw" },
"5xl": { width: "1536px", maxWidth: "95vw" },
full: { width: "100vw", height: "100vh", maxWidth: "100vw", maxHeight: "100vh" }
}, f = {
sm: "640px",
md: "768px",
lg: "1024px",
xl: "1280px",
"2xl": "1536px"
}, m = {
/**
* Check if screen size matches breakpoint
*/
isBreakpoint: (a) => typeof window > "u" ? !1 : window.matchMedia(`(min-width: ${f[a]})`).matches,
/**
* Get current breakpoint
*/
getCurrentBreakpoint: () => {
if (typeof window > "u") return "md";
const a = Object.entries(f).reverse();
for (const [r, e] of a)
if (window.matchMedia(`(min-width: ${e})`).matches)
return r;
return "sm";
},
/**
* Create responsive value getter
*/
getResponsiveValue: (a, r) => {
const e = m.getCurrentBreakpoint(), s = ["2xl", "xl", "lg", "md", "sm"], n = s.indexOf(e);
for (let t = n; t < s.length; t++) {
const o = s[t];
if (a[o] !== void 0)
return a[o];
}
return r;
}
};
class v {
constructor(r) {
c(this, "config"), c(this, "listeners", /* @__PURE__ */ new Set()), this.config = this.mergeAppearanceConfig(p, r);
}
/**
* Get current appearance configuration
*/
getConfig() {
return { ...this.config };
}
/**
* Update appearance configuration
*/
updateConfig(r) {
this.config = this.mergeAppearanceConfig(this.config, r), this.notifyListeners();
}
/**
* Apply organization branding
*/
applyOrganizationBranding(r) {
const e = {
logo: {
url: r.settings.branding?.logo,
alt: r.name
},
colors: {
primary: r.settings.branding?.primaryColor || this.config.branding.colors.primary,
secondary: r.settings.branding?.secondaryColor || this.config.branding.colors.secondary
},
fonts: this.config.branding.fonts,
customCSS: r.settings.branding?.customCSS
};
this.updateConfig({ branding: e });
}
/**
* Get component styles for a specific component
*/
getComponentStyles(r, e, s, n) {
const t = this.config.components[r];
let o = this.getBaseComponentStyles(r, t);
if (e) {
const l = this.getVariantStyles(r, e);
o = this.mergeStyles(o, l);
}
const i = s || t?.size || "md", d = this.getSizeStyles(i);
if (o = this.mergeStyles(o, d), n) {
const l = this.getColorStyles(n);
o = this.mergeStyles(o, l);
}
return o;
}
/**
* Get layout styles
*/
getLayoutStyles() {
return {
"--container-max-width": this.config.layout.containerMaxWidth,
"--sidebar-width": this.config.layout.sidebarWidth,
"--header-height": this.config.layout.headerHeight,
"--footer-height": this.config.layout.footerHeight,
"--content-padding": this.config.layout.contentPadding
};
}
/**
* Get branding CSS variables
*/
getBrandingVariables() {
const { branding: r } = this.config;
return {
"--brand-primary": r.colors.primary,
"--brand-secondary": r.colors.secondary,
"--brand-accent": r.colors.accent || r.colors.primary,
"--brand-font-primary": r.fonts.primary,
"--brand-font-secondary": r.fonts.secondary || r.fonts.primary
};
}
/**
* Generate complete CSS for appearance
*/
generateCSS() {
const r = this.getBrandingVariables(), e = this.getLayoutStyles();
let s = `:root {
`;
return Object.entries(r).forEach(([n, t]) => {
s += ` ${n}: ${t};
`;
}), Object.entries(e).forEach(([n, t]) => {
s += ` ${n}: ${t};
`;
}), s += `}
`, this.config.customCSS && (s += this.config.customCSS + `
`), this.config.branding.customCSS && (s += this.config.branding.customCSS + `
`), s;
}
/**
* Apply appearance to DOM
*/
applyToDOM() {
if (typeof document > "u") return;
const r = this.getBrandingVariables(), e = this.getLayoutStyles(), s = document.documentElement;
Object.entries({ ...r, ...e }).forEach(([i, d]) => {
s.style.setProperty(i, d);
});
const n = "frank-auth-custom-css";
let t = document.getElementById(n);
t || (t = document.createElement("style"), t.id = n, document.head.appendChild(t));
const o = [this.config.customCSS, this.config.branding.customCSS].filter(Boolean).join(`
`);
t.textContent = o;
}
/**
* Subscribe to appearance changes
*/
subscribe(r) {
return this.listeners.add(r), () => {
this.listeners.delete(r);
};
}
// Private methods
mergeAppearanceConfig(r, e) {
return e ? {
...r,
...e,
layout: { ...r.layout, ...e.layout },
components: { ...r.components, ...e.components },
branding: {
...r.branding,
...e.branding,
logo: { ...r.branding.logo, ...e.branding?.logo },
colors: { ...r.branding.colors, ...e.branding?.colors },
fonts: { ...r.branding.fonts, ...e.branding?.fonts }
}
} : { ...r };
}
getBaseComponentStyles(r, e) {
return {
className: `frank-${r}`,
style: {
borderRadius: `var(--border-radius-${e?.radius || "md"})`,
transition: "all var(--duration-normal) var(--easing-ease-out)"
}
};
}
getVariantStyles(r, e) {
switch (r) {
case "input":
return u[e] || u.bordered;
case "button":
return g[e] || g.solid;
case "card":
return h[e] || h.shadow;
default:
return { className: "", style: {} };
}
}
getSizeStyles(r) {
const e = x[r];
return {
className: `frank-size-${r}`,
style: {
padding: e.padding,
fontSize: e.fontSize,
minHeight: e.minHeight
}
};
}
getColorStyles(r) {
return {
className: `frank-color-${r}`,
style: {
"--component-color": `var(--color-${r})`,
"--component-color-foreground": `var(--color-${r}-foreground)`
}
};
}
mergeStyles(r, e) {
return {
className: [r.className, e.className].filter(Boolean).join(" "),
style: { ...r.style, ...e.style }
};
}
notifyListeners() {
this.listeners.forEach((r) => r(this.config));
}
}
function w(a) {
return new v(a);
}
function N(a, r, e, s, n, t) {
const o = [`frank-${a}`];
e && o.push(`frank-${a}-${e}`);
const i = s || r[a]?.size || "md";
return o.push(`frank-size-${i}`), n && o.push(`frank-color-${n}`), t && o.push(...t), o.join(" ");
}
function k(a) {
const r = {};
if (a.input) {
const { variant: e, size: s, color: n, radius: t } = a.input, o = ["transition-all", "duration-200"];
switch (e) {
case "flat":
o.push("bg-default-100", "hover:bg-default-200", "focus:bg-default-100");
break;
case "bordered":
o.push("border-2", "border-default-200", "hover:border-default-300", "focus:border-primary");
break;
case "underlined":
o.push("border-b-2", "border-default-300", "hover:border-default-400", "focus:border-primary");
break;
case "faded":
o.push("bg-default-50", "border", "border-default-200", "hover:bg-default-100");
break;
}
switch (s) {
case "sm":
o.push("px-2", "py-1", "text-sm", "h-8");
break;
case "md":
o.push("px-3", "py-2", "text-base", "h-10");
break;
case "lg":
o.push("px-4", "py-3", "text-lg", "h-12");
break;
}
t === "none" ? o.push("rounded-none") : t === "sm" ? o.push("rounded-sm") : t === "md" ? o.push("rounded-md") : t === "lg" ? o.push("rounded-lg") : t === "xl" ? o.push("rounded-xl") : t === "full" && o.push("rounded-full"), r.input = o.join(" ");
}
return r;
}
function A(a, r) {
return m.getResponsiveValue(a, r);
}
export {
v as AppearanceManager,
f as BREAKPOINTS,
g as BUTTON_VARIANTS,
h as CARD_VARIANTS,
p as DEFAULT_APPEARANCE_CONFIG,
I as DEFAULT_BRANDING_CONFIG,
O as DEFAULT_COMPONENT_APPEARANCE,
B as DEFAULT_LAYOUT_CONFIG,
u as INPUT_VARIANTS,
C as MODAL_SIZES,
m as RESPONSIVE_UTILITIES,
x as SIZE_CONFIGS,
k as appearanceConfigToTailwind,
w as createAppearanceManager,
A as createResponsiveProps,
N as getComponentClassNames
};
//# sourceMappingURL=appearance.js.map