@asafarim/react-themes 1.8.7 → 1.8.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +37 -203
- package/dist/index.d.ts +37 -203
- package/dist/index.js +1 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -13
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +6 -166
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,14 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
inline-flex items-center justify-center
|
|
3
|
-
focus:outline-none focus:ring-2 focus:ring-blue-500
|
|
4
|
-
transition-all duration-200
|
|
5
|
-
${e}
|
|
6
|
-
`.trim(),g=d=>W.isValidElement(d)?d:typeof d=="function"?(0,f.jsx)(d,{"aria-hidden":"true"}):d,u=()=>{switch(c){case"light":return g(r);case"dark":return g(a);case"auto":default:return"\u{1F313}"}},y=()=>{switch(c){case"light":return"Light";case"dark":return"Dark";case"auto":default:return"Auto"}},C={borderRadius:"var(--theme-radius-md, 0.375rem)",padding:"0.5rem",cursor:"pointer",display:"inline-flex",alignItems:"center",justifyContent:"center",fontSize:h[n],transition:"all 0.2s ease-in-out",color:"var(--color-text, #0f172a)"},v={default:{background:"var(--color-surface, white)",border:"1px solid var(--color-border, #e5e7eb)",color:"var(--color-text, #0f172a)",textAlign:"center"},outline:{background:"transparent",border:"1px solid var(--color-border, #e5e7eb)",color:"var(--color-text, #0f172a)",textAlign:"center",outline:"none"},ghost:{background:"transparent",border:"none",color:"var(--color-text, #0f172a)",textAlign:"center"},link:{background:"transparent",border:"none",padding:0,fontSize:"1rem",color:"var(--color-primary, #2563eb)",textAlign:"center"},circle:{background:"var(--color-surface, white)",border:"1px solid var(--color-border, #e5e7eb)",borderRadius:"9999px",textAlign:"center"},icon:{background:"transparent",border:"none",padding:0,fontSize:"1.5rem",textAlign:"center"}},i={...{...C,...v[s]??v.default,...t},...s==="circle"?{width:b[n],height:b[n]}:{}};return(0,f.jsxs)("button",{"aria-label":l,type:"button",style:i,onClick:w,className:M,title:l,children:[(0,f.jsx)("span",{role:"img","aria-hidden":"true",children:u()}),o&&(0,f.jsx)("span",{className:"ml-2 text-sm font-medium",children:y()})]})};var R=require("react/jsx-runtime"),V=({className:e="",style:t={},showLabels:o=!0,options:n=[{mode:"light",label:"Light",icon:"\u2600\uFE0F"},{mode:"dark",label:"Dark",icon:"\u{1F319}"},{mode:"auto",label:"Auto",icon:"\u{1F313}"}]})=>{let{mode:r,setMode:a}=p(),l=`
|
|
7
|
-
px-3 py-2 border border-gray-300 rounded-md
|
|
8
|
-
bg-white dark:bg-gray-800 dark:border-gray-600
|
|
9
|
-
text-gray-900 dark:text-gray-100
|
|
10
|
-
focus:outline-none focus:ring-2 focus:ring-blue-500
|
|
11
|
-
transition-all duration-200
|
|
12
|
-
${e}
|
|
13
|
-
`.trim();return(0,R.jsx)("select",{value:r,onChange:s=>a(s.target.value),className:l,style:t,"aria-label":"Select theme mode",children:n.map(s=>(0,R.jsx)("option",{value:s.mode,children:o?`${s.icon?s.icon+" ":""}${s.label}`:s.icon||s.label},s.mode))})};function D(e,t){return{...e,...t,name:t.name||`${e.name}-custom`,colors:{...e.colors,...t.colors},spacing:{...e.spacing,...t.spacing},radius:{...e.radius,...t.radius},typography:{...e.typography,...t.typography,fontFamily:{...e.typography.fontFamily,...t.typography?.fontFamily},fontSize:{...e.typography.fontSize,...t.typography?.fontSize},fontWeight:{...e.typography.fontWeight,...t.typography?.fontWeight},lineHeight:{...e.typography.lineHeight,...t.typography?.lineHeight}},transitions:{...e.transitions,...t.transitions},zIndex:{...e.zIndex,...t.zIndex}}}function B(...e){if(e.length===0)throw new Error("At least one theme must be provided to mergeThemes");let[t,...o]=e;if(!ae(t))throw new Error("First theme must be a complete theme object");return o.reduce((n,r)=>({...n,...r,name:r.name||n.name,mode:r.mode||n.mode,colors:{...n.colors,...r.colors},spacing:{...n.spacing,...r.spacing},radius:{...n.radius,...r.radius},typography:{...n.typography,...r.typography,fontFamily:{...n.typography.fontFamily,...r.typography?.fontFamily},fontSize:{...n.typography.fontSize,...r.typography?.fontSize},fontWeight:{...n.typography.fontWeight,...r.typography?.fontWeight},lineHeight:{...n.typography.lineHeight,...r.typography?.lineHeight}},transitions:{...n.transitions,...r.transitions},zIndex:{...n.zIndex,...r.zIndex}}),t)}function ae(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 G(e,...t){return t.reduce((o,n)=>({...o,...n}),e)}function Q(e,...t){return t.reduce((o,n)=>{let r={...o};for(let a in n){let l=n[a],s=o[a];l&&typeof l=="object"&&!Array.isArray(l)&&s&&typeof s=="object"?r[a]={...s,...l}:l!==void 0&&(r[a]=l)}return r},e)}0&&(module.exports={ThemeProvider,ThemeSelector,ThemeToggle,applyTheme,createTheme,darkTheme,deepMergeThemes,defaultTheme,defaultThemes,lightTheme,mergeTheme,mergeThemeColors,mergeThemes,themes,useTheme,useThemeToggle});
|
|
1
|
+
"use strict";var O=Object.create;var M=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var X=Object.getOwnPropertyNames;var Y=Object.getPrototypeOf,Z=Object.prototype.hasOwnProperty;var _=(e,a)=>{for(var n in a)M(e,n,{get:a[n],enumerable:!0})},w=(e,a,n,c)=>{if(a&&typeof a=="object"||typeof a=="function")for(let i of X(a))!Z.call(e,i)&&i!==n&&M(e,i,{get:()=>a[i],enumerable:!(c=U(a,i))||c.enumerable});return e};var j=(e,a,n)=>(n=e!=null?O(Y(e)):{},w(a||!e||!e.__esModule?M(n,"default",{value:e,enumerable:!0}):n,e)),K=e=>w(M({},"__esModule",{value:!0}),e);var ee={};_(ee,{DensitySelector:()=>Q,ThemeProvider:()=>L,ThemeSelector:()=>W,ThemeToggle:()=>$,default:()=>L,useTheme:()=>b});module.exports=K(ee);var m=require("react"),re=require("@asafarim/design-tokens/css/index.css"),A=require("react/jsx-runtime"),E=(0,m.createContext)(void 0),L=({children:e,defaultMode:a="auto",defaultDensity:n="default",defaultDirection:c="ltr",storageKey:i="asafarim-theme",enableTransitions:u=!0,persistMode:g=!0,persistDensity:s=!1,persistDirection:t=!1})=>{let o=(r,p)=>{if(typeof window>"u")return p;try{return localStorage.getItem(`${i}-${r}`)||p}catch{return p}},h=(r,p,P)=>{if(!(!P||typeof window>"u"))try{localStorage.setItem(`${i}-${r}`,p)}catch(J){console.warn(`Failed to save ${r} to localStorage:`,J)}},[d,k]=(0,m.useState)(()=>g?o("mode",a):a),[y,z]=(0,m.useState)(()=>s?o("density",n):n),[C,R]=(0,m.useState)(()=>t?o("direction",c):c),[x,l]=(0,m.useState)(!1),T=d==="auto"?x?"dark":"light":d,D=r=>{k(r),h("mode",r,g)},B=r=>{z(r),h("density",r,s)},q=r=>{R(r),h("direction",r,t)},G=()=>{D(d==="auto"?x?"light":"dark":d==="light"?"dark":"light")};(0,m.useEffect)(()=>{let r=window.matchMedia("(prefers-color-scheme: dark)");l(r.matches);let p=P=>{l(P.matches)};return r.addEventListener("change",p),()=>r.removeEventListener("change",p)},[]),(0,m.useEffect)(()=>{let r=document.documentElement;return u&&r.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)"),r.setAttribute("data-theme",T),y!=="default"?r.setAttribute("data-density",y):r.removeAttribute("data-density"),r.setAttribute("dir",C),()=>{u&&r.style.removeProperty("transition")}},[T,y,C,u]);let H={mode:d,setMode:D,toggleMode:G,density:y,setDensity:B,direction:C,setDirection:q,isDark:T==="dark",isLight:T==="light",isAuto:d==="auto",systemPrefersDark:x,resolvedMode:T};return(0,A.jsx)(E.Provider,{value:H,children:e})},V=()=>{let e=(0,m.useContext)(E);if(e===void 0)throw new Error("useThemeContext must be used within a ThemeProvider");return e};function b(){return V()}var F=j(require("react"));var I=require("lucide-react"),v=require("react/jsx-runtime"),$=({className:e="",style:a={},showLabels:n=!1,size:c="md",lightIcon:i=(0,v.jsx)(I.Sun,{}),darkIcon:u=(0,v.jsx)(I.Moon,{}),ariaLabel:g="Toggle theme",variant:s="default"})=>{let{resolvedMode:t,toggleMode:o}=b(),h={sm:"var(--asm-icon-size-sm)",md:"var(--asm-icon-size-md)",lg:"var(--asm-icon-size-lg)"},d={sm:"32px",md:"40px",lg:"48px"},k=l=>F.isValidElement(l)?l:typeof l=="function"?(0,v.jsx)(l,{size:h[c],strokeWidth:1.5,"aria-hidden":"true"}):l,y=()=>k(t==="dark"?u:i),z=()=>t==="dark"?"Dark":"Light",C={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"},R={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}},x={...C,...R[s]??R.default,...s==="circle"?{width:d[c],height:d[c]}:{},...a};return(0,v.jsxs)("button",{"aria-label":g,type:"button",style:x,onClick:o,className:e,title:g,onMouseEnter:l=>{(s==="ghost"||s==="icon")&&(l.currentTarget.style.background="var(--asm-color-button-ghost-bg-hover)")},onMouseLeave:l=>{(s==="ghost"||s==="icon")&&(l.currentTarget.style.background="transparent")},children:[y(),n&&(0,v.jsx)("span",{style:{fontSize:"var(--asm-font-size-sm)",fontWeight:"var(--asm-font-weight-500)"},children:z()})]})};var S=require("lucide-react"),f=require("react/jsx-runtime"),W=({className:e="",style:a={},variant:n="buttons"})=>{let{mode:c,setMode:i}=b(),u=[{mode:"light",label:"Light",Icon:S.Sun},{mode:"dark",label:"Dark",Icon:S.Moon},{mode:"auto",label:"Auto",Icon:S.Monitor}];if(n==="dropdown"){let t={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",...a};return(0,f.jsx)("select",{value:c,onChange:o=>i(o.target.value),style:t,className:e,"aria-label":"Select theme mode",onFocus:o=>{o.currentTarget.style.borderColor="var(--asm-color-input-border-focus)",o.currentTarget.style.boxShadow="0 0 0 2px var(--asm-color-focus-ring)"},onBlur:o=>{o.currentTarget.style.borderColor="var(--asm-color-input-border)",o.currentTarget.style.boxShadow="none"},children:u.map(o=>(0,f.jsx)("option",{value:o.mode,children:o.label},o.mode))})}let g={display:"inline-flex",gap:"var(--asm-space-1)",padding:"var(--asm-space-1)",borderRadius:"var(--asm-radius-lg)",backgroundColor:"var(--asm-color-surface-muted)",...a},s=t=>({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: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), var(--asm-transition-scale)"});return(0,f.jsx)("div",{style:g,className:e,role:"radiogroup","aria-label":"Theme mode selector",children:u.map(t=>{let o=c===t.mode,h=t.Icon;return(0,f.jsxs)("button",{onClick:()=>i(t.mode),style:s(o),role:"radio","aria-checked":o,"aria-label":`${t.label} mode`,onMouseEnter:d=>{o||(d.currentTarget.style.backgroundColor="var(--asm-color-button-ghost-bg-hover)")},onMouseLeave:d=>{o||(d.currentTarget.style.backgroundColor="transparent")},children:[(0,f.jsx)(h,{size:16,strokeWidth:1.5}),(0,f.jsx)("span",{children:t.label})]},t.mode)})})};var N=require("react/jsx-runtime"),Q=({className:e="",style:a={}})=>{let{density:n,setDensity:c}=b(),i=[{mode:"compact",label:"Compact"},{mode:"default",label:"Default"},{mode:"comfortable",label:"Comfortable"}],u={display:"inline-flex",gap:"var(--asm-space-1)",padding:"var(--asm-space-1)",borderRadius:"var(--asm-radius-lg)",backgroundColor:"var(--asm-color-surface-muted)",...a},g=s=>({display:"inline-flex",alignItems:"center",justifyContent:"center",padding:"var(--asm-space-2) var(--asm-space-3)",borderRadius:"var(--asm-radius-md)",border:"none",backgroundColor:s?"var(--asm-color-button-primary-bg)":"transparent",color:s?"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(0,N.jsx)("div",{style:u,className:e,role:"radiogroup","aria-label":"Density selector",children:i.map(s=>{let t=n===s.mode;return(0,N.jsx)("button",{onClick:()=>c(s.mode),style:g(t),role:"radio","aria-checked":t,"aria-label":`${s.label} density`,onMouseEnter:o=>{t||(o.currentTarget.style.backgroundColor="var(--asm-color-button-ghost-bg-hover)")},onMouseLeave:o=>{t||(o.currentTarget.style.backgroundColor="transparent")},children:s.label},s.mode)})})};0&&(module.exports={DensitySelector,ThemeProvider,ThemeSelector,ThemeToggle,useTheme});
|
|
14
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/themes.ts","../src/components/ThemeProvider.tsx","../src/utils/applyTheme.ts","../src/hooks/useTheme.ts","../src/hooks/useThemeToggle.ts","../src/components/ThemeToggle.tsx","../src/components/ThemeSelector.tsx","../src/utils/createTheme.ts","../src/utils/mergeThemes.ts"],"sourcesContent":["// @asafarim/react-themes - A comprehensive theme management system for React apps\n// Export all types and interfaces\nexport * from './types';\n\n// Export all themes and utilities\nexport * from './themes';\n\n// Export main components and hooks\nexport { ThemeProvider } from './components/ThemeProvider';\nexport type { ThemeContextType } from './components/ThemeProvider';\nexport { useTheme } from './hooks/useTheme';\nexport { useThemeToggle } from './hooks/useThemeToggle';\nexport { ThemeToggle } from './components/ThemeToggle';\nexport { ThemeSelector } from './components/ThemeSelector';\n\n// Export theme utilities\nexport { createTheme } from './utils/createTheme';\nexport { applyTheme } from './utils/applyTheme';\nexport { mergeThemes, mergeThemeColors, deepMergeThemes } from './utils/mergeThemes';\n\n// Default export for convenience\nexport { ThemeProvider as default } from './components/ThemeProvider';\n","import type { Theme, ThemeColors } from './types';\n\n// Light theme colors\nconst lightColors: ThemeColors = {\n // Background colors\n background: '#ffffff',\n backgroundSecondary: '#f8fafc',\n backgroundTertiary: '#f1f5f9',\n \n // Text colors\n text: '#0f172a',\n textSecondary: '#475569',\n textMuted: '#64748b',\n \n // Border colors\n border: '#e2e8f0',\n borderLight: '#f1f5f9',\n borderHover: '#cbd5e1',\n \n // Accent colors\n primary: '#3b82f6',\n primaryHover: '#2563eb',\n primaryActive: '#1d4ed8',\n \n // Status colors\n success: '#10b981',\n warning: '#f59e0b',\n error: '#ef4444',\n info: '#06b6d4',\n \n // Interactive states\n hover: '#f8fafc',\n active: '#f1f5f9',\n focus: 'rgba(59, 130, 246, 0.1)',\n \n // Shadows\n shadow: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',\n shadowMd: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n shadowLg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',\n};\n\n// Dark theme colors\nconst darkColors: ThemeColors = {\n // Background colors\n background: '#0f172a',\n backgroundSecondary: '#1e293b',\n backgroundTertiary: '#334155',\n \n // Text colors\n text: '#f8fafc',\n textSecondary: '#cbd5e1',\n textMuted: '#94a3b8',\n \n // Border colors\n border: '#334155',\n borderLight: '#475569',\n borderHover: '#64748b',\n \n // Accent colors\n primary: '#60a5fa',\n primaryHover: '#3b82f6',\n primaryActive: '#2563eb',\n \n // Status colors\n success: '#34d399',\n warning: '#fbbf24',\n error: '#f87171',\n info: '#22d3ee',\n \n // Interactive states\n hover: '#1e293b',\n active: '#334155',\n focus: 'rgba(96, 165, 250, 0.1)',\n \n // Shadows\n shadow: '0 1px 2px 0 rgba(0, 0, 0, 0.3)',\n shadowMd: '0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3)',\n shadowLg: '0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -2px rgba(0, 0, 0, 0.3)',\n};\n\n// Base theme structure\nconst baseTheme = {\n spacing: {\n xs: '0.25rem',\n sm: '0.5rem',\n md: '0.75rem',\n lg: '1rem',\n xl: '1.25rem',\n '2xl': '1.5rem',\n '3xl': '2rem',\n '4xl': '3rem',\n },\n radius: {\n none: '0',\n sm: '0.25rem',\n md: '0.375rem',\n lg: '0.5rem',\n xl: '0.75rem',\n '2xl': '1rem',\n full: '9999px',\n },\n typography: {\n fontFamily: {\n sans: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif',\n serif: 'ui-serif, Georgia, Cambria, \"Times New Roman\", Times, serif',\n mono: 'ui-monospace, SFMono-Regular, \"SF Mono\", Consolas, \"Liberation Mono\", Menlo, monospace',\n },\n fontSize: {\n xs: '0.75rem',\n sm: '0.875rem',\n base: '1rem',\n lg: '1.125rem',\n xl: '1.25rem',\n '2xl': '1.5rem',\n '3xl': '1.875rem',\n '4xl': '2.25rem',\n '5xl': '3rem',\n },\n fontWeight: {\n light: '300',\n normal: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n },\n lineHeight: {\n tight: '1.25',\n normal: '1.5',\n relaxed: '1.75',\n },\n },\n transitions: {\n fast: 'all 0.1s ease',\n normal: 'all 0.2s ease',\n slow: 'all 0.3s ease',\n bounce: 'all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)',\n },\n zIndex: {\n dropdown: 1000,\n modal: 1050,\n tooltip: 1100,\n overlay: 1200,\n },\n};\n\n// Light theme\nexport const lightTheme: Theme = {\n name: 'light',\n mode: 'light',\n colors: lightColors,\n ...baseTheme,\n};\n\n// Dark theme\nexport const darkTheme: Theme = {\n name: 'dark',\n mode: 'dark',\n colors: darkColors,\n ...baseTheme,\n};\n\n// Default theme (light)\nexport const defaultTheme = lightTheme;\n\n// Theme presets\nexport const themes = {\n light: lightTheme,\n dark: darkTheme,\n};\n\n// Default themes for the provider\nexport const defaultThemes = {\n default: lightTheme,\n light: lightTheme,\n dark: darkTheme,\n};\n\n// Helper function to merge themes\nexport function mergeTheme(baseTheme: Theme, customTheme: Partial<Theme>): Theme {\n return {\n ...baseTheme,\n ...customTheme,\n colors: {\n ...baseTheme.colors,\n ...customTheme.colors,\n },\n spacing: {\n ...baseTheme.spacing,\n ...customTheme.spacing,\n },\n radius: {\n ...baseTheme.radius,\n ...customTheme.radius,\n },\n typography: {\n ...baseTheme.typography,\n ...customTheme.typography,\n fontFamily: {\n ...baseTheme.typography.fontFamily,\n ...customTheme.typography?.fontFamily,\n },\n fontSize: {\n ...baseTheme.typography.fontSize,\n ...customTheme.typography?.fontSize,\n },\n fontWeight: {\n ...baseTheme.typography.fontWeight,\n ...customTheme.typography?.fontWeight,\n },\n lineHeight: {\n ...baseTheme.typography.lineHeight,\n ...customTheme.typography?.lineHeight,\n },\n },\n transitions: {\n ...baseTheme.transitions,\n ...customTheme.transitions,\n },\n zIndex: {\n ...baseTheme.zIndex,\n ...customTheme.zIndex,\n },\n };\n}\n","import * as React from 'react';\nimport { createContext, useContext, useEffect, useState, ReactNode } from 'react';\nimport { Theme, ThemeConfig, ThemeMode } from '../types';\nimport { defaultThemes } from '../themes';\nimport { applyTheme } from '../utils/applyTheme';\n\nexport interface ThemeContextType {\n currentTheme: Theme;\n mode: ThemeMode;\n setMode: (mode: ThemeMode) => void;\n setTheme: (theme: Theme) => void;\n themes: Record<string, Theme>;\n toggleMode: () => void;\n}\n\nconst ThemeContext = createContext<ThemeContextType | undefined>(undefined);\n\nexport interface ThemeProviderProps {\n children: ReactNode;\n config?: ThemeConfig;\n defaultMode?: ThemeMode;\n defaultTheme?: string;\n persistMode?: boolean;\n storageKey?: string;\n customThemes?: Record<string, Theme>;\n}\n\nexport const ThemeProvider: React.FC<ThemeProviderProps> = ({\n children,\n defaultMode = 'auto',\n defaultTheme = 'default',\n persistMode = true,\n storageKey = 'asafarim-theme-mode',\n customThemes = {},\n}) => {\n const allThemes = { ...defaultThemes, ...customThemes };\n \n // Get initial mode from localStorage or use default\n const getInitialMode = (): ThemeMode => {\n if (!persistMode || typeof window === 'undefined') return defaultMode;\n \n try {\n const stored = localStorage.getItem(storageKey);\n if (stored && ['light', 'dark', 'auto'].includes(stored)) {\n return stored as ThemeMode;\n }\n } catch (error) {\n console.warn('Failed to read theme mode from localStorage:', error);\n }\n \n return defaultMode;\n };\n const [mode, setModeState] = useState<ThemeMode>(getInitialMode);\n const [currentThemeName, setCurrentThemeName] = useState<string>(defaultTheme);\n\n // Get the effective mode (resolving 'auto' to actual light/dark)\n const getEffectiveMode = (): 'light' | 'dark' => {\n if (mode === 'auto') {\n if (typeof window !== 'undefined') {\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n return 'light'; // fallback for SSR\n }\n return mode;\n };\n // Get the current theme based on mode and theme name\n const getCurrentTheme = (): Theme => {\n const effectiveMode = getEffectiveMode();\n \n // If user selected a specific theme, use it\n if (currentThemeName !== 'default' && currentThemeName in allThemes) {\n return allThemes[currentThemeName as keyof typeof allThemes];\n }\n \n // Otherwise use the theme that matches the effective mode\n return effectiveMode === 'dark' ? allThemes.dark : allThemes.light;\n };\n\n const currentTheme = getCurrentTheme();\n\n // Update mode and persist if enabled\n const setMode = (newMode: ThemeMode) => {\n setModeState(newMode);\n \n if (persistMode && typeof window !== 'undefined') {\n try {\n localStorage.setItem(storageKey, newMode);\n } catch (error) {\n console.warn('Failed to save theme mode to localStorage:', error);\n }\n }\n };\n\n // Toggle between light and dark modes\n const toggleMode = () => {\n if (mode === 'auto') {\n // If auto, switch to opposite of system preference\n const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n setMode(systemDark ? 'light' : 'dark');\n } else {\n setMode(mode === 'light' ? 'dark' : 'light');\n }\n };\n // Set theme by name\n const setTheme = (theme: Theme) => {\n setCurrentThemeName(theme.name);\n };\n // Apply theme to document\n useEffect(() => {\n applyTheme(currentTheme, mode);\n }, [currentTheme, mode, currentThemeName]); // Add currentThemeName as dependency\n\n // Listen for system theme changes when in auto mode\n useEffect(() => {\n if (mode !== 'auto') return;\n\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const handleChange = () => {\n // Force re-render when system preference changes\n applyTheme(getCurrentTheme(), mode);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, [mode]);\n\n const contextValue: ThemeContextType = {\n currentTheme,\n mode,\n setMode,\n setTheme,\n themes: allThemes,\n toggleMode,\n };\n\n return (\n <ThemeContext.Provider value={contextValue}>\n {children}\n </ThemeContext.Provider>\n );\n};\n\nexport const useThemeContext = () => {\n const context = useContext(ThemeContext);\n if (context === undefined) {\n throw new Error('useThemeContext must be used within a ThemeProvider');\n }\n return context;\n};\n","import { Theme, ThemeMode } from '../types';\n\n/**\n * Applies theme CSS variables to the document root\n */\nexport function applyTheme(theme: Theme, mode: ThemeMode): void {\n if (typeof document === 'undefined') return;\n\n const root = document.documentElement;\n \n // Determine the effective mode\n let effectiveMode = mode;\n if (mode === 'auto') {\n effectiveMode = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n\n // Set data attributes for CSS targeting\n root.setAttribute('data-theme', theme.name);\n root.setAttribute('data-theme-mode', effectiveMode);\n\n // Apply color variables\n Object.entries(theme.colors).forEach(([key, value]) => {\n root.style.setProperty(`--theme-color-${kebabCase(key)}`, value);\n });\n\n // Apply spacing variables\n Object.entries(theme.spacing).forEach(([key, value]) => {\n root.style.setProperty(`--theme-spacing-${key}`, value);\n });\n\n // Apply radius variables\n Object.entries(theme.radius).forEach(([key, value]) => {\n root.style.setProperty(`--theme-radius-${key}`, value);\n });\n\n // Apply typography variables\n Object.entries(theme.typography.fontFamily).forEach(([key, value]) => {\n root.style.setProperty(`--theme-font-family-${key}`, value);\n });\n\n Object.entries(theme.typography.fontSize).forEach(([key, value]) => {\n root.style.setProperty(`--theme-font-size-${key}`, value);\n });\n\n Object.entries(theme.typography.fontWeight).forEach(([key, value]) => {\n root.style.setProperty(`--theme-font-weight-${key}`, value);\n });\n\n Object.entries(theme.typography.lineHeight).forEach(([key, value]) => {\n root.style.setProperty(`--theme-line-height-${key}`, value);\n });\n\n // Apply transition variables\n Object.entries(theme.transitions).forEach(([key, value]) => {\n root.style.setProperty(`--theme-transition-${key}`, value);\n });\n\n // Apply z-index variables\n Object.entries(theme.zIndex).forEach(([key, value]) => {\n root.style.setProperty(`--theme-z-index-${kebabCase(key)}`, value.toString());\n });\n\n // Add theme class to body for additional styling\n document.body.className = document.body.className.replace(/theme-\\w+/g, '');\n document.body.classList.add(`theme-${theme.name}`, `theme-${effectiveMode}`);\n}\n\n/**\n * Removes all theme-related CSS variables and classes\n */\nexport function removeTheme(): void {\n if (typeof document === 'undefined') return;\n\n const root = document.documentElement;\n \n // Remove data attributes\n root.removeAttribute('data-theme');\n root.removeAttribute('data-theme-mode');\n\n // Remove CSS variables (this is a simplified approach - in production you might want to track which variables were set)\n const styles = root.style;\n for (let i = styles.length - 1; i >= 0; i--) {\n const property = styles[i];\n if (property.startsWith('--theme-')) {\n root.style.removeProperty(property);\n }\n }\n\n // Remove theme classes from body\n document.body.className = document.body.className.replace(/theme-\\w+/g, '');\n}\n\n/**\n * Converts camelCase to kebab-case\n */\nfunction kebabCase(str: string): string {\n return str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\n}\n","import { useThemeContext, ThemeContextType } from '../components/ThemeProvider';\n\n/**\n * Hook to access theme context\n */\nexport function useTheme(): ThemeContextType {\n return useThemeContext();\n}\n","import { useTheme } from './useTheme';\n\n/**\n * Hook that provides theme toggle functionality\n */\nexport function useThemeToggle() {\n const { mode, setMode, toggleMode } = useTheme();\n \n // Get effective mode (resolving 'auto' to actual light/dark)\n const getEffectiveMode = (): 'light' | 'dark' => {\n if (mode === 'auto') {\n if (typeof window !== 'undefined') {\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n return 'light'; // fallback for SSR\n }\n return mode;\n };\n\n const effectiveMode = getEffectiveMode();\n \n return {\n mode,\n setMode,\n toggleMode,\n isDark: effectiveMode === 'dark',\n isLight: effectiveMode === 'light',\n isAuto: mode === 'auto',\n effectiveMode, // Expose the resolved mode\n };\n}\n","import * as React from \"react\";\nimport { useTheme } from \"../hooks/useTheme\";\nimport type { CSSProperties, ReactNode } from 'react';\nimport { Moon, Sun, type LucideIcon } from \"lucide-react\";\n\ntype ThemeToggleVariant =\n | \"default\"\n | \"outline\"\n | \"ghost\"\n | \"link\"\n | \"circle\"\n | \"icon\";\n\nexport interface ThemeToggleProps {\n className?: string;\n style?: React.CSSProperties;\n showLabels?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Custom light icon (default: ☀️)\n */\n lightIcon?: ReactNode | LucideIcon | string;\n\n /**\n * Custom dark icon (default: 🌙)\n */\n darkIcon?: ReactNode | LucideIcon | string;\n\n /**\n * Button aria-label\n */\n ariaLabel?: string;\n\n /**\n * Button variant\n */\n variant?: ThemeToggleVariant;\n}\n\nexport const ThemeToggle: React.FC<ThemeToggleProps> = ({\n className = \"\",\n style = {},\n showLabels = false,\n size = \"md\",\n lightIcon = <Sun /> as ReactNode | LucideIcon | string,\n darkIcon = <Moon /> as ReactNode | LucideIcon | string,\n ariaLabel = \"Toggle theme\",\n variant = \"default\",\n}) => {\n const { mode, toggleMode } = useTheme();\n\n const fontSizeMap: Record<NonNullable<ThemeToggleProps['size']>, string> = {\n sm: '1rem',\n md: '1.25rem',\n lg: '1.5rem',\n };\n\n const circleSizeMap: Record<NonNullable<ThemeToggleProps['size']>, string> = {\n sm: '2rem',\n md: '2.5rem',\n lg: '3rem',\n };\n\n const buttonClass = `\n inline-flex items-center justify-center\n focus:outline-none focus:ring-2 focus:ring-blue-500\n transition-all duration-200\n ${className}\n `.trim();\n\n\n const renderIcon = (icon: ReactNode | LucideIcon | string) => {\n if (React.isValidElement(icon)) {\n return icon;\n }\n if (typeof icon === 'function') {\n const IconComp = icon as LucideIcon;\n return <IconComp aria-hidden=\"true\" />;\n }\n return icon as React.ReactNode;\n };\n\n const getIcon = () => {\n switch (mode) {\n case \"light\":\n return renderIcon(lightIcon);\n case \"dark\":\n return renderIcon(darkIcon);\n case \"auto\":\n default:\n return \"🌓\";\n }\n };\n\n\n const getLabel = () => {\n switch (mode) {\n case \"light\":\n return \"Light\";\n case \"dark\":\n return \"Dark\";\n case \"auto\":\n default:\n return \"Auto\";\n }\n };\n\n \n const baseStyles: CSSProperties = {\n borderRadius: 'var(--theme-radius-md, 0.375rem)',\n padding: '0.5rem',\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: fontSizeMap[size],\n transition: 'all 0.2s ease-in-out',\n color: 'var(--color-text, #0f172a)',\n };\n\n\n const variantStyles: Record<ThemeToggleVariant, CSSProperties> = {\n default: {\n background: 'var(--color-surface, white)',\n border: '1px solid var(--color-border, #e5e7eb)',\n color: 'var(--color-text, #0f172a)',\n textAlign: 'center',\n },\n outline: {\n background: 'transparent',\n border: '1px solid var(--color-border, #e5e7eb)',\n color: 'var(--color-text, #0f172a)',\n textAlign: 'center',\n outline: 'none',\n \n },\n ghost: {\n background: 'transparent',\n border: 'none',\n color: 'var(--color-text, #0f172a)',\n textAlign: 'center',\n },\n link: {\n background: 'transparent',\n border: 'none',\n padding: 0,\n fontSize: '1rem',\n color: 'var(--color-primary, #2563eb)',\n textAlign: 'center',\n\n },\n circle: {\n background: 'var(--color-surface, white)',\n border: '1px solid var(--color-border, #e5e7eb)',\n borderRadius: '9999px',\n textAlign: 'center',\n },\n\n icon: {\n background: 'transparent',\n border: 'none',\n padding: 0,\n fontSize: '1.5rem',\n textAlign: 'center',\n },\n };\n\n const mergedStyles = {\n ...baseStyles,\n ...(variantStyles[variant] ?? variantStyles.default),\n ...style,\n };\n\n const finalStyles: CSSProperties = {\n ...mergedStyles,\n ...(variant === \"circle\" ? { width: circleSizeMap[size], height: circleSizeMap[size] } : {}),\n };\n \n return (\n <button\n aria-label={ariaLabel}\n type=\"button\"\n style={finalStyles}\n onClick={toggleMode}\n className={buttonClass}\n title={ariaLabel}\n >\n\n <span role=\"img\" aria-hidden=\"true\">\n {getIcon()}\n </span>\n {showLabels && (\n <span className=\"ml-2 text-sm font-medium\">{getLabel()}</span>\n )}\n </button>\n );\n};\n","import * as React from \"react\";\nimport { useTheme } from \"../hooks/useTheme\";\nimport { ThemeMode } from \"../types\";\n\nexport interface ThemeSelectorProps {\n className?: string;\n style?: React.CSSProperties;\n showLabels?: boolean;\n options?: Array<{\n mode: ThemeMode;\n label: string;\n icon?: string;\n }>;\n}\n\nexport const ThemeSelector: React.FC<ThemeSelectorProps> = ({\n className = \"\",\n style = {},\n showLabels = true,\n options = [\n { mode: \"light\", label: \"Light\", icon: \"☀️\" },\n { mode: \"dark\", label: \"Dark\", icon: \"🌙\" },\n { mode: \"auto\", label: \"Auto\", icon: \"🌓\" },\n ],\n}) => {\n const { mode, setMode } = useTheme();\n\n const selectClass = `\n px-3 py-2 border border-gray-300 rounded-md\n bg-white dark:bg-gray-800 dark:border-gray-600\n text-gray-900 dark:text-gray-100\n focus:outline-none focus:ring-2 focus:ring-blue-500\n transition-all duration-200\n ${className}\n `.trim();\n\n return (\n <select\n value={mode}\n onChange={(e) => setMode(e.target.value as ThemeMode)}\n className={selectClass}\n style={style}\n aria-label=\"Select theme mode\"\n >\n {options.map((option) => (\n <option key={option.mode} value={option.mode}>\n {showLabels\n ? `${option.icon ? option.icon + \" \" : \"\"}${option.label}`\n : option.icon || option.label}\n </option>\n ))}\n </select>\n );\n};\n","import { Theme } from '../types';\n\n/**\n * Creates a new theme by merging a base theme with custom properties\n */\nexport function createTheme(\n baseTheme: Theme,\n customTheme: Partial<Theme>\n): Theme {\n return {\n ...baseTheme,\n ...customTheme,\n name: customTheme.name || `${baseTheme.name}-custom`,\n colors: {\n ...baseTheme.colors,\n ...customTheme.colors,\n },\n spacing: {\n ...baseTheme.spacing,\n ...customTheme.spacing,\n },\n radius: {\n ...baseTheme.radius,\n ...customTheme.radius,\n },\n typography: {\n ...baseTheme.typography,\n ...customTheme.typography,\n fontFamily: {\n ...baseTheme.typography.fontFamily,\n ...customTheme.typography?.fontFamily,\n },\n fontSize: {\n ...baseTheme.typography.fontSize,\n ...customTheme.typography?.fontSize,\n },\n fontWeight: {\n ...baseTheme.typography.fontWeight,\n ...customTheme.typography?.fontWeight,\n },\n lineHeight: {\n ...baseTheme.typography.lineHeight,\n ...customTheme.typography?.lineHeight,\n },\n },\n transitions: {\n ...baseTheme.transitions,\n ...customTheme.transitions,\n },\n zIndex: {\n ...baseTheme.zIndex,\n ...customTheme.zIndex,\n },\n };\n}\n\n/**\n * Creates a theme variant with modified colors\n */\nexport function createThemeVariant(\n baseTheme: Theme,\n colorOverrides: Partial<Theme['colors']>,\n name?: string\n): Theme {\n return createTheme(baseTheme, {\n name: name || `${baseTheme.name}-variant`,\n colors: {\n ...baseTheme.colors,\n ...colorOverrides,\n },\n });\n}\n","import { Theme } from '../types';\n\n/**\n * Merges multiple themes into a single theme\n * Later themes in the array take precedence over earlier ones\n */\nexport function mergeThemes(...themes: Array<Theme | Partial<Theme>>): Theme {\n if (themes.length === 0) {\n throw new Error('At least one theme must be provided to mergeThemes');\n }\n\n const [baseTheme, ...additionalThemes] = themes;\n \n if (!isFullTheme(baseTheme)) {\n throw new Error('First theme must be a complete theme object');\n }\n return additionalThemes.reduce((merged: Theme, theme): Theme => {\n return {\n ...merged,\n ...theme,\n name: theme.name || merged.name,\n mode: theme.mode || merged.mode,\n colors: {\n ...merged.colors,\n ...theme.colors,\n },\n spacing: {\n ...merged.spacing,\n ...theme.spacing,\n },\n radius: {\n ...merged.radius,\n ...theme.radius,\n },\n typography: {\n ...merged.typography,\n ...theme.typography,\n fontFamily: {\n ...merged.typography.fontFamily,\n ...theme.typography?.fontFamily,\n },\n fontSize: {\n ...merged.typography.fontSize,\n ...theme.typography?.fontSize,\n },\n fontWeight: {\n ...merged.typography.fontWeight,\n ...theme.typography?.fontWeight,\n },\n lineHeight: {\n ...merged.typography.lineHeight,\n ...theme.typography?.lineHeight,\n },\n },\n transitions: {\n ...merged.transitions,\n ...theme.transitions,\n },\n zIndex: {\n ...merged.zIndex,\n ...theme.zIndex,\n },\n };\n }, baseTheme);\n}\n\n/**\n * Type guard to check if an object is a complete theme\n */\nfunction isFullTheme(theme: Theme | Partial<Theme>): theme is Theme {\n return !!(\n theme &&\n typeof theme === 'object' &&\n 'name' in theme &&\n 'mode' in theme &&\n 'colors' in theme &&\n 'spacing' in theme &&\n 'radius' in theme &&\n 'typography' in theme &&\n 'transitions' in theme &&\n 'zIndex' in theme\n );\n}\n\n/**\n * Merges theme colors only\n */\nexport function mergeThemeColors(\n baseColors: Theme['colors'],\n ...colorSets: Array<Partial<Theme['colors']>>\n): Theme['colors'] {\n return colorSets.reduce((merged: Theme['colors'], colors): Theme['colors'] => ({\n ...merged,\n ...colors,\n }), baseColors);\n}\n\n/**\n * Deep merge utility for complex theme objects\n */\nexport function deepMergeThemes(target: Theme, ...sources: Array<Partial<Theme>>): Theme {\n return sources.reduce((merged: Theme, source): Theme => {\n const result = { ...merged };\n \n for (const key in source) {\n const sourceValue = source[key as keyof Theme];\n const targetValue = merged[key as keyof Theme];\n \n if (sourceValue && typeof sourceValue === 'object' && !Array.isArray(sourceValue) && targetValue && typeof targetValue === 'object') {\n result[key as keyof Theme] = {\n ...targetValue,\n ...sourceValue,\n } as any;\n } else if (sourceValue !== undefined) {\n result[key as keyof Theme] = sourceValue as any;\n }\n }\n \n return result;\n }, target);\n}\n"],"mappings":"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","names":["index_exports","__export","ThemeProvider","ThemeSelector","ThemeToggle","applyTheme","createTheme","darkTheme","deepMergeThemes","defaultTheme","defaultThemes","lightTheme","mergeTheme","mergeThemeColors","mergeThemes","themes","useTheme","useThemeToggle","__toCommonJS","lightColors","darkColors","baseTheme","lightTheme","darkTheme","defaultTheme","themes","defaultThemes","mergeTheme","customTheme","import_react","applyTheme","theme","mode","root","effectiveMode","key","value","kebabCase","kebabCase","str","match","import_jsx_runtime","ThemeContext","ThemeProvider","children","defaultMode","defaultTheme","persistMode","storageKey","customThemes","allThemes","defaultThemes","getInitialMode","stored","error","mode","setModeState","currentThemeName","setCurrentThemeName","getEffectiveMode","getCurrentTheme","effectiveMode","currentTheme","setMode","newMode","toggleMode","systemDark","setTheme","theme","applyTheme","mediaQuery","handleChange","contextValue","useThemeContext","context","useTheme","useThemeContext","useThemeToggle","mode","setMode","toggleMode","useTheme","effectiveMode","React","import_lucide_react","import_jsx_runtime","ThemeToggle","className","style","showLabels","size","lightIcon","darkIcon","ariaLabel","variant","mode","toggleMode","useTheme","fontSizeMap","circleSizeMap","buttonClass","renderIcon","icon","getIcon","getLabel","baseStyles","variantStyles","finalStyles","import_jsx_runtime","ThemeSelector","className","style","showLabels","options","mode","setMode","useTheme","selectClass","e","option","createTheme","baseTheme","customTheme","mergeThemes","themes","baseTheme","additionalThemes","isFullTheme","merged","theme","mergeThemeColors","baseColors","colorSets","colors","deepMergeThemes","target","sources","source","result","key","sourceValue","targetValue"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/ThemeProvider.tsx","../src/hooks/useTheme.ts","../src/components/ThemeToggle.tsx","../src/components/ThemeSelector.tsx","../src/components/DensitySelector.tsx"],"sourcesContent":["export * from './types';\n\nexport { ThemeProvider } from './components/ThemeProvider';\nexport { useTheme } from './hooks/useTheme';\nexport { ThemeToggle } from './components/ThemeToggle';\nexport { ThemeSelector } from './components/ThemeSelector';\nexport { DensitySelector } from './components/DensitySelector';\n\nexport { ThemeProvider as default } from './components/ThemeProvider';\n","import * as React from 'react';\nimport { createContext, useContext, useEffect, useState } from 'react';\nimport type { ThemeContextValue, ThemeProviderProps, ThemeMode, DensityMode, DirectionMode } from '../types';\nimport '@asafarim/design-tokens/css/index.css';\n\nconst ThemeContext = createContext<ThemeContextValue | undefined>(undefined);\n\nexport const ThemeProvider: React.FC<ThemeProviderProps> = ({\n children,\n defaultMode = 'auto',\n defaultDensity = 'default',\n defaultDirection = 'ltr',\n storageKey = 'asafarim-theme',\n enableTransitions = true,\n persistMode = true,\n persistDensity = false,\n persistDirection = false,\n}) => {\n const getStoredValue = <T extends string>(key: string, defaultValue: T): T => {\n if (typeof window === 'undefined') return defaultValue;\n try {\n const stored = localStorage.getItem(`${storageKey}-${key}`);\n return (stored as T) || defaultValue;\n } catch {\n return defaultValue;\n }\n };\n\n const setStoredValue = (key: string, value: string, persist: boolean) => {\n if (!persist || typeof window === 'undefined') return;\n try {\n localStorage.setItem(`${storageKey}-${key}`, value);\n } catch (error) {\n console.warn(`Failed to save ${key} to localStorage:`, error);\n }\n };\n\n const [mode, setModeState] = useState<ThemeMode>(() => \n persistMode ? getStoredValue('mode', defaultMode) : defaultMode\n );\n const [density, setDensityState] = useState<DensityMode>(() => \n persistDensity ? getStoredValue('density', defaultDensity) : defaultDensity\n );\n const [direction, setDirectionState] = useState<DirectionMode>(() => \n persistDirection ? getStoredValue('direction', defaultDirection) : defaultDirection\n );\n const [systemPrefersDark, setSystemPrefersDark] = useState<boolean>(false);\n\n const resolvedMode: 'light' | 'dark' = \n mode === 'auto' \n ? (systemPrefersDark ? 'dark' : 'light')\n : mode;\n\n const setMode = (newMode: ThemeMode) => {\n setModeState(newMode);\n setStoredValue('mode', newMode, persistMode);\n };\n\n const setDensity = (newDensity: DensityMode) => {\n setDensityState(newDensity);\n setStoredValue('density', newDensity, persistDensity);\n };\n\n const setDirection = (newDirection: DirectionMode) => {\n setDirectionState(newDirection);\n setStoredValue('direction', newDirection, persistDirection);\n };\n\n const toggleMode = () => {\n if (mode === 'auto') {\n setMode(systemPrefersDark ? 'light' : 'dark');\n } else {\n setMode(mode === 'light' ? 'dark' : 'light');\n }\n };\n\n useEffect(() => {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n setSystemPrefersDark(mediaQuery.matches);\n\n const handleChange = (e: MediaQueryListEvent) => {\n setSystemPrefersDark(e.matches);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, []);\n\n useEffect(() => {\n const root = document.documentElement;\n\n if (enableTransitions) {\n root.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)');\n }\n\n root.setAttribute('data-theme', resolvedMode);\n\n if (density !== 'default') {\n root.setAttribute('data-density', density);\n } else {\n root.removeAttribute('data-density');\n }\n\n root.setAttribute('dir', direction);\n\n return () => {\n if (enableTransitions) {\n root.style.removeProperty('transition');\n }\n };\n }, [resolvedMode, density, direction, enableTransitions]);\n\n const contextValue: ThemeContextValue = {\n mode,\n setMode,\n toggleMode,\n density,\n setDensity,\n direction,\n setDirection,\n isDark: resolvedMode === 'dark',\n isLight: resolvedMode === 'light',\n isAuto: mode === 'auto',\n systemPrefersDark,\n resolvedMode,\n };\n\n return (\n <ThemeContext.Provider value={contextValue}>\n {children}\n </ThemeContext.Provider>\n );\n};\n\nexport const useThemeContext = () => {\n const context = useContext(ThemeContext);\n if (context === undefined) {\n throw new Error('useThemeContext must be used within a ThemeProvider');\n }\n return context;\n};\n","import { useThemeContext } from '../components/ThemeProvider';\nimport type { ThemeContextValue } from '../types';\n\nexport function useTheme(): ThemeContextValue {\n return useThemeContext();\n}\n","import * as React from \"react\";\nimport { useTheme } from \"../hooks/useTheme\";\nimport type { CSSProperties, ReactNode } from 'react';\nimport { Moon, Sun, type LucideIcon } from \"lucide-react\";\n\ntype ThemeToggleVariant =\n | \"default\"\n | \"outline\"\n | \"ghost\"\n | \"link\"\n | \"circle\"\n | \"icon\";\n\nexport interface ThemeToggleProps {\n className?: string;\n style?: React.CSSProperties;\n showLabels?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n lightIcon?: ReactNode | LucideIcon | string;\n darkIcon?: ReactNode | LucideIcon | string;\n ariaLabel?: string;\n variant?: ThemeToggleVariant;\n}\n\nexport const ThemeToggle: React.FC<ThemeToggleProps> = ({\n className = \"\",\n style = {},\n showLabels = false,\n size = \"md\",\n lightIcon = <Sun /> as ReactNode | LucideIcon | string,\n darkIcon = <Moon /> as ReactNode | LucideIcon | string,\n ariaLabel = \"Toggle theme\",\n variant = \"default\",\n}) => {\n const { resolvedMode, toggleMode } = useTheme();\n\n const iconSizeMap: Record<NonNullable<ThemeToggleProps['size']>, string> = {\n sm: 'var(--asm-icon-size-sm)',\n md: 'var(--asm-icon-size-md)',\n lg: 'var(--asm-icon-size-lg)',\n };\n\n const circleSizeMap: Record<NonNullable<ThemeToggleProps['size']>, string> = {\n sm: '32px',\n md: '40px',\n lg: '48px',\n };\n\n const renderIcon = (icon: ReactNode | LucideIcon | string) => {\n if (React.isValidElement(icon)) {\n return icon;\n }\n if (typeof icon === 'function') {\n const IconComp = icon as LucideIcon;\n return <IconComp size={iconSizeMap[size]} strokeWidth={1.5} aria-hidden=\"true\" />;\n }\n return icon as React.ReactNode;\n };\n\n const getIcon = () => {\n return resolvedMode === \"dark\" ? renderIcon(darkIcon) : renderIcon(lightIcon);\n };\n\n const getLabel = () => {\n return resolvedMode === \"dark\" ? \"Dark\" : \"Light\";\n };\n\n const baseStyles: CSSProperties = {\n borderRadius: 'var(--asm-radius-md)',\n padding: 'var(--asm-space-2)',\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--asm-space-2)',\n fontSize: 'var(--asm-font-size-md)',\n transition: 'var(--asm-transition-fade), var(--asm-transition-scale)',\n border: 'none',\n };\n\n const variantStyles: Record<ThemeToggleVariant, CSSProperties> = {\n default: {\n background: 'var(--asm-color-button-secondary-bg)',\n border: `var(--asm-border-hairline) solid var(--asm-color-border)`,\n color: 'var(--asm-color-button-secondary-text)',\n },\n outline: {\n background: 'transparent',\n border: `var(--asm-border-hairline) solid var(--asm-color-border)`,\n color: 'var(--asm-color-text)',\n },\n ghost: {\n background: 'transparent',\n color: 'var(--asm-color-text)',\n },\n link: {\n background: 'transparent',\n padding: 0,\n color: 'var(--asm-color-button-primary-bg)',\n },\n circle: {\n background: 'var(--asm-color-button-secondary-bg)',\n border: `var(--asm-border-hairline) solid var(--asm-color-border)`,\n borderRadius: 'var(--asm-radius-full)',\n },\n icon: {\n background: 'transparent',\n padding: 0,\n },\n };\n\n const mergedStyles: CSSProperties = {\n ...baseStyles,\n ...(variantStyles[variant] ?? variantStyles.default),\n ...(variant === \"circle\" ? { width: circleSizeMap[size], height: circleSizeMap[size] } : {}),\n ...style,\n };\n \n return (\n <button\n aria-label={ariaLabel}\n type=\"button\"\n style={mergedStyles}\n onClick={toggleMode}\n className={className}\n title={ariaLabel}\n onMouseEnter={(e) => {\n if (variant === 'ghost' || variant === 'icon') {\n e.currentTarget.style.background = 'var(--asm-color-button-ghost-bg-hover)';\n }\n }}\n onMouseLeave={(e) => {\n if (variant === 'ghost' || variant === 'icon') {\n e.currentTarget.style.background = 'transparent';\n }\n }}\n >\n {getIcon()}\n {showLabels && (\n <span style={{ fontSize: 'var(--asm-font-size-sm)', fontWeight: 'var(--asm-font-weight-500)' }}>\n {getLabel()}\n </span>\n )}\n </button>\n );\n};\n","import * as React from \"react\";\nimport { useTheme } from \"../hooks/useTheme\";\nimport type { ThemeMode } from \"../types\";\nimport { Sun, Moon, Monitor } from \"lucide-react\";\n\nexport interface ThemeSelectorProps {\n className?: string;\n style?: React.CSSProperties;\n variant?: \"buttons\" | \"dropdown\";\n}\n\nexport const ThemeSelector: React.FC<ThemeSelectorProps> = ({\n className = \"\",\n style = {},\n variant = \"buttons\",\n}) => {\n const { mode, setMode } = useTheme();\n\n const options = [\n { mode: \"light\" as ThemeMode, label: \"Light\", Icon: Sun },\n { mode: \"dark\" as ThemeMode, label: \"Dark\", Icon: Moon },\n { mode: \"auto\" as ThemeMode, label: \"Auto\", Icon: Monitor },\n ];\n\n if (variant === \"dropdown\") {\n const selectStyles: React.CSSProperties = {\n padding: 'var(--asm-space-control-padding-y) var(--asm-space-control-padding-x)',\n borderRadius: 'var(--asm-radius-md)',\n border: `var(--asm-border-hairline) solid var(--asm-color-input-border)`,\n backgroundColor: 'var(--asm-color-input-bg)',\n color: 'var(--asm-color-input-text)',\n fontSize: 'var(--asm-font-size-sm)',\n fontFamily: 'var(--asm-font-family-primary)',\n cursor: 'pointer',\n transition: 'var(--asm-transition-fade)',\n outline: 'none',\n ...style,\n };\n\n return (\n <select\n value={mode}\n onChange={(e) => setMode(e.target.value as ThemeMode)}\n style={selectStyles}\n className={className}\n aria-label=\"Select theme mode\"\n onFocus={(e) => {\n e.currentTarget.style.borderColor = 'var(--asm-color-input-border-focus)';\n e.currentTarget.style.boxShadow = `0 0 0 2px var(--asm-color-focus-ring)`;\n }}\n onBlur={(e) => {\n e.currentTarget.style.borderColor = 'var(--asm-color-input-border)';\n e.currentTarget.style.boxShadow = 'none';\n }}\n >\n {options.map((option) => (\n <option key={option.mode} value={option.mode}>\n {option.label}\n </option>\n ))}\n </select>\n );\n }\n\n const containerStyles: React.CSSProperties = {\n display: 'inline-flex',\n gap: 'var(--asm-space-1)',\n padding: 'var(--asm-space-1)',\n borderRadius: 'var(--asm-radius-lg)',\n backgroundColor: 'var(--asm-color-surface-muted)',\n ...style,\n };\n\n const buttonStyles = (isActive: boolean): React.CSSProperties => ({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--asm-space-2)',\n padding: 'var(--asm-space-2) var(--asm-space-3)',\n borderRadius: 'var(--asm-radius-md)',\n border: 'none',\n backgroundColor: isActive ? 'var(--asm-color-button-primary-bg)' : 'transparent',\n color: isActive ? 'var(--asm-color-button-primary-text)' : 'var(--asm-color-text)',\n fontSize: 'var(--asm-font-size-sm)',\n fontWeight: 'var(--asm-font-weight-500)',\n cursor: 'pointer',\n transition: 'var(--asm-transition-fade), var(--asm-transition-scale)',\n });\n\n return (\n <div style={containerStyles} className={className} role=\"radiogroup\" aria-label=\"Theme mode selector\">\n {options.map((option) => {\n const isActive = mode === option.mode;\n const Icon = option.Icon;\n return (\n <button\n key={option.mode}\n onClick={() => setMode(option.mode)}\n style={buttonStyles(isActive)}\n role=\"radio\"\n aria-checked={isActive}\n aria-label={`${option.label} mode`}\n onMouseEnter={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'var(--asm-color-button-ghost-bg-hover)';\n }\n }}\n onMouseLeave={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'transparent';\n }\n }}\n >\n <Icon size={16} strokeWidth={1.5} />\n <span>{option.label}</span>\n </button>\n );\n })}\n </div>\n );\n};\n","import * as React from \"react\";\nimport { useTheme } from \"../hooks/useTheme\";\nimport type { DensityMode } from \"../types\";\n\nexport interface DensitySelectorProps {\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const DensitySelector: React.FC<DensitySelectorProps> = ({\n className = \"\",\n style = {},\n}) => {\n const { density, setDensity } = useTheme();\n\n const options: Array<{ mode: DensityMode; label: string }> = [\n { mode: \"compact\", label: \"Compact\" },\n { mode: \"default\", label: \"Default\" },\n { mode: \"comfortable\", label: \"Comfortable\" },\n ];\n\n const containerStyles: React.CSSProperties = {\n display: 'inline-flex',\n gap: 'var(--asm-space-1)',\n padding: 'var(--asm-space-1)',\n borderRadius: 'var(--asm-radius-lg)',\n backgroundColor: 'var(--asm-color-surface-muted)',\n ...style,\n };\n\n const buttonStyles = (isActive: boolean): React.CSSProperties => ({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 'var(--asm-space-2) var(--asm-space-3)',\n borderRadius: 'var(--asm-radius-md)',\n border: 'none',\n backgroundColor: isActive ? 'var(--asm-color-button-primary-bg)' : 'transparent',\n color: isActive ? 'var(--asm-color-button-primary-text)' : 'var(--asm-color-text)',\n fontSize: 'var(--asm-font-size-sm)',\n fontWeight: 'var(--asm-font-weight-500)',\n cursor: 'pointer',\n transition: 'var(--asm-transition-fade)',\n });\n\n return (\n <div style={containerStyles} className={className} role=\"radiogroup\" aria-label=\"Density selector\">\n {options.map((option) => {\n const isActive = density === option.mode;\n return (\n <button\n key={option.mode}\n onClick={() => setDensity(option.mode)}\n style={buttonStyles(isActive)}\n role=\"radio\"\n aria-checked={isActive}\n aria-label={`${option.label} density`}\n onMouseEnter={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'var(--asm-color-button-ghost-bg-hover)';\n }\n }}\n onMouseLeave={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'transparent';\n }\n }}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n );\n};\n"],"mappings":"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","names":["index_exports","__export","DensitySelector","ThemeProvider","ThemeSelector","ThemeToggle","useTheme","__toCommonJS","import_react","import_css","import_jsx_runtime","ThemeContext","ThemeProvider","children","defaultMode","defaultDensity","defaultDirection","storageKey","enableTransitions","persistMode","persistDensity","persistDirection","getStoredValue","key","defaultValue","setStoredValue","value","persist","error","mode","setModeState","density","setDensityState","direction","setDirectionState","systemPrefersDark","setSystemPrefersDark","resolvedMode","setMode","newMode","setDensity","newDensity","setDirection","newDirection","toggleMode","mediaQuery","handleChange","e","root","contextValue","useThemeContext","context","useTheme","useThemeContext","React","import_lucide_react","import_jsx_runtime","ThemeToggle","className","style","showLabels","size","lightIcon","darkIcon","ariaLabel","variant","resolvedMode","toggleMode","useTheme","iconSizeMap","circleSizeMap","renderIcon","icon","getIcon","getLabel","baseStyles","variantStyles","mergedStyles","e","import_lucide_react","import_jsx_runtime","ThemeSelector","className","style","variant","mode","setMode","useTheme","options","selectStyles","e","option","containerStyles","buttonStyles","isActive","Icon","import_jsx_runtime","DensitySelector","className","style","density","setDensity","useTheme","options","containerStyles","buttonStyles","isActive","option","e"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
inline-flex items-center justify-center
|
|
3
|
-
focus:outline-none focus:ring-2 focus:ring-blue-500
|
|
4
|
-
transition-all duration-200
|
|
5
|
-
${e}
|
|
6
|
-
`.trim(),f=d=>E.isValidElement(d)?d:typeof d=="function"?u(d,{"aria-hidden":"true"}):d,h=()=>{switch(c){case"light":return f(t);case"dark":return f(n);case"auto":default:return"\u{1F313}"}},g=()=>{switch(c){case"light":return"Light";case"dark":return"Dark";case"auto":default:return"Auto"}},S={borderRadius:"var(--theme-radius-md, 0.375rem)",padding:"0.5rem",cursor:"pointer",display:"inline-flex",alignItems:"center",justifyContent:"center",fontSize:p[o],transition:"all 0.2s ease-in-out",color:"var(--color-text, #0f172a)"},x={default:{background:"var(--color-surface, white)",border:"1px solid var(--color-border, #e5e7eb)",color:"var(--color-text, #0f172a)",textAlign:"center"},outline:{background:"transparent",border:"1px solid var(--color-border, #e5e7eb)",color:"var(--color-text, #0f172a)",textAlign:"center",outline:"none"},ghost:{background:"transparent",border:"none",color:"var(--color-text, #0f172a)",textAlign:"center"},link:{background:"transparent",border:"none",padding:0,fontSize:"1rem",color:"var(--color-primary, #2563eb)",textAlign:"center"},circle:{background:"var(--color-surface, white)",border:"1px solid var(--color-border, #e5e7eb)",borderRadius:"9999px",textAlign:"center"},icon:{background:"transparent",border:"none",padding:0,fontSize:"1.5rem",textAlign:"center"}},i={...{...S,...x[s]??x.default,...r},...s==="circle"?{width:y[o],height:y[o]}:{}};return Q("button",{"aria-label":l,type:"button",style:i,onClick:v,className:k,title:l,children:[u("span",{role:"img","aria-hidden":"true",children:h()}),a&&u("span",{className:"ml-2 text-sm font-medium",children:g()})]})};import{jsx as F}from"react/jsx-runtime";var U=({className:e="",style:r={},showLabels:a=!0,options:o=[{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:n}=m(),l=`
|
|
7
|
-
px-3 py-2 border border-gray-300 rounded-md
|
|
8
|
-
bg-white dark:bg-gray-800 dark:border-gray-600
|
|
9
|
-
text-gray-900 dark:text-gray-100
|
|
10
|
-
focus:outline-none focus:ring-2 focus:ring-blue-500
|
|
11
|
-
transition-all duration-200
|
|
12
|
-
${e}
|
|
13
|
-
`.trim();return F("select",{value:t,onChange:s=>n(s.target.value),className:l,style:r,"aria-label":"Select theme mode",children:o.map(s=>F("option",{value:s.mode,children:a?`${s.icon?s.icon+" ":""}${s.label}`:s.icon||s.label},s.mode))})};function Z(e,r){return{...e,...r,name:r.name||`${e.name}-custom`,colors:{...e.colors,...r.colors},spacing:{...e.spacing,...r.spacing},radius:{...e.radius,...r.radius},typography:{...e.typography,...r.typography,fontFamily:{...e.typography.fontFamily,...r.typography?.fontFamily},fontSize:{...e.typography.fontSize,...r.typography?.fontSize},fontWeight:{...e.typography.fontWeight,...r.typography?.fontWeight},lineHeight:{...e.typography.lineHeight,...r.typography?.lineHeight}},transitions:{...e.transitions,...r.transitions},zIndex:{...e.zIndex,...r.zIndex}}}function q(...e){if(e.length===0)throw new Error("At least one theme must be provided to mergeThemes");let[r,...a]=e;if(!J(r))throw new Error("First theme must be a complete theme object");return a.reduce((o,t)=>({...o,...t,name:t.name||o.name,mode:t.mode||o.mode,colors:{...o.colors,...t.colors},spacing:{...o.spacing,...t.spacing},radius:{...o.radius,...t.radius},typography:{...o.typography,...t.typography,fontFamily:{...o.typography.fontFamily,...t.typography?.fontFamily},fontSize:{...o.typography.fontSize,...t.typography?.fontSize},fontWeight:{...o.typography.fontWeight,...t.typography?.fontWeight},lineHeight:{...o.typography.lineHeight,...t.typography?.lineHeight}},transitions:{...o.transitions,...t.transitions},zIndex:{...o.zIndex,...t.zIndex}}),r)}function J(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 K(e,...r){return r.reduce((a,o)=>({...a,...o}),e)}function X(e,...r){return r.reduce((a,o)=>{let t={...a};for(let n in o){let l=o[n],s=a[n];l&&typeof l=="object"&&!Array.isArray(l)&&s&&typeof s=="object"?t[n]={...s,...l}:l!==void 0&&(t[n]=l)}return t},e)}export{A as ThemeProvider,U as ThemeSelector,G as ThemeToggle,b as applyTheme,Z as createTheme,C as darkTheme,X as deepMergeThemes,A as default,_ as defaultTheme,P as defaultThemes,T as lightTheme,te as mergeTheme,K as mergeThemeColors,q as mergeThemes,ee as themes,m as useTheme,V as useThemeToggle};
|
|
1
|
+
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};
|
|
14
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/themes.ts","../src/components/ThemeProvider.tsx","../src/utils/applyTheme.ts","../src/hooks/useTheme.ts","../src/hooks/useThemeToggle.ts","../src/components/ThemeToggle.tsx","../src/components/ThemeSelector.tsx","../src/utils/createTheme.ts","../src/utils/mergeThemes.ts"],"sourcesContent":["import type { Theme, ThemeColors } from './types';\n\n// Light theme colors\nconst lightColors: ThemeColors = {\n // Background colors\n background: '#ffffff',\n backgroundSecondary: '#f8fafc',\n backgroundTertiary: '#f1f5f9',\n \n // Text colors\n text: '#0f172a',\n textSecondary: '#475569',\n textMuted: '#64748b',\n \n // Border colors\n border: '#e2e8f0',\n borderLight: '#f1f5f9',\n borderHover: '#cbd5e1',\n \n // Accent colors\n primary: '#3b82f6',\n primaryHover: '#2563eb',\n primaryActive: '#1d4ed8',\n \n // Status colors\n success: '#10b981',\n warning: '#f59e0b',\n error: '#ef4444',\n info: '#06b6d4',\n \n // Interactive states\n hover: '#f8fafc',\n active: '#f1f5f9',\n focus: 'rgba(59, 130, 246, 0.1)',\n \n // Shadows\n shadow: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',\n shadowMd: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n shadowLg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',\n};\n\n// Dark theme colors\nconst darkColors: ThemeColors = {\n // Background colors\n background: '#0f172a',\n backgroundSecondary: '#1e293b',\n backgroundTertiary: '#334155',\n \n // Text colors\n text: '#f8fafc',\n textSecondary: '#cbd5e1',\n textMuted: '#94a3b8',\n \n // Border colors\n border: '#334155',\n borderLight: '#475569',\n borderHover: '#64748b',\n \n // Accent colors\n primary: '#60a5fa',\n primaryHover: '#3b82f6',\n primaryActive: '#2563eb',\n \n // Status colors\n success: '#34d399',\n warning: '#fbbf24',\n error: '#f87171',\n info: '#22d3ee',\n \n // Interactive states\n hover: '#1e293b',\n active: '#334155',\n focus: 'rgba(96, 165, 250, 0.1)',\n \n // Shadows\n shadow: '0 1px 2px 0 rgba(0, 0, 0, 0.3)',\n shadowMd: '0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3)',\n shadowLg: '0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -2px rgba(0, 0, 0, 0.3)',\n};\n\n// Base theme structure\nconst baseTheme = {\n spacing: {\n xs: '0.25rem',\n sm: '0.5rem',\n md: '0.75rem',\n lg: '1rem',\n xl: '1.25rem',\n '2xl': '1.5rem',\n '3xl': '2rem',\n '4xl': '3rem',\n },\n radius: {\n none: '0',\n sm: '0.25rem',\n md: '0.375rem',\n lg: '0.5rem',\n xl: '0.75rem',\n '2xl': '1rem',\n full: '9999px',\n },\n typography: {\n fontFamily: {\n sans: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif',\n serif: 'ui-serif, Georgia, Cambria, \"Times New Roman\", Times, serif',\n mono: 'ui-monospace, SFMono-Regular, \"SF Mono\", Consolas, \"Liberation Mono\", Menlo, monospace',\n },\n fontSize: {\n xs: '0.75rem',\n sm: '0.875rem',\n base: '1rem',\n lg: '1.125rem',\n xl: '1.25rem',\n '2xl': '1.5rem',\n '3xl': '1.875rem',\n '4xl': '2.25rem',\n '5xl': '3rem',\n },\n fontWeight: {\n light: '300',\n normal: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n },\n lineHeight: {\n tight: '1.25',\n normal: '1.5',\n relaxed: '1.75',\n },\n },\n transitions: {\n fast: 'all 0.1s ease',\n normal: 'all 0.2s ease',\n slow: 'all 0.3s ease',\n bounce: 'all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)',\n },\n zIndex: {\n dropdown: 1000,\n modal: 1050,\n tooltip: 1100,\n overlay: 1200,\n },\n};\n\n// Light theme\nexport const lightTheme: Theme = {\n name: 'light',\n mode: 'light',\n colors: lightColors,\n ...baseTheme,\n};\n\n// Dark theme\nexport const darkTheme: Theme = {\n name: 'dark',\n mode: 'dark',\n colors: darkColors,\n ...baseTheme,\n};\n\n// Default theme (light)\nexport const defaultTheme = lightTheme;\n\n// Theme presets\nexport const themes = {\n light: lightTheme,\n dark: darkTheme,\n};\n\n// Default themes for the provider\nexport const defaultThemes = {\n default: lightTheme,\n light: lightTheme,\n dark: darkTheme,\n};\n\n// Helper function to merge themes\nexport function mergeTheme(baseTheme: Theme, customTheme: Partial<Theme>): Theme {\n return {\n ...baseTheme,\n ...customTheme,\n colors: {\n ...baseTheme.colors,\n ...customTheme.colors,\n },\n spacing: {\n ...baseTheme.spacing,\n ...customTheme.spacing,\n },\n radius: {\n ...baseTheme.radius,\n ...customTheme.radius,\n },\n typography: {\n ...baseTheme.typography,\n ...customTheme.typography,\n fontFamily: {\n ...baseTheme.typography.fontFamily,\n ...customTheme.typography?.fontFamily,\n },\n fontSize: {\n ...baseTheme.typography.fontSize,\n ...customTheme.typography?.fontSize,\n },\n fontWeight: {\n ...baseTheme.typography.fontWeight,\n ...customTheme.typography?.fontWeight,\n },\n lineHeight: {\n ...baseTheme.typography.lineHeight,\n ...customTheme.typography?.lineHeight,\n },\n },\n transitions: {\n ...baseTheme.transitions,\n ...customTheme.transitions,\n },\n zIndex: {\n ...baseTheme.zIndex,\n ...customTheme.zIndex,\n },\n };\n}\n","import * as React from 'react';\nimport { createContext, useContext, useEffect, useState, ReactNode } from 'react';\nimport { Theme, ThemeConfig, ThemeMode } from '../types';\nimport { defaultThemes } from '../themes';\nimport { applyTheme } from '../utils/applyTheme';\n\nexport interface ThemeContextType {\n currentTheme: Theme;\n mode: ThemeMode;\n setMode: (mode: ThemeMode) => void;\n setTheme: (theme: Theme) => void;\n themes: Record<string, Theme>;\n toggleMode: () => void;\n}\n\nconst ThemeContext = createContext<ThemeContextType | undefined>(undefined);\n\nexport interface ThemeProviderProps {\n children: ReactNode;\n config?: ThemeConfig;\n defaultMode?: ThemeMode;\n defaultTheme?: string;\n persistMode?: boolean;\n storageKey?: string;\n customThemes?: Record<string, Theme>;\n}\n\nexport const ThemeProvider: React.FC<ThemeProviderProps> = ({\n children,\n defaultMode = 'auto',\n defaultTheme = 'default',\n persistMode = true,\n storageKey = 'asafarim-theme-mode',\n customThemes = {},\n}) => {\n const allThemes = { ...defaultThemes, ...customThemes };\n \n // Get initial mode from localStorage or use default\n const getInitialMode = (): ThemeMode => {\n if (!persistMode || typeof window === 'undefined') return defaultMode;\n \n try {\n const stored = localStorage.getItem(storageKey);\n if (stored && ['light', 'dark', 'auto'].includes(stored)) {\n return stored as ThemeMode;\n }\n } catch (error) {\n console.warn('Failed to read theme mode from localStorage:', error);\n }\n \n return defaultMode;\n };\n const [mode, setModeState] = useState<ThemeMode>(getInitialMode);\n const [currentThemeName, setCurrentThemeName] = useState<string>(defaultTheme);\n\n // Get the effective mode (resolving 'auto' to actual light/dark)\n const getEffectiveMode = (): 'light' | 'dark' => {\n if (mode === 'auto') {\n if (typeof window !== 'undefined') {\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n return 'light'; // fallback for SSR\n }\n return mode;\n };\n // Get the current theme based on mode and theme name\n const getCurrentTheme = (): Theme => {\n const effectiveMode = getEffectiveMode();\n \n // If user selected a specific theme, use it\n if (currentThemeName !== 'default' && currentThemeName in allThemes) {\n return allThemes[currentThemeName as keyof typeof allThemes];\n }\n \n // Otherwise use the theme that matches the effective mode\n return effectiveMode === 'dark' ? allThemes.dark : allThemes.light;\n };\n\n const currentTheme = getCurrentTheme();\n\n // Update mode and persist if enabled\n const setMode = (newMode: ThemeMode) => {\n setModeState(newMode);\n \n if (persistMode && typeof window !== 'undefined') {\n try {\n localStorage.setItem(storageKey, newMode);\n } catch (error) {\n console.warn('Failed to save theme mode to localStorage:', error);\n }\n }\n };\n\n // Toggle between light and dark modes\n const toggleMode = () => {\n if (mode === 'auto') {\n // If auto, switch to opposite of system preference\n const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n setMode(systemDark ? 'light' : 'dark');\n } else {\n setMode(mode === 'light' ? 'dark' : 'light');\n }\n };\n // Set theme by name\n const setTheme = (theme: Theme) => {\n setCurrentThemeName(theme.name);\n };\n // Apply theme to document\n useEffect(() => {\n applyTheme(currentTheme, mode);\n }, [currentTheme, mode, currentThemeName]); // Add currentThemeName as dependency\n\n // Listen for system theme changes when in auto mode\n useEffect(() => {\n if (mode !== 'auto') return;\n\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const handleChange = () => {\n // Force re-render when system preference changes\n applyTheme(getCurrentTheme(), mode);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, [mode]);\n\n const contextValue: ThemeContextType = {\n currentTheme,\n mode,\n setMode,\n setTheme,\n themes: allThemes,\n toggleMode,\n };\n\n return (\n <ThemeContext.Provider value={contextValue}>\n {children}\n </ThemeContext.Provider>\n );\n};\n\nexport const useThemeContext = () => {\n const context = useContext(ThemeContext);\n if (context === undefined) {\n throw new Error('useThemeContext must be used within a ThemeProvider');\n }\n return context;\n};\n","import { Theme, ThemeMode } from '../types';\n\n/**\n * Applies theme CSS variables to the document root\n */\nexport function applyTheme(theme: Theme, mode: ThemeMode): void {\n if (typeof document === 'undefined') return;\n\n const root = document.documentElement;\n \n // Determine the effective mode\n let effectiveMode = mode;\n if (mode === 'auto') {\n effectiveMode = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n\n // Set data attributes for CSS targeting\n root.setAttribute('data-theme', theme.name);\n root.setAttribute('data-theme-mode', effectiveMode);\n\n // Apply color variables\n Object.entries(theme.colors).forEach(([key, value]) => {\n root.style.setProperty(`--theme-color-${kebabCase(key)}`, value);\n });\n\n // Apply spacing variables\n Object.entries(theme.spacing).forEach(([key, value]) => {\n root.style.setProperty(`--theme-spacing-${key}`, value);\n });\n\n // Apply radius variables\n Object.entries(theme.radius).forEach(([key, value]) => {\n root.style.setProperty(`--theme-radius-${key}`, value);\n });\n\n // Apply typography variables\n Object.entries(theme.typography.fontFamily).forEach(([key, value]) => {\n root.style.setProperty(`--theme-font-family-${key}`, value);\n });\n\n Object.entries(theme.typography.fontSize).forEach(([key, value]) => {\n root.style.setProperty(`--theme-font-size-${key}`, value);\n });\n\n Object.entries(theme.typography.fontWeight).forEach(([key, value]) => {\n root.style.setProperty(`--theme-font-weight-${key}`, value);\n });\n\n Object.entries(theme.typography.lineHeight).forEach(([key, value]) => {\n root.style.setProperty(`--theme-line-height-${key}`, value);\n });\n\n // Apply transition variables\n Object.entries(theme.transitions).forEach(([key, value]) => {\n root.style.setProperty(`--theme-transition-${key}`, value);\n });\n\n // Apply z-index variables\n Object.entries(theme.zIndex).forEach(([key, value]) => {\n root.style.setProperty(`--theme-z-index-${kebabCase(key)}`, value.toString());\n });\n\n // Add theme class to body for additional styling\n document.body.className = document.body.className.replace(/theme-\\w+/g, '');\n document.body.classList.add(`theme-${theme.name}`, `theme-${effectiveMode}`);\n}\n\n/**\n * Removes all theme-related CSS variables and classes\n */\nexport function removeTheme(): void {\n if (typeof document === 'undefined') return;\n\n const root = document.documentElement;\n \n // Remove data attributes\n root.removeAttribute('data-theme');\n root.removeAttribute('data-theme-mode');\n\n // Remove CSS variables (this is a simplified approach - in production you might want to track which variables were set)\n const styles = root.style;\n for (let i = styles.length - 1; i >= 0; i--) {\n const property = styles[i];\n if (property.startsWith('--theme-')) {\n root.style.removeProperty(property);\n }\n }\n\n // Remove theme classes from body\n document.body.className = document.body.className.replace(/theme-\\w+/g, '');\n}\n\n/**\n * Converts camelCase to kebab-case\n */\nfunction kebabCase(str: string): string {\n return str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\n}\n","import { useThemeContext, ThemeContextType } from '../components/ThemeProvider';\n\n/**\n * Hook to access theme context\n */\nexport function useTheme(): ThemeContextType {\n return useThemeContext();\n}\n","import { useTheme } from './useTheme';\n\n/**\n * Hook that provides theme toggle functionality\n */\nexport function useThemeToggle() {\n const { mode, setMode, toggleMode } = useTheme();\n \n // Get effective mode (resolving 'auto' to actual light/dark)\n const getEffectiveMode = (): 'light' | 'dark' => {\n if (mode === 'auto') {\n if (typeof window !== 'undefined') {\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n return 'light'; // fallback for SSR\n }\n return mode;\n };\n\n const effectiveMode = getEffectiveMode();\n \n return {\n mode,\n setMode,\n toggleMode,\n isDark: effectiveMode === 'dark',\n isLight: effectiveMode === 'light',\n isAuto: mode === 'auto',\n effectiveMode, // Expose the resolved mode\n };\n}\n","import * as React from \"react\";\nimport { useTheme } from \"../hooks/useTheme\";\nimport type { CSSProperties, ReactNode } from 'react';\nimport { Moon, Sun, type LucideIcon } from \"lucide-react\";\n\ntype ThemeToggleVariant =\n | \"default\"\n | \"outline\"\n | \"ghost\"\n | \"link\"\n | \"circle\"\n | \"icon\";\n\nexport interface ThemeToggleProps {\n className?: string;\n style?: React.CSSProperties;\n showLabels?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Custom light icon (default: ☀️)\n */\n lightIcon?: ReactNode | LucideIcon | string;\n\n /**\n * Custom dark icon (default: 🌙)\n */\n darkIcon?: ReactNode | LucideIcon | string;\n\n /**\n * Button aria-label\n */\n ariaLabel?: string;\n\n /**\n * Button variant\n */\n variant?: ThemeToggleVariant;\n}\n\nexport const ThemeToggle: React.FC<ThemeToggleProps> = ({\n className = \"\",\n style = {},\n showLabels = false,\n size = \"md\",\n lightIcon = <Sun /> as ReactNode | LucideIcon | string,\n darkIcon = <Moon /> as ReactNode | LucideIcon | string,\n ariaLabel = \"Toggle theme\",\n variant = \"default\",\n}) => {\n const { mode, toggleMode } = useTheme();\n\n const fontSizeMap: Record<NonNullable<ThemeToggleProps['size']>, string> = {\n sm: '1rem',\n md: '1.25rem',\n lg: '1.5rem',\n };\n\n const circleSizeMap: Record<NonNullable<ThemeToggleProps['size']>, string> = {\n sm: '2rem',\n md: '2.5rem',\n lg: '3rem',\n };\n\n const buttonClass = `\n inline-flex items-center justify-center\n focus:outline-none focus:ring-2 focus:ring-blue-500\n transition-all duration-200\n ${className}\n `.trim();\n\n\n const renderIcon = (icon: ReactNode | LucideIcon | string) => {\n if (React.isValidElement(icon)) {\n return icon;\n }\n if (typeof icon === 'function') {\n const IconComp = icon as LucideIcon;\n return <IconComp aria-hidden=\"true\" />;\n }\n return icon as React.ReactNode;\n };\n\n const getIcon = () => {\n switch (mode) {\n case \"light\":\n return renderIcon(lightIcon);\n case \"dark\":\n return renderIcon(darkIcon);\n case \"auto\":\n default:\n return \"🌓\";\n }\n };\n\n\n const getLabel = () => {\n switch (mode) {\n case \"light\":\n return \"Light\";\n case \"dark\":\n return \"Dark\";\n case \"auto\":\n default:\n return \"Auto\";\n }\n };\n\n \n const baseStyles: CSSProperties = {\n borderRadius: 'var(--theme-radius-md, 0.375rem)',\n padding: '0.5rem',\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: fontSizeMap[size],\n transition: 'all 0.2s ease-in-out',\n color: 'var(--color-text, #0f172a)',\n };\n\n\n const variantStyles: Record<ThemeToggleVariant, CSSProperties> = {\n default: {\n background: 'var(--color-surface, white)',\n border: '1px solid var(--color-border, #e5e7eb)',\n color: 'var(--color-text, #0f172a)',\n textAlign: 'center',\n },\n outline: {\n background: 'transparent',\n border: '1px solid var(--color-border, #e5e7eb)',\n color: 'var(--color-text, #0f172a)',\n textAlign: 'center',\n outline: 'none',\n \n },\n ghost: {\n background: 'transparent',\n border: 'none',\n color: 'var(--color-text, #0f172a)',\n textAlign: 'center',\n },\n link: {\n background: 'transparent',\n border: 'none',\n padding: 0,\n fontSize: '1rem',\n color: 'var(--color-primary, #2563eb)',\n textAlign: 'center',\n\n },\n circle: {\n background: 'var(--color-surface, white)',\n border: '1px solid var(--color-border, #e5e7eb)',\n borderRadius: '9999px',\n textAlign: 'center',\n },\n\n icon: {\n background: 'transparent',\n border: 'none',\n padding: 0,\n fontSize: '1.5rem',\n textAlign: 'center',\n },\n };\n\n const mergedStyles = {\n ...baseStyles,\n ...(variantStyles[variant] ?? variantStyles.default),\n ...style,\n };\n\n const finalStyles: CSSProperties = {\n ...mergedStyles,\n ...(variant === \"circle\" ? { width: circleSizeMap[size], height: circleSizeMap[size] } : {}),\n };\n \n return (\n <button\n aria-label={ariaLabel}\n type=\"button\"\n style={finalStyles}\n onClick={toggleMode}\n className={buttonClass}\n title={ariaLabel}\n >\n\n <span role=\"img\" aria-hidden=\"true\">\n {getIcon()}\n </span>\n {showLabels && (\n <span className=\"ml-2 text-sm font-medium\">{getLabel()}</span>\n )}\n </button>\n );\n};\n","import * as React from \"react\";\nimport { useTheme } from \"../hooks/useTheme\";\nimport { ThemeMode } from \"../types\";\n\nexport interface ThemeSelectorProps {\n className?: string;\n style?: React.CSSProperties;\n showLabels?: boolean;\n options?: Array<{\n mode: ThemeMode;\n label: string;\n icon?: string;\n }>;\n}\n\nexport const ThemeSelector: React.FC<ThemeSelectorProps> = ({\n className = \"\",\n style = {},\n showLabels = true,\n options = [\n { mode: \"light\", label: \"Light\", icon: \"☀️\" },\n { mode: \"dark\", label: \"Dark\", icon: \"🌙\" },\n { mode: \"auto\", label: \"Auto\", icon: \"🌓\" },\n ],\n}) => {\n const { mode, setMode } = useTheme();\n\n const selectClass = `\n px-3 py-2 border border-gray-300 rounded-md\n bg-white dark:bg-gray-800 dark:border-gray-600\n text-gray-900 dark:text-gray-100\n focus:outline-none focus:ring-2 focus:ring-blue-500\n transition-all duration-200\n ${className}\n `.trim();\n\n return (\n <select\n value={mode}\n onChange={(e) => setMode(e.target.value as ThemeMode)}\n className={selectClass}\n style={style}\n aria-label=\"Select theme mode\"\n >\n {options.map((option) => (\n <option key={option.mode} value={option.mode}>\n {showLabels\n ? `${option.icon ? option.icon + \" \" : \"\"}${option.label}`\n : option.icon || option.label}\n </option>\n ))}\n </select>\n );\n};\n","import { Theme } from '../types';\n\n/**\n * Creates a new theme by merging a base theme with custom properties\n */\nexport function createTheme(\n baseTheme: Theme,\n customTheme: Partial<Theme>\n): Theme {\n return {\n ...baseTheme,\n ...customTheme,\n name: customTheme.name || `${baseTheme.name}-custom`,\n colors: {\n ...baseTheme.colors,\n ...customTheme.colors,\n },\n spacing: {\n ...baseTheme.spacing,\n ...customTheme.spacing,\n },\n radius: {\n ...baseTheme.radius,\n ...customTheme.radius,\n },\n typography: {\n ...baseTheme.typography,\n ...customTheme.typography,\n fontFamily: {\n ...baseTheme.typography.fontFamily,\n ...customTheme.typography?.fontFamily,\n },\n fontSize: {\n ...baseTheme.typography.fontSize,\n ...customTheme.typography?.fontSize,\n },\n fontWeight: {\n ...baseTheme.typography.fontWeight,\n ...customTheme.typography?.fontWeight,\n },\n lineHeight: {\n ...baseTheme.typography.lineHeight,\n ...customTheme.typography?.lineHeight,\n },\n },\n transitions: {\n ...baseTheme.transitions,\n ...customTheme.transitions,\n },\n zIndex: {\n ...baseTheme.zIndex,\n ...customTheme.zIndex,\n },\n };\n}\n\n/**\n * Creates a theme variant with modified colors\n */\nexport function createThemeVariant(\n baseTheme: Theme,\n colorOverrides: Partial<Theme['colors']>,\n name?: string\n): Theme {\n return createTheme(baseTheme, {\n name: name || `${baseTheme.name}-variant`,\n colors: {\n ...baseTheme.colors,\n ...colorOverrides,\n },\n });\n}\n","import { Theme } from '../types';\n\n/**\n * Merges multiple themes into a single theme\n * Later themes in the array take precedence over earlier ones\n */\nexport function mergeThemes(...themes: Array<Theme | Partial<Theme>>): Theme {\n if (themes.length === 0) {\n throw new Error('At least one theme must be provided to mergeThemes');\n }\n\n const [baseTheme, ...additionalThemes] = themes;\n \n if (!isFullTheme(baseTheme)) {\n throw new Error('First theme must be a complete theme object');\n }\n return additionalThemes.reduce((merged: Theme, theme): Theme => {\n return {\n ...merged,\n ...theme,\n name: theme.name || merged.name,\n mode: theme.mode || merged.mode,\n colors: {\n ...merged.colors,\n ...theme.colors,\n },\n spacing: {\n ...merged.spacing,\n ...theme.spacing,\n },\n radius: {\n ...merged.radius,\n ...theme.radius,\n },\n typography: {\n ...merged.typography,\n ...theme.typography,\n fontFamily: {\n ...merged.typography.fontFamily,\n ...theme.typography?.fontFamily,\n },\n fontSize: {\n ...merged.typography.fontSize,\n ...theme.typography?.fontSize,\n },\n fontWeight: {\n ...merged.typography.fontWeight,\n ...theme.typography?.fontWeight,\n },\n lineHeight: {\n ...merged.typography.lineHeight,\n ...theme.typography?.lineHeight,\n },\n },\n transitions: {\n ...merged.transitions,\n ...theme.transitions,\n },\n zIndex: {\n ...merged.zIndex,\n ...theme.zIndex,\n },\n };\n }, baseTheme);\n}\n\n/**\n * Type guard to check if an object is a complete theme\n */\nfunction isFullTheme(theme: Theme | Partial<Theme>): theme is Theme {\n return !!(\n theme &&\n typeof theme === 'object' &&\n 'name' in theme &&\n 'mode' in theme &&\n 'colors' in theme &&\n 'spacing' in theme &&\n 'radius' in theme &&\n 'typography' in theme &&\n 'transitions' in theme &&\n 'zIndex' in theme\n );\n}\n\n/**\n * Merges theme colors only\n */\nexport function mergeThemeColors(\n baseColors: Theme['colors'],\n ...colorSets: Array<Partial<Theme['colors']>>\n): Theme['colors'] {\n return colorSets.reduce((merged: Theme['colors'], colors): Theme['colors'] => ({\n ...merged,\n ...colors,\n }), baseColors);\n}\n\n/**\n * Deep merge utility for complex theme objects\n */\nexport function deepMergeThemes(target: Theme, ...sources: Array<Partial<Theme>>): Theme {\n return sources.reduce((merged: Theme, source): Theme => {\n const result = { ...merged };\n \n for (const key in source) {\n const sourceValue = source[key as keyof Theme];\n const targetValue = merged[key as keyof Theme];\n \n if (sourceValue && typeof sourceValue === 'object' && !Array.isArray(sourceValue) && targetValue && typeof targetValue === 'object') {\n result[key as keyof Theme] = {\n ...targetValue,\n ...sourceValue,\n } as any;\n } else if (sourceValue !== undefined) {\n result[key as keyof Theme] = sourceValue as any;\n }\n }\n \n return result;\n }, target);\n}\n"],"mappings":"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","names":["lightColors","darkColors","baseTheme","lightTheme","darkTheme","defaultTheme","themes","defaultThemes","mergeTheme","customTheme","createContext","useContext","useEffect","useState","applyTheme","theme","mode","root","effectiveMode","key","value","kebabCase","kebabCase","str","match","jsx","ThemeContext","createContext","ThemeProvider","children","defaultMode","defaultTheme","persistMode","storageKey","customThemes","allThemes","defaultThemes","getInitialMode","stored","error","mode","setModeState","useState","currentThemeName","setCurrentThemeName","getEffectiveMode","getCurrentTheme","effectiveMode","currentTheme","setMode","newMode","toggleMode","systemDark","setTheme","theme","useEffect","applyTheme","mediaQuery","handleChange","contextValue","useThemeContext","context","useContext","useTheme","useThemeContext","useThemeToggle","mode","setMode","toggleMode","useTheme","effectiveMode","React","Moon","Sun","jsx","jsxs","ThemeToggle","className","style","showLabels","size","lightIcon","darkIcon","ariaLabel","variant","mode","toggleMode","useTheme","fontSizeMap","circleSizeMap","buttonClass","renderIcon","icon","getIcon","getLabel","baseStyles","variantStyles","finalStyles","jsx","ThemeSelector","className","style","showLabels","options","mode","setMode","useTheme","selectClass","e","option","createTheme","baseTheme","customTheme","mergeThemes","themes","baseTheme","additionalThemes","isFullTheme","merged","theme","mergeThemeColors","baseColors","colorSets","colors","deepMergeThemes","target","sources","source","result","key","sourceValue","targetValue"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/ThemeProvider.tsx","../src/hooks/useTheme.ts","../src/components/ThemeToggle.tsx","../src/components/ThemeSelector.tsx","../src/components/DensitySelector.tsx"],"sourcesContent":["import * as React from 'react';\nimport { createContext, useContext, useEffect, useState } from 'react';\nimport type { ThemeContextValue, ThemeProviderProps, ThemeMode, DensityMode, DirectionMode } from '../types';\nimport '@asafarim/design-tokens/css/index.css';\n\nconst ThemeContext = createContext<ThemeContextValue | undefined>(undefined);\n\nexport const ThemeProvider: React.FC<ThemeProviderProps> = ({\n children,\n defaultMode = 'auto',\n defaultDensity = 'default',\n defaultDirection = 'ltr',\n storageKey = 'asafarim-theme',\n enableTransitions = true,\n persistMode = true,\n persistDensity = false,\n persistDirection = false,\n}) => {\n const getStoredValue = <T extends string>(key: string, defaultValue: T): T => {\n if (typeof window === 'undefined') return defaultValue;\n try {\n const stored = localStorage.getItem(`${storageKey}-${key}`);\n return (stored as T) || defaultValue;\n } catch {\n return defaultValue;\n }\n };\n\n const setStoredValue = (key: string, value: string, persist: boolean) => {\n if (!persist || typeof window === 'undefined') return;\n try {\n localStorage.setItem(`${storageKey}-${key}`, value);\n } catch (error) {\n console.warn(`Failed to save ${key} to localStorage:`, error);\n }\n };\n\n const [mode, setModeState] = useState<ThemeMode>(() => \n persistMode ? getStoredValue('mode', defaultMode) : defaultMode\n );\n const [density, setDensityState] = useState<DensityMode>(() => \n persistDensity ? getStoredValue('density', defaultDensity) : defaultDensity\n );\n const [direction, setDirectionState] = useState<DirectionMode>(() => \n persistDirection ? getStoredValue('direction', defaultDirection) : defaultDirection\n );\n const [systemPrefersDark, setSystemPrefersDark] = useState<boolean>(false);\n\n const resolvedMode: 'light' | 'dark' = \n mode === 'auto' \n ? (systemPrefersDark ? 'dark' : 'light')\n : mode;\n\n const setMode = (newMode: ThemeMode) => {\n setModeState(newMode);\n setStoredValue('mode', newMode, persistMode);\n };\n\n const setDensity = (newDensity: DensityMode) => {\n setDensityState(newDensity);\n setStoredValue('density', newDensity, persistDensity);\n };\n\n const setDirection = (newDirection: DirectionMode) => {\n setDirectionState(newDirection);\n setStoredValue('direction', newDirection, persistDirection);\n };\n\n const toggleMode = () => {\n if (mode === 'auto') {\n setMode(systemPrefersDark ? 'light' : 'dark');\n } else {\n setMode(mode === 'light' ? 'dark' : 'light');\n }\n };\n\n useEffect(() => {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n setSystemPrefersDark(mediaQuery.matches);\n\n const handleChange = (e: MediaQueryListEvent) => {\n setSystemPrefersDark(e.matches);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, []);\n\n useEffect(() => {\n const root = document.documentElement;\n\n if (enableTransitions) {\n root.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)');\n }\n\n root.setAttribute('data-theme', resolvedMode);\n\n if (density !== 'default') {\n root.setAttribute('data-density', density);\n } else {\n root.removeAttribute('data-density');\n }\n\n root.setAttribute('dir', direction);\n\n return () => {\n if (enableTransitions) {\n root.style.removeProperty('transition');\n }\n };\n }, [resolvedMode, density, direction, enableTransitions]);\n\n const contextValue: ThemeContextValue = {\n mode,\n setMode,\n toggleMode,\n density,\n setDensity,\n direction,\n setDirection,\n isDark: resolvedMode === 'dark',\n isLight: resolvedMode === 'light',\n isAuto: mode === 'auto',\n systemPrefersDark,\n resolvedMode,\n };\n\n return (\n <ThemeContext.Provider value={contextValue}>\n {children}\n </ThemeContext.Provider>\n );\n};\n\nexport const useThemeContext = () => {\n const context = useContext(ThemeContext);\n if (context === undefined) {\n throw new Error('useThemeContext must be used within a ThemeProvider');\n }\n return context;\n};\n","import { useThemeContext } from '../components/ThemeProvider';\nimport type { ThemeContextValue } from '../types';\n\nexport function useTheme(): ThemeContextValue {\n return useThemeContext();\n}\n","import * as React from \"react\";\nimport { useTheme } from \"../hooks/useTheme\";\nimport type { CSSProperties, ReactNode } from 'react';\nimport { Moon, Sun, type LucideIcon } from \"lucide-react\";\n\ntype ThemeToggleVariant =\n | \"default\"\n | \"outline\"\n | \"ghost\"\n | \"link\"\n | \"circle\"\n | \"icon\";\n\nexport interface ThemeToggleProps {\n className?: string;\n style?: React.CSSProperties;\n showLabels?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n lightIcon?: ReactNode | LucideIcon | string;\n darkIcon?: ReactNode | LucideIcon | string;\n ariaLabel?: string;\n variant?: ThemeToggleVariant;\n}\n\nexport const ThemeToggle: React.FC<ThemeToggleProps> = ({\n className = \"\",\n style = {},\n showLabels = false,\n size = \"md\",\n lightIcon = <Sun /> as ReactNode | LucideIcon | string,\n darkIcon = <Moon /> as ReactNode | LucideIcon | string,\n ariaLabel = \"Toggle theme\",\n variant = \"default\",\n}) => {\n const { resolvedMode, toggleMode } = useTheme();\n\n const iconSizeMap: Record<NonNullable<ThemeToggleProps['size']>, string> = {\n sm: 'var(--asm-icon-size-sm)',\n md: 'var(--asm-icon-size-md)',\n lg: 'var(--asm-icon-size-lg)',\n };\n\n const circleSizeMap: Record<NonNullable<ThemeToggleProps['size']>, string> = {\n sm: '32px',\n md: '40px',\n lg: '48px',\n };\n\n const renderIcon = (icon: ReactNode | LucideIcon | string) => {\n if (React.isValidElement(icon)) {\n return icon;\n }\n if (typeof icon === 'function') {\n const IconComp = icon as LucideIcon;\n return <IconComp size={iconSizeMap[size]} strokeWidth={1.5} aria-hidden=\"true\" />;\n }\n return icon as React.ReactNode;\n };\n\n const getIcon = () => {\n return resolvedMode === \"dark\" ? renderIcon(darkIcon) : renderIcon(lightIcon);\n };\n\n const getLabel = () => {\n return resolvedMode === \"dark\" ? \"Dark\" : \"Light\";\n };\n\n const baseStyles: CSSProperties = {\n borderRadius: 'var(--asm-radius-md)',\n padding: 'var(--asm-space-2)',\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--asm-space-2)',\n fontSize: 'var(--asm-font-size-md)',\n transition: 'var(--asm-transition-fade), var(--asm-transition-scale)',\n border: 'none',\n };\n\n const variantStyles: Record<ThemeToggleVariant, CSSProperties> = {\n default: {\n background: 'var(--asm-color-button-secondary-bg)',\n border: `var(--asm-border-hairline) solid var(--asm-color-border)`,\n color: 'var(--asm-color-button-secondary-text)',\n },\n outline: {\n background: 'transparent',\n border: `var(--asm-border-hairline) solid var(--asm-color-border)`,\n color: 'var(--asm-color-text)',\n },\n ghost: {\n background: 'transparent',\n color: 'var(--asm-color-text)',\n },\n link: {\n background: 'transparent',\n padding: 0,\n color: 'var(--asm-color-button-primary-bg)',\n },\n circle: {\n background: 'var(--asm-color-button-secondary-bg)',\n border: `var(--asm-border-hairline) solid var(--asm-color-border)`,\n borderRadius: 'var(--asm-radius-full)',\n },\n icon: {\n background: 'transparent',\n padding: 0,\n },\n };\n\n const mergedStyles: CSSProperties = {\n ...baseStyles,\n ...(variantStyles[variant] ?? variantStyles.default),\n ...(variant === \"circle\" ? { width: circleSizeMap[size], height: circleSizeMap[size] } : {}),\n ...style,\n };\n \n return (\n <button\n aria-label={ariaLabel}\n type=\"button\"\n style={mergedStyles}\n onClick={toggleMode}\n className={className}\n title={ariaLabel}\n onMouseEnter={(e) => {\n if (variant === 'ghost' || variant === 'icon') {\n e.currentTarget.style.background = 'var(--asm-color-button-ghost-bg-hover)';\n }\n }}\n onMouseLeave={(e) => {\n if (variant === 'ghost' || variant === 'icon') {\n e.currentTarget.style.background = 'transparent';\n }\n }}\n >\n {getIcon()}\n {showLabels && (\n <span style={{ fontSize: 'var(--asm-font-size-sm)', fontWeight: 'var(--asm-font-weight-500)' }}>\n {getLabel()}\n </span>\n )}\n </button>\n );\n};\n","import * as React from \"react\";\nimport { useTheme } from \"../hooks/useTheme\";\nimport type { ThemeMode } from \"../types\";\nimport { Sun, Moon, Monitor } from \"lucide-react\";\n\nexport interface ThemeSelectorProps {\n className?: string;\n style?: React.CSSProperties;\n variant?: \"buttons\" | \"dropdown\";\n}\n\nexport const ThemeSelector: React.FC<ThemeSelectorProps> = ({\n className = \"\",\n style = {},\n variant = \"buttons\",\n}) => {\n const { mode, setMode } = useTheme();\n\n const options = [\n { mode: \"light\" as ThemeMode, label: \"Light\", Icon: Sun },\n { mode: \"dark\" as ThemeMode, label: \"Dark\", Icon: Moon },\n { mode: \"auto\" as ThemeMode, label: \"Auto\", Icon: Monitor },\n ];\n\n if (variant === \"dropdown\") {\n const selectStyles: React.CSSProperties = {\n padding: 'var(--asm-space-control-padding-y) var(--asm-space-control-padding-x)',\n borderRadius: 'var(--asm-radius-md)',\n border: `var(--asm-border-hairline) solid var(--asm-color-input-border)`,\n backgroundColor: 'var(--asm-color-input-bg)',\n color: 'var(--asm-color-input-text)',\n fontSize: 'var(--asm-font-size-sm)',\n fontFamily: 'var(--asm-font-family-primary)',\n cursor: 'pointer',\n transition: 'var(--asm-transition-fade)',\n outline: 'none',\n ...style,\n };\n\n return (\n <select\n value={mode}\n onChange={(e) => setMode(e.target.value as ThemeMode)}\n style={selectStyles}\n className={className}\n aria-label=\"Select theme mode\"\n onFocus={(e) => {\n e.currentTarget.style.borderColor = 'var(--asm-color-input-border-focus)';\n e.currentTarget.style.boxShadow = `0 0 0 2px var(--asm-color-focus-ring)`;\n }}\n onBlur={(e) => {\n e.currentTarget.style.borderColor = 'var(--asm-color-input-border)';\n e.currentTarget.style.boxShadow = 'none';\n }}\n >\n {options.map((option) => (\n <option key={option.mode} value={option.mode}>\n {option.label}\n </option>\n ))}\n </select>\n );\n }\n\n const containerStyles: React.CSSProperties = {\n display: 'inline-flex',\n gap: 'var(--asm-space-1)',\n padding: 'var(--asm-space-1)',\n borderRadius: 'var(--asm-radius-lg)',\n backgroundColor: 'var(--asm-color-surface-muted)',\n ...style,\n };\n\n const buttonStyles = (isActive: boolean): React.CSSProperties => ({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--asm-space-2)',\n padding: 'var(--asm-space-2) var(--asm-space-3)',\n borderRadius: 'var(--asm-radius-md)',\n border: 'none',\n backgroundColor: isActive ? 'var(--asm-color-button-primary-bg)' : 'transparent',\n color: isActive ? 'var(--asm-color-button-primary-text)' : 'var(--asm-color-text)',\n fontSize: 'var(--asm-font-size-sm)',\n fontWeight: 'var(--asm-font-weight-500)',\n cursor: 'pointer',\n transition: 'var(--asm-transition-fade), var(--asm-transition-scale)',\n });\n\n return (\n <div style={containerStyles} className={className} role=\"radiogroup\" aria-label=\"Theme mode selector\">\n {options.map((option) => {\n const isActive = mode === option.mode;\n const Icon = option.Icon;\n return (\n <button\n key={option.mode}\n onClick={() => setMode(option.mode)}\n style={buttonStyles(isActive)}\n role=\"radio\"\n aria-checked={isActive}\n aria-label={`${option.label} mode`}\n onMouseEnter={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'var(--asm-color-button-ghost-bg-hover)';\n }\n }}\n onMouseLeave={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'transparent';\n }\n }}\n >\n <Icon size={16} strokeWidth={1.5} />\n <span>{option.label}</span>\n </button>\n );\n })}\n </div>\n );\n};\n","import * as React from \"react\";\nimport { useTheme } from \"../hooks/useTheme\";\nimport type { DensityMode } from \"../types\";\n\nexport interface DensitySelectorProps {\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const DensitySelector: React.FC<DensitySelectorProps> = ({\n className = \"\",\n style = {},\n}) => {\n const { density, setDensity } = useTheme();\n\n const options: Array<{ mode: DensityMode; label: string }> = [\n { mode: \"compact\", label: \"Compact\" },\n { mode: \"default\", label: \"Default\" },\n { mode: \"comfortable\", label: \"Comfortable\" },\n ];\n\n const containerStyles: React.CSSProperties = {\n display: 'inline-flex',\n gap: 'var(--asm-space-1)',\n padding: 'var(--asm-space-1)',\n borderRadius: 'var(--asm-radius-lg)',\n backgroundColor: 'var(--asm-color-surface-muted)',\n ...style,\n };\n\n const buttonStyles = (isActive: boolean): React.CSSProperties => ({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 'var(--asm-space-2) var(--asm-space-3)',\n borderRadius: 'var(--asm-radius-md)',\n border: 'none',\n backgroundColor: isActive ? 'var(--asm-color-button-primary-bg)' : 'transparent',\n color: isActive ? 'var(--asm-color-button-primary-text)' : 'var(--asm-color-text)',\n fontSize: 'var(--asm-font-size-sm)',\n fontWeight: 'var(--asm-font-weight-500)',\n cursor: 'pointer',\n transition: 'var(--asm-transition-fade)',\n });\n\n return (\n <div style={containerStyles} className={className} role=\"radiogroup\" aria-label=\"Density selector\">\n {options.map((option) => {\n const isActive = density === option.mode;\n return (\n <button\n key={option.mode}\n onClick={() => setDensity(option.mode)}\n style={buttonStyles(isActive)}\n role=\"radio\"\n aria-checked={isActive}\n aria-label={`${option.label} density`}\n onMouseEnter={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'var(--asm-color-button-ghost-bg-hover)';\n }\n }}\n onMouseLeave={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'transparent';\n }\n }}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n );\n};\n"],"mappings":"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","names":["createContext","useContext","useEffect","useState","jsx","ThemeContext","ThemeProvider","children","defaultMode","defaultDensity","defaultDirection","storageKey","enableTransitions","persistMode","persistDensity","persistDirection","getStoredValue","key","defaultValue","setStoredValue","value","persist","error","mode","setModeState","density","setDensityState","direction","setDirectionState","systemPrefersDark","setSystemPrefersDark","resolvedMode","setMode","newMode","setDensity","newDensity","setDirection","newDirection","toggleMode","mediaQuery","handleChange","e","root","contextValue","useThemeContext","context","useTheme","useThemeContext","React","Moon","Sun","jsx","jsxs","ThemeToggle","className","style","showLabels","size","lightIcon","darkIcon","ariaLabel","variant","resolvedMode","toggleMode","useTheme","iconSizeMap","circleSizeMap","renderIcon","icon","getIcon","getLabel","baseStyles","variantStyles","mergedStyles","e","Sun","Moon","Monitor","jsx","jsxs","ThemeSelector","className","style","variant","mode","setMode","useTheme","options","selectStyles","option","containerStyles","buttonStyles","isActive","Icon","e","jsx","DensitySelector","className","style","density","setDensity","useTheme","options","containerStyles","buttonStyles","isActive","option"]}
|