@asafarim/react-themes
Version:
A comprehensive theme management system for React applications with automatic dark/light mode detection, custom theme creation, and smooth transitions.
2 lines • 7.79 kB
JavaScript
import{createContext as W,useContext as Q,useEffect as I,useState as k}from"react";import"@asafarim/design-tokens/css/index.css";import{jsx as B}from"react/jsx-runtime";var z=W(void 0),D=({children:n,defaultMode:d="auto",defaultDensity:u="default",defaultDirection:i="ltr",storageKey:l="asafarim-theme",enableTransitions:c=!0,persistMode:m=!0,persistDensity:t=!1,persistDirection:r=!1})=>{let e=(o,g)=>{if(typeof window>"u")return g;try{return localStorage.getItem(`${l}-${o}`)||g}catch{return g}},p=(o,g,x)=>{if(!(!x||typeof window>"u"))try{localStorage.setItem(`${l}-${o}`,g)}catch($){console.warn(`Failed to save ${o} to localStorage:`,$)}},[a,S]=k(()=>m?e("mode",d):d),[f,P]=k(()=>t?e("density",u):u),[v,C]=k(()=>r?e("direction",i):i),[y,s]=k(!1),h=a==="auto"?y?"dark":"light":a,M=o=>{S(o),p("mode",o,m)},E=o=>{P(o),p("density",o,t)},V=o=>{C(o),p("direction",o,r)},A=()=>{M(a==="auto"?y?"light":"dark":a==="light"?"dark":"light")};I(()=>{let o=window.matchMedia("(prefers-color-scheme: dark)");s(o.matches);let g=x=>{s(x.matches)};return o.addEventListener("change",g),()=>o.removeEventListener("change",g)},[]),I(()=>{let o=document.documentElement;return c&&o.style.setProperty("transition","background-color var(--asm-motion-duration-normal) var(--asm-motion-easing-standard), color var(--asm-motion-duration-normal) var(--asm-motion-easing-standard)"),o.setAttribute("data-theme",h),f!=="default"?o.setAttribute("data-density",f):o.removeAttribute("data-density"),o.setAttribute("dir",v),()=>{c&&o.style.removeProperty("transition")}},[h,f,v,c]);let F={mode:a,setMode:M,toggleMode:A,density:f,setDensity:E,direction:v,setDirection:V,isDark:h==="dark",isLight:h==="light",isAuto:a==="auto",systemPrefersDark:y,resolvedMode:h};return B(z.Provider,{value:F,children:n})},L=()=>{let n=Q(z);if(n===void 0)throw new Error("useThemeContext must be used within a ThemeProvider");return n};function b(){return L()}import*as N from"react";import{Moon as q,Sun as G}from"lucide-react";import{jsx as R,jsxs as J}from"react/jsx-runtime";var H=({className:n="",style:d={},showLabels:u=!1,size:i="md",lightIcon:l=R(G,{}),darkIcon:c=R(q,{}),ariaLabel:m="Toggle theme",variant:t="default"})=>{let{resolvedMode:r,toggleMode:e}=b(),p={sm:"var(--asm-icon-size-sm)",md:"var(--asm-icon-size-md)",lg:"var(--asm-icon-size-lg)"},a={sm:"32px",md:"40px",lg:"48px"},S=s=>N.isValidElement(s)?s:typeof s=="function"?R(s,{size:p[i],strokeWidth:1.5,"aria-hidden":"true"}):s,f=()=>S(r==="dark"?c:l),P=()=>r==="dark"?"Dark":"Light",v={borderRadius:"var(--asm-radius-md)",padding:"var(--asm-space-2)",cursor:"pointer",display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"var(--asm-space-2)",fontSize:"var(--asm-font-size-md)",transition:"var(--asm-transition-fade), var(--asm-transition-scale)",border:"none"},C={default:{background:"var(--asm-color-button-secondary-bg)",border:"var(--asm-border-hairline) solid var(--asm-color-border)",color:"var(--asm-color-button-secondary-text)"},outline:{background:"transparent",border:"var(--asm-border-hairline) solid var(--asm-color-border)",color:"var(--asm-color-text)"},ghost:{background:"transparent",color:"var(--asm-color-text)"},link:{background:"transparent",padding:0,color:"var(--asm-color-button-primary-bg)"},circle:{background:"var(--asm-color-button-secondary-bg)",border:"var(--asm-border-hairline) solid var(--asm-color-border)",borderRadius:"var(--asm-radius-full)"},icon:{background:"transparent",padding:0}},y={...v,...C[t]??C.default,...t==="circle"?{width:a[i],height:a[i]}:{},...d};return J("button",{"aria-label":m,type:"button",style:y,onClick:e,className:n,title:m,onMouseEnter:s=>{(t==="ghost"||t==="icon")&&(s.currentTarget.style.background="var(--asm-color-button-ghost-bg-hover)")},onMouseLeave:s=>{(t==="ghost"||t==="icon")&&(s.currentTarget.style.background="transparent")},children:[f(),u&&R("span",{style:{fontSize:"var(--asm-font-size-sm)",fontWeight:"var(--asm-font-weight-500)"},children:P()})]})};import{Sun as O,Moon as U,Monitor as X}from"lucide-react";import{jsx as T,jsxs as Z}from"react/jsx-runtime";var Y=({className:n="",style:d={},variant:u="buttons"})=>{let{mode:i,setMode:l}=b(),c=[{mode:"light",label:"Light",Icon:O},{mode:"dark",label:"Dark",Icon:U},{mode:"auto",label:"Auto",Icon:X}];if(u==="dropdown"){let r={padding:"var(--asm-space-control-padding-y) var(--asm-space-control-padding-x)",borderRadius:"var(--asm-radius-md)",border:"var(--asm-border-hairline) solid var(--asm-color-input-border)",backgroundColor:"var(--asm-color-input-bg)",color:"var(--asm-color-input-text)",fontSize:"var(--asm-font-size-sm)",fontFamily:"var(--asm-font-family-primary)",cursor:"pointer",transition:"var(--asm-transition-fade)",outline:"none",...d};return T("select",{value:i,onChange:e=>l(e.target.value),style:r,className:n,"aria-label":"Select theme mode",onFocus:e=>{e.currentTarget.style.borderColor="var(--asm-color-input-border-focus)",e.currentTarget.style.boxShadow="0 0 0 2px var(--asm-color-focus-ring)"},onBlur:e=>{e.currentTarget.style.borderColor="var(--asm-color-input-border)",e.currentTarget.style.boxShadow="none"},children:c.map(e=>T("option",{value:e.mode,children:e.label},e.mode))})}let m={display:"inline-flex",gap:"var(--asm-space-1)",padding:"var(--asm-space-1)",borderRadius:"var(--asm-radius-lg)",backgroundColor:"var(--asm-color-surface-muted)",...d},t=r=>({display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"var(--asm-space-2)",padding:"var(--asm-space-2) var(--asm-space-3)",borderRadius:"var(--asm-radius-md)",border:"none",backgroundColor:r?"var(--asm-color-button-primary-bg)":"transparent",color:r?"var(--asm-color-button-primary-text)":"var(--asm-color-text)",fontSize:"var(--asm-font-size-sm)",fontWeight:"var(--asm-font-weight-500)",cursor:"pointer",transition:"var(--asm-transition-fade), var(--asm-transition-scale)"});return T("div",{style:m,className:n,role:"radiogroup","aria-label":"Theme mode selector",children:c.map(r=>{let e=i===r.mode,p=r.Icon;return Z("button",{onClick:()=>l(r.mode),style:t(e),role:"radio","aria-checked":e,"aria-label":`${r.label} mode`,onMouseEnter:a=>{e||(a.currentTarget.style.backgroundColor="var(--asm-color-button-ghost-bg-hover)")},onMouseLeave:a=>{e||(a.currentTarget.style.backgroundColor="transparent")},children:[T(p,{size:16,strokeWidth:1.5}),T("span",{children:r.label})]},r.mode)})})};import{jsx as w}from"react/jsx-runtime";var _=({className:n="",style:d={}})=>{let{density:u,setDensity:i}=b(),l=[{mode:"compact",label:"Compact"},{mode:"default",label:"Default"},{mode:"comfortable",label:"Comfortable"}],c={display:"inline-flex",gap:"var(--asm-space-1)",padding:"var(--asm-space-1)",borderRadius:"var(--asm-radius-lg)",backgroundColor:"var(--asm-color-surface-muted)",...d},m=t=>({display:"inline-flex",alignItems:"center",justifyContent:"center",padding:"var(--asm-space-2) var(--asm-space-3)",borderRadius:"var(--asm-radius-md)",border:"none",backgroundColor:t?"var(--asm-color-button-primary-bg)":"transparent",color:t?"var(--asm-color-button-primary-text)":"var(--asm-color-text)",fontSize:"var(--asm-font-size-sm)",fontWeight:"var(--asm-font-weight-500)",cursor:"pointer",transition:"var(--asm-transition-fade)"});return w("div",{style:c,className:n,role:"radiogroup","aria-label":"Density selector",children:l.map(t=>{let r=u===t.mode;return w("button",{onClick:()=>i(t.mode),style:m(r),role:"radio","aria-checked":r,"aria-label":`${t.label} density`,onMouseEnter:e=>{r||(e.currentTarget.style.backgroundColor="var(--asm-color-button-ghost-bg-hover)")},onMouseLeave:e=>{r||(e.currentTarget.style.backgroundColor="transparent")},children:t.label},t.mode)})})};export{_ as DensitySelector,D as ThemeProvider,Y as ThemeSelector,H as ThemeToggle,D as default,b as useTheme};
//# sourceMappingURL=index.mjs.map