@aejkatappaja/phantom-ui 0.2.4 → 0.4.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
@@ -280,9 +280,14 @@ declare module "@builder.io/qwik" {
280
280
  | Attribute | Type | Default | Description |
281
281
  | --- | --- | --- | --- |
282
282
  | `loading` | `boolean` | `false` | Show shimmer overlay or real content |
283
+ | `animation` | `string` | `shimmer` | Animation mode: `shimmer`, `pulse`, `breathe`, or `solid` |
283
284
  | `shimmer-color` | `string` | `rgba(255,255,255,0.3)` | Color of the animated gradient sweep |
284
285
  | `background-color` | `string` | `rgba(255,255,255,0.08)` | Background of each shimmer block |
285
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 |
289
+ | `count` | `number` | `1` | Number of skeleton rows to repeat from a single template |
290
+ | `count-gap` | `number` | `0` | Gap in pixels between repeated rows |
286
291
  | `fallback-radius` | `number` | `4` | Border radius (px) for flat elements like text |
287
292
 
288
293
  ## Fine-grained control
@@ -309,6 +314,35 @@ Two data attributes let you control which elements get shimmer treatment:
309
314
  </phantom-ui>
310
315
  ```
311
316
 
317
+ ## Repeat mode
318
+
319
+ When loading a dynamic list or table, you often don't have the data yet to render N rows. The `count` attribute lets you define a single template element and generate multiple skeleton rows from it:
320
+
321
+ ```html
322
+ <phantom-ui loading count="5" count-gap="8">
323
+ <div class="user-row">
324
+ <img src="avatar.png" width="32" height="32" />
325
+ <span>John Doe</span>
326
+ <span>john@acme.io</span>
327
+ </div>
328
+ </phantom-ui>
329
+ ```
330
+
331
+ The component measures the template once, then duplicates the skeleton blocks vertically for each count. `count-gap` adds spacing (in pixels) between repeated rows. When `loading` is removed, only the real template element is shown.
332
+
333
+ This is useful with framework loops where the list is empty before data loads:
334
+
335
+ ```tsx
336
+ // React
337
+ <phantom-ui loading={!users} count={5} count-gap={8}>
338
+ <div className="row-template">
339
+ <img src="/placeholder.png" width="32" height="32" />
340
+ <span>Placeholder Name</span>
341
+ <span>placeholder@email.com</span>
342
+ </div>
343
+ </phantom-ui>
344
+ ```
345
+
312
346
  ## How it works
313
347
 
314
348
  1. Your real content is rendered in the DOM with `color: transparent` and media elements hidden. Container backgrounds and borders stay visible, preserving the natural card/section outline.
@@ -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,60 @@
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
+ },
102
+ {
103
+ "kind": "field",
104
+ "name": "count",
105
+ "type": {
106
+ "text": "number"
107
+ },
108
+ "default": "1",
109
+ "description": "Number of skeleton rows to generate from a single template element",
110
+ "attribute": "count"
111
+ },
112
+ {
113
+ "kind": "field",
114
+ "name": "countGap",
115
+ "type": {
116
+ "text": "number"
117
+ },
118
+ "default": "0",
119
+ "description": "Gap in pixels between each repeated skeleton row (only used when count > 1)",
120
+ "attribute": "count-gap"
121
+ },
71
122
  {
72
123
  "kind": "field",
73
124
  "name": "_blocks",
@@ -77,6 +128,15 @@
77
128
  "privacy": "private",
78
129
  "default": "[]"
79
130
  },
131
+ {
132
+ "kind": "field",
133
+ "name": "_revealing",
134
+ "type": {
135
+ "text": "boolean"
136
+ },
137
+ "privacy": "private",
138
+ "default": "false"
139
+ },
80
140
  {
81
141
  "kind": "field",
82
142
  "name": "_resizeObserver",
@@ -104,6 +164,15 @@
104
164
  "privacy": "private",
105
165
  "default": "false"
106
166
  },
167
+ {
168
+ "kind": "field",
169
+ "name": "_revealTimeout",
170
+ "type": {
171
+ "text": "ReturnType<typeof setTimeout> | null"
172
+ },
173
+ "privacy": "private",
174
+ "default": "null"
175
+ },
107
176
  {
108
177
  "kind": "method",
109
178
  "name": "_scheduleMeasure",
@@ -144,6 +213,16 @@
144
213
  }
145
214
  }
146
215
  },
216
+ {
217
+ "kind": "method",
218
+ "name": "_clearRevealTimeout",
219
+ "privacy": "private",
220
+ "return": {
221
+ "type": {
222
+ "text": "void"
223
+ }
224
+ }
225
+ },
147
226
  {
148
227
  "kind": "method",
149
228
  "name": "_renderBlocks",
@@ -152,49 +231,94 @@
152
231
  ],
153
232
  "attributes": [
154
233
  {
155
- "name": "loading",
156
234
  "type": {
157
235
  "text": "boolean"
158
236
  },
159
- "default": "false",
160
237
  "description": "Whether to show the shimmer overlay or the real content",
238
+ "name": "loading",
239
+ "default": "false",
161
240
  "fieldName": "loading"
162
241
  },
163
242
  {
164
- "name": "shimmer-color",
165
243
  "type": {
166
244
  "text": "string"
167
245
  },
168
- "default": "\"rgba(255, 255, 255, 0.3)\"",
169
246
  "description": "Color of the animated shimmer gradient wave",
247
+ "name": "shimmer-color",
248
+ "default": "\"rgba(255, 255, 255, 0.3)\"",
170
249
  "fieldName": "shimmerColor"
171
250
  },
172
251
  {
173
- "name": "background-color",
174
252
  "type": {
175
253
  "text": "string"
176
254
  },
177
- "default": "\"rgba(255, 255, 255, 0.08)\"",
178
255
  "description": "Background color of each shimmer block",
256
+ "name": "background-color",
257
+ "default": "\"rgba(255, 255, 255, 0.08)\"",
179
258
  "fieldName": "backgroundColor"
180
259
  },
181
260
  {
182
- "name": "duration",
183
261
  "type": {
184
262
  "text": "number"
185
263
  },
186
- "default": "1.5",
187
264
  "description": "Animation cycle duration in seconds",
265
+ "name": "duration",
266
+ "default": "1.5",
188
267
  "fieldName": "duration"
189
268
  },
190
269
  {
191
- "name": "fallback-radius",
192
270
  "type": {
193
271
  "text": "number"
194
272
  },
273
+ "description": "Border radius applied to elements with border-radius: 0 (like text)",
274
+ "name": "fallback-radius",
195
275
  "default": "4",
196
- "description": "Border radius (px) for elements with border-radius: 0",
197
276
  "fieldName": "fallbackRadius"
277
+ },
278
+ {
279
+ "type": {
280
+ "text": "Animation"
281
+ },
282
+ "description": "Animation mode: \"shimmer\" (gradient sweep), \"pulse\" (opacity), \"breathe\" (scale + fade), or \"solid\" (static)",
283
+ "name": "animation",
284
+ "default": "\"shimmer\"",
285
+ "fieldName": "animation"
286
+ },
287
+ {
288
+ "type": {
289
+ "text": "number"
290
+ },
291
+ "description": "Delay in seconds between each block's animation start (0 = no stagger)",
292
+ "name": "stagger",
293
+ "default": "0",
294
+ "fieldName": "stagger"
295
+ },
296
+ {
297
+ "type": {
298
+ "text": "number"
299
+ },
300
+ "description": "Fade-out duration in seconds when loading ends (0 = instant)",
301
+ "name": "reveal",
302
+ "default": "0",
303
+ "fieldName": "reveal"
304
+ },
305
+ {
306
+ "type": {
307
+ "text": "number"
308
+ },
309
+ "description": "Number of skeleton rows to generate from a single template element",
310
+ "name": "count",
311
+ "default": "1",
312
+ "fieldName": "count"
313
+ },
314
+ {
315
+ "type": {
316
+ "text": "number"
317
+ },
318
+ "description": "Gap in pixels between each repeated skeleton row (only used when count > 1)",
319
+ "name": "count-gap",
320
+ "default": "0",
321
+ "fieldName": "countGap"
198
322
  }
199
323
  ],
200
324
  "superclass": {
@@ -1,9 +1,10 @@
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:Nt,getOwnPropertyNames:Ut,getOwnPropertySymbols:kt,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}=Nt(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=[...Ut(e),...kt(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]},N=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),k=/([.?@])?(.*)/.exec(m);a.push({type:1,index:o,name:k[2],strings:_,ctor:k[1]==="."?J:k[1]==="?"?X:k[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 U(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++}},U=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=N.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 N(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?.(N,U),(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 U(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)}return s(i),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:Mt,getOwnPropertyDescriptor:Nt,getOwnPropertyNames:Pt,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}},B=(i,t)=>!kt(i,t),lt={attribute:!0,type:String,converter:T,reflect:!1,useDefault:!1,hasChanged:B};Symbol.metadata??=Symbol("metadata"),L.litPropertyMetadata??=new WeakMap;var _=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&&Mt(this.prototype,t,r)}}static getPropertyDescriptor(t,e,s){let{get:r,set:o}=Nt(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=[...Pt(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??B)(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){}};_.elementStyles=[],_.shadowRootOptions={mode:"open"},_[O("elementProperties")]=new Map,_[O("finalized")]=new Map,Lt?.({ReactiveElement:_}),(L.reactiveElementVersions??=[]).push("2.1.2");var Q=globalThis,ht=i=>i,D=Q.trustedTypes,ct=D?D.createPolicy("lit-html",{createHTML:i=>i}):void 0,gt="$lit$",y=`lit$${Math.random().toFixed(9).slice(2)}$`,_t="?"+y,Bt=`<${_t}>`,S=document,k=()=>S.createComment(""),M=i=>i===null||typeof i!="object"&&typeof i!="function",tt=Array.isArray,Dt=i=>tt(i)||typeof i?.[Symbol.iterator]=="function",G=`[
2
+ \f\r]`,R=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,ut=/-->/g,dt=/>/g,A=RegExp(`>|${G}(?:([^\\s"'>=/]+)(${G}*=${G}*(?:[^
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"),d=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,u,c=-1,g=0;for(;g<a.length&&(n.lastIndex=g,u=n.exec(a),u!==null);)g=n.lastIndex,n===R?u[1]==="!--"?n=ut:u[1]!==void 0?n=dt:u[2]!==void 0?($t.test(u[2])&&(r=RegExp("</"+u[2],"g")),n=A):u[3]!==void 0&&(n=A):n===A?u[0]===">"?(n=r??R,c=-1):u[1]===void 0?c=-2:(c=n.lastIndex-u[2].length,h=u[1],n=u[3]===void 0?A:u[3]==='"'?mt:pt):n===mt||n===pt?n=A:n===ut||n===dt?n=R:(n=A,r=void 0);let v=n===A&&i[l+1].startsWith("/>")?" ":"";o+=n===R?a+Bt:c>=0?(s.push(h),a.slice(0,c)+gt+a.slice(c)+y+v):a+y+(c===-2?l:v)}return[vt(i,o+(i[e]||"<?>")+(t===2?"</svg>":t===3?"</math>":"")),s]},N=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,u]=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(gt)){let g=u[n++],v=r.getAttribute(c).split(y),U=/([.?@])?(.*)/.exec(g);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),g=c.length-1;if(g>0){r.textContent=D?D.emptyScript:"";for(let v=0;v<g;v++)r.append(c[v],k()),E.nextNode(),a.push({type:2,index:++o});r.append(c[g],k())}}}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 K=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 P(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++}},P=class i{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,e,s,r){this.type=2,this._$AH=d,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===d||t==null||t===""?(this._$AH!==d&&this._$AR(),this._$AH=d):t!==this._$AH&&t!==$&&this._(t):t._$litType$!==void 0?this.$(t):t.nodeType!==void 0?this.T(t):Dt(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!==d&&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=N.createElement(vt(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===r)this._$AH.p(e);else{let o=new K(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 N(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=d,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=d}_$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 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||=!M(h)||h!==this._$AH[a],h===d?t=d:t!==d&&(t+=(h??"")+o[a+1]),this._$AH[a]=h}n&&!r&&this.j(t)}j(t){t===d?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===d?void 0:t}},X=class extends w{constructor(){super(...arguments),this.type=4}j(t){this.element.toggleAttribute(this.name,!!t&&t!==d)}},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)??d)===$)return;let s=this._$AH,r=t===d&&s!==d||t.capture!==s.capture||t.once!==s.once||t.passive!==s.passive,o=t!==d&&(s===d||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?.(N,P),(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 P(t.insertBefore(k(),o),o,void 0,e??{})}return r._$AI(i),r};var st=globalThis,b=class extends _{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:B},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 Gt=new Set(["IMG","SVG","VIDEO","CANVAS","IFRAME","INPUT","TEXTAREA","BUTTON","HR"]),Kt=new Set(["BR","WBR","HR"]);function Jt(i){if(Gt.has(i.tagName))return!0;for(let t of i.children)if(!Kt.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 u=h.getBoundingClientRect();r.removeChild(h),e.push({x:o.left-t.left,y:o.top-t.top,width:Math.min(u.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;
7
+ overflow: hidden;
7
8
  --shimmer-color: rgba(255, 255, 255, 0.3);
8
9
  --shimmer-duration: 1.5s;
9
10
  --shimmer-bg: rgba(255, 255, 255, 0.08);
@@ -28,6 +29,11 @@
28
29
  inset: 0;
29
30
  pointer-events: none;
30
31
  overflow: hidden;
32
+ transition: opacity var(--reveal-duration, 0s) ease-out;
33
+ }
34
+
35
+ .shimmer-overlay.revealing {
36
+ opacity: 0;
31
37
  }
32
38
 
33
39
  .shimmer-block {
@@ -35,6 +41,7 @@
35
41
  overflow: hidden;
36
42
  }
37
43
 
44
+ /* Shimmer mode (default) */
38
45
  .shimmer-block::after {
39
46
  content: "";
40
47
  position: absolute;
@@ -57,14 +64,63 @@
57
64
  background-position: -200% 0;
58
65
  }
59
66
  }
60
- `;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`
61
- <slot></slot>
62
- ${this.loading?z`
63
- <div class="shimmer-overlay" style=${e} aria-hidden="true">
64
- ${this._renderBlocks()}
65
- </div>
66
- `:""}
67
- `}_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`
67
+
68
+ /* Pulse mode */
69
+ :host([animation="pulse"]) .shimmer-block {
70
+ animation: phantom-pulse var(--shimmer-duration, 1.5s) ease-in-out infinite;
71
+ }
72
+
73
+ :host([animation="pulse"]) .shimmer-block::after {
74
+ display: none;
75
+ }
76
+
77
+ @keyframes phantom-pulse {
78
+ 0%,
79
+ 100% {
80
+ opacity: 1;
81
+ }
82
+ 50% {
83
+ opacity: 0.4;
84
+ }
85
+ }
86
+
87
+ /* Breathe mode - subtle scale + fade */
88
+ :host([animation="breathe"]) .shimmer-block {
89
+ animation: phantom-breathe var(--shimmer-duration, 1.5s) ease-in-out infinite;
90
+ }
91
+
92
+ :host([animation="breathe"]) .shimmer-block::after {
93
+ display: none;
94
+ }
95
+
96
+ @keyframes phantom-breathe {
97
+ 0%,
98
+ 100% {
99
+ opacity: 0.6;
100
+ transform: scale(1);
101
+ }
102
+ 50% {
103
+ opacity: 1;
104
+ transform: scale(1.02);
105
+ }
106
+ }
107
+
108
+ /* Solid mode */
109
+ :host([animation="solid"]) .shimmer-block::after {
110
+ display: none;
111
+ }
112
+ `;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.count=1;this.countGap=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("count")||e.has("countGap"))&&this.loading&&this._scheduleMeasure(),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.style.minHeight=""},this.reveal*1e3)):(this._blocks=[],this._teardownObservers(),this.style.minHeight=""))}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`
113
+ <slot></slot>
114
+ ${s?z`
115
+ <div
116
+ class="shimmer-overlay ${this._revealing?"revealing":""}"
117
+ style=${e}
118
+ aria-hidden="true"
119
+ >
120
+ ${this._renderBlocks()}
121
+ </div>
122
+ `:""}
123
+ `}_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)}if(this.count>1&&o.length>0){let n=0;for(let h of r){let u=h.getBoundingClientRect();n=Math.max(n,u.bottom-e.top)}let l=[...o];for(let h=1;h<this.count;h++)for(let u of l)o.push({...u,y:u.y+h*(n+this.countGap)});let a=this.count*n+(this.count-1)*this.countGap;this.style.minHeight=`${a}px`}else this.style.minHeight="";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`
68
124
  <div
69
125
  class="shimmer-block"
70
126
  style="
@@ -72,11 +128,12 @@
72
128
  top: ${e.y}px;
73
129
  width: ${e.width}px;
74
130
  height: ${e.height}px;
75
- border-radius: ${s};
131
+ border-radius: ${r};
76
132
  background: var(--shimmer-bg, ${this.backgroundColor});
133
+ ${n}
77
134
  "
78
135
  ></div>
79
- `})}};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);})();
136
+ `})}};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([f({type:Number,converter:e=>Math.max(1,Math.round(Number(e)||1))})],p.prototype,"count",2),m([f({type:Number,attribute:"count-gap",converter:e=>Math.max(0,Number(e)||0)})],p.prototype,"countGap",2),m([rt()],p.prototype,"_blocks",2),m([rt()],p.prototype,"_revealing",2),p=m([bt("phantom-ui")],p);})();
80
137
  /*! Bundled license information:
81
138
 
82
139
  @lit/reactive-element/css-tag.js:
@@ -1,22 +1,28 @@
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)
20
+ * @attr {number} count - Number of skeleton rows to generate from a single template (1 = no repeat)
21
+ * @attr {number} count-gap - Gap in pixels between repeated rows (only used when count > 1)
16
22
  *
17
23
  * @example
18
24
  * ```html
19
- * <phantom-ui loading>
25
+ * <phantom-ui loading animation="pulse" stagger="0.05">
20
26
  * <div class="card">
21
27
  * <img src="avatar.png" width="48" height="48" />
22
28
  * <h3>User Name</h3>
@@ -37,10 +43,22 @@ export declare class PhantomUi extends LitElement {
37
43
  duration: number;
38
44
  /** Border radius applied to elements with border-radius: 0 (like text) */
39
45
  fallbackRadius: number;
46
+ /** Animation mode: "shimmer" (gradient sweep), "pulse" (opacity), "breathe" (scale + fade), or "solid" (static) */
47
+ animation: Animation;
48
+ /** Delay in seconds between each block's animation start (0 = no stagger) */
49
+ stagger: number;
50
+ /** Fade-out duration in seconds when loading ends (0 = instant) */
51
+ reveal: number;
52
+ /** Number of skeleton rows to generate from a single template element */
53
+ count: number;
54
+ /** Gap in pixels between each repeated skeleton row (only used when count > 1) */
55
+ countGap: number;
40
56
  private _blocks;
57
+ private _revealing;
41
58
  private _resizeObserver;
42
59
  private _mutationObserver;
43
60
  private _measureScheduled;
61
+ private _revealTimeout;
44
62
  disconnectedCallback(): void;
45
63
  updated(changedProperties: Map<PropertyKey, unknown>): void;
46
64
  render(): import("lit-html").TemplateResult<1>;
@@ -48,6 +66,7 @@ export declare class PhantomUi extends LitElement {
48
66
  private _measure;
49
67
  private _setupObservers;
50
68
  private _teardownObservers;
69
+ private _clearRevealTimeout;
51
70
  private _renderBlocks;
52
71
  }
53
72
  export interface PhantomUiAttributes {
@@ -56,6 +75,11 @@ export interface PhantomUiAttributes {
56
75
  "background-color"?: string;
57
76
  duration?: number;
58
77
  "fallback-radius"?: number;
78
+ animation?: "shimmer" | "pulse" | "breathe" | "solid";
79
+ stagger?: number;
80
+ reveal?: number;
81
+ count?: number;
82
+ "count-gap"?: number;
59
83
  children?: unknown;
60
84
  class?: string;
61
85
  id?: string;
@@ -76,3 +100,4 @@ declare global {
76
100
  }
77
101
  }
78
102
  }
103
+ export {};
@@ -1,7 +1,8 @@
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)}return i(o),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 n=(l,i,e,s)=>{for(var t=s>1?void 0:s?_(i,e):i,r=l.length-1,a;r>=0;r--)(a=l[r])&&(t=(s?a(i,e,t):a(t))||t);return s&&t&&y(i,e,t),t};import{LitElement as E,html as b}from"lit";import{customElement as T,property as m,state as f}from"lit/decorators.js";import{styleMap as C}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(l){if(k.has(l.tagName))return!0;for(let i of l.children)if(!w.has(i.tagName))return!1;return!0}function x(l){for(let i of l.childNodes)if(i.nodeType===Node.TEXT_NODE&&i.textContent?.trim())return!0;return!1}function p(l,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")&&x(t)){let u=document.createElement("span");u.style.visibility="hidden",u.style.position="absolute",u.textContent=t.textContent,t.appendChild(u);let c=u.getBoundingClientRect();t.removeChild(u),e.push({x:r.left-i.left,y:r.top-i.top,width:Math.min(c.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(l),e}function v(l,i){let e=null,s=new ResizeObserver(()=>{e!==null&&cancelAnimationFrame(e),e=requestAnimationFrame(()=>{e=null,i()})});return s.observe(l),s}import{css as R}from"lit";var g=R`
2
2
  :host {
3
3
  display: block;
4
4
  position: relative;
5
+ overflow: hidden;
5
6
  --shimmer-color: rgba(255, 255, 255, 0.3);
6
7
  --shimmer-duration: 1.5s;
7
8
  --shimmer-bg: rgba(255, 255, 255, 0.08);
@@ -26,6 +27,11 @@ var v=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var a=(o,r,e,i
26
27
  inset: 0;
27
28
  pointer-events: none;
28
29
  overflow: hidden;
30
+ transition: opacity var(--reveal-duration, 0s) ease-out;
31
+ }
32
+
33
+ .shimmer-overlay.revealing {
34
+ opacity: 0;
29
35
  }
30
36
 
31
37
  .shimmer-block {
@@ -33,6 +39,7 @@ var v=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var a=(o,r,e,i
33
39
  overflow: hidden;
34
40
  }
35
41
 
42
+ /* Shimmer mode (default) */
36
43
  .shimmer-block::after {
37
44
  content: "";
38
45
  position: absolute;
@@ -55,14 +62,63 @@ var v=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var a=(o,r,e,i
55
62
  background-position: -200% 0;
56
63
  }
57
64
  }
58
- `;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`
59
- <slot></slot>
60
- ${this.loading?c`
61
- <div class="shimmer-overlay" style=${e} aria-hidden="true">
62
- ${this._renderBlocks()}
63
- </div>
64
- `:""}
65
- `}_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`
65
+
66
+ /* Pulse mode */
67
+ :host([animation="pulse"]) .shimmer-block {
68
+ animation: phantom-pulse var(--shimmer-duration, 1.5s) ease-in-out infinite;
69
+ }
70
+
71
+ :host([animation="pulse"]) .shimmer-block::after {
72
+ display: none;
73
+ }
74
+
75
+ @keyframes phantom-pulse {
76
+ 0%,
77
+ 100% {
78
+ opacity: 1;
79
+ }
80
+ 50% {
81
+ opacity: 0.4;
82
+ }
83
+ }
84
+
85
+ /* Breathe mode - subtle scale + fade */
86
+ :host([animation="breathe"]) .shimmer-block {
87
+ animation: phantom-breathe var(--shimmer-duration, 1.5s) ease-in-out infinite;
88
+ }
89
+
90
+ :host([animation="breathe"]) .shimmer-block::after {
91
+ display: none;
92
+ }
93
+
94
+ @keyframes phantom-breathe {
95
+ 0%,
96
+ 100% {
97
+ opacity: 0.6;
98
+ transform: scale(1);
99
+ }
100
+ 50% {
101
+ opacity: 1;
102
+ transform: scale(1.02);
103
+ }
104
+ }
105
+
106
+ /* Solid mode */
107
+ :host([animation="solid"]) .shimmer-block::after {
108
+ display: none;
109
+ }
110
+ `;var o=class extends E{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.count=1;this.countGap=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("count")||e.has("countGap"))&&this.loading&&this._scheduleMeasure(),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.style.minHeight=""},this.reveal*1e3)):(this._blocks=[],this._teardownObservers(),this.style.minHeight=""))}render(){let e=C({"--shimmer-color":this.shimmerColor,"--shimmer-duration":`${this.duration}s`,"--shimmer-bg":this.backgroundColor,"--reveal-duration":`${this.reveal}s`}),s=this.loading||this._revealing;return b`
111
+ <slot></slot>
112
+ ${s?b`
113
+ <div
114
+ class="shimmer-overlay ${this._revealing?"revealing":""}"
115
+ style=${e}
116
+ aria-hidden="true"
117
+ >
118
+ ${this._renderBlocks()}
119
+ </div>
120
+ `:""}
121
+ `}_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 a of t){let h=p(a,e);r.push(...h)}if(this.count>1&&r.length>0){let a=0;for(let u of t){let c=u.getBoundingClientRect();a=Math.max(a,c.bottom-e.top)}let h=[...r];for(let u=1;u<this.count;u++)for(let c of h)r.push({...c,y:c.y+u*(a+this.countGap)});let d=this.count*a+(this.count-1)*this.countGap;this.style.minHeight=`${d}px`}else this.style.minHeight="";this._blocks=r}_setupObservers(){this._teardownObservers(),this._resizeObserver=v(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,a=r>0?`animation-delay: ${s*r}s;`:"";return b`
66
122
  <div
67
123
  class="shimmer-block"
68
124
  style="
@@ -70,8 +126,9 @@ var v=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var a=(o,r,e,i
70
126
  top: ${e.y}px;
71
127
  width: ${e.width}px;
72
128
  height: ${e.height}px;
73
- border-radius: ${i};
129
+ border-radius: ${t};
74
130
  background: var(--shimmer-bg, ${this.backgroundColor});
131
+ ${a}
75
132
  "
76
133
  ></div>
77
- `})}};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};
134
+ `})}};o.styles=g,n([m({type:Boolean,reflect:!0})],o.prototype,"loading",2),n([m({attribute:"shimmer-color"})],o.prototype,"shimmerColor",2),n([m({attribute:"background-color"})],o.prototype,"backgroundColor",2),n([m({type:Number})],o.prototype,"duration",2),n([m({type:Number,attribute:"fallback-radius"})],o.prototype,"fallbackRadius",2),n([m({reflect:!0})],o.prototype,"animation",2),n([m({type:Number})],o.prototype,"stagger",2),n([m({type:Number})],o.prototype,"reveal",2),n([m({type:Number,converter:e=>Math.max(1,Math.round(Number(e)||1))})],o.prototype,"count",2),n([m({type:Number,attribute:"count-gap",converter:e=>Math.max(0,Number(e)||0)})],o.prototype,"countGap",2),n([f()],o.prototype,"_blocks",2),n([f()],o.prototype,"_revealing",2),o=n([T("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.4",
3
+ "version": "0.4.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",