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