adopted-style-sheets
Version:
This library implements functions to use the adopted style of web components for multiple themes.
12 lines (9 loc) • 10.3 kB
JavaScript
import h from"loglevel";const j=(t,e)=>s=>s(t,e),F=(t,e)=>s=>s(t,e,{append:!1}),Y=()=>{const t=typeof process<"u"&&process.env?process.env:{},e=t.NODE_ENV==="test",s="VITEST"in t,a="JEST_WORKER_ID"in t,o="PLAYWRIGHT_TEST_BASE_URL"in t,r=t.CI==="true",i=t.TEST==="true"||t.IS_TEST==="true",c=typeof navigator<"u"&&navigator.webdriver===!0,u=typeof navigator<"u"&&/playwright|puppeteer|webdriver|selenium|testcafe/i.test(navigator.userAgent);return e||s||a||o||r||i||c||u},n={A11yUi:{CSS_STYLE_CACHE:new Map,IS_TEST_ENVIRONMENT:Y(),PERFORMANCE_MEASURES:new Map,STYLING_TASK_QUEUE:new Map,THEMES:new Map,showAverageTimes:()=>{const t={};for(const[s,a]of n.A11yUi.PERFORMANCE_MEASURES.entries())t[s]=[a.totalTime/a.count,a.count];const e=Object.entries(t).sort((s,a)=>a[1][0]-s[1][0]);return console.table(Object.fromEntries(e.map(([s,[a,o]])=>[s,{"avg (ms)":parseFloat(a.toFixed(2)),count:o}]))),t}}};let T=!0,f=!1;const k=/^[a-z][a-z0-9]{1,}(-[a-z0-9]+)?$/,G=t=>typeof t=="string"&&k.test(t),A=t=>{if(!G(t))throw new Error(`[Theming] The theme identifier "${typeof t=="string"?t:""}" (Type: ${typeof t}) is not valid. Please use only follow this pattern: /^[a-z][a-z0-9]{1,}(-[a-z0-9]+)?$/`)},b=t=>t.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\s*([{},;])\s*/g,"$1").replace(/:\s+/g,":").replace(/\s+/g," ").replace(/;\}/g,"}").trim(),x=(t,e,s,a)=>g(t,e,s,a),g=(t,e,s,a)=>{a=a??{},a.append=a.append??!1,A(t),T&&!f&&(f=!0,h.warn(`[Theming] The theme process is locked. This means that the theme "${t}" should not be patched.
import { register } from 'adopted-style-sheets';
import { defineCustomElements } from '...';
import { THEME } from '...';
register(THEME, defineCustomElements)
.then(() => {
// run your app or website
})
.catch(console.warn);`));let o=n.A11yUi.THEMES.get(t);if(o||(o=new Map,n.A11yUi.THEMES.set(t,o)),a.append&&o.has(e)){const r=o.get(e);o.set(e,b(`${r}${s}`))}else o.set(e,b(s))},K=(t,e,s,a)=>E(t,e,s,a),E=(t,e,s,a)=>(A(t),typeof e=="object"&&e!==null&&Object.getOwnPropertyNames(e).forEach(o=>{const r=e[o],i=o.toLowerCase(),c=typeof a?.transformTagName=="function"&&!["GLOBAL","PROPERTIES"].includes(o)?a.transformTagName(i):o;typeof r=="string"&&r.length>0&&g(t,c.toUpperCase(),r,s)}),t),U=t=>{if(t instanceof HTMLElement){if(typeof t.dataset.theme=="string")return t;{let e=t.parentNode;for(;e instanceof ShadowRoot;)e=e.host;return U(e)}}else return null},C=(t={})=>t.themeEncroachCss==="false"||t.themeReset==="true"?!1:{mode:t.themeEncroachCssMode==="after"||t.themeEncroachCssMode==="before"?t.themeEncroachCssMode:"before"},d=()=>typeof n.A11yUi.Theme=="object"&&n.A11yUi.Theme!==null&&typeof n.A11yUi.Theme.cache=="boolean"&&typeof n.A11yUi.Theme.encroachCss=="object"&&n.A11yUi.Theme.encroachCss!==null&&typeof n.A11yUi.Theme.encroachCss.mode=="string"&&typeof n.A11yUi.Theme.name=="string",B=()=>!(typeof n.A11yUi.Theme=="object"&&n.A11yUi.Theme!==null)||n.A11yUi.Theme.name!=="default",w=t=>{if(d())return n.A11yUi.Theme;{const e={cache:!0,encroachCss:C(),loglevel:"silent",mode:"csr",name:null},s=U(t);return s instanceof HTMLElement&&(e.cache=s.dataset.themeCache!=="false",e.encroachCss=C(s.dataset),e.loglevel=s.dataset.themeLoglevel==="debug"?s.dataset.themeLoglevel:"silent",e.mode=s.dataset.themeMode==="ssr"?s.dataset.themeMode:"csr",e.name=s.dataset.theme||null),e}},D=t=>w(t).name,z=()=>d()?n.A11yUi.Theme.name:null,Q=()=>d()?n.A11yUi.Theme:null,V=(t,e)=>({cache:e.cache!==!1,detect:e.detect==="auto"?"auto":"fixed",encroachCss:e.encroachCss===!1?!1:typeof e.encroachCss=="object"&&e.encroachCss!=null&&(e.encroachCss.mode==="after"||e.encroachCss.mode==="before")?e.encroachCss:{mode:"before"},loglevel:e.loglevel==="debug"?e.loglevel:"silent",mode:e.mode==="ssr"?e.mode:"csr",name:typeof e.name=="string"?e.name:t}),W=(t,e)=>{d()===!1&&B()&&typeof e=="object"&&e!==null&&(e=V(t,e),e.detect==="fixed"?(e.name===null&&typeof t=="string"&&(e.name=t),t===e.name&&(n.A11yUi.Theme=e,h.info(`[Theming] Theme "${t}" was set as default theme.`))):f||(f=!0,h.warn("[Theming] The presetting of theme options is only relevant by using 'fixed' detection mode.")))},q=()=>Array.from(n.A11yUi.THEMES.keys()),J=()=>n.A11yUi.THEMES,X=t=>n.A11yUi.THEMES.get(t);let M=!1;const Z=(t,e,s={})=>{M||(M=!0,T=!1,typeof window<"u"&&(window.A11yUi=n.A11yUi)),typeof t=="function"?t=new Set([t]):Array.isArray(t)&&(t=new Set(t)),t instanceof Set&&t.forEach(o=>{typeof o=="function"&&o.length===1?W(o((r,i,c)=>E(r,i,c,s)),{cache:s.theme?.cache,detect:s.theme?.detect,encroachCss:s.theme?.encroachCss,mode:s.theme?.mode,name:s.theme?.name}):h.error("[Theming] An attempt was made to load an incompatible theme.")}),T=!0,typeof e=="function"?e=new Set([e]):Array.isArray(e)&&(e=new Set(e));const a=[];return e.forEach(o=>{const r=o();r instanceof Promise&&a.push(r)}),Promise.all(a)};class l{static options={enumerable:!1,immutable:!1};static instances=new Map;store;constructor(e,s){this.store=this.createStore(e,s)}static getInstance(e,s){let a=l.instances.get(e);return a===void 0&&(a=new l(s,e),l.instances.set(e,a)),a}createStore(e,s){return Object.defineProperty(e,s,{enumerable:!1,value:{},writable:!1}),e[s]}recursiveSetItem(e,s,a,o=l.options){let r=typeof a=="object"&&a!==null?{}:a;if(Object.defineProperty(e,s,{enumerable:o.enumerable===!0,get:()=>r,set:o.immutable===!0?void 0:i=>r=i}),typeof a=="object"&&a!==null)for(const[i,c]of Object.entries(a))this.recursiveSetItem(e[s],i,c,o)}setItem(e,s,a=l.options){return this.recursiveSetItem(this.store,e,s,a),this}getItem(e){return Array.isArray(e)?e.map(s=>this.getItem(s)):this.store[e]}}const v=new Set,N=new Map,ee=/--[^;]+/g,te=/:/,se=typeof MutationObserver<"u";let L=25,R=()=>{L=Math.min(25+Math.log2(n.A11yUi.STYLING_TASK_QUEUE.size+1)*20,250)};const ae=(t,e)=>{let s=e.match(ee);if(Array.isArray(s)){s=s.filter(o=>te.test(o));const a=document.createElement("style");a.innerHTML=`.${t} {${s.join(";")}}`,document.querySelector("head")?.appendChild(a)}v.add(t)},y=(t,e)=>{const s=n.A11yUi.THEMES.get(t);if(s instanceof Map){const a=s.get(e);if(a!==void 0)return a}return""},oe=t=>{const e=t.firstChild;if(!(!(e instanceof HTMLStyleElement)||e.dataset.themingFallback!==void 0))for(const s of Array.from(t.childNodes))if(s instanceof HTMLStyleElement&&s.tagName==="STYLE"&&s.dataset.themingFallback===void 0)t.removeChild(s);else break},ne=(t,e)=>{try{if(n.A11yUi.Theme?.mode==="ssr")throw new Error("SSR");const s=e.filter(a=>typeof a=="string"&&a.length>0).map(a=>{let o=N.get(a);return o||(o=new CSSStyleSheet,o.replaceSync(a),N.set(a,o)),o});t.adoptedStyleSheets=s}catch{for(let a=e.length-1;a>=0;a--){const o=e[a];if(typeof o!="string"||o.length===0)continue;const r=e.length-1-a,i=document.createElement("style");switch(i.dataset.themingFallback="",r){case 4:i.dataset.themingBaseA11y="";break;case 3:i.dataset.themingBaseGlobal="";break;case 2:i.dataset.themingBaseComponent="";break;case 1:i.dataset.themingCustomGlobal="";break;case 0:i.dataset.themingCustomComponent="";break;default:i.dataset.themingUnknown="";break}i.innerHTML=o,t.insertBefore(i,t.firstChild)}}},re=(t,e,s)=>{if(s===!1||s?.mode!=="before"&&s?.mode!=="after")return;const a=Array.from(t.childNodes).filter(r=>r instanceof HTMLStyleElement&&r.tagName==="STYLE");let o;try{o=Array.from(t.adoptedStyleSheets)}catch{o=[]}if(!(a.length===0&&o.length===0))if(s.mode==="before"){const r=[...o.map(i=>Array.from(i.cssRules).map(c=>c.cssText).join("")),...a.map(i=>i.innerHTML)];e.unshift(...r)}else a.forEach(r=>e.push(r.innerHTML)),o.forEach(r=>e.push(Array.from(r.cssRules).map(i=>i.cssText).join("")))},ie=(t,e,s)=>{const a=e.name||"default";let o;try{if(t.shadowRoot===null)throw new Error("ShadowRoot is null");o=t.shadowRoot}catch{o=t}const r=n.A11yUi.CSS_STYLE_CACHE.get(a)?.get(t.tagName);if(r)_(t,o,r,s);else{const i=y(a,"PROPERTIES"),c=y(a,"GLOBAL"),u=y(a,t.tagName);v.has(a)===!1&&ae(a,c);const p=[i,c,u];if(re(o,p,e.encroachCss),e.cache===!0){let m=n.A11yUi.CSS_STYLE_CACHE.get(a);m||(m=new Map,n.A11yUi.CSS_STYLE_CACHE.set(a,m)),m.set(t.tagName,p)}_(t,o,p,s)}},_=(t,e,s,a)=>{const o=n.A11yUi.Theme?.loglevel==="debug",r=o?performance.now():0;if(oe(e),ne(e,s),fe(t),requestAnimationFrame(a),o){const i=performance.now()-r,c=n.A11yUi.PERFORMANCE_MEASURES.get(t.tagName);c?(c.count+=1,c.totalTime+=i):n.A11yUi.PERFORMANCE_MEASURES.set(t.tagName,{count:1,totalTime:i})}},O=t=>{const e=n.A11yUi.STYLING_TASK_QUEUE.get(t);if(e){const{resetCss:s,themeDetails:a}=e;ie(t,a,s)}},ce=100;let S=(t,e=0)=>{if(e>=ce)return;const s=setTimeout(()=>{clearTimeout(s),t.classList.contains("hydrated")?O(t):S(t,e+1)},L)};const le={attributes:!0,attributeFilter:["class"],childList:!1,subtree:!1},me={attributes:!0,attributeFilter:[],childList:!1,subtree:!1},I=se?new MutationObserver((t,e)=>{const s=[];for(const a of t){const o=a.target;o.classList.contains("hydrated")&&n.A11yUi.STYLING_TASK_QUEUE.has(o)&&(O(o),s.push(o))}for(const a of s)e.observe(a,me)}):null;I&&(S=t=>I.observe(t,le),R=()=>{});const H=new Map;let P=(t,e)=>{if(e){const o=H.get(e);if(o!==void 0)return o}const s=getComputedStyle(t).getPropertyValue("--theme-visibility-delay").trim();let a;if(s.endsWith("ms"))a=parseFloat(s);else if(s.endsWith("s"))a=parseFloat(s)*1e3;else{const o=parseFloat(s);a=isNaN(o)?0:o}return e&&H.set(e,a),a};n.A11yUi.IS_TEST_ENVIRONMENT&&(P=()=>0);const $=(t,e)=>{t.style.setProperty("visibility",e),t.dataset.themed=""},he=(t,e)=>{const s=t.style.visibility||null,a=e.name||"default";n.A11yUi.STYLING_TASK_QUEUE.set(t,{resetCss:()=>{const o=P(t,a);o>0?setTimeout(()=>{$(t,s)},o):$(t,s)},themeDetails:e}),t.style.setProperty("visibility","hidden","important"),S(t)},fe=t=>{n.A11yUi.STYLING_TASK_QUEUE.delete(t),R()},de=(t,e)=>{he(t,{...n.A11yUi.Theme,...e})};class ye{Prefix;Key;Tag;createTheme=(e,s)=>F(e,s);createTranslation=(e,s)=>j(e,s);constructor(e,s,a){this.Prefix=e,this.Key=Object.getOwnPropertyNames(s),this.Tag=Object.getOwnPropertyNames(a)}}export{l as RobustStore,n as STORE,ye as Theme,y as getCssStyle,Q as getDefaultThemeDetails,z as getDefaultThemeName,X as getRegisteredThemeByName,q as getRegisteredThemeNames,J as getRegisteredThemes,D as getTheme,w as getThemeDetails,K as patchTheme,x as patchThemeTag,Z as register,E as setTheme,de as setThemeStyle,g as setThemeTag};