@aejkatappaja/phantom-ui 0.2.3 → 0.3.0

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/README.md CHANGED
@@ -1,22 +1,3 @@
1
- <!--
2
- ```
3
- <custom-element-demo>
4
- <template>
5
- <script src="https://cdn.jsdelivr.net/npm/@aejkatappaja/phantom-ui/dist/phantom-ui.cdn.js"></script>
6
- <next-code-block></next-code-block>
7
- </template>
8
- </custom-element-demo>
9
- ```
10
- -->
11
- ```html
12
- <phantom-ui loading>
13
- <div style="background:#16213e;border-radius:12px;padding:20px;width:320px;color:#e0e0e0;font-family:system-ui">
14
- <h3 style="margin:0 0 8px">Sarah Chen</h3>
15
- <p style="margin:0;font-size:13px;color:#8899aa">Senior Engineer</p>
16
- </div>
17
- </phantom-ui>
18
- ```
19
-
20
1
  <p align="center">
21
2
  <img src="logo-phantom.svg" alt="phantom-ui" width="200" />
22
3
  </p>
@@ -32,13 +13,18 @@
32
13
  <a href="https://www.webcomponents.org/element/@aejkatappaja/phantom-ui"><img src="https://img.shields.io/badge/webcomponents.org-published-blue.svg?style=flat-square" alt="Published on webcomponents.org" /></a>
33
14
  </p>
34
15
 
16
+ <p align="center">
17
+ <a href="https://aejkatappaja.github.io/phantom-ui/">Documentation</a> &middot;
18
+ <a href="https://aejkatappaja.github.io/phantom-ui/demo/">Live Demo</a>
19
+ </p>
20
+
35
21
  ---
36
22
 
37
23
  <br />
38
24
 
39
25
  <div align="center">
40
26
  <picture>
41
- <img src="preview.gif" alt="phantom-ui demo" width="400" />
27
+ <img src="preview.gif" alt="phantom-ui demo" width="640" />
42
28
  </picture>
43
29
  </div>
44
30
 
@@ -294,9 +280,12 @@ declare module "@builder.io/qwik" {
294
280
  | Attribute | Type | Default | Description |
295
281
  | --- | --- | --- | --- |
296
282
  | `loading` | `boolean` | `false` | Show shimmer overlay or real content |
283
+ | `animation` | `string` | `shimmer` | Animation mode: `shimmer`, `pulse`, `breathe`, or `solid` |
297
284
  | `shimmer-color` | `string` | `rgba(255,255,255,0.3)` | Color of the animated gradient sweep |
298
285
  | `background-color` | `string` | `rgba(255,255,255,0.08)` | Background of each shimmer block |
299
286
  | `duration` | `number` | `1.5` | Animation cycle in seconds |
287
+ | `stagger` | `number` | `0` | Delay in seconds between each block's animation start |
288
+ | `reveal` | `number` | `0` | Fade-out duration in seconds when loading ends |
300
289
  | `fallback-radius` | `number` | `4` | Border radius (px) for flat elements like text |
301
290
 
302
291
  ## Fine-grained control
@@ -371,6 +360,10 @@ bun run lint:fix # biome auto-fix
371
360
 
372
361
  The `examples/` directory contains test apps for React, Vue, Solid, Angular, and Qwik, each wired to the local package.
373
362
 
363
+ ## Acknowledgements
364
+
365
+ The structure-aware approach is inspired by [shimmer-from-structure](https://github.com/darula-hpp/shimmer-from-structure), which pioneered the idea of measuring real DOM to generate skeleton placeholders. phantom-ui reimagines this concept as a single universal Web Component instead of framework-specific adapters.
366
+
374
367
  ## License
375
368
 
376
369
  MIT
@@ -8,7 +8,7 @@
8
8
  "declarations": [
9
9
  {
10
10
  "kind": "class",
11
- "description": "`<phantom-ui>` A structure-aware shimmer skeleton loader.\n\nWraps real content and, when `loading` is true, measures the DOM structure\nof the slotted children to generate perfectly-aligned shimmer overlay blocks.",
11
+ "description": "`<phantom-ui>` -- A structure-aware shimmer skeleton loader.\n\nWraps real content and, when `loading` is true, measures the DOM structure\nof the slotted children to generate perfectly-aligned shimmer overlay blocks.",
12
12
  "name": "PhantomUi",
13
13
  "slots": [
14
14
  {
@@ -65,9 +65,40 @@
65
65
  "text": "number"
66
66
  },
67
67
  "default": "4",
68
- "description": "Border radius (px) for elements with border-radius: 0",
68
+ "description": "Border radius applied to elements with border-radius: 0 (like text)",
69
69
  "attribute": "fallback-radius"
70
70
  },
71
+ {
72
+ "kind": "field",
73
+ "name": "animation",
74
+ "type": {
75
+ "text": "Animation"
76
+ },
77
+ "default": "\"shimmer\"",
78
+ "description": "Animation mode: \"shimmer\" (gradient sweep), \"pulse\" (opacity), \"breathe\" (scale + fade), or \"solid\" (static)",
79
+ "attribute": "animation",
80
+ "reflects": true
81
+ },
82
+ {
83
+ "kind": "field",
84
+ "name": "stagger",
85
+ "type": {
86
+ "text": "number"
87
+ },
88
+ "default": "0",
89
+ "description": "Delay in seconds between each block's animation start (0 = no stagger)",
90
+ "attribute": "stagger"
91
+ },
92
+ {
93
+ "kind": "field",
94
+ "name": "reveal",
95
+ "type": {
96
+ "text": "number"
97
+ },
98
+ "default": "0",
99
+ "description": "Fade-out duration in seconds when loading ends (0 = instant)",
100
+ "attribute": "reveal"
101
+ },
71
102
  {
72
103
  "kind": "field",
73
104
  "name": "_blocks",
@@ -77,6 +108,15 @@
77
108
  "privacy": "private",
78
109
  "default": "[]"
79
110
  },
111
+ {
112
+ "kind": "field",
113
+ "name": "_revealing",
114
+ "type": {
115
+ "text": "boolean"
116
+ },
117
+ "privacy": "private",
118
+ "default": "false"
119
+ },
80
120
  {
81
121
  "kind": "field",
82
122
  "name": "_resizeObserver",
@@ -104,6 +144,15 @@
104
144
  "privacy": "private",
105
145
  "default": "false"
106
146
  },
147
+ {
148
+ "kind": "field",
149
+ "name": "_revealTimeout",
150
+ "type": {
151
+ "text": "ReturnType<typeof setTimeout> | null"
152
+ },
153
+ "privacy": "private",
154
+ "default": "null"
155
+ },
107
156
  {
108
157
  "kind": "method",
109
158
  "name": "_scheduleMeasure",
@@ -144,6 +193,16 @@
144
193
  }
145
194
  }
146
195
  },
196
+ {
197
+ "kind": "method",
198
+ "name": "_clearRevealTimeout",
199
+ "privacy": "private",
200
+ "return": {
201
+ "type": {
202
+ "text": "void"
203
+ }
204
+ }
205
+ },
147
206
  {
148
207
  "kind": "method",
149
208
  "name": "_renderBlocks",
@@ -152,49 +211,76 @@
152
211
  ],
153
212
  "attributes": [
154
213
  {
155
- "name": "loading",
156
214
  "type": {
157
215
  "text": "boolean"
158
216
  },
159
- "default": "false",
160
217
  "description": "Whether to show the shimmer overlay or the real content",
218
+ "name": "loading",
219
+ "default": "false",
161
220
  "fieldName": "loading"
162
221
  },
163
222
  {
164
- "name": "shimmer-color",
165
223
  "type": {
166
224
  "text": "string"
167
225
  },
168
- "default": "\"rgba(255, 255, 255, 0.3)\"",
169
226
  "description": "Color of the animated shimmer gradient wave",
227
+ "name": "shimmer-color",
228
+ "default": "\"rgba(255, 255, 255, 0.3)\"",
170
229
  "fieldName": "shimmerColor"
171
230
  },
172
231
  {
173
- "name": "background-color",
174
232
  "type": {
175
233
  "text": "string"
176
234
  },
177
- "default": "\"rgba(255, 255, 255, 0.08)\"",
178
235
  "description": "Background color of each shimmer block",
236
+ "name": "background-color",
237
+ "default": "\"rgba(255, 255, 255, 0.08)\"",
179
238
  "fieldName": "backgroundColor"
180
239
  },
181
240
  {
182
- "name": "duration",
183
241
  "type": {
184
242
  "text": "number"
185
243
  },
186
- "default": "1.5",
187
244
  "description": "Animation cycle duration in seconds",
245
+ "name": "duration",
246
+ "default": "1.5",
188
247
  "fieldName": "duration"
189
248
  },
190
249
  {
191
- "name": "fallback-radius",
192
250
  "type": {
193
251
  "text": "number"
194
252
  },
253
+ "description": "Border radius applied to elements with border-radius: 0 (like text)",
254
+ "name": "fallback-radius",
195
255
  "default": "4",
196
- "description": "Border radius (px) for elements with border-radius: 0",
197
256
  "fieldName": "fallbackRadius"
257
+ },
258
+ {
259
+ "type": {
260
+ "text": "Animation"
261
+ },
262
+ "description": "Animation mode: \"shimmer\" (gradient sweep), \"pulse\" (opacity), \"breathe\" (scale + fade), or \"solid\" (static)",
263
+ "name": "animation",
264
+ "default": "\"shimmer\"",
265
+ "fieldName": "animation"
266
+ },
267
+ {
268
+ "type": {
269
+ "text": "number"
270
+ },
271
+ "description": "Delay in seconds between each block's animation start (0 = no stagger)",
272
+ "name": "stagger",
273
+ "default": "0",
274
+ "fieldName": "stagger"
275
+ },
276
+ {
277
+ "type": {
278
+ "text": "number"
279
+ },
280
+ "description": "Fade-out duration in seconds when loading ends (0 = instant)",
281
+ "name": "reveal",
282
+ "default": "0",
283
+ "fieldName": "reveal"
198
284
  }
199
285
  ],
200
286
  "superclass": {
@@ -1,6 +1,6 @@
1
- "use strict";(()=>{var Rt=Object.defineProperty;var Tt=Object.getOwnPropertyDescriptor;var g=(i,t,e,s)=>{for(var r=s>1?void 0:s?Tt(t,e):t,o=i.length-1,n;o>=0;o--)(n=i[o])&&(r=(s?n(t,e,r):n(r))||r);return s&&r&&Rt(t,e,r),r};var H=globalThis,I=H.ShadowRoot&&(H.ShadyCSS===void 0||H.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,V=Symbol(),rt=new WeakMap,w=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==V)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o,e=this.t;if(I&&t===void 0){let s=e!==void 0&&e.length===1;s&&(t=rt.get(e)),t===void 0&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),s&&rt.set(e,t))}return t}toString(){return this.cssText}},it=i=>new w(typeof i=="string"?i:i+"",void 0,V),W=(i,...t)=>{let e=i.length===1?i[0]:t.reduce((s,r,o)=>s+(n=>{if(n._$cssResult$===!0)return n.cssText;if(typeof n=="number")return n;throw Error("Value passed to 'css' function must be a 'css' function result: "+n+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(r)+i[o+1],i[0]);return new w(e,i,V)},ot=(i,t)=>{if(I)i.adoptedStyleSheets=t.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(let e of t){let s=document.createElement("style"),r=H.litNonce;r!==void 0&&s.setAttribute("nonce",r),s.textContent=e.cssText,i.appendChild(s)}},F=I?i=>i:i=>i instanceof CSSStyleSheet?(t=>{let e="";for(let s of t.cssRules)e+=s.cssText;return it(e)})(i):i;var{is:Pt,defineProperty:Mt,getOwnPropertyDescriptor:kt,getOwnPropertyNames:Nt,getOwnPropertySymbols:Ut,getPrototypeOf:Ht}=Object,L=globalThis,nt=L.trustedTypes,It=nt?nt.emptyScript:"",Lt=L.reactiveElementPolyfillSupport,O=(i,t)=>i,R={toAttribute(i,t){switch(t){case Boolean:i=i?It:null;break;case Object:case Array:i=i==null?i:JSON.stringify(i)}return i},fromAttribute(i,t){let e=i;switch(t){case Boolean:e=i!==null;break;case Number:e=i===null?null:Number(i);break;case Object:case Array:try{e=JSON.parse(i)}catch{e=null}}return e}},D=(i,t)=>!Pt(i,t),at={attribute:!0,type:String,converter:R,reflect:!1,useDefault:!1,hasChanged:D};Symbol.metadata??=Symbol("metadata"),L.litPropertyMetadata??=new WeakMap;var f=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=at){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){let s=Symbol(),r=this.getPropertyDescriptor(t,s,e);r!==void 0&&Mt(this.prototype,t,r)}}static getPropertyDescriptor(t,e,s){let{get:r,set:o}=kt(this.prototype,t)??{get(){return this[e]},set(n){this[e]=n}};return{get:r,set(n){let h=r?.call(this);o?.call(this,n),this.requestUpdate(t,h,s)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??at}static _$Ei(){if(this.hasOwnProperty(O("elementProperties")))return;let t=Ht(this);t.finalize(),t.l!==void 0&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(O("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(O("properties"))){let e=this.properties,s=[...Nt(e),...Ut(e)];for(let r of s)this.createProperty(r,e[r])}let t=this[Symbol.metadata];if(t!==null){let e=litPropertyMetadata.get(t);if(e!==void 0)for(let[s,r]of e)this.elementProperties.set(s,r)}this._$Eh=new Map;for(let[e,s]of this.elementProperties){let r=this._$Eu(e,s);r!==void 0&&this._$Eh.set(r,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){let e=[];if(Array.isArray(t)){let s=new Set(t.flat(1/0).reverse());for(let r of s)e.unshift(F(r))}else t!==void 0&&e.push(F(t));return e}static _$Eu(t,e){let s=e.attribute;return s===!1?void 0:typeof s=="string"?s:typeof t=="string"?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),this.renderRoot!==void 0&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){let t=new Map,e=this.constructor.elementProperties;for(let s of e.keys())this.hasOwnProperty(s)&&(t.set(s,this[s]),delete this[s]);t.size>0&&(this._$Ep=t)}createRenderRoot(){let t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return ot(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,s){this._$AK(t,s)}_$ET(t,e){let s=this.constructor.elementProperties.get(t),r=this.constructor._$Eu(t,s);if(r!==void 0&&s.reflect===!0){let o=(s.converter?.toAttribute!==void 0?s.converter:R).toAttribute(e,s.type);this._$Em=t,o==null?this.removeAttribute(r):this.setAttribute(r,o),this._$Em=null}}_$AK(t,e){let s=this.constructor,r=s._$Eh.get(t);if(r!==void 0&&this._$Em!==r){let o=s.getPropertyOptions(r),n=typeof o.converter=="function"?{fromAttribute:o.converter}:o.converter?.fromAttribute!==void 0?o.converter:R;this._$Em=r;let h=n.fromAttribute(e,o.type);this[r]=h??this._$Ej?.get(r)??h,this._$Em=null}}requestUpdate(t,e,s,r=!1,o){if(t!==void 0){let n=this.constructor;if(r===!1&&(o=this[t]),s??=n.getPropertyOptions(t),!((s.hasChanged??D)(o,e)||s.useDefault&&s.reflect&&o===this._$Ej?.get(t)&&!this.hasAttribute(n._$Eu(t,s))))return;this.C(t,e,s)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(t,e,{useDefault:s,reflect:r,wrapped:o},n){s&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,n??e??this[t]),o!==!0||n!==void 0)||(this._$AL.has(t)||(this.hasUpdated||s||(e=void 0),this._$AL.set(t,e)),r===!0&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}let t=this.scheduleUpdate();return t!=null&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(let[r,o]of this._$Ep)this[r]=o;this._$Ep=void 0}let s=this.constructor.elementProperties;if(s.size>0)for(let[r,o]of s){let{wrapped:n}=o,h=this[r];n!==!0||this._$AL.has(r)||h===void 0||this.C(r,void 0,o,h)}}let t=!1,e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(s=>s.hostUpdate?.()),this.update(e)):this._$EM()}catch(s){throw t=!1,this._$EM(),s}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(t){}firstUpdated(t){}};f.elementStyles=[],f.shadowRootOptions={mode:"open"},f[O("elementProperties")]=new Map,f[O("finalized")]=new Map,Lt?.({ReactiveElement:f}),(L.reactiveElementVersions??=[]).push("2.1.2");var Q=globalThis,ht=i=>i,B=Q.trustedTypes,lt=B?B.createPolicy("lit-html",{createHTML:i=>i}):void 0,ft="$lit$",y=`lit$${Math.random().toFixed(9).slice(2)}$`,$t="?"+y,Dt=`<${$t}>`,S=document,P=()=>S.createComment(""),M=i=>i===null||typeof i!="object"&&typeof i!="function",tt=Array.isArray,Bt=i=>tt(i)||typeof i?.[Symbol.iterator]=="function",K=`[
2
- \f\r]`,T=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,ct=/-->/g,dt=/>/g,A=RegExp(`>|${K}(?:([^\\s"'>=/]+)(${K}*=${K}*(?:[^
3
- \f\r"'\`<>=]|("|')|))|$)`,"g"),ut=/'/g,pt=/"/g,_t=/^(?:script|style|textarea|title)$/i,et=i=>(t,...e)=>({_$litType$:i,strings:t,values:e}),z=et(1),se=et(2),re=et(3),$=Symbol.for("lit-noChange"),u=Symbol.for("lit-nothing"),mt=new WeakMap,E=S.createTreeWalker(S,129);function gt(i,t){if(!tt(i)||!i.hasOwnProperty("raw"))throw Error("invalid template strings array");return lt!==void 0?lt.createHTML(t):t}var zt=(i,t)=>{let e=i.length-1,s=[],r,o=t===2?"<svg>":t===3?"<math>":"",n=T;for(let h=0;h<e;h++){let a=i[h],l,d,c=-1,m=0;for(;m<a.length&&(n.lastIndex=m,d=n.exec(a),d!==null);)m=n.lastIndex,n===T?d[1]==="!--"?n=ct:d[1]!==void 0?n=dt:d[2]!==void 0?(_t.test(d[2])&&(r=RegExp("</"+d[2],"g")),n=A):d[3]!==void 0&&(n=A):n===A?d[0]===">"?(n=r??T,c=-1):d[1]===void 0?c=-2:(c=n.lastIndex-d[2].length,l=d[1],n=d[3]===void 0?A:d[3]==='"'?pt:ut):n===pt||n===ut?n=A:n===ct||n===dt?n=T:(n=A,r=void 0);let _=n===A&&i[h+1].startsWith("/>")?" ":"";o+=n===T?a+Dt:c>=0?(s.push(l),a.slice(0,c)+ft+a.slice(c)+y+_):a+y+(c===-2?h:_)}return[gt(i,o+(i[e]||"<?>")+(t===2?"</svg>":t===3?"</math>":"")),s]},k=class i{constructor({strings:t,_$litType$:e},s){let r;this.parts=[];let o=0,n=0,h=t.length-1,a=this.parts,[l,d]=zt(t,e);if(this.el=i.createElement(l,s),E.currentNode=this.el.content,e===2||e===3){let c=this.el.content.firstChild;c.replaceWith(...c.childNodes)}for(;(r=E.nextNode())!==null&&a.length<h;){if(r.nodeType===1){if(r.hasAttributes())for(let c of r.getAttributeNames())if(c.endsWith(ft)){let m=d[n++],_=r.getAttribute(c).split(y),U=/([.?@])?(.*)/.exec(m);a.push({type:1,index:o,name:U[2],strings:_,ctor:U[1]==="."?J:U[1]==="?"?X:U[1]==="@"?Y:C}),r.removeAttribute(c)}else c.startsWith(y)&&(a.push({type:6,index:o}),r.removeAttribute(c));if(_t.test(r.tagName)){let c=r.textContent.split(y),m=c.length-1;if(m>0){r.textContent=B?B.emptyScript:"";for(let _=0;_<m;_++)r.append(c[_],P()),E.nextNode(),a.push({type:2,index:++o});r.append(c[m],P())}}}else if(r.nodeType===8)if(r.data===$t)a.push({type:2,index:o});else{let c=-1;for(;(c=r.data.indexOf(y,c+1))!==-1;)a.push({type:7,index:o}),c+=y.length-1}o++}}static createElement(t,e){let s=S.createElement("template");return s.innerHTML=t,s}};function x(i,t,e=i,s){if(t===$)return t;let r=s!==void 0?e._$Co?.[s]:e._$Cl,o=M(t)?void 0:t._$litDirective$;return r?.constructor!==o&&(r?._$AO?.(!1),o===void 0?r=void 0:(r=new o(i),r._$AT(i,e,s)),s!==void 0?(e._$Co??=[])[s]=r:e._$Cl=r),r!==void 0&&(t=x(i,r._$AS(i,t.values),r,s)),t}var G=class{constructor(t,e){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=e}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){let{el:{content:e},parts:s}=this._$AD,r=(t?.creationScope??S).importNode(e,!0);E.currentNode=r;let o=E.nextNode(),n=0,h=0,a=s[0];for(;a!==void 0;){if(n===a.index){let l;a.type===2?l=new N(o,o.nextSibling,this,t):a.type===1?l=new a.ctor(o,a.name,a.strings,this,t):a.type===6&&(l=new Z(o,this,t)),this._$AV.push(l),a=s[++h]}n!==a?.index&&(o=E.nextNode(),n++)}return E.currentNode=S,r}p(t){let e=0;for(let s of this._$AV)s!==void 0&&(s.strings!==void 0?(s._$AI(t,s,e),e+=s.strings.length-2):s._$AI(t[e])),e++}},N=class i{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,e,s,r){this.type=2,this._$AH=u,this._$AN=void 0,this._$AA=t,this._$AB=e,this._$AM=s,this.options=r,this._$Cv=r?.isConnected??!0}get parentNode(){let t=this._$AA.parentNode,e=this._$AM;return e!==void 0&&t?.nodeType===11&&(t=e.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,e=this){t=x(this,t,e),M(t)?t===u||t==null||t===""?(this._$AH!==u&&this._$AR(),this._$AH=u):t!==this._$AH&&t!==$&&this._(t):t._$litType$!==void 0?this.$(t):t.nodeType!==void 0?this.T(t):Bt(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==u&&M(this._$AH)?this._$AA.nextSibling.data=t:this.T(S.createTextNode(t)),this._$AH=t}$(t){let{values:e,_$litType$:s}=t,r=typeof s=="number"?this._$AC(t):(s.el===void 0&&(s.el=k.createElement(gt(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===r)this._$AH.p(e);else{let o=new G(r,this),n=o.u(this.options);o.p(e),this.T(n),this._$AH=o}}_$AC(t){let e=mt.get(t.strings);return e===void 0&&mt.set(t.strings,e=new k(t)),e}k(t){tt(this._$AH)||(this._$AH=[],this._$AR());let e=this._$AH,s,r=0;for(let o of t)r===e.length?e.push(s=new i(this.O(P()),this.O(P()),this,this.options)):s=e[r],s._$AI(o),r++;r<e.length&&(this._$AR(s&&s._$AB.nextSibling,r),e.length=r)}_$AR(t=this._$AA.nextSibling,e){for(this._$AP?.(!1,!0,e);t!==this._$AB;){let s=ht(t).nextSibling;ht(t).remove(),t=s}}setConnected(t){this._$AM===void 0&&(this._$Cv=t,this._$AP?.(t))}},C=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,e,s,r,o){this.type=1,this._$AH=u,this._$AN=void 0,this.element=t,this.name=e,this._$AM=r,this.options=o,s.length>2||s[0]!==""||s[1]!==""?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=u}_$AI(t,e=this,s,r){let o=this.strings,n=!1;if(o===void 0)t=x(this,t,e,0),n=!M(t)||t!==this._$AH&&t!==$,n&&(this._$AH=t);else{let h=t,a,l;for(t=o[0],a=0;a<o.length-1;a++)l=x(this,h[s+a],e,a),l===$&&(l=this._$AH[a]),n||=!M(l)||l!==this._$AH[a],l===u?t=u:t!==u&&(t+=(l??"")+o[a+1]),this._$AH[a]=l}n&&!r&&this.j(t)}j(t){t===u?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??"")}},J=class extends C{constructor(){super(...arguments),this.type=3}j(t){this.element[this.name]=t===u?void 0:t}},X=class extends C{constructor(){super(...arguments),this.type=4}j(t){this.element.toggleAttribute(this.name,!!t&&t!==u)}},Y=class extends C{constructor(t,e,s,r,o){super(t,e,s,r,o),this.type=5}_$AI(t,e=this){if((t=x(this,t,e,0)??u)===$)return;let s=this._$AH,r=t===u&&s!==u||t.capture!==s.capture||t.once!==s.once||t.passive!==s.passive,o=t!==u&&(s===u||r);r&&this.element.removeEventListener(this.name,this,s),o&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t)}},Z=class{constructor(t,e,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=e,this.options=s}get _$AU(){return this._$AM._$AU}_$AI(t){x(this,t)}};var jt=Q.litHtmlPolyfillSupport;jt?.(k,N),(Q.litHtmlVersions??=[]).push("3.3.2");var yt=(i,t,e)=>{let s=e?.renderBefore??t,r=s._$litPart$;if(r===void 0){let o=e?.renderBefore??null;s._$litPart$=r=new N(t.insertBefore(P(),o),o,void 0,e??{})}return r._$AI(i),r};var st=globalThis,b=class extends f{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){let e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=yt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return $}};b._$litElement$=!0,b.finalized=!0,st.litElementHydrateSupport?.({LitElement:b});var qt=st.litElementPolyfillSupport;qt?.({LitElement:b});(st.litElementVersions??=[]).push("4.2.2");var bt=i=>(t,e)=>{e!==void 0?e.addInitializer(()=>{customElements.define(i,t)}):customElements.define(i,t)};var Vt={attribute:!0,type:String,converter:R,reflect:!1,hasChanged:D},Wt=(i=Vt,t,e)=>{let{kind:s,metadata:r}=e,o=globalThis.litPropertyMetadata.get(r);if(o===void 0&&globalThis.litPropertyMetadata.set(r,o=new Map),s==="setter"&&((i=Object.create(i)).wrapped=!0),o.set(e.name,i),s==="accessor"){let{name:n}=e;return{set(h){let a=t.get.call(this);t.set.call(this,h),this.requestUpdate(n,a,i,!0,h)},init(h){return h!==void 0&&this.C(n,void 0,i,h),h}}}if(s==="setter"){let{name:n}=e;return function(h){let a=this[n];t.call(this,h),this.requestUpdate(n,a,i,!0,h)}}throw Error("Unsupported decorator location: "+s)};function v(i){return(t,e)=>typeof e=="object"?Wt(i,t,e):((s,r,o)=>{let n=r.hasOwnProperty(o);return r.constructor.createProperty(o,s),n?Object.getOwnPropertyDescriptor(r,o):void 0})(i,t,e)}function vt(i){return v({...i,state:!0,attribute:!1})}var At={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},Et=i=>(...t)=>({_$litDirective$:i,values:t}),q=class{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,s){this._$Ct=t,this._$AM=e,this._$Ci=s}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}};var St="important",Ft=" !"+St,xt=Et(class extends q{constructor(i){if(super(i),i.type!==At.ATTRIBUTE||i.name!=="style"||i.strings?.length>2)throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.")}render(i){return Object.keys(i).reduce((t,e)=>{let s=i[e];return s==null?t:t+`${e=e.includes("-")?e:e.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,"-$&").toLowerCase()}:${s};`},"")}update(i,[t]){let{style:e}=i.element;if(this.ft===void 0)return this.ft=new Set(Object.keys(t)),this.render(t);for(let s of this.ft)t[s]==null&&(this.ft.delete(s),s.includes("-")?e.removeProperty(s):e[s]=null);for(let s in t){let r=t[s];if(r!=null){this.ft.add(s);let o=typeof r=="string"&&r.endsWith(Ft);s.includes("-")||o?e.setProperty(s,o?r.slice(0,-11):r,o?St:""):e[s]=r}}return $}});var Kt=new Set(["IMG","SVG","VIDEO","CANVAS","IFRAME","INPUT","TEXTAREA","BUTTON","HR"]),Gt=new Set(["BR","WBR","HR"]);function Jt(i){if(Kt.has(i.tagName))return!0;for(let t of i.children)if(!Gt.has(t.tagName))return!1;return!0}function Xt(i){for(let t of i.childNodes)if(t.nodeType===Node.TEXT_NODE&&t.textContent?.trim())return!0;return!1}function Ct(i,t){let e=[];function s(r){let o=r.getBoundingClientRect();if(o.width===0||o.height===0||r.hasAttribute("data-shimmer-ignore"))return;if(r.hasAttribute("data-shimmer-no-children")||Jt(r)){let a=getComputedStyle(r).borderRadius;if((r.tagName==="TD"||r.tagName==="TH")&&Xt(r)){let l=document.createElement("span");l.style.visibility="hidden",l.style.position="absolute",l.textContent=r.textContent,r.appendChild(l);let d=l.getBoundingClientRect();r.removeChild(l),e.push({x:o.left-t.left,y:o.top-t.top,width:Math.min(d.width,o.width),height:o.height,tag:r.tagName.toLowerCase(),borderRadius:a==="0px"?"":a});return}e.push({x:o.left-t.left,y:o.top-t.top,width:o.width,height:o.height,tag:r.tagName.toLowerCase(),borderRadius:a==="0px"?"":a});return}for(let h of r.children)s(h)}for(let r of i.children)s(r);return e}function wt(i,t){let e=null,s=new ResizeObserver(()=>{e!==null&&cancelAnimationFrame(e),e=requestAnimationFrame(()=>{e=null,t()})});return s.observe(i),s}var Ot=W`
1
+ "use strict";(()=>{var Tt=Object.defineProperty;var Rt=Object.getOwnPropertyDescriptor;var m=(i,t,e,s)=>{for(var r=s>1?void 0:s?Rt(t,e):t,o=i.length-1,n;o>=0;o--)(n=i[o])&&(r=(s?n(t,e,r):n(r))||r);return s&&r&&Tt(t,e,r),r};var H=globalThis,I=H.ShadowRoot&&(H.ShadyCSS===void 0||H.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,V=Symbol(),it=new WeakMap,C=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==V)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o,e=this.t;if(I&&t===void 0){let s=e!==void 0&&e.length===1;s&&(t=it.get(e)),t===void 0&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),s&&it.set(e,t))}return t}toString(){return this.cssText}},ot=i=>new C(typeof i=="string"?i:i+"",void 0,V),W=(i,...t)=>{let e=i.length===1?i[0]:t.reduce((s,r,o)=>s+(n=>{if(n._$cssResult$===!0)return n.cssText;if(typeof n=="number")return n;throw Error("Value passed to 'css' function must be a 'css' function result: "+n+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(r)+i[o+1],i[0]);return new C(e,i,V)},nt=(i,t)=>{if(I)i.adoptedStyleSheets=t.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(let e of t){let s=document.createElement("style"),r=H.litNonce;r!==void 0&&s.setAttribute("nonce",r),s.textContent=e.cssText,i.appendChild(s)}},F=I?i=>i:i=>i instanceof CSSStyleSheet?(t=>{let e="";for(let s of t.cssRules)e+=s.cssText;return ot(e)})(i):i;var{is:kt,defineProperty:Pt,getOwnPropertyDescriptor:Mt,getOwnPropertyNames:Nt,getOwnPropertySymbols:Ut,getPrototypeOf:Ht}=Object,L=globalThis,at=L.trustedTypes,It=at?at.emptyScript:"",Lt=L.reactiveElementPolyfillSupport,O=(i,t)=>i,T={toAttribute(i,t){switch(t){case Boolean:i=i?It:null;break;case Object:case Array:i=i==null?i:JSON.stringify(i)}return i},fromAttribute(i,t){let e=i;switch(t){case Boolean:e=i!==null;break;case Number:e=i===null?null:Number(i);break;case Object:case Array:try{e=JSON.parse(i)}catch{e=null}}return e}},D=(i,t)=>!kt(i,t),lt={attribute:!0,type:String,converter:T,reflect:!1,useDefault:!1,hasChanged:D};Symbol.metadata??=Symbol("metadata"),L.litPropertyMetadata??=new WeakMap;var g=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=lt){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){let s=Symbol(),r=this.getPropertyDescriptor(t,s,e);r!==void 0&&Pt(this.prototype,t,r)}}static getPropertyDescriptor(t,e,s){let{get:r,set:o}=Mt(this.prototype,t)??{get(){return this[e]},set(n){this[e]=n}};return{get:r,set(n){let l=r?.call(this);o?.call(this,n),this.requestUpdate(t,l,s)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??lt}static _$Ei(){if(this.hasOwnProperty(O("elementProperties")))return;let t=Ht(this);t.finalize(),t.l!==void 0&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(O("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(O("properties"))){let e=this.properties,s=[...Nt(e),...Ut(e)];for(let r of s)this.createProperty(r,e[r])}let t=this[Symbol.metadata];if(t!==null){let e=litPropertyMetadata.get(t);if(e!==void 0)for(let[s,r]of e)this.elementProperties.set(s,r)}this._$Eh=new Map;for(let[e,s]of this.elementProperties){let r=this._$Eu(e,s);r!==void 0&&this._$Eh.set(r,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){let e=[];if(Array.isArray(t)){let s=new Set(t.flat(1/0).reverse());for(let r of s)e.unshift(F(r))}else t!==void 0&&e.push(F(t));return e}static _$Eu(t,e){let s=e.attribute;return s===!1?void 0:typeof s=="string"?s:typeof t=="string"?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),this.renderRoot!==void 0&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){let t=new Map,e=this.constructor.elementProperties;for(let s of e.keys())this.hasOwnProperty(s)&&(t.set(s,this[s]),delete this[s]);t.size>0&&(this._$Ep=t)}createRenderRoot(){let t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return nt(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,s){this._$AK(t,s)}_$ET(t,e){let s=this.constructor.elementProperties.get(t),r=this.constructor._$Eu(t,s);if(r!==void 0&&s.reflect===!0){let o=(s.converter?.toAttribute!==void 0?s.converter:T).toAttribute(e,s.type);this._$Em=t,o==null?this.removeAttribute(r):this.setAttribute(r,o),this._$Em=null}}_$AK(t,e){let s=this.constructor,r=s._$Eh.get(t);if(r!==void 0&&this._$Em!==r){let o=s.getPropertyOptions(r),n=typeof o.converter=="function"?{fromAttribute:o.converter}:o.converter?.fromAttribute!==void 0?o.converter:T;this._$Em=r;let l=n.fromAttribute(e,o.type);this[r]=l??this._$Ej?.get(r)??l,this._$Em=null}}requestUpdate(t,e,s,r=!1,o){if(t!==void 0){let n=this.constructor;if(r===!1&&(o=this[t]),s??=n.getPropertyOptions(t),!((s.hasChanged??D)(o,e)||s.useDefault&&s.reflect&&o===this._$Ej?.get(t)&&!this.hasAttribute(n._$Eu(t,s))))return;this.C(t,e,s)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(t,e,{useDefault:s,reflect:r,wrapped:o},n){s&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,n??e??this[t]),o!==!0||n!==void 0)||(this._$AL.has(t)||(this.hasUpdated||s||(e=void 0),this._$AL.set(t,e)),r===!0&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}let t=this.scheduleUpdate();return t!=null&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(let[r,o]of this._$Ep)this[r]=o;this._$Ep=void 0}let s=this.constructor.elementProperties;if(s.size>0)for(let[r,o]of s){let{wrapped:n}=o,l=this[r];n!==!0||this._$AL.has(r)||l===void 0||this.C(r,void 0,o,l)}}let t=!1,e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(s=>s.hostUpdate?.()),this.update(e)):this._$EM()}catch(s){throw t=!1,this._$EM(),s}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(t){}firstUpdated(t){}};g.elementStyles=[],g.shadowRootOptions={mode:"open"},g[O("elementProperties")]=new Map,g[O("finalized")]=new Map,Lt?.({ReactiveElement:g}),(L.reactiveElementVersions??=[]).push("2.1.2");var Q=globalThis,ht=i=>i,B=Q.trustedTypes,ct=B?B.createPolicy("lit-html",{createHTML:i=>i}):void 0,_t="$lit$",y=`lit$${Math.random().toFixed(9).slice(2)}$`,gt="?"+y,Dt=`<${gt}>`,S=document,k=()=>S.createComment(""),P=i=>i===null||typeof i!="object"&&typeof i!="function",tt=Array.isArray,Bt=i=>tt(i)||typeof i?.[Symbol.iterator]=="function",K=`[
2
+ \f\r]`,R=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,dt=/-->/g,ut=/>/g,A=RegExp(`>|${K}(?:([^\\s"'>=/]+)(${K}*=${K}*(?:[^
3
+ \f\r"'\`<>=]|("|')|))|$)`,"g"),pt=/'/g,mt=/"/g,$t=/^(?:script|style|textarea|title)$/i,et=i=>(t,...e)=>({_$litType$:i,strings:t,values:e}),z=et(1),se=et(2),re=et(3),$=Symbol.for("lit-noChange"),u=Symbol.for("lit-nothing"),ft=new WeakMap,E=S.createTreeWalker(S,129);function vt(i,t){if(!tt(i)||!i.hasOwnProperty("raw"))throw Error("invalid template strings array");return ct!==void 0?ct.createHTML(t):t}var zt=(i,t)=>{let e=i.length-1,s=[],r,o=t===2?"<svg>":t===3?"<math>":"",n=R;for(let l=0;l<e;l++){let a=i[l],h,d,c=-1,_=0;for(;_<a.length&&(n.lastIndex=_,d=n.exec(a),d!==null);)_=n.lastIndex,n===R?d[1]==="!--"?n=dt:d[1]!==void 0?n=ut:d[2]!==void 0?($t.test(d[2])&&(r=RegExp("</"+d[2],"g")),n=A):d[3]!==void 0&&(n=A):n===A?d[0]===">"?(n=r??R,c=-1):d[1]===void 0?c=-2:(c=n.lastIndex-d[2].length,h=d[1],n=d[3]===void 0?A:d[3]==='"'?mt:pt):n===mt||n===pt?n=A:n===dt||n===ut?n=R:(n=A,r=void 0);let v=n===A&&i[l+1].startsWith("/>")?" ":"";o+=n===R?a+Dt:c>=0?(s.push(h),a.slice(0,c)+_t+a.slice(c)+y+v):a+y+(c===-2?l:v)}return[vt(i,o+(i[e]||"<?>")+(t===2?"</svg>":t===3?"</math>":"")),s]},M=class i{constructor({strings:t,_$litType$:e},s){let r;this.parts=[];let o=0,n=0,l=t.length-1,a=this.parts,[h,d]=zt(t,e);if(this.el=i.createElement(h,s),E.currentNode=this.el.content,e===2||e===3){let c=this.el.content.firstChild;c.replaceWith(...c.childNodes)}for(;(r=E.nextNode())!==null&&a.length<l;){if(r.nodeType===1){if(r.hasAttributes())for(let c of r.getAttributeNames())if(c.endsWith(_t)){let _=d[n++],v=r.getAttribute(c).split(y),U=/([.?@])?(.*)/.exec(_);a.push({type:1,index:o,name:U[2],strings:v,ctor:U[1]==="."?J:U[1]==="?"?X:U[1]==="@"?Y:w}),r.removeAttribute(c)}else c.startsWith(y)&&(a.push({type:6,index:o}),r.removeAttribute(c));if($t.test(r.tagName)){let c=r.textContent.split(y),_=c.length-1;if(_>0){r.textContent=B?B.emptyScript:"";for(let v=0;v<_;v++)r.append(c[v],k()),E.nextNode(),a.push({type:2,index:++o});r.append(c[_],k())}}}else if(r.nodeType===8)if(r.data===gt)a.push({type:2,index:o});else{let c=-1;for(;(c=r.data.indexOf(y,c+1))!==-1;)a.push({type:7,index:o}),c+=y.length-1}o++}}static createElement(t,e){let s=S.createElement("template");return s.innerHTML=t,s}};function x(i,t,e=i,s){if(t===$)return t;let r=s!==void 0?e._$Co?.[s]:e._$Cl,o=P(t)?void 0:t._$litDirective$;return r?.constructor!==o&&(r?._$AO?.(!1),o===void 0?r=void 0:(r=new o(i),r._$AT(i,e,s)),s!==void 0?(e._$Co??=[])[s]=r:e._$Cl=r),r!==void 0&&(t=x(i,r._$AS(i,t.values),r,s)),t}var G=class{constructor(t,e){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=e}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){let{el:{content:e},parts:s}=this._$AD,r=(t?.creationScope??S).importNode(e,!0);E.currentNode=r;let o=E.nextNode(),n=0,l=0,a=s[0];for(;a!==void 0;){if(n===a.index){let h;a.type===2?h=new N(o,o.nextSibling,this,t):a.type===1?h=new a.ctor(o,a.name,a.strings,this,t):a.type===6&&(h=new Z(o,this,t)),this._$AV.push(h),a=s[++l]}n!==a?.index&&(o=E.nextNode(),n++)}return E.currentNode=S,r}p(t){let e=0;for(let s of this._$AV)s!==void 0&&(s.strings!==void 0?(s._$AI(t,s,e),e+=s.strings.length-2):s._$AI(t[e])),e++}},N=class i{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,e,s,r){this.type=2,this._$AH=u,this._$AN=void 0,this._$AA=t,this._$AB=e,this._$AM=s,this.options=r,this._$Cv=r?.isConnected??!0}get parentNode(){let t=this._$AA.parentNode,e=this._$AM;return e!==void 0&&t?.nodeType===11&&(t=e.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,e=this){t=x(this,t,e),P(t)?t===u||t==null||t===""?(this._$AH!==u&&this._$AR(),this._$AH=u):t!==this._$AH&&t!==$&&this._(t):t._$litType$!==void 0?this.$(t):t.nodeType!==void 0?this.T(t):Bt(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==u&&P(this._$AH)?this._$AA.nextSibling.data=t:this.T(S.createTextNode(t)),this._$AH=t}$(t){let{values:e,_$litType$:s}=t,r=typeof s=="number"?this._$AC(t):(s.el===void 0&&(s.el=M.createElement(vt(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===r)this._$AH.p(e);else{let o=new G(r,this),n=o.u(this.options);o.p(e),this.T(n),this._$AH=o}}_$AC(t){let e=ft.get(t.strings);return e===void 0&&ft.set(t.strings,e=new M(t)),e}k(t){tt(this._$AH)||(this._$AH=[],this._$AR());let e=this._$AH,s,r=0;for(let o of t)r===e.length?e.push(s=new i(this.O(k()),this.O(k()),this,this.options)):s=e[r],s._$AI(o),r++;r<e.length&&(this._$AR(s&&s._$AB.nextSibling,r),e.length=r)}_$AR(t=this._$AA.nextSibling,e){for(this._$AP?.(!1,!0,e);t!==this._$AB;){let s=ht(t).nextSibling;ht(t).remove(),t=s}}setConnected(t){this._$AM===void 0&&(this._$Cv=t,this._$AP?.(t))}},w=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,e,s,r,o){this.type=1,this._$AH=u,this._$AN=void 0,this.element=t,this.name=e,this._$AM=r,this.options=o,s.length>2||s[0]!==""||s[1]!==""?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=u}_$AI(t,e=this,s,r){let o=this.strings,n=!1;if(o===void 0)t=x(this,t,e,0),n=!P(t)||t!==this._$AH&&t!==$,n&&(this._$AH=t);else{let l=t,a,h;for(t=o[0],a=0;a<o.length-1;a++)h=x(this,l[s+a],e,a),h===$&&(h=this._$AH[a]),n||=!P(h)||h!==this._$AH[a],h===u?t=u:t!==u&&(t+=(h??"")+o[a+1]),this._$AH[a]=h}n&&!r&&this.j(t)}j(t){t===u?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??"")}},J=class extends w{constructor(){super(...arguments),this.type=3}j(t){this.element[this.name]=t===u?void 0:t}},X=class extends w{constructor(){super(...arguments),this.type=4}j(t){this.element.toggleAttribute(this.name,!!t&&t!==u)}},Y=class extends w{constructor(t,e,s,r,o){super(t,e,s,r,o),this.type=5}_$AI(t,e=this){if((t=x(this,t,e,0)??u)===$)return;let s=this._$AH,r=t===u&&s!==u||t.capture!==s.capture||t.once!==s.once||t.passive!==s.passive,o=t!==u&&(s===u||r);r&&this.element.removeEventListener(this.name,this,s),o&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t)}},Z=class{constructor(t,e,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=e,this.options=s}get _$AU(){return this._$AM._$AU}_$AI(t){x(this,t)}};var jt=Q.litHtmlPolyfillSupport;jt?.(M,N),(Q.litHtmlVersions??=[]).push("3.3.2");var yt=(i,t,e)=>{let s=e?.renderBefore??t,r=s._$litPart$;if(r===void 0){let o=e?.renderBefore??null;s._$litPart$=r=new N(t.insertBefore(k(),o),o,void 0,e??{})}return r._$AI(i),r};var st=globalThis,b=class extends g{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){let e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=yt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return $}};b._$litElement$=!0,b.finalized=!0,st.litElementHydrateSupport?.({LitElement:b});var qt=st.litElementPolyfillSupport;qt?.({LitElement:b});(st.litElementVersions??=[]).push("4.2.2");var bt=i=>(t,e)=>{e!==void 0?e.addInitializer(()=>{customElements.define(i,t)}):customElements.define(i,t)};var Vt={attribute:!0,type:String,converter:T,reflect:!1,hasChanged:D},Wt=(i=Vt,t,e)=>{let{kind:s,metadata:r}=e,o=globalThis.litPropertyMetadata.get(r);if(o===void 0&&globalThis.litPropertyMetadata.set(r,o=new Map),s==="setter"&&((i=Object.create(i)).wrapped=!0),o.set(e.name,i),s==="accessor"){let{name:n}=e;return{set(l){let a=t.get.call(this);t.set.call(this,l),this.requestUpdate(n,a,i,!0,l)},init(l){return l!==void 0&&this.C(n,void 0,i,l),l}}}if(s==="setter"){let{name:n}=e;return function(l){let a=this[n];t.call(this,l),this.requestUpdate(n,a,i,!0,l)}}throw Error("Unsupported decorator location: "+s)};function f(i){return(t,e)=>typeof e=="object"?Wt(i,t,e):((s,r,o)=>{let n=r.hasOwnProperty(o);return r.constructor.createProperty(o,s),n?Object.getOwnPropertyDescriptor(r,o):void 0})(i,t,e)}function rt(i){return f({...i,state:!0,attribute:!1})}var At={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},Et=i=>(...t)=>({_$litDirective$:i,values:t}),q=class{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,s){this._$Ct=t,this._$AM=e,this._$Ci=s}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}};var St="important",Ft=" !"+St,xt=Et(class extends q{constructor(i){if(super(i),i.type!==At.ATTRIBUTE||i.name!=="style"||i.strings?.length>2)throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.")}render(i){return Object.keys(i).reduce((t,e)=>{let s=i[e];return s==null?t:t+`${e=e.includes("-")?e:e.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,"-$&").toLowerCase()}:${s};`},"")}update(i,[t]){let{style:e}=i.element;if(this.ft===void 0)return this.ft=new Set(Object.keys(t)),this.render(t);for(let s of this.ft)t[s]==null&&(this.ft.delete(s),s.includes("-")?e.removeProperty(s):e[s]=null);for(let s in t){let r=t[s];if(r!=null){this.ft.add(s);let o=typeof r=="string"&&r.endsWith(Ft);s.includes("-")||o?e.setProperty(s,o?r.slice(0,-11):r,o?St:""):e[s]=r}}return $}});var Kt=new Set(["IMG","SVG","VIDEO","CANVAS","IFRAME","INPUT","TEXTAREA","BUTTON","HR"]),Gt=new Set(["BR","WBR","HR"]);function Jt(i){if(Kt.has(i.tagName))return!0;for(let t of i.children)if(!Gt.has(t.tagName))return!1;return!0}function Xt(i){for(let t of i.childNodes)if(t.nodeType===Node.TEXT_NODE&&t.textContent?.trim())return!0;return!1}function wt(i,t){let e=[];function s(r){let o=r.getBoundingClientRect();if(o.width===0||o.height===0||r.hasAttribute("data-shimmer-ignore"))return;if(r.hasAttribute("data-shimmer-no-children")||Jt(r)){let a=getComputedStyle(r).borderRadius;if((r.tagName==="TD"||r.tagName==="TH")&&Xt(r)){let h=document.createElement("span");h.style.visibility="hidden",h.style.position="absolute",h.textContent=r.textContent,r.appendChild(h);let d=h.getBoundingClientRect();r.removeChild(h),e.push({x:o.left-t.left,y:o.top-t.top,width:Math.min(d.width,o.width),height:o.height,tag:r.tagName.toLowerCase(),borderRadius:a==="0px"?"":a});return}e.push({x:o.left-t.left,y:o.top-t.top,width:o.width,height:o.height,tag:r.tagName.toLowerCase(),borderRadius:a==="0px"?"":a});return}for(let l of r.children)s(l)}return s(i),e}function Ct(i,t){let e=null,s=new ResizeObserver(()=>{e!==null&&cancelAnimationFrame(e),e=requestAnimationFrame(()=>{e=null,t()})});return s.observe(i),s}var Ot=W`
4
4
  :host {
5
5
  display: block;
6
6
  position: relative;
@@ -28,6 +28,11 @@
28
28
  inset: 0;
29
29
  pointer-events: none;
30
30
  overflow: hidden;
31
+ transition: opacity var(--reveal-duration, 0s) ease-out;
32
+ }
33
+
34
+ .shimmer-overlay.revealing {
35
+ opacity: 0;
31
36
  }
32
37
 
33
38
  .shimmer-block {
@@ -35,43 +40,86 @@
35
40
  overflow: hidden;
36
41
  }
37
42
 
43
+ /* Shimmer mode (default) */
38
44
  .shimmer-block::after {
39
45
  content: "";
40
46
  position: absolute;
41
47
  inset: 0;
42
- animation: shimmer-sweep var(--shimmer-duration, 1.5s) ease-in-out infinite;
48
+ background: linear-gradient(
49
+ 90deg,
50
+ var(--shimmer-bg) 30%,
51
+ var(--shimmer-color) 50%,
52
+ var(--shimmer-bg) 70%
53
+ );
54
+ background-size: 200% 100%;
55
+ animation: shimmer-sweep var(--shimmer-duration, 1.5s) linear infinite;
43
56
  }
44
57
 
45
58
  @keyframes shimmer-sweep {
46
59
  0% {
47
- background: linear-gradient(
48
- 90deg,
49
- transparent 0%,
50
- var(--shimmer-color) 50%,
51
- transparent 100%
52
- );
53
- background-size: 200% 100%;
54
- background-position: -100% 0;
60
+ background-position: 200% 0;
55
61
  }
56
62
  100% {
57
- background: linear-gradient(
58
- 90deg,
59
- transparent 0%,
60
- var(--shimmer-color) 50%,
61
- transparent 100%
62
- );
63
- background-size: 200% 100%;
64
- background-position: 200% 0;
63
+ background-position: -200% 0;
64
+ }
65
+ }
66
+
67
+ /* Pulse mode */
68
+ :host([animation="pulse"]) .shimmer-block {
69
+ animation: phantom-pulse var(--shimmer-duration, 1.5s) ease-in-out infinite;
70
+ }
71
+
72
+ :host([animation="pulse"]) .shimmer-block::after {
73
+ display: none;
74
+ }
75
+
76
+ @keyframes phantom-pulse {
77
+ 0%,
78
+ 100% {
79
+ opacity: 1;
65
80
  }
81
+ 50% {
82
+ opacity: 0.4;
83
+ }
84
+ }
85
+
86
+ /* Breathe mode - subtle scale + fade */
87
+ :host([animation="breathe"]) .shimmer-block {
88
+ animation: phantom-breathe var(--shimmer-duration, 1.5s) ease-in-out infinite;
89
+ }
90
+
91
+ :host([animation="breathe"]) .shimmer-block::after {
92
+ display: none;
93
+ }
94
+
95
+ @keyframes phantom-breathe {
96
+ 0%,
97
+ 100% {
98
+ opacity: 0.6;
99
+ transform: scale(1);
100
+ }
101
+ 50% {
102
+ opacity: 1;
103
+ transform: scale(1.02);
104
+ }
105
+ }
106
+
107
+ /* Solid mode */
108
+ :host([animation="solid"]) .shimmer-block::after {
109
+ display: none;
66
110
  }
67
- `;var p=class extends b{constructor(){super(...arguments);this.loading=!1;this.shimmerColor="rgba(255, 255, 255, 0.3)";this.backgroundColor="rgba(255, 255, 255, 0.08)";this.duration=1.5;this.fallbackRadius=4;this._blocks=[];this._resizeObserver=null;this._mutationObserver=null;this._measureScheduled=!1}disconnectedCallback(){super.disconnectedCallback(),this._teardownObservers()}updated(e){e.has("loading")&&(this.loading?(this._scheduleMeasure(),this._setupObservers()):(this._blocks=[],this._teardownObservers()))}render(){let e=xt({"--shimmer-color":this.shimmerColor,"--shimmer-duration":`${this.duration}s`,"--shimmer-bg":this.backgroundColor});return z`
68
- <slot></slot>
69
- ${this.loading?z`
70
- <div class="shimmer-overlay" style=${e} aria-hidden="true">
71
- ${this._renderBlocks()}
72
- </div>
73
- `:""}
74
- `}_scheduleMeasure(){this._measureScheduled||(this._measureScheduled=!0,requestAnimationFrame(()=>{this._measureScheduled=!1,this._measure()}))}_measure(){if(!this.loading)return;let e=this.getBoundingClientRect();if(e.width===0||e.height===0)return;let s=this.shadowRoot?.querySelector("slot");if(!s)return;let r=s.assignedElements({flatten:!0}),o=[];for(let n of r){let h=Ct(n,e);o.push(...h)}this._blocks=o}_setupObservers(){this._teardownObservers(),this._resizeObserver=wt(this,()=>{this._scheduleMeasure()}),this._mutationObserver=new MutationObserver(()=>{this._scheduleMeasure()}),this._mutationObserver.observe(this,{childList:!0,subtree:!0,attributes:!0})}_teardownObservers(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._mutationObserver&&(this._mutationObserver.disconnect(),this._mutationObserver=null)}_renderBlocks(){return this._blocks.map(e=>{let s=e.borderRadius||`${this.fallbackRadius}px`;return z`
111
+ `;var p=class extends b{constructor(){super(...arguments);this.loading=!1;this.shimmerColor="rgba(255, 255, 255, 0.3)";this.backgroundColor="rgba(255, 255, 255, 0.08)";this.duration=1.5;this.fallbackRadius=4;this.animation="shimmer";this.stagger=0;this.reveal=0;this._blocks=[];this._revealing=!1;this._resizeObserver=null;this._mutationObserver=null;this._measureScheduled=!1;this._revealTimeout=null}disconnectedCallback(){super.disconnectedCallback(),this._teardownObservers(),this._clearRevealTimeout()}updated(e){e.has("loading")&&(this.setAttribute("aria-busy",String(this.loading)),this.loading?(this._revealing=!1,this._clearRevealTimeout(),this._scheduleMeasure(),this._setupObservers()):this.reveal>0&&this._blocks.length>0?(this._revealing=!0,this._teardownObservers(),this._revealTimeout=setTimeout(()=>{this._revealing=!1,this._blocks=[],this._revealTimeout=null},this.reveal*1e3)):(this._blocks=[],this._teardownObservers()))}render(){let e=xt({"--shimmer-color":this.shimmerColor,"--shimmer-duration":`${this.duration}s`,"--shimmer-bg":this.backgroundColor,"--reveal-duration":`${this.reveal}s`}),s=this.loading||this._revealing;return z`
112
+ <slot></slot>
113
+ ${s?z`
114
+ <div
115
+ class="shimmer-overlay ${this._revealing?"revealing":""}"
116
+ style=${e}
117
+ aria-hidden="true"
118
+ >
119
+ ${this._renderBlocks()}
120
+ </div>
121
+ `:""}
122
+ `}_scheduleMeasure(){this._measureScheduled||(this._measureScheduled=!0,requestAnimationFrame(()=>{this._measureScheduled=!1,this._measure()}))}_measure(){if(!this.loading)return;let e=this.getBoundingClientRect();if(e.width===0||e.height===0)return;let s=this.shadowRoot?.querySelector("slot");if(!s)return;let r=s.assignedElements({flatten:!0}),o=[];for(let n of r){let l=wt(n,e);o.push(...l)}this._blocks=o}_setupObservers(){this._teardownObservers(),this._resizeObserver=Ct(this,()=>{this._scheduleMeasure()}),this._mutationObserver=new MutationObserver(()=>{this._scheduleMeasure()}),this._mutationObserver.observe(this,{childList:!0,subtree:!0,attributes:!0})}_teardownObservers(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._mutationObserver&&(this._mutationObserver.disconnect(),this._mutationObserver=null)}_clearRevealTimeout(){this._revealTimeout!==null&&(clearTimeout(this._revealTimeout),this._revealTimeout=null)}_renderBlocks(){return this._blocks.map((e,s)=>{let r=e.borderRadius||`${this.fallbackRadius}px`,o=this.stagger,n=o>0?`animation-delay: ${s*o}s;`:"";return z`
75
123
  <div
76
124
  class="shimmer-block"
77
125
  style="
@@ -79,11 +127,12 @@
79
127
  top: ${e.y}px;
80
128
  width: ${e.width}px;
81
129
  height: ${e.height}px;
82
- border-radius: ${s};
130
+ border-radius: ${r};
83
131
  background: var(--shimmer-bg, ${this.backgroundColor});
132
+ ${n}
84
133
  "
85
134
  ></div>
86
- `})}};p.styles=Ot,g([v({type:Boolean,reflect:!0})],p.prototype,"loading",2),g([v({attribute:"shimmer-color"})],p.prototype,"shimmerColor",2),g([v({attribute:"background-color"})],p.prototype,"backgroundColor",2),g([v({type:Number})],p.prototype,"duration",2),g([v({type:Number,attribute:"fallback-radius"})],p.prototype,"fallbackRadius",2),g([vt()],p.prototype,"_blocks",2),p=g([bt("phantom-ui")],p);})();
135
+ `})}};p.styles=Ot,m([f({type:Boolean,reflect:!0})],p.prototype,"loading",2),m([f({attribute:"shimmer-color"})],p.prototype,"shimmerColor",2),m([f({attribute:"background-color"})],p.prototype,"backgroundColor",2),m([f({type:Number})],p.prototype,"duration",2),m([f({type:Number,attribute:"fallback-radius"})],p.prototype,"fallbackRadius",2),m([f({reflect:!0})],p.prototype,"animation",2),m([f({type:Number})],p.prototype,"stagger",2),m([f({type:Number})],p.prototype,"reveal",2),m([rt()],p.prototype,"_blocks",2),m([rt()],p.prototype,"_revealing",2),p=m([bt("phantom-ui")],p);})();
87
136
  /*! Bundled license information:
88
137
 
89
138
  @lit/reactive-element/css-tag.js:
@@ -1,22 +1,26 @@
1
1
  import { LitElement } from "lit";
2
2
  import type { CSSResult } from "lit";
3
+ type Animation = "shimmer" | "pulse" | "breathe" | "solid";
3
4
  /**
4
- * `<phantom-ui>` A structure-aware shimmer skeleton loader.
5
+ * `<phantom-ui>` -- A structure-aware shimmer skeleton loader.
5
6
  *
6
7
  * Wraps real content and, when `loading` is true, measures the DOM structure
7
8
  * of the slotted children to generate perfectly-aligned shimmer overlay blocks.
8
9
  *
9
10
  * @slot - The real content to show (or measure for skeleton generation)
10
11
  *
11
- * @property {boolean} loading - Whether to show the shimmer overlay or the real content
12
- * @property {string} shimmerColor - Color of the animated shimmer gradient wave
13
- * @property {string} backgroundColor - Background color of each shimmer block
14
- * @property {number} duration - Animation cycle duration in seconds
15
- * @property {number} fallbackRadius - Border radius (px) for elements with border-radius: 0
12
+ * @attr {boolean} loading - Show the shimmer overlay or real content
13
+ * @attr {string} shimmer-color - Color of the animated gradient wave
14
+ * @attr {string} background-color - Background color of each shimmer block
15
+ * @attr {number} duration - Animation cycle duration in seconds
16
+ * @attr {number} fallback-radius - Border radius (px) for elements with no radius
17
+ * @attr {Animation} animation - Animation mode: shimmer, pulse, breathe, or solid
18
+ * @attr {number} stagger - Delay in seconds between each block's animation start
19
+ * @attr {number} reveal - Fade-out duration in seconds when loading ends (0 = instant)
16
20
  *
17
21
  * @example
18
22
  * ```html
19
- * <phantom-ui loading>
23
+ * <phantom-ui loading animation="pulse" stagger="0.05">
20
24
  * <div class="card">
21
25
  * <img src="avatar.png" width="48" height="48" />
22
26
  * <h3>User Name</h3>
@@ -37,10 +41,18 @@ export declare class PhantomUi extends LitElement {
37
41
  duration: number;
38
42
  /** Border radius applied to elements with border-radius: 0 (like text) */
39
43
  fallbackRadius: number;
44
+ /** Animation mode: "shimmer" (gradient sweep), "pulse" (opacity), "breathe" (scale + fade), or "solid" (static) */
45
+ animation: Animation;
46
+ /** Delay in seconds between each block's animation start (0 = no stagger) */
47
+ stagger: number;
48
+ /** Fade-out duration in seconds when loading ends (0 = instant) */
49
+ reveal: number;
40
50
  private _blocks;
51
+ private _revealing;
41
52
  private _resizeObserver;
42
53
  private _mutationObserver;
43
54
  private _measureScheduled;
55
+ private _revealTimeout;
44
56
  disconnectedCallback(): void;
45
57
  updated(changedProperties: Map<PropertyKey, unknown>): void;
46
58
  render(): import("lit-html").TemplateResult<1>;
@@ -48,6 +60,7 @@ export declare class PhantomUi extends LitElement {
48
60
  private _measure;
49
61
  private _setupObservers;
50
62
  private _teardownObservers;
63
+ private _clearRevealTimeout;
51
64
  private _renderBlocks;
52
65
  }
53
66
  export interface PhantomUiAttributes {
@@ -56,6 +69,9 @@ export interface PhantomUiAttributes {
56
69
  "background-color"?: string;
57
70
  duration?: number;
58
71
  "fallback-radius"?: number;
72
+ animation?: "shimmer" | "pulse" | "breathe" | "solid";
73
+ stagger?: number;
74
+ reveal?: number;
59
75
  children?: unknown;
60
76
  class?: string;
61
77
  id?: string;
@@ -76,3 +92,4 @@ declare global {
76
92
  }
77
93
  }
78
94
  }
95
+ export {};
@@ -1,4 +1,4 @@
1
- var v=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var a=(o,r,e,i)=>{for(var t=i>1?void 0:i?_(r,e):r,s=o.length-1,l;s>=0;s--)(l=o[s])&&(t=(i?l(r,e,t):l(t))||t);return i&&t&&v(r,e,t),t};import{LitElement as x,html as c}from"lit";import{customElement as R,property as d,state as C}from"lit/decorators.js";import{styleMap as S}from"lit/directives/style-map.js";var y=new Set(["IMG","SVG","VIDEO","CANVAS","IFRAME","INPUT","TEXTAREA","BUTTON","HR"]),k=new Set(["BR","WBR","HR"]);function w(o){if(y.has(o.tagName))return!0;for(let r of o.children)if(!k.has(r.tagName))return!1;return!0}function O(o){for(let r of o.childNodes)if(r.nodeType===Node.TEXT_NODE&&r.textContent?.trim())return!0;return!1}function b(o,r){let e=[];function i(t){let s=t.getBoundingClientRect();if(s.width===0||s.height===0||t.hasAttribute("data-shimmer-ignore"))return;if(t.hasAttribute("data-shimmer-no-children")||w(t)){let h=getComputedStyle(t).borderRadius;if((t.tagName==="TD"||t.tagName==="TH")&&O(t)){let u=document.createElement("span");u.style.visibility="hidden",u.style.position="absolute",u.textContent=t.textContent,t.appendChild(u);let g=u.getBoundingClientRect();t.removeChild(u),e.push({x:s.left-r.left,y:s.top-r.top,width:Math.min(g.width,s.width),height:s.height,tag:t.tagName.toLowerCase(),borderRadius:h==="0px"?"":h});return}e.push({x:s.left-r.left,y:s.top-r.top,width:s.width,height:s.height,tag:t.tagName.toLowerCase(),borderRadius:h==="0px"?"":h});return}for(let m of t.children)i(m)}for(let t of o.children)i(t);return e}function p(o,r){let e=null,i=new ResizeObserver(()=>{e!==null&&cancelAnimationFrame(e),e=requestAnimationFrame(()=>{e=null,r()})});return i.observe(o),i}import{css as E}from"lit";var f=E`
1
+ var y=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var a=(n,i,e,s)=>{for(var t=s>1?void 0:s?_(i,e):i,r=n.length-1,l;r>=0;r--)(l=n[r])&&(t=(s?l(i,e,t):l(t))||t);return s&&t&&y(i,e,t),t};import{LitElement as T,html as c}from"lit";import{customElement as x,property as m,state as f}from"lit/decorators.js";import{styleMap as S}from"lit/directives/style-map.js";var k=new Set(["IMG","SVG","VIDEO","CANVAS","IFRAME","INPUT","TEXTAREA","BUTTON","HR"]),w=new Set(["BR","WBR","HR"]);function O(n){if(k.has(n.tagName))return!0;for(let i of n.children)if(!w.has(i.tagName))return!1;return!0}function R(n){for(let i of n.childNodes)if(i.nodeType===Node.TEXT_NODE&&i.textContent?.trim())return!0;return!1}function b(n,i){let e=[];function s(t){let r=t.getBoundingClientRect();if(r.width===0||r.height===0||t.hasAttribute("data-shimmer-ignore"))return;if(t.hasAttribute("data-shimmer-no-children")||O(t)){let d=getComputedStyle(t).borderRadius;if((t.tagName==="TD"||t.tagName==="TH")&&R(t)){let u=document.createElement("span");u.style.visibility="hidden",u.style.position="absolute",u.textContent=t.textContent,t.appendChild(u);let g=u.getBoundingClientRect();t.removeChild(u),e.push({x:r.left-i.left,y:r.top-i.top,width:Math.min(g.width,r.width),height:r.height,tag:t.tagName.toLowerCase(),borderRadius:d==="0px"?"":d});return}e.push({x:r.left-i.left,y:r.top-i.top,width:r.width,height:r.height,tag:t.tagName.toLowerCase(),borderRadius:d==="0px"?"":d});return}for(let h of t.children)s(h)}return s(n),e}function p(n,i){let e=null,s=new ResizeObserver(()=>{e!==null&&cancelAnimationFrame(e),e=requestAnimationFrame(()=>{e=null,i()})});return s.observe(n),s}import{css as E}from"lit";var v=E`
2
2
  :host {
3
3
  display: block;
4
4
  position: relative;
@@ -26,6 +26,11 @@ var v=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var a=(o,r,e,i
26
26
  inset: 0;
27
27
  pointer-events: none;
28
28
  overflow: hidden;
29
+ transition: opacity var(--reveal-duration, 0s) ease-out;
30
+ }
31
+
32
+ .shimmer-overlay.revealing {
33
+ opacity: 0;
29
34
  }
30
35
 
31
36
  .shimmer-block {
@@ -33,43 +38,86 @@ var v=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var a=(o,r,e,i
33
38
  overflow: hidden;
34
39
  }
35
40
 
41
+ /* Shimmer mode (default) */
36
42
  .shimmer-block::after {
37
43
  content: "";
38
44
  position: absolute;
39
45
  inset: 0;
40
- animation: shimmer-sweep var(--shimmer-duration, 1.5s) ease-in-out infinite;
46
+ background: linear-gradient(
47
+ 90deg,
48
+ var(--shimmer-bg) 30%,
49
+ var(--shimmer-color) 50%,
50
+ var(--shimmer-bg) 70%
51
+ );
52
+ background-size: 200% 100%;
53
+ animation: shimmer-sweep var(--shimmer-duration, 1.5s) linear infinite;
41
54
  }
42
55
 
43
56
  @keyframes shimmer-sweep {
44
57
  0% {
45
- background: linear-gradient(
46
- 90deg,
47
- transparent 0%,
48
- var(--shimmer-color) 50%,
49
- transparent 100%
50
- );
51
- background-size: 200% 100%;
52
- background-position: -100% 0;
58
+ background-position: 200% 0;
53
59
  }
54
60
  100% {
55
- background: linear-gradient(
56
- 90deg,
57
- transparent 0%,
58
- var(--shimmer-color) 50%,
59
- transparent 100%
60
- );
61
- background-size: 200% 100%;
62
- background-position: 200% 0;
61
+ background-position: -200% 0;
62
+ }
63
+ }
64
+
65
+ /* Pulse mode */
66
+ :host([animation="pulse"]) .shimmer-block {
67
+ animation: phantom-pulse var(--shimmer-duration, 1.5s) ease-in-out infinite;
68
+ }
69
+
70
+ :host([animation="pulse"]) .shimmer-block::after {
71
+ display: none;
72
+ }
73
+
74
+ @keyframes phantom-pulse {
75
+ 0%,
76
+ 100% {
77
+ opacity: 1;
63
78
  }
79
+ 50% {
80
+ opacity: 0.4;
81
+ }
82
+ }
83
+
84
+ /* Breathe mode - subtle scale + fade */
85
+ :host([animation="breathe"]) .shimmer-block {
86
+ animation: phantom-breathe var(--shimmer-duration, 1.5s) ease-in-out infinite;
87
+ }
88
+
89
+ :host([animation="breathe"]) .shimmer-block::after {
90
+ display: none;
91
+ }
92
+
93
+ @keyframes phantom-breathe {
94
+ 0%,
95
+ 100% {
96
+ opacity: 0.6;
97
+ transform: scale(1);
98
+ }
99
+ 50% {
100
+ opacity: 1;
101
+ transform: scale(1.02);
102
+ }
103
+ }
104
+
105
+ /* Solid mode */
106
+ :host([animation="solid"]) .shimmer-block::after {
107
+ display: none;
64
108
  }
65
- `;var n=class extends x{constructor(){super(...arguments);this.loading=!1;this.shimmerColor="rgba(255, 255, 255, 0.3)";this.backgroundColor="rgba(255, 255, 255, 0.08)";this.duration=1.5;this.fallbackRadius=4;this._blocks=[];this._resizeObserver=null;this._mutationObserver=null;this._measureScheduled=!1}disconnectedCallback(){super.disconnectedCallback(),this._teardownObservers()}updated(e){e.has("loading")&&(this.loading?(this._scheduleMeasure(),this._setupObservers()):(this._blocks=[],this._teardownObservers()))}render(){let e=S({"--shimmer-color":this.shimmerColor,"--shimmer-duration":`${this.duration}s`,"--shimmer-bg":this.backgroundColor});return c`
66
- <slot></slot>
67
- ${this.loading?c`
68
- <div class="shimmer-overlay" style=${e} aria-hidden="true">
69
- ${this._renderBlocks()}
70
- </div>
71
- `:""}
72
- `}_scheduleMeasure(){this._measureScheduled||(this._measureScheduled=!0,requestAnimationFrame(()=>{this._measureScheduled=!1,this._measure()}))}_measure(){if(!this.loading)return;let e=this.getBoundingClientRect();if(e.width===0||e.height===0)return;let i=this.shadowRoot?.querySelector("slot");if(!i)return;let t=i.assignedElements({flatten:!0}),s=[];for(let l of t){let m=b(l,e);s.push(...m)}this._blocks=s}_setupObservers(){this._teardownObservers(),this._resizeObserver=p(this,()=>{this._scheduleMeasure()}),this._mutationObserver=new MutationObserver(()=>{this._scheduleMeasure()}),this._mutationObserver.observe(this,{childList:!0,subtree:!0,attributes:!0})}_teardownObservers(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._mutationObserver&&(this._mutationObserver.disconnect(),this._mutationObserver=null)}_renderBlocks(){return this._blocks.map(e=>{let i=e.borderRadius||`${this.fallbackRadius}px`;return c`
109
+ `;var o=class extends T{constructor(){super(...arguments);this.loading=!1;this.shimmerColor="rgba(255, 255, 255, 0.3)";this.backgroundColor="rgba(255, 255, 255, 0.08)";this.duration=1.5;this.fallbackRadius=4;this.animation="shimmer";this.stagger=0;this.reveal=0;this._blocks=[];this._revealing=!1;this._resizeObserver=null;this._mutationObserver=null;this._measureScheduled=!1;this._revealTimeout=null}disconnectedCallback(){super.disconnectedCallback(),this._teardownObservers(),this._clearRevealTimeout()}updated(e){e.has("loading")&&(this.setAttribute("aria-busy",String(this.loading)),this.loading?(this._revealing=!1,this._clearRevealTimeout(),this._scheduleMeasure(),this._setupObservers()):this.reveal>0&&this._blocks.length>0?(this._revealing=!0,this._teardownObservers(),this._revealTimeout=setTimeout(()=>{this._revealing=!1,this._blocks=[],this._revealTimeout=null},this.reveal*1e3)):(this._blocks=[],this._teardownObservers()))}render(){let e=S({"--shimmer-color":this.shimmerColor,"--shimmer-duration":`${this.duration}s`,"--shimmer-bg":this.backgroundColor,"--reveal-duration":`${this.reveal}s`}),s=this.loading||this._revealing;return c`
110
+ <slot></slot>
111
+ ${s?c`
112
+ <div
113
+ class="shimmer-overlay ${this._revealing?"revealing":""}"
114
+ style=${e}
115
+ aria-hidden="true"
116
+ >
117
+ ${this._renderBlocks()}
118
+ </div>
119
+ `:""}
120
+ `}_scheduleMeasure(){this._measureScheduled||(this._measureScheduled=!0,requestAnimationFrame(()=>{this._measureScheduled=!1,this._measure()}))}_measure(){if(!this.loading)return;let e=this.getBoundingClientRect();if(e.width===0||e.height===0)return;let s=this.shadowRoot?.querySelector("slot");if(!s)return;let t=s.assignedElements({flatten:!0}),r=[];for(let l of t){let h=b(l,e);r.push(...h)}this._blocks=r}_setupObservers(){this._teardownObservers(),this._resizeObserver=p(this,()=>{this._scheduleMeasure()}),this._mutationObserver=new MutationObserver(()=>{this._scheduleMeasure()}),this._mutationObserver.observe(this,{childList:!0,subtree:!0,attributes:!0})}_teardownObservers(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._mutationObserver&&(this._mutationObserver.disconnect(),this._mutationObserver=null)}_clearRevealTimeout(){this._revealTimeout!==null&&(clearTimeout(this._revealTimeout),this._revealTimeout=null)}_renderBlocks(){return this._blocks.map((e,s)=>{let t=e.borderRadius||`${this.fallbackRadius}px`,r=this.stagger,l=r>0?`animation-delay: ${s*r}s;`:"";return c`
73
121
  <div
74
122
  class="shimmer-block"
75
123
  style="
@@ -77,8 +125,9 @@ var v=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var a=(o,r,e,i
77
125
  top: ${e.y}px;
78
126
  width: ${e.width}px;
79
127
  height: ${e.height}px;
80
- border-radius: ${i};
128
+ border-radius: ${t};
81
129
  background: var(--shimmer-bg, ${this.backgroundColor});
130
+ ${l}
82
131
  "
83
132
  ></div>
84
- `})}};n.styles=f,a([d({type:Boolean,reflect:!0})],n.prototype,"loading",2),a([d({attribute:"shimmer-color"})],n.prototype,"shimmerColor",2),a([d({attribute:"background-color"})],n.prototype,"backgroundColor",2),a([d({type:Number})],n.prototype,"duration",2),a([d({type:Number,attribute:"fallback-radius"})],n.prototype,"fallbackRadius",2),a([C()],n.prototype,"_blocks",2),n=a([R("phantom-ui")],n);export{n as PhantomUi};
133
+ `})}};o.styles=v,a([m({type:Boolean,reflect:!0})],o.prototype,"loading",2),a([m({attribute:"shimmer-color"})],o.prototype,"shimmerColor",2),a([m({attribute:"background-color"})],o.prototype,"backgroundColor",2),a([m({type:Number})],o.prototype,"duration",2),a([m({type:Number,attribute:"fallback-radius"})],o.prototype,"fallbackRadius",2),a([m({reflect:!0})],o.prototype,"animation",2),a([m({type:Number})],o.prototype,"stagger",2),a([m({type:Number})],o.prototype,"reveal",2),a([f()],o.prototype,"_blocks",2),a([f()],o.prototype,"_revealing",2),o=a([x("phantom-ui")],o);export{o as PhantomUi};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aejkatappaja/phantom-ui",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Structure-aware shimmer skeleton loader as a universal Web Component built with Lit. Works with React, Vue, Svelte, Angular, Solid, or vanilla JS.",
5
5
  "repository": {
6
6
  "type": "git",