UNPKG

adopted-style-sheets

Version:

This library implements functions to use the adopted style of web components for multiple themes.

12 lines (9 loc) 9.71 kB
import h from"loglevel";const I=(t,e)=>s=>s(t,e),P=(t,e)=>s=>s(t,e,{append:!1}),$=()=>{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,m=typeof navigator<"u"&&/playwright|puppeteer|webdriver|selenium|testcafe/i.test(navigator.userAgent);return e||s||a||o||r||i||c||m},n={A11yUi:{CSS_STYLE_CACHE:new Map,IS_TEST_ENVIRONMENT:$(),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 d=!0,f=!1;const j=/^[a-z][a-z0-9]{1,}(-[a-z0-9]+)?$/,F=t=>typeof t=="string"&&j.test(t),E=t=>{if(!F(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]+)?$/`)},g=t=>t.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\s*([{}:;,])\s*/g,"$1").replace(/\s+/g," ").replace(/;\}/g,"}").trim(),Y=(t,e,s,a)=>u(t,e,s,a),u=(t,e,s,a)=>{a=a??{},a.append=a.append??!1,E(t),d&&!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,g(`${r}${s}`))}else o.set(e,g(s))},k=(t,e,s,a)=>p(t,e,s,a),p=(t,e,s,a)=>(E(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&&u(t,c.toUpperCase(),r,s)}),t),S=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 S(e)}}else return null},A=(t={})=>t.themeEncroachCss==="false"||t.themeReset==="true"?!1:{mode:t.themeEncroachCssMode==="after"||t.themeEncroachCssMode==="before"?t.themeEncroachCssMode:"before"},C=()=>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",G=()=>!(typeof n.A11yUi.Theme=="object"&&n.A11yUi.Theme!==null)||n.A11yUi.Theme.name!=="default",b=t=>{if(C())return n.A11yUi.Theme;{const e={cache:!0,encroachCss:A(),loglevel:"silent",mode:"csr",name:null},s=S(t);return s instanceof HTMLElement&&(e.cache=s.dataset.themeCache!=="false",e.encroachCss=A(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}},x=t=>b(t).name,B=(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}),K=(t,e)=>{C()===!1&&G()&&typeof e=="object"&&e!==null&&(e=B(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.")))},z=()=>Array.from(n.A11yUi.THEMES.keys()),D=()=>n.A11yUi.THEMES,Q=t=>n.A11yUi.THEMES.get(t);let U=!1;const V=(t,e,s={})=>{U||(U=!0,d=!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?K(o((r,i,c)=>p(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.")}),d=!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 w=new Set,W=/--[^;]+/g,q=/:/,J=typeof MutationObserver<"u";let M=25,N=()=>{M=Math.min(25+Math.log2(n.A11yUi.STYLING_TASK_QUEUE.size+1)*20,250)};const X=(t,e)=>{let s=e.match(W);if(Array.isArray(s)){s=s.filter(o=>q.test(o));const a=document.createElement("style");a.innerHTML=`.${t} {${s.join(";")}}`,document.querySelector("head")?.appendChild(a)}w.add(t)},y=(t,e)=>{const s=n.A11yUi.THEMES.get(t);return s instanceof Map&&s.has(e)?s.get(e):""},Z=t=>{for(const e of Array.from(t.childNodes))if(e instanceof HTMLStyleElement&&e.tagName==="STYLE"&&e.dataset.themingFallback===void 0)t.removeChild(e);else break},ee=(t,e)=>{try{if(n.A11yUi.Theme?.mode==="ssr")throw new Error("SSR");const s=[];e.forEach(a=>{const o=new CSSStyleSheet;o.replaceSync(a),s.push(o)}),t.adoptedStyleSheets=s}catch{[...e].reverse().forEach((a,o)=>{if(typeof a!="string"||a.length===0)return;const r=document.createElement("style");switch(r.dataset.themingFallback="",o){case 4:r.dataset.themingBaseA11y="";break;case 3:r.dataset.themingBaseGlobal="";break;case 2:r.dataset.themingBaseComponent="";break;case 1:r.dataset.themingCustomGlobal="";break;case 0:r.dataset.themingCustomComponent="";break;default:r.dataset.themingUnknown="";break}r.innerHTML=a,t.insertBefore(r,t.firstChild)})}},te=(t,e,s)=>{if(s!==!1){const a=[...Array.from(t.childNodes).filter(r=>r instanceof HTMLStyleElement&&r.tagName==="STYLE")];let o;try{o=[...Array.from(t.adoptedStyleSheets)]}catch{o=[]}s?.mode==="before"?(a.reverse().forEach(r=>e.unshift(r.innerHTML)),o.reverse().forEach(r=>e.unshift(Array.from(r.cssRules).map(i=>i.cssText).join("")))):s?.mode==="after"&&(a.forEach(r=>e.push(r.innerHTML)),o.forEach(r=>e.push(Array.from(r.cssRules).map(i=>i.cssText).join(""))))}},se=(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}if(n.A11yUi.CSS_STYLE_CACHE.get(a)?.has(t.tagName))v(t,o,n.A11yUi.CSS_STYLE_CACHE.get(a)?.get(t.tagName),s);else{const r=y(a,"PROPERTIES"),i=y(a,"GLOBAL"),c=y(a,t.tagName);w.has(a)===!1&&X(a,i);const m=[r,i,c];te(o,m,e.encroachCss),e.cache===!0&&(n.A11yUi.CSS_STYLE_CACHE.has(a)===!1&&n.A11yUi.CSS_STYLE_CACHE.set(a,new Map),n.A11yUi.CSS_STYLE_CACHE.get(a)?.set(t.tagName,m)),v(t,o,m,s)}},v=(t,e,s,a)=>{const o=performance.now();if(Z(e),ee(e,s),H(t),a(),n.A11yUi.PERFORMANCE_MEASURES.has(t.tagName)){const r=n.A11yUi.PERFORMANCE_MEASURES.get(t.tagName);r.count+=1,r.totalTime+=performance.now()-o}else n.A11yUi.PERFORMANCE_MEASURES.set(t.tagName,{count:1,totalTime:performance.now()-o})},L=t=>{const e=n.A11yUi.STYLING_TASK_QUEUE.get(t);if(e){const{resetCss:s,themeDetails:a}=e;se(t,a,s),H(t)}};let T=t=>{const e=setTimeout(()=>{clearTimeout(e),t.classList.contains("hydrated")?L(t):T(t)},M)};const ae={attributes:!0,attributeFilter:["class"],childList:!1,subtree:!1},oe={attributes:!0,attributeFilter:[],childList:!1,subtree:!1},R=J?new MutationObserver((t,e)=>{for(const s of t){const a=s.target;a.classList.contains("hydrated")&&(L(a),e.observe(a,oe))}}):null;R&&(T=t=>R.observe(t,ae),N=()=>{});let _=t=>{const e=getComputedStyle(t).getPropertyValue("--theme-visibility-delay").trim();if(e.endsWith("ms"))return parseFloat(e);if(e.endsWith("s"))return parseFloat(e)*1e3;{const s=parseFloat(e);return isNaN(s)?0:s}};n.A11yUi.IS_TEST_ENVIRONMENT&&(_=()=>0);const O=(t,e)=>{t.style.setProperty("visibility",e),t.dataset.themed=""},re=(t,e)=>{const s=t.style.visibility||null;n.A11yUi.STYLING_TASK_QUEUE.set(t,{resetCss:()=>{const a=_(t);a>0?setTimeout(()=>{O(t,s)},a):O(t,s)},themeDetails:e}),t.style.setProperty("visibility","hidden","important"),T(t)},H=t=>{n.A11yUi.STYLING_TASK_QUEUE.delete(t),N()},ne=(t,e)=>{re(t,{...n.A11yUi.Theme,...e})};class ie{Prefix;Key;Tag;createTheme=(e,s)=>P(e,s);createTranslation=(e,s)=>I(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,ie as Theme,y as getCssStyle,Q as getRegisteredThemeByName,z as getRegisteredThemeNames,D as getRegisteredThemes,x as getTheme,b as getThemeDetails,k as patchTheme,Y as patchThemeTag,V as register,p as setTheme,ne as setThemeStyle,u as setThemeTag};