UNPKG

@frank-auth/react

Version:

Flexible and customizable React UI components for Frank Authentication

435 lines (433 loc) 12.9 kB
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