UNPKG

@asafarim/react-themes

Version:

A comprehensive theme management system for React applications with automatic dark/light mode detection, custom theme creation, and smooth transitions.

18 lines 9.82 kB
var N={background:"#ffffff",backgroundSecondary:"#f8fafc",backgroundTertiary:"#f1f5f9",text:"#0f172a",textSecondary:"#475569",textMuted:"#64748b",border:"#e2e8f0",borderLight:"#f1f5f9",borderHover:"#cbd5e1",primary:"#3b82f6",primaryHover:"#2563eb",primaryActive:"#1d4ed8",success:"#10b981",warning:"#f59e0b",error:"#ef4444",info:"#06b6d4",hover:"#f8fafc",active:"#f1f5f9",focus:"rgba(59, 130, 246, 0.1)",shadow:"0 1px 2px 0 rgba(0, 0, 0, 0.05)",shadowMd:"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",shadowLg:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"},L={background:"#0f172a",backgroundSecondary:"#1e293b",backgroundTertiary:"#334155",text:"#f8fafc",textSecondary:"#cbd5e1",textMuted:"#94a3b8",border:"#334155",borderLight:"#475569",borderHover:"#64748b",primary:"#60a5fa",primaryHover:"#3b82f6",primaryActive:"#2563eb",success:"#34d399",warning:"#fbbf24",error:"#f87171",info:"#22d3ee",hover:"#1e293b",active:"#334155",focus:"rgba(96, 165, 250, 0.1)",shadow:"0 1px 2px 0 rgba(0, 0, 0, 0.3)",shadowMd:"0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3)",shadowLg:"0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -2px rgba(0, 0, 0, 0.3)"},T={spacing:{xs:"0.25rem",sm:"0.5rem",md:"0.75rem",lg:"1rem",xl:"1.25rem","2xl":"1.5rem","3xl":"2rem","4xl":"3rem"},radius:{none:"0",sm:"0.25rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"},typography:{fontFamily:{sans:'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif',serif:'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',mono:'ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace'},fontSize:{xs:"0.75rem",sm:"0.875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem","5xl":"3rem"},fontWeight:{light:"300",normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.75"}},transitions:{fast:"all 0.1s ease",normal:"all 0.2s ease",slow:"all 0.3s ease",bounce:"all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)"},zIndex:{dropdown:1e3,modal:1050,tooltip:1100,overlay:1200}},f={name:"light",mode:"light",colors:N,...T},b={name:"dark",mode:"dark",colors:L,...T},J=f,K={light:f,dark:b},k={default:f,light:f,dark:b};function X(e,o){return{...e,...o,colors:{...e.colors,...o.colors},spacing:{...e.spacing,...o.spacing},radius:{...e.radius,...o.radius},typography:{...e.typography,...o.typography,fontFamily:{...e.typography.fontFamily,...o.typography?.fontFamily},fontSize:{...e.typography.fontSize,...o.typography?.fontSize},fontWeight:{...e.typography.fontWeight,...o.typography?.fontWeight},lineHeight:{...e.typography.lineHeight,...o.typography?.lineHeight}},transitions:{...e.transitions,...o.transitions},zIndex:{...e.zIndex,...o.zIndex}}}import{createContext as R,useContext as W,useEffect as v,useState as M}from"react";function g(e,o){if(typeof document>"u")return;let n=document.documentElement,r=o;o==="auto"&&(r=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"),n.setAttribute("data-theme",e.name),n.setAttribute("data-theme-mode",r),Object.entries(e.colors).forEach(([t,a])=>{n.style.setProperty(`--theme-color-${w(t)}`,a)}),Object.entries(e.spacing).forEach(([t,a])=>{n.style.setProperty(`--theme-spacing-${t}`,a)}),Object.entries(e.radius).forEach(([t,a])=>{n.style.setProperty(`--theme-radius-${t}`,a)}),Object.entries(e.typography.fontFamily).forEach(([t,a])=>{n.style.setProperty(`--theme-font-family-${t}`,a)}),Object.entries(e.typography.fontSize).forEach(([t,a])=>{n.style.setProperty(`--theme-font-size-${t}`,a)}),Object.entries(e.typography.fontWeight).forEach(([t,a])=>{n.style.setProperty(`--theme-font-weight-${t}`,a)}),Object.entries(e.typography.lineHeight).forEach(([t,a])=>{n.style.setProperty(`--theme-line-height-${t}`,a)}),Object.entries(e.transitions).forEach(([t,a])=>{n.style.setProperty(`--theme-transition-${t}`,a)}),Object.entries(e.zIndex).forEach(([t,a])=>{n.style.setProperty(`--theme-z-index-${w(t)}`,a.toString())}),document.body.className=document.body.className.replace(/theme-\w+/g,""),document.body.classList.add(`theme-${e.name}`,`theme-${r}`)}function w(e){return e.replace(/[A-Z]/g,o=>`-${o.toLowerCase()}`)}import{jsx as j}from"react/jsx-runtime";var C=R(void 0),S=({children:e,defaultMode:o="auto",defaultTheme:n="default",persistMode:r=!0,storageKey:t="asafarim-theme-mode",customThemes:a={}})=>{let l={...k,...a},i=()=>{if(!r||typeof window>"u")return o;try{let s=localStorage.getItem(t);if(s&&["light","dark","auto"].includes(s))return s}catch(s){console.warn("Failed to read theme mode from localStorage:",s)}return o},[m,c]=M(i),[p,$]=M(n),E=()=>m==="auto"?typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":m,x=()=>{let s=E();return p!=="default"&&p in l?l[p]:s==="dark"?l.dark:l.light},y=x(),u=s=>{if(c(s),r&&typeof window<"u")try{localStorage.setItem(t,s)}catch(h){console.warn("Failed to save theme mode to localStorage:",h)}},A=()=>{if(m==="auto"){let s=window.matchMedia("(prefers-color-scheme: dark)").matches;u(s?"light":"dark")}else u(m==="light"?"dark":"light")},I=s=>{$(s.name)};v(()=>{g(y,m)},[y,m,p]),v(()=>{if(m!=="auto")return;let s=window.matchMedia("(prefers-color-scheme: dark)"),h=()=>{g(x(),m)};return s.addEventListener("change",h),()=>s.removeEventListener("change",h)},[m]);let H={currentTheme:y,mode:m,setMode:u,setTheme:I,themes:l,toggleMode:A};return j(C.Provider,{value:H,children:e})},P=()=>{let e=W(C);if(e===void 0)throw new Error("useThemeContext must be used within a ThemeProvider");return e};function d(){return P()}function O(){let{mode:e,setMode:o,toggleMode:n}=d(),t=e==="auto"?typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":e;return{mode:e,setMode:o,toggleMode:n,isDark:t==="dark",isLight:t==="light",isAuto:e==="auto",effectiveMode:t}}import{jsx as z,jsxs as V}from"react/jsx-runtime";var D=({className:e="",style:o={},showLabels:n=!1,size:r="md"})=>{let{mode:t,toggleMode:a}=d(),i=` ${{sm:"w-8 h-8 text-sm",md:"w-10 h-10 text-base",lg:"w-12 h-12 text-lg"}[r]} inline-flex items-center justify-center rounded-md border border-gray-300 bg-white hover:bg-gray-50 dark:bg-gray-800 dark:border-gray-600 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all duration-200 ${e} `.trim(),m=()=>{switch(t){case"light":return"\u2600\uFE0F";case"dark":return"\u{1F319}";case"auto":default:return"\u{1F313}"}},c=()=>{switch(t){case"light":return"Light";case"dark":return"Dark";case"auto":default:return"Auto"}};return V("button",{onClick:a,className:i,style:o,title:`Current theme: ${c()}. Click to toggle.`,"aria-label":`Switch theme. Current: ${c()}`,children:[z("span",{role:"img","aria-hidden":"true",children:m()}),n&&z("span",{className:"ml-2 text-sm font-medium",children:c()})]})};import{jsx as F}from"react/jsx-runtime";var B=({className:e="",style:o={},showLabels:n=!0,options:r=[{mode:"light",label:"Light",icon:"\u2600\uFE0F"},{mode:"dark",label:"Dark",icon:"\u{1F319}"},{mode:"auto",label:"Auto",icon:"\u{1F313}"}]})=>{let{mode:t,setMode:a}=d(),l=` px-3 py-2 border border-gray-300 rounded-md bg-white dark:bg-gray-800 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all duration-200 ${e} `.trim();return F("select",{value:t,onChange:i=>a(i.target.value),className:l,style:o,"aria-label":"Select theme mode",children:r.map(i=>F("option",{value:i.mode,children:n?`${i.icon?i.icon+" ":""}${i.label}`:i.icon||i.label},i.mode))})};function G(e,o){return{...e,...o,name:o.name||`${e.name}-custom`,colors:{...e.colors,...o.colors},spacing:{...e.spacing,...o.spacing},radius:{...e.radius,...o.radius},typography:{...e.typography,...o.typography,fontFamily:{...e.typography.fontFamily,...o.typography?.fontFamily},fontSize:{...e.typography.fontSize,...o.typography?.fontSize},fontWeight:{...e.typography.fontWeight,...o.typography?.fontWeight},lineHeight:{...e.typography.lineHeight,...o.typography?.lineHeight}},transitions:{...e.transitions,...o.transitions},zIndex:{...e.zIndex,...o.zIndex}}}function Q(...e){if(e.length===0)throw new Error("At least one theme must be provided to mergeThemes");let[o,...n]=e;if(!U(o))throw new Error("First theme must be a complete theme object");return n.reduce((r,t)=>({...r,...t,name:t.name||r.name,mode:t.mode||r.mode,colors:{...r.colors,...t.colors},spacing:{...r.spacing,...t.spacing},radius:{...r.radius,...t.radius},typography:{...r.typography,...t.typography,fontFamily:{...r.typography.fontFamily,...t.typography?.fontFamily},fontSize:{...r.typography.fontSize,...t.typography?.fontSize},fontWeight:{...r.typography.fontWeight,...t.typography?.fontWeight},lineHeight:{...r.typography.lineHeight,...t.typography?.lineHeight}},transitions:{...r.transitions,...t.transitions},zIndex:{...r.zIndex,...t.zIndex}}),o)}function U(e){return!!(e&&typeof e=="object"&&"name"in e&&"mode"in e&&"colors"in e&&"spacing"in e&&"radius"in e&&"typography"in e&&"transitions"in e&&"zIndex"in e)}function Z(e,...o){return o.reduce((n,r)=>({...n,...r}),e)}function q(e,...o){return o.reduce((n,r)=>{let t={...n};for(let a in r){let l=r[a],i=n[a];l&&typeof l=="object"&&!Array.isArray(l)&&i&&typeof i=="object"?t[a]={...i,...l}:l!==void 0&&(t[a]=l)}return t},e)}export{S as ThemeProvider,B as ThemeSelector,D as ThemeToggle,g as applyTheme,G as createTheme,b as darkTheme,q as deepMergeThemes,S as default,J as defaultTheme,k as defaultThemes,f as lightTheme,X as mergeTheme,Z as mergeThemeColors,Q as mergeThemes,K as themes,d as useTheme,O as useThemeToggle}; //# sourceMappingURL=index.mjs.map