urnovl-web-components 0.0.59 → 0.0.60

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.
Files changed (52) hide show
  1. package/dist/cjs/button-base-f4219018.js +3423 -0
  2. package/dist/{urnovl-web-components/p-4c272cd5.entry.js.map → cjs/button-base-f4219018.js.map} +1 -1
  3. package/dist/cjs/ur-button-arrow-left_2.cjs.entry.js +166 -4
  4. package/dist/cjs/ur-button-arrow-left_2.cjs.entry.js.map +1 -1
  5. package/dist/cjs/ur-profile.cjs.entry.js +25 -3432
  6. package/dist/cjs/ur-profile.cjs.entry.js.map +1 -1
  7. package/dist/collection/components/ur-button-arrow-left/ur-button-arrow-left.css +7 -1
  8. package/dist/collection/components/ur-button-arrow-left/ur-button-arrow-left.js +2 -1
  9. package/dist/collection/components/ur-button-arrow-left/ur-button-arrow-left.js.map +1 -1
  10. package/dist/collection/components/ur-button-arrow-right/ur-button-arrow-right.css +7 -1
  11. package/dist/collection/components/ur-button-arrow-right/ur-button-arrow-right.js +2 -1
  12. package/dist/collection/components/ur-button-arrow-right/ur-button-arrow-right.js.map +1 -1
  13. package/dist/collection/stories/Mdui.stories.js +0 -4
  14. package/dist/collection/stories/Mdui.stories.js.map +1 -1
  15. package/dist/collection/stories/Profile.stories.js +0 -3
  16. package/dist/collection/stories/Profile.stories.js.map +1 -1
  17. package/dist/components/p-24f4ff71.js +36 -0
  18. package/dist/components/p-24f4ff71.js.map +1 -0
  19. package/dist/components/p-291d60ec.js +164 -0
  20. package/dist/components/p-291d60ec.js.map +1 -0
  21. package/dist/components/p-a3558c16.js +36 -0
  22. package/dist/components/p-a3558c16.js.map +1 -0
  23. package/dist/components/p-aec308e7.js +3411 -0
  24. package/dist/components/p-aec308e7.js.map +1 -0
  25. package/dist/components/ur-button-arrow-left.js +1 -1
  26. package/dist/components/ur-button-arrow-right.js +1 -1
  27. package/dist/components/ur-novl-carousel.js +2 -2
  28. package/dist/components/ur-profile.js +9 -3416
  29. package/dist/components/ur-profile.js.map +1 -1
  30. package/dist/esm/button-base-e9b7f052.js +3411 -0
  31. package/dist/esm/button-base-e9b7f052.js.map +1 -0
  32. package/dist/esm/ur-button-arrow-left_2.entry.js +166 -4
  33. package/dist/esm/ur-button-arrow-left_2.entry.js.map +1 -1
  34. package/dist/esm/ur-profile.entry.js +9 -3416
  35. package/dist/esm/ur-profile.entry.js.map +1 -1
  36. package/dist/types/components/ur-button-arrow-left/ur-button-arrow-left.d.ts +1 -0
  37. package/dist/types/components/ur-button-arrow-right/ur-button-arrow-right.d.ts +1 -0
  38. package/dist/urnovl-web-components/p-230530b0.entry.js +4 -0
  39. package/dist/urnovl-web-components/p-230530b0.entry.js.map +1 -0
  40. package/dist/urnovl-web-components/p-44e9e715.js +92 -0
  41. package/dist/urnovl-web-components/p-44e9e715.js.map +1 -0
  42. package/dist/urnovl-web-components/p-a1ffa9fb.entry.js +4 -0
  43. package/dist/urnovl-web-components/p-a1ffa9fb.entry.js.map +1 -0
  44. package/dist/urnovl-web-components/urnovl-web-components.esm.js +1 -1
  45. package/package.json +1 -1
  46. package/dist/components/p-03108de8.js +0 -35
  47. package/dist/components/p-03108de8.js.map +0 -1
  48. package/dist/components/p-bf15a67b.js +0 -35
  49. package/dist/components/p-bf15a67b.js.map +0 -1
  50. package/dist/urnovl-web-components/p-4c272cd5.entry.js +0 -94
  51. package/dist/urnovl-web-components/p-ff23b233.entry.js +0 -2
  52. package/dist/urnovl-web-components/p-ff23b233.entry.js.map +0 -1
@@ -0,0 +1,3423 @@
1
+ 'use strict';
2
+
3
+ /******************************************************************************
4
+ Copyright (c) Microsoft Corporation.
5
+
6
+ Permission to use, copy, modify, and/or distribute this software for any
7
+ purpose with or without fee is hereby granted.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
16
+ ***************************************************************************** */
17
+
18
+ function __decorate(decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ }
24
+
25
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
26
+ var e = new Error(message);
27
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
28
+ };
29
+
30
+ /**
31
+ * @license
32
+ * Copyright 2019 Google LLC
33
+ * SPDX-License-Identifier: BSD-3-Clause
34
+ */
35
+ const t$2=globalThis,e$2=t$2.ShadowRoot&&(void 0===t$2.ShadyCSS||t$2.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,s=Symbol(),o$2=new WeakMap;class n$3{constructor(t,e,o){if(this._$cssResult$=!0,o!==s)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e;}get styleSheet(){let t=this.o;const s=this.t;if(e$2&&void 0===t){const e=void 0!==s&&1===s.length;e&&(t=o$2.get(s)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&o$2.set(s,t));}return t}toString(){return this.cssText}}const r$3=t=>new n$3("string"==typeof t?t:t+"",void 0,s),i$2=(t,...e)=>{const o=1===t.length?t[0]:e.reduce(((e,s,o)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(s)+t[o+1]),t[0]);return new n$3(o,t,s)},S$1=(s,o)=>{if(e$2)s.adoptedStyleSheets=o.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet));else for(const e of o){const o=document.createElement("style"),n=t$2.litNonce;void 0!==n&&o.setAttribute("nonce",n),o.textContent=e.cssText,s.appendChild(o);}},c$2=e$2?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const s of t.cssRules)e+=s.cssText;return r$3(e)})(t):t;
36
+
37
+ /**
38
+ * @license
39
+ * Copyright 2017 Google LLC
40
+ * SPDX-License-Identifier: BSD-3-Clause
41
+ */const{is:i$1,defineProperty:e$1,getOwnPropertyDescriptor:r$2,getOwnPropertyNames:h$2,getOwnPropertySymbols:o$1,getPrototypeOf:n$2}=Object,a=globalThis,c$1=a.trustedTypes,l=c$1?c$1.emptyScript:"",p=a.reactiveElementPolyfillSupport,d=(t,s)=>t,u={toAttribute(t,s){switch(s){case Boolean:t=t?l:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t);}return t},fromAttribute(t,s){let i=t;switch(s){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t);}catch(t){i=null;}}return i}},f$2=(t,s)=>!i$1(t,s),y={attribute:!0,type:String,converter:u,reflect:!1,hasChanged:f$2};Symbol.metadata??=Symbol("metadata"),a.litPropertyMetadata??=new WeakMap;class b 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,s=y){if(s.state&&(s.attribute=!1),this._$Ei(),this.elementProperties.set(t,s),!s.noAccessor){const i=Symbol(),r=this.getPropertyDescriptor(t,i,s);void 0!==r&&e$1(this.prototype,t,r);}}static getPropertyDescriptor(t,s,i){const{get:e,set:h}=r$2(this.prototype,t)??{get(){return this[s]},set(t){this[s]=t;}};return {get(){return e?.call(this)},set(s){const r=e?.call(this);h.call(this,s),this.requestUpdate(t,r,i);},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??y}static _$Ei(){if(this.hasOwnProperty(d("elementProperties")))return;const t=n$2(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties);}static finalize(){if(this.hasOwnProperty(d("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(d("properties"))){const t=this.properties,s=[...h$2(t),...o$1(t)];for(const i of s)this.createProperty(i,t[i]);}const t=this[Symbol.metadata];if(null!==t){const s=litPropertyMetadata.get(t);if(void 0!==s)for(const[t,i]of s)this.elementProperties.set(t,i);}this._$Eh=new Map;for(const[t,s]of this.elementProperties){const i=this._$Eu(t,s);void 0!==i&&this._$Eh.set(i,t);}this.elementStyles=this.finalizeStyles(this.styles);}static finalizeStyles(s){const i=[];if(Array.isArray(s)){const e=new Set(s.flat(1/0).reverse());for(const s of e)i.unshift(c$2(s));}else void 0!==s&&i.push(c$2(s));return i}static _$Eu(t,s){const i=s.attribute;return !1===i?void 0:"string"==typeof i?i:"string"==typeof t?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),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.();}removeController(t){this._$EO?.delete(t);}_$E_(){const t=new Map,s=this.constructor.elementProperties;for(const i of s.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t);}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return S$1(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,s,i){this._$AK(t,i);}_$EC(t,s){const i=this.constructor.elementProperties.get(t),e=this.constructor._$Eu(t,i);if(void 0!==e&&!0===i.reflect){const r=(void 0!==i.converter?.toAttribute?i.converter:u).toAttribute(s,i.type);this._$Em=t,null==r?this.removeAttribute(e):this.setAttribute(e,r),this._$Em=null;}}_$AK(t,s){const i=this.constructor,e=i._$Eh.get(t);if(void 0!==e&&this._$Em!==e){const t=i.getPropertyOptions(e),r="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:u;this._$Em=e,this[e]=r.fromAttribute(s,t.type),this._$Em=null;}}requestUpdate(t,s,i){if(void 0!==t){if(i??=this.constructor.getPropertyOptions(t),!(i.hasChanged??f$2)(this[t],s))return;this.P(t,s,i);}!1===this.isUpdatePending&&(this._$ES=this._$ET());}P(t,s,i){this._$AL.has(t)||this._$AL.set(t,s),!0===i.reflect&&this._$Em!==t&&(this._$Ej??=new Set).add(t);}async _$ET(){this.isUpdatePending=!0;try{await this._$ES;}catch(t){Promise.reject(t);}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,s]of this._$Ep)this[t]=s;this._$Ep=void 0;}const t=this.constructor.elementProperties;if(t.size>0)for(const[s,i]of t)!0!==i.wrapped||this._$AL.has(s)||void 0===this[s]||this.P(s,this[s],i);}let t=!1;const s=this._$AL;try{t=this.shouldUpdate(s),t?(this.willUpdate(s),this._$EO?.forEach((t=>t.hostUpdate?.())),this.update(s)):this._$EU();}catch(s){throw t=!1,this._$EU(),s}t&&this._$AE(s);}willUpdate(t){}_$AE(t){this._$EO?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t);}_$EU(){this._$AL=new Map,this.isUpdatePending=!1;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return !0}update(t){this._$Ej&&=this._$Ej.forEach((t=>this._$EC(t,this[t]))),this._$EU();}updated(t){}firstUpdated(t){}}b.elementStyles=[],b.shadowRootOptions={mode:"open"},b[d("elementProperties")]=new Map,b[d("finalized")]=new Map,p?.({ReactiveElement:b}),(a.reactiveElementVersions??=[]).push("2.0.4");
42
+
43
+ /**
44
+ * @license
45
+ * Copyright 2017 Google LLC
46
+ * SPDX-License-Identifier: BSD-3-Clause
47
+ */
48
+ const n$1=globalThis,c=n$1.trustedTypes,h$1=c?c.createPolicy("lit-html",{createHTML:t=>t}):void 0,f$1="$lit$",v=`lit$${Math.random().toFixed(9).slice(2)}$`,m="?"+v,_=`<${m}>`,w=document,lt=()=>w.createComment(""),st$1=t=>null===t||"object"!=typeof t&&"function"!=typeof t,g=Array.isArray,$$1=t=>g(t)||"function"==typeof t?.[Symbol.iterator],x="[ \t\n\f\r]",T=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,E=/-->/g,k=/>/g,O=RegExp(`>|${x}(?:([^\\s"'>=/]+)(${x}*=${x}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),S=/'/g,j=/"/g,M=/^(?:script|style|textarea|title)$/i,P=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),ke=P(1),R=Symbol.for("lit-noChange"),D=Symbol.for("lit-nothing"),V=new WeakMap,I=w.createTreeWalker(w,129);function N(t,i){if(!g(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==h$1?h$1.createHTML(i):i}const U=(t,i)=>{const s=t.length-1,e=[];let h,o=2===i?"<svg>":3===i?"<math>":"",n=T;for(let i=0;i<s;i++){const s=t[i];let r,l,c=-1,a=0;for(;a<s.length&&(n.lastIndex=a,l=n.exec(s),null!==l);)a=n.lastIndex,n===T?"!--"===l[1]?n=E:void 0!==l[1]?n=k:void 0!==l[2]?(M.test(l[2])&&(h=RegExp("</"+l[2],"g")),n=O):void 0!==l[3]&&(n=O):n===O?">"===l[0]?(n=h??T,c=-1):void 0===l[1]?c=-2:(c=n.lastIndex-l[2].length,r=l[1],n=void 0===l[3]?O:'"'===l[3]?j:S):n===j||n===S?n=O:n===E||n===k?n=T:(n=O,h=void 0);const u=n===O&&t[i+1].startsWith("/>")?" ":"";o+=n===T?s+_:c>=0?(e.push(r),s.slice(0,c)+f$1+s.slice(c)+v+u):s+v+(-2===c?i:u);}return [N(t,o+(t[s]||"<?>")+(2===i?"</svg>":3===i?"</math>":"")),e]};class B{constructor({strings:t,_$litType$:i},s){let e;this.parts=[];let h=0,o=0;const n=t.length-1,r=this.parts,[l,a]=U(t,i);if(this.el=B.createElement(l,s),I.currentNode=this.el.content,2===i||3===i){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes);}for(;null!==(e=I.nextNode())&&r.length<n;){if(1===e.nodeType){if(e.hasAttributes())for(const t of e.getAttributeNames())if(t.endsWith(f$1)){const i=a[o++],s=e.getAttribute(t).split(v),n=/([.?@])?(.*)/.exec(i);r.push({type:1,index:h,name:n[2],strings:s,ctor:"."===n[1]?Y:"?"===n[1]?Z:"@"===n[1]?q:G}),e.removeAttribute(t);}else t.startsWith(v)&&(r.push({type:6,index:h}),e.removeAttribute(t));if(M.test(e.tagName)){const t=e.textContent.split(v),i=t.length-1;if(i>0){e.textContent=c?c.emptyScript:"";for(let s=0;s<i;s++)e.append(t[s],lt()),I.nextNode(),r.push({type:2,index:++h});e.append(t[i],lt());}}}else if(8===e.nodeType)if(e.data===m)r.push({type:2,index:h});else {let t=-1;for(;-1!==(t=e.data.indexOf(v,t+1));)r.push({type:7,index:h}),t+=v.length-1;}h++;}}static createElement(t,i){const s=w.createElement("template");return s.innerHTML=t,s}}function z(t,i,s=t,e){if(i===R)return i;let h=void 0!==e?s.o?.[e]:s.l;const o=st$1(i)?void 0:i._$litDirective$;return h?.constructor!==o&&(h?._$AO?.(!1),void 0===o?h=void 0:(h=new o(t),h._$AT(t,s,e)),void 0!==e?(s.o??=[])[e]=h:s.l=h),void 0!==h&&(i=z(t,h._$AS(t,i.values),h,e)),i}class F{constructor(t,i){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=i;}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){const{el:{content:i},parts:s}=this._$AD,e=(t?.creationScope??w).importNode(i,!0);I.currentNode=e;let h=I.nextNode(),o=0,n=0,r=s[0];for(;void 0!==r;){if(o===r.index){let i;2===r.type?i=new et(h,h.nextSibling,this,t):1===r.type?i=new r.ctor(h,r.name,r.strings,this,t):6===r.type&&(i=new K(h,this,t)),this._$AV.push(i),r=s[++n];}o!==r?.index&&(h=I.nextNode(),o++);}return I.currentNode=w,e}p(t){let i=0;for(const s of this._$AV)void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,i),i+=s.strings.length-2):s._$AI(t[i])),i++;}}class et{get _$AU(){return this._$AM?._$AU??this.v}constructor(t,i,s,e){this.type=2,this._$AH=D,this._$AN=void 0,this._$AA=t,this._$AB=i,this._$AM=s,this.options=e,this.v=e?.isConnected??!0;}get parentNode(){let t=this._$AA.parentNode;const i=this._$AM;return void 0!==i&&11===t?.nodeType&&(t=i.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,i=this){t=z(this,t,i),st$1(t)?t===D||null==t||""===t?(this._$AH!==D&&this._$AR(),this._$AH=D):t!==this._$AH&&t!==R&&this._(t):void 0!==t._$litType$?this.$(t):void 0!==t.nodeType?this.T(t):$$1(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&&st$1(this._$AH)?this._$AA.nextSibling.data=t:this.T(w.createTextNode(t)),this._$AH=t;}$(t){const{values:i,_$litType$:s}=t,e="number"==typeof s?this._$AC(t):(void 0===s.el&&(s.el=B.createElement(N(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===e)this._$AH.p(i);else {const t=new F(e,this),s=t.u(this.options);t.p(i),this.T(s),this._$AH=t;}}_$AC(t){let i=V.get(t.strings);return void 0===i&&V.set(t.strings,i=new B(t)),i}k(t){g(this._$AH)||(this._$AH=[],this._$AR());const i=this._$AH;let s,e=0;for(const h of t)e===i.length?i.push(s=new et(this.O(lt()),this.O(lt()),this,this.options)):s=i[e],s._$AI(h),e++;e<i.length&&(this._$AR(s&&s._$AB.nextSibling,e),i.length=e);}_$AR(t=this._$AA.nextSibling,i){for(this._$AP?.(!1,!0,i);t&&t!==this._$AB;){const i=t.nextSibling;t.remove(),t=i;}}setConnected(t){void 0===this._$AM&&(this.v=t,this._$AP?.(t));}}class G{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,i,s,e,h){this.type=1,this._$AH=D,this._$AN=void 0,this.element=t,this.name=i,this._$AM=e,this.options=h,s.length>2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=D;}_$AI(t,i=this,s,e){const h=this.strings;let o=!1;if(void 0===h)t=z(this,t,i,0),o=!st$1(t)||t!==this._$AH&&t!==R,o&&(this._$AH=t);else {const e=t;let n,r;for(t=h[0],n=0;n<h.length-1;n++)r=z(this,e[s+n],i,n),r===R&&(r=this._$AH[n]),o||=!st$1(r)||r!==this._$AH[n],r===D?t=D:t!==D&&(t+=(r??"")+h[n+1]),this._$AH[n]=r;}o&&!e&&this.j(t);}j(t){t===D?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??"");}}class Y extends G{constructor(){super(...arguments),this.type=3;}j(t){this.element[this.name]=t===D?void 0:t;}}class Z extends G{constructor(){super(...arguments),this.type=4;}j(t){this.element.toggleAttribute(this.name,!!t&&t!==D);}}class q extends G{constructor(t,i,s,e,h){super(t,i,s,e,h),this.type=5;}_$AI(t,i=this){if((t=z(this,t,i,0)??D)===R)return;const s=this._$AH,e=t===D&&s!==D||t.capture!==s.capture||t.once!==s.once||t.passive!==s.passive,h=t!==D&&(s===D||e);e&&this.element.removeEventListener(this.name,this,s),h&&this.element.addEventListener(this.name,this,t),this._$AH=t;}handleEvent(t){"function"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t);}}class K{constructor(t,i,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=i,this.options=s;}get _$AU(){return this._$AM._$AU}_$AI(t){z(this,t);}}const Re=n$1.litHtmlPolyfillSupport;Re?.(B,et),(n$1.litHtmlVersions??=[]).push("3.2.0");const Q=(t,i,s)=>{const e=s?.renderBefore??i;let h=e._$litPart$;if(void 0===h){const t=s?.renderBefore??null;e._$litPart$=h=new et(i.insertBefore(lt(),t),t,void 0,s??{});}return h._$AI(t),h};
49
+
50
+ /**
51
+ * @license
52
+ * Copyright 2017 Google LLC
53
+ * SPDX-License-Identifier: BSD-3-Clause
54
+ */class h extends b{constructor(){super(...arguments),this.renderOptions={host:this},this.o=void 0;}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this.o=Q(e,this.renderRoot,this.renderOptions);}connectedCallback(){super.connectedCallback(),this.o?.setConnected(!0);}disconnectedCallback(){super.disconnectedCallback(),this.o?.setConnected(!1);}render(){return R}}h._$litElement$=!0,h["finalized"]=!0,globalThis.litElementHydrateSupport?.({LitElement:h});const f=globalThis.litElementPolyfillSupport;f?.({LitElement:h});(globalThis.litElementVersions??=[]).push("4.1.0");
55
+
56
+ /**
57
+ * @license
58
+ * Copyright 2017 Google LLC
59
+ * SPDX-License-Identifier: BSD-3-Clause
60
+ */
61
+ const t$1=t=>(e,o)=>{void 0!==o?o.addInitializer((()=>{customElements.define(t,e);})):customElements.define(t,e);};
62
+
63
+ /**
64
+ * @license
65
+ * Copyright 2017 Google LLC
66
+ * SPDX-License-Identifier: BSD-3-Clause
67
+ */const o={attribute:!0,type:String,converter:u,reflect:!1,hasChanged:f$2},r$1=(t=o,e,r)=>{const{kind:n,metadata:i}=r;let s=globalThis.litPropertyMetadata.get(i);if(void 0===s&&globalThis.litPropertyMetadata.set(i,s=new Map),s.set(r.name,t),"accessor"===n){const{name:o}=r;return {set(r){const n=e.get.call(this);e.set.call(this,r),this.requestUpdate(o,n,t);},init(e){return void 0!==e&&this.P(o,void 0,t),e}}}if("setter"===n){const{name:o}=r;return function(r){const n=this[o];e.call(this,r),this.requestUpdate(o,n,t);}}throw Error("Unsupported decorator location: "+n)};function n(t){return (e,o)=>"object"==typeof o?r$1(t,e,o):((t,e,o)=>{const r=e.hasOwnProperty(o);return e.constructor.createProperty(o,r?{...t,wrapped:!0}:t),r?Object.getOwnPropertyDescriptor(e,o):void 0})(t,e,o)}
68
+
69
+ /**
70
+ * @license
71
+ * Copyright 2017 Google LLC
72
+ * SPDX-License-Identifier: BSD-3-Clause
73
+ */function r(r){return n({...r,state:!0,attribute:!1})}
74
+
75
+ /**
76
+ * @license
77
+ * Copyright 2020 Google LLC
78
+ * SPDX-License-Identifier: BSD-3-Clause
79
+ */const st=o=>null===o||"object"!=typeof o&&"function"!=typeof o,rt=o=>void 0===o.strings;
80
+
81
+ /**
82
+ * @license
83
+ * Copyright 2017 Google LLC
84
+ * SPDX-License-Identifier: BSD-3-Clause
85
+ */
86
+ const t={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},e=t=>(...e)=>({_$litDirective$:t,values:e});class i{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this.t=t,this._$AM=e,this.i=i;}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}}
87
+
88
+ /**
89
+ * @license
90
+ * Copyright 2017 Google LLC
91
+ * SPDX-License-Identifier: BSD-3-Clause
92
+ */const mt=(i,t)=>{const e=i._$AN;if(void 0===e)return !1;for(const i of e)i._$AO?.(t,!1),mt(i,t);return !0},_t=i=>{let t,e;do{if(void 0===(t=i._$AM))break;e=t._$AN,e.delete(i),i=t;}while(0===e?.size)},wt=i=>{for(let t;t=i._$AM;i=t){let e=t._$AN;if(void 0===e)t._$AN=e=new Set;else if(e.has(i))break;e.add(i),gt(t);}};function bt(i){void 0!==this._$AN?(_t(this),this._$AM=i,wt(this)):this._$AM=i;}function yt(i,t=!1,e=0){const s=this._$AH,o=this._$AN;if(void 0!==o&&0!==o.size)if(t)if(Array.isArray(s))for(let i=e;i<s.length;i++)mt(s[i],!1),_t(s[i]);else null!=s&&(mt(s,!1),_t(s));else mt(this,i);}const gt=i=>{i.type==t.CHILD&&(i._$AP??=yt,i._$AQ??=bt);};class $t extends i{constructor(){super(...arguments),this._$AN=void 0;}_$AT(i,t,e){super._$AT(i,t,e),wt(this),this.isConnected=i._$AU;}_$AO(i,t=!0){i!==this.isConnected&&(this.isConnected=i,i?this.reconnected?.():this.disconnected?.()),t&&(mt(this,i),_t(this));}setValue(i){if(rt(this.t))this.t._$AI(i,this);else {const t=[...this.t._$AH];t[this.i]=i,this.t._$AI(t,this,0);}}disconnected(){}reconnected(){}}
93
+
94
+ /**
95
+ * @license
96
+ * Copyright 2020 Google LLC
97
+ * SPDX-License-Identifier: BSD-3-Clause
98
+ */const ii=()=>new Zt;class Zt{}const qt=new WeakMap,Kt=e(class extends $t{render(t){return D}update(t,[i]){const s=i!==this.Y;return s&&void 0!==this.Y&&this.rt(void 0),(s||this.lt!==this.ct)&&(this.Y=i,this.ht=t.options?.host,this.rt(this.ct=t.element)),D}rt(t){if(this.isConnected||(t=void 0),"function"==typeof this.Y){const i=this.ht??globalThis;let s=qt.get(i);void 0===s&&(s=new WeakMap,qt.set(i,s)),void 0!==s.get(this.Y)&&this.Y.call(this.ht,void 0),s.set(this.Y,t),void 0!==t&&this.Y.call(this.ht,t);}else this.Y.value=t;}get lt(){return "function"==typeof this.Y?qt.get(this.ht??globalThis)?.get(this.Y):this.Y?.value}disconnected(){this.lt===this.ct&&this.rt(void 0);}reconnected(){this.rt(this.ct);}});
99
+
100
+ /**
101
+ * 在原生的 HTML 中,布尔属性只要添加了属性名,不论属性值设置成什么,属性值都是 true
102
+ * 但这里设置了 attr="false" 时,要把属性设置为 false
103
+ *
104
+ * 原因是:
105
+ * 在 vue3 中,通过 :attr="value" 设置属性时,vue 会优先从 DOM 属性中寻找是否存在 attr 属性名,
106
+ * 若存在,则设置对应的 DOM 属性,否则设置对应的 attribute 属性
107
+ * 但在 vue 的服务端渲染(ssr)时,不存在 DOM 对象,所以会把 attribute 属性设置成 attr="true" 或 attr="false"
108
+ * 所以在 attribute 属性 attr="false" 时,需要把属性值转换为布尔值 false
109
+ *
110
+ * 这段代码不能封装成函数,否则生成 custom-elements.json 会识别不了
111
+ * 这段注释仅在这里写一次,其他地方不再重复
112
+ *
113
+ * @see https://v3-migration.vuejs.org/zh/breaking-changes/attribute-coercion.html
114
+ */
115
+ const booleanConverter = (value) => {
116
+ return value !== null && value !== 'false';
117
+ };
118
+
119
+ const nothingTemplate = ke `${D}`;
120
+
121
+ /**
122
+ * @license
123
+ * Copyright 2018 Google LLC
124
+ * SPDX-License-Identifier: BSD-3-Clause
125
+ */const ee="important",ie=" !"+ee,se=e(class extends i{constructor(e){if(super(e),e.type!==t.ATTRIBUTE||"style"!==e.name||e.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(t){return Object.keys(t).reduce(((e,r)=>{const s=t[r];return null==s?e:e+`${r=r.includes("-")?r:r.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,"-$&").toLowerCase()}:${s};`}),"")}update(t,[e]){const{style:r}=t.element;if(void 0===this.ft)return this.ft=new Set(Object.keys(e)),this.render(e);for(const t of this.ft)null==e[t]&&(this.ft.delete(t),t.includes("-")?r.removeProperty(t):r[t]=null);for(const t in e){const s=e[t];if(null!=s){this.ft.add(t);const e="string"==typeof s&&s.endsWith(ie);t.includes("-")||e?r.setProperty(t,e?s.slice(0,-11):s,e?ee:""):r[t]=s;}}return R}});
126
+
127
+ /**
128
+ * @license
129
+ * Copyright 2017 Google LLC
130
+ * SPDX-License-Identifier: BSD-3-Clause
131
+ */class le extends i{constructor(i){if(super(i),this.it=D,i.type!==t.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(t){if(t===D||null==t)return this._t=void 0,this.it=t;if(t===R)return t;if("string"!=typeof t)throw Error(this.constructor.directiveName+"() called with a non-string value");if(t===this.it)return this._t;this.it=t;const i=[t];return i.raw=i,this._t={_$litType$:this.constructor.resultType,strings:i,values:[]}}}le.directiveName="unsafeHTML",le.resultType=1;
132
+
133
+ /**
134
+ * @license
135
+ * Copyright 2017 Google LLC
136
+ * SPDX-License-Identifier: BSD-3-Clause
137
+ */class pe extends le{}pe.directiveName="unsafeSVG",pe.resultType=2;const fe=e(pe);
138
+
139
+ /**
140
+ * @license
141
+ * Copyright 2021 Google LLC
142
+ * SPDX-License-Identifier: BSD-3-Clause
143
+ */
144
+ class Tt{constructor(t){this.Y=t;}disconnect(){this.Y=void 0;}reconnect(t){this.Y=t;}deref(){return this.Y}}class Et{constructor(){this.Z=void 0,this.q=void 0;}get(){return this.Z}pause(){this.Z??=new Promise((t=>this.q=t));}resume(){this.q?.(),this.Z=this.q=void 0;}}
145
+
146
+ /**
147
+ * @license
148
+ * Copyright 2017 Google LLC
149
+ * SPDX-License-Identifier: BSD-3-Clause
150
+ */const me=t=>!st(t)&&"function"==typeof t.then,_e=1073741823;class we extends $t{constructor(){super(...arguments),this.wt=_e,this.bt=[],this.K=new Tt(this),this.X=new Et;}render(...t){return t.find((t=>!me(t)))??R}update(t,s){const i=this.bt;let e=i.length;this.bt=s;const r=this.K,o=this.X;this.isConnected||this.disconnected();for(let t=0;t<s.length&&!(t>this.wt);t++){const n=s[t];if(!me(n))return this.wt=t,n;t<e&&n===i[t]||(this.wt=_e,e=0,Promise.resolve(n).then((async t=>{for(;o.get();)await o.get();const s=r.deref();if(void 0!==s){const i=s.bt.indexOf(n);i>-1&&i<s.wt&&(s.wt=i,s.setValue(t));}})));}return R}disconnected(){this.K.disconnect(),this.X.pause();}reconnected(){this.K.reconnect(this),this.X.resume();}}const be=e(we);
151
+
152
+ /**
153
+ * SSR Window 4.0.2
154
+ * Better handling for window object in SSR environment
155
+ * https://github.com/nolimits4web/ssr-window
156
+ *
157
+ * Copyright 2021, Vladimir Kharlampidi
158
+ *
159
+ * Licensed under MIT
160
+ *
161
+ * Released on: December 13, 2021
162
+ */
163
+ /* eslint-disable no-param-reassign */
164
+ function isObject(obj) {
165
+ return (obj !== null &&
166
+ typeof obj === 'object' &&
167
+ 'constructor' in obj &&
168
+ obj.constructor === Object);
169
+ }
170
+ function extend$1(target = {}, src = {}) {
171
+ Object.keys(src).forEach((key) => {
172
+ if (typeof target[key] === 'undefined')
173
+ target[key] = src[key];
174
+ else if (isObject(src[key]) &&
175
+ isObject(target[key]) &&
176
+ Object.keys(src[key]).length > 0) {
177
+ extend$1(target[key], src[key]);
178
+ }
179
+ });
180
+ }
181
+
182
+ const ssrDocument = {
183
+ body: {},
184
+ addEventListener() { },
185
+ removeEventListener() { },
186
+ activeElement: {
187
+ blur() { },
188
+ nodeName: '',
189
+ },
190
+ querySelector() {
191
+ return null;
192
+ },
193
+ querySelectorAll() {
194
+ return [];
195
+ },
196
+ getElementById() {
197
+ return null;
198
+ },
199
+ createEvent() {
200
+ return {
201
+ initEvent() { },
202
+ };
203
+ },
204
+ createElement() {
205
+ return {
206
+ children: [],
207
+ childNodes: [],
208
+ style: {},
209
+ setAttribute() { },
210
+ getElementsByTagName() {
211
+ return [];
212
+ },
213
+ };
214
+ },
215
+ createElementNS() {
216
+ return {};
217
+ },
218
+ importNode() {
219
+ return null;
220
+ },
221
+ location: {
222
+ hash: '',
223
+ host: '',
224
+ hostname: '',
225
+ href: '',
226
+ origin: '',
227
+ pathname: '',
228
+ protocol: '',
229
+ search: '',
230
+ },
231
+ };
232
+ function getDocument() {
233
+ const doc = typeof document !== 'undefined' ? document : {};
234
+ extend$1(doc, ssrDocument);
235
+ return doc;
236
+ }
237
+
238
+ const ssrWindow = {
239
+ document: ssrDocument,
240
+ navigator: {
241
+ userAgent: '',
242
+ },
243
+ location: {
244
+ hash: '',
245
+ host: '',
246
+ hostname: '',
247
+ href: '',
248
+ origin: '',
249
+ pathname: '',
250
+ protocol: '',
251
+ search: '',
252
+ },
253
+ history: {
254
+ replaceState() { },
255
+ pushState() { },
256
+ go() { },
257
+ back() { },
258
+ },
259
+ CustomEvent: function CustomEvent() {
260
+ return this;
261
+ },
262
+ addEventListener() { },
263
+ removeEventListener() { },
264
+ getComputedStyle() {
265
+ return {
266
+ getPropertyValue() {
267
+ return '';
268
+ },
269
+ };
270
+ },
271
+ Image() { },
272
+ Date() { },
273
+ screen: {},
274
+ setTimeout() { },
275
+ clearTimeout() { },
276
+ matchMedia() {
277
+ return {};
278
+ },
279
+ requestAnimationFrame(callback) {
280
+ if (typeof setTimeout === 'undefined') {
281
+ callback();
282
+ return null;
283
+ }
284
+ return setTimeout(callback, 0);
285
+ },
286
+ cancelAnimationFrame(id) {
287
+ if (typeof setTimeout === 'undefined') {
288
+ return;
289
+ }
290
+ clearTimeout(id);
291
+ },
292
+ };
293
+ function getWindow() {
294
+ const win = typeof window !== 'undefined' ? window : {};
295
+ extend$1(win, ssrWindow);
296
+ return win;
297
+ }
298
+
299
+ /**
300
+ * 获取指定元素的标签名(小写),不存在元素的返回空字符串
301
+ * @param element
302
+ */
303
+ // eslint-disable-next-line @typescript-eslint/ban-types
304
+ const isFunction = (target) => {
305
+ return typeof target === 'function';
306
+ };
307
+ const isString = (target) => {
308
+ return typeof target === 'string';
309
+ };
310
+ const isNumber = (target) => {
311
+ return typeof target === 'number';
312
+ };
313
+ const isBoolean = (target) => {
314
+ return typeof target === 'boolean';
315
+ };
316
+ const isUndefined = (target) => {
317
+ return typeof target === 'undefined';
318
+ };
319
+ const isNull = (target) => {
320
+ return target === null;
321
+ };
322
+ const isWindow = (target) => {
323
+ return typeof Window !== 'undefined' && target instanceof Window;
324
+ };
325
+ const isDocument = (target) => {
326
+ return typeof Document !== 'undefined' && target instanceof Document;
327
+ };
328
+ const isElement = (target) => {
329
+ return typeof Element !== 'undefined' && target instanceof Element;
330
+ };
331
+ const isNode = (target) => {
332
+ return typeof Node !== 'undefined' && target instanceof Node;
333
+ };
334
+ const isArrayLike = (target) => {
335
+ return (!isFunction(target) &&
336
+ !isWindow(target) &&
337
+ isNumber(target.length));
338
+ };
339
+ const isObjectLike = (target) => {
340
+ return typeof target === 'object' && target !== null;
341
+ };
342
+ const toElement = (target) => {
343
+ return isDocument(target) ? target.documentElement : target;
344
+ };
345
+ /**
346
+ * 把用 - 分隔的字符串转为驼峰(如 box-sizing 转换为 boxSizing)
347
+ * @param string
348
+ */
349
+ const toCamelCase = (string) => {
350
+ return string.replace(/-([a-z])/g, (_, letter) => {
351
+ return letter.toUpperCase();
352
+ });
353
+ };
354
+ /**
355
+ * 把驼峰法转为用 - 分隔的字符串(如 boxSizing 转换为 box-sizing)
356
+ * @param string
357
+ */
358
+ const toKebabCase = (string) => {
359
+ if (!string) {
360
+ return string;
361
+ }
362
+ return string
363
+ .replace(/^./, string[0].toLowerCase()) // 首字母转小写
364
+ .replace(/[A-Z]/g, (replacer) => {
365
+ return '-' + replacer.toLowerCase();
366
+ });
367
+ };
368
+ /**
369
+ * 始终返回 false 的函数
370
+ */
371
+ const returnFalse = () => {
372
+ return false;
373
+ };
374
+ /**
375
+ * 遍历数组
376
+ * @param target
377
+ * @param callback
378
+ */
379
+ const eachArray = (target, callback) => {
380
+ for (let i = 0; i < target.length; i += 1) {
381
+ if (callback.call(target[i], target[i], i) === false) {
382
+ return target;
383
+ }
384
+ }
385
+ return target;
386
+ };
387
+ /**
388
+ * 遍历对象
389
+ * @param target
390
+ * @param callback
391
+ */
392
+ const eachObject = (target, callback) => {
393
+ const keys = Object.keys(target);
394
+ for (let i = 0; i < keys.length; i += 1) {
395
+ const key = keys[i];
396
+ if (callback.call(target[key], key, target[key]) === false) {
397
+ return target;
398
+ }
399
+ }
400
+ return target;
401
+ };
402
+
403
+ /**
404
+ * 为了使用模块扩充,这里不能使用默认导出
405
+ */
406
+ class JQ {
407
+ constructor(arr) {
408
+ this.length = 0;
409
+ if (!arr) {
410
+ return this;
411
+ }
412
+ eachArray(arr, (item, i) => {
413
+ this[i] = item;
414
+ });
415
+ this.length = arr.length;
416
+ return this;
417
+ }
418
+ }
419
+
420
+ /**
421
+ * DOM 是否已加载完成
422
+ *
423
+ * 在 Web Components 中操作组件外部的 DOM、或组件中的 slot 的 DOM 时,必须先判断 DOM 是否已加载完成。
424
+ */
425
+ const isDomReady = (document = getDocument()) => {
426
+ return /complete|interactive/.test(document.readyState);
427
+ };
428
+ const createElement = (tagName) => {
429
+ const document = getDocument();
430
+ return document.createElement(tagName);
431
+ };
432
+ const appendChild = (element, child) => {
433
+ return element.appendChild(child);
434
+ };
435
+ const removeChild = (element) => {
436
+ return element.parentNode ? element.parentNode.removeChild(element) : element;
437
+ };
438
+ /**
439
+ * 获取子节点组成的数组
440
+ * @param target
441
+ * @param parent
442
+ */
443
+ const getChildNodesArray = (target, parent) => {
444
+ const tempParent = createElement(parent);
445
+ tempParent.innerHTML = target;
446
+ return [].slice.call(tempParent.childNodes);
447
+ };
448
+
449
+ const get$ = () => {
450
+ const $ = function (selector) {
451
+ if (!selector) {
452
+ return new JQ();
453
+ }
454
+ // JQ
455
+ if (selector instanceof JQ) {
456
+ return selector;
457
+ }
458
+ // function
459
+ if (isFunction(selector)) {
460
+ const document = getDocument();
461
+ if (isDomReady(document)) {
462
+ selector.call(document, $);
463
+ }
464
+ else {
465
+ document.addEventListener('DOMContentLoaded', () => selector.call(document, $), { once: true });
466
+ }
467
+ return new JQ([document]);
468
+ }
469
+ // String
470
+ if (isString(selector)) {
471
+ const html = selector.trim();
472
+ // 根据 HTML 字符串创建 JQ 对象
473
+ if (html.startsWith('<') && html.endsWith('>')) {
474
+ let toCreate = 'div';
475
+ const tags = {
476
+ li: 'ul',
477
+ tr: 'tbody',
478
+ td: 'tr',
479
+ th: 'tr',
480
+ tbody: 'table',
481
+ option: 'select',
482
+ };
483
+ eachObject(tags, (childTag, parentTag) => {
484
+ if (html.startsWith(`<${childTag}`)) {
485
+ toCreate = parentTag;
486
+ return false;
487
+ }
488
+ return;
489
+ });
490
+ return new JQ(getChildNodesArray(html, toCreate));
491
+ }
492
+ const document = getDocument();
493
+ // 根据 CSS 选择器创建 JQ 对象
494
+ return new JQ(document.querySelectorAll(selector));
495
+ }
496
+ if (isArrayLike(selector) && !isNode(selector)) {
497
+ return new JQ(selector);
498
+ }
499
+ return new JQ([selector]);
500
+ };
501
+ $.fn = JQ.prototype;
502
+ return $;
503
+ };
504
+ const $ = get$();
505
+
506
+ /**
507
+ * 检查 container 元素内是否包含 contains 元素
508
+ * @param container 父元素
509
+ * @param contains 子元素
510
+ * @example
511
+ ```js
512
+ contains( document, document.body ); // true
513
+ contains( document.getElementById('test'), document ); // false
514
+ contains( $('.container').get(0), $('.contains').get(0) ); // false
515
+ ```
516
+ */
517
+ const contains = (container, contains) => {
518
+ return container !== contains && toElement(container).contains(contains);
519
+ };
520
+
521
+ /**
522
+ * 把第二个数组的元素追加到第一个数组中,并返回合并后的数组
523
+ * @param first 第一个数组
524
+ * @param second 该数组的元素将被追加到第一个数组中
525
+ * @example
526
+ ```js
527
+ merge( [ 0, 1, 2 ], [ 2, 3, 4 ] )
528
+ // [ 0, 1, 2, 2, 3, 4 ]
529
+ ```
530
+ */
531
+ const merge = (first, second) => {
532
+ eachArray(second, (value) => {
533
+ first.push(value);
534
+ });
535
+ return first;
536
+ };
537
+
538
+ // eslint-disable-next-line
539
+ $.fn.each = function (callback) {
540
+ return eachArray(this, (value, index) => {
541
+ return callback.call(value, index, value);
542
+ });
543
+ };
544
+
545
+ // eslint-disable-next-line
546
+ $.fn.get = function (index) {
547
+ return index === undefined
548
+ ? [].slice.call(this)
549
+ : this[index >= 0 ? index : index + this.length];
550
+ };
551
+
552
+ $.fn.find = function (selector) {
553
+ const foundElements = [];
554
+ this.each((_, element) => {
555
+ merge(foundElements, $(element.querySelectorAll(selector)).get());
556
+ });
557
+ return new JQ(foundElements);
558
+ };
559
+
560
+ // 直接使用 CustomEvent 在 ssr 环境下会报错
561
+ const CustomEvent$1 = getWindow().CustomEvent;
562
+ /**
563
+ * 封装 CustomEvent,使之支持 data:事件监听参数,namespace:命名空间
564
+ */
565
+ class MduiCustomEvent extends CustomEvent$1 {
566
+ constructor(type, options) {
567
+ super(type, options);
568
+ this.data = options.data;
569
+ this.namespace = options.namespace;
570
+ }
571
+ }
572
+ const elementIdMap = new WeakMap();
573
+ let elementId = 1;
574
+ /**
575
+ * 为元素赋予一个唯一的ID
576
+ */
577
+ const getElementId = (element) => {
578
+ if (!elementIdMap.has(element)) {
579
+ elementIdMap.set(element, ++elementId);
580
+ }
581
+ return elementIdMap.get(element);
582
+ };
583
+ // 存储唯一ID及事件处理
584
+ const handlersMap = new Map();
585
+ /**
586
+ * 获取元素上的事件处理器数组
587
+ * @param element
588
+ */
589
+ const getHandlers = (element) => {
590
+ const id = getElementId(element);
591
+ return handlersMap.get(id) || handlersMap.set(id, []).get(id);
592
+ };
593
+ /**
594
+ * 解析事件名中的命名空间
595
+ */
596
+ const parse = (type) => {
597
+ const parts = type.split('.');
598
+ return {
599
+ type: parts[0],
600
+ namespace: parts.slice(1).sort().join(' '),
601
+ };
602
+ };
603
+ /**
604
+ * 命名空间匹配规则
605
+ */
606
+ const matcherFor = (namespace) => {
607
+ return new RegExp('(?:^| )' + namespace.replace(' ', ' .* ?') + '(?: |$)');
608
+ };
609
+ /**
610
+ * 获取匹配的事件
611
+ * @param element
612
+ * @param type
613
+ * @param func
614
+ * @param selector
615
+ */
616
+ const getMatchedHandlers = (element, type, func, selector) => {
617
+ const event = parse(type);
618
+ return getHandlers(element).filter((handler) => {
619
+ return (handler &&
620
+ (!event.type || handler.type === event.type) &&
621
+ (!event.namespace ||
622
+ matcherFor(event.namespace).test(handler.namespace)) &&
623
+ (!func || getElementId(handler.func) === getElementId(func)) &&
624
+ (!selector || handler.selector === selector));
625
+ });
626
+ };
627
+ /**
628
+ * 添加事件监听
629
+ * @param element
630
+ * @param types
631
+ * @param func
632
+ * @param data
633
+ * @param selector
634
+ */
635
+ const add = (element, types, func, data, selector) => {
636
+ // 传入 data.useCapture 来设置 useCapture: true
637
+ let useCapture = false;
638
+ if (isObjectLike(data) && data.useCapture) {
639
+ useCapture = true;
640
+ }
641
+ types.split(' ').forEach((type) => {
642
+ if (!type) {
643
+ return;
644
+ }
645
+ const event = parse(type);
646
+ const callFn = (e, elem) => {
647
+ const result = func.apply(elem,
648
+ // @ts-ignore
649
+ e.detail === null ? [e] : [e].concat(e.detail));
650
+ if (result === false) {
651
+ e.preventDefault();
652
+ e.stopPropagation();
653
+ }
654
+ };
655
+ const proxyFn = (e) => {
656
+ if (e.namespace && !matcherFor(e.namespace).test(event.namespace)) {
657
+ return;
658
+ }
659
+ e.data = data;
660
+ if (selector) {
661
+ // 事件代理
662
+ $(element)
663
+ .find(selector)
664
+ .get()
665
+ .reverse()
666
+ .forEach((elem) => {
667
+ if (elem === e.target || contains(elem, e.target)) {
668
+ callFn(e, elem);
669
+ }
670
+ });
671
+ }
672
+ else {
673
+ // 不使用事件代理
674
+ callFn(e, element);
675
+ }
676
+ };
677
+ const handler = {
678
+ type: event.type,
679
+ namespace: event.namespace,
680
+ func,
681
+ selector,
682
+ id: getHandlers(element).length,
683
+ proxy: proxyFn,
684
+ };
685
+ getHandlers(element).push(handler);
686
+ // @ts-ignore
687
+ element.addEventListener(handler.type, proxyFn, useCapture);
688
+ });
689
+ };
690
+ /**
691
+ * 移除事件监听
692
+ * @param element
693
+ * @param types
694
+ * @param func
695
+ * @param selector
696
+ */
697
+ const remove = (element, types, func, selector) => {
698
+ const handlersInElement = getHandlers(element);
699
+ const removeEvent = (handler) => {
700
+ delete handlersInElement[handler.id];
701
+ // @ts-ignore
702
+ element.removeEventListener(handler.type, handler.proxy, false);
703
+ };
704
+ if (!types) {
705
+ handlersInElement.forEach((handler) => {
706
+ removeEvent(handler);
707
+ });
708
+ }
709
+ else {
710
+ types.split(' ').forEach((type) => {
711
+ if (type) {
712
+ getMatchedHandlers(element, type, func, selector).forEach((handler) => {
713
+ removeEvent(handler);
714
+ });
715
+ }
716
+ });
717
+ }
718
+ };
719
+
720
+ $.fn.trigger = function (name,
721
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
722
+ detail = null, options) {
723
+ const { type, namespace } = parse(name);
724
+ const event = new MduiCustomEvent(type, {
725
+ detail,
726
+ data: null,
727
+ namespace,
728
+ bubbles: true,
729
+ cancelable: false,
730
+ composed: true,
731
+ ...options,
732
+ });
733
+ return this.each((_, element) => {
734
+ element.dispatchEvent(event);
735
+ });
736
+ };
737
+
738
+ function extend(target, ...objectN) {
739
+ eachArray(objectN, (object) => {
740
+ eachObject(object, (prop, value) => {
741
+ if (!isUndefined(value)) {
742
+ target[prop] = value;
743
+ }
744
+ });
745
+ });
746
+ return target;
747
+ }
748
+
749
+ // 全局事件名
750
+ const ajaxStart = 'ajaxStart';
751
+ const ajaxSuccess = 'ajaxSuccess';
752
+ const ajaxError = 'ajaxError';
753
+ const ajaxComplete = 'ajaxComplete';
754
+ // 全局配置参数
755
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
756
+ const globalOptions = {};
757
+ /**
758
+ * 判断此请求方法是否通过查询字符串提交参数
759
+ * @param method 请求方法,大写
760
+ */
761
+ const isQueryStringData = (method) => {
762
+ return ['GET', 'HEAD'].includes(method);
763
+ };
764
+ /**
765
+ * 添加参数到 URL 上,且 URL 中不存在 ? 时,自动把第一个 & 替换为 ?
766
+ * @param url
767
+ * @param query
768
+ */
769
+ const appendQuery = (url, query) => {
770
+ return `${url}&${query}`.replace(/[&?]{1,2}/, '?');
771
+ };
772
+ /**
773
+ * url 是否跨域
774
+ * @param url
775
+ */
776
+ const isCrossDomain = (url) => {
777
+ const window = getWindow();
778
+ return (/^([\w-]+:)?\/\/([^/]+)/.test(url) && RegExp.$2 !== window.location.host);
779
+ };
780
+ /**
781
+ * HTTP 状态码是否表示请求成功
782
+ * @param status
783
+ */
784
+ const isHttpStatusSuccess = (status) => {
785
+ return (status >= 200 && status < 300) || [0, 304].includes(status);
786
+ };
787
+ /**
788
+ * 合并请求参数,参数优先级:options > globalOptions > defaults
789
+ * @param options
790
+ */
791
+ const mergeOptions = (options) => {
792
+ // 默认参数
793
+ const defaults = {
794
+ url: '',
795
+ method: 'GET',
796
+ data: '',
797
+ processData: true,
798
+ async: true,
799
+ cache: true,
800
+ username: '',
801
+ password: '',
802
+ headers: {},
803
+ xhrFields: {},
804
+ statusCode: {},
805
+ dataType: '',
806
+ contentType: 'application/x-www-form-urlencoded',
807
+ timeout: 0,
808
+ global: true,
809
+ };
810
+ // globalOptions 中的回调函数不合并
811
+ eachObject(globalOptions, (key, value) => {
812
+ const callbacks = [
813
+ 'beforeSend',
814
+ 'success',
815
+ 'error',
816
+ 'complete',
817
+ 'statusCode',
818
+ ];
819
+ if (!callbacks.includes(key) && !isUndefined(value)) {
820
+ defaults[key] = value;
821
+ }
822
+ });
823
+ return extend({}, defaults, options);
824
+ };
825
+
826
+ /**
827
+ * 将数组或对象序列化,序列化后的字符串可作为 URL 查询字符串使用
828
+ *
829
+ * 若传入数组,则格式必须和 serializeArray 方法的返回值一样
830
+ * @param obj 对象或数组
831
+ * @example
832
+ ```js
833
+ param({ width: 1680, height: 1050 });
834
+ // width=1680&height=1050
835
+ ```
836
+ * @example
837
+ ```js
838
+ param({ foo: { one: 1, two: 2 }})
839
+ // foo[one]=1&foo[two]=2
840
+ ```
841
+ * @example
842
+ ```js
843
+ param({ids: [1, 2, 3]})
844
+ // ids[]=1&ids[]=2&ids[]=3
845
+ ```
846
+ * @example
847
+ ```js
848
+ param([
849
+ {"name":"name","value":"mdui"},
850
+ {"name":"password","value":"123456"}
851
+ ])
852
+ // name=mdui&password=123456
853
+ ```
854
+ */
855
+ const param = (obj) => {
856
+ if (!isObjectLike(obj) && !Array.isArray(obj)) {
857
+ return '';
858
+ }
859
+ const args = [];
860
+ const destructure = (key, value) => {
861
+ let keyTmp;
862
+ if (isObjectLike(value)) {
863
+ eachObject(value, (i, v) => {
864
+ keyTmp = Array.isArray(value) && !isObjectLike(v) ? '' : i;
865
+ destructure(`${key}[${keyTmp}]`, v);
866
+ });
867
+ }
868
+ else {
869
+ keyTmp =
870
+ value == null || value === '' ? '=' : `=${encodeURIComponent(value)}`;
871
+ args.push(encodeURIComponent(key) + keyTmp);
872
+ }
873
+ };
874
+ if (Array.isArray(obj)) {
875
+ eachArray(obj, ({ name, value }) => {
876
+ return destructure(name, value);
877
+ });
878
+ }
879
+ else {
880
+ eachObject(obj, destructure);
881
+ }
882
+ return args.join('&');
883
+ };
884
+
885
+ /**
886
+ * 发送 ajax 请求
887
+ * @param options
888
+ * @example
889
+ ```js
890
+ ajax({
891
+ method: "POST",
892
+ url: "some.php",
893
+ data: { name: "John", location: "Boston" }
894
+ }).then(function( msg ) {
895
+ alert( "Data Saved: " + msg );
896
+ });
897
+ ```
898
+ */
899
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
900
+ const ajax = (options) => {
901
+ const document = getDocument();
902
+ const window = getWindow();
903
+ // 是否已取消请求
904
+ let isCanceled = false;
905
+ // ajaxStart、ajaxError、ajaxComplete 事件参数
906
+ // @ts-ignore
907
+ const eventParams = {};
908
+ // ajaxSuccess 事件参数
909
+ // @ts-ignore
910
+ const successEventParams = {};
911
+ // 参数合并
912
+ const mergedOptions = mergeOptions(options);
913
+ const method = mergedOptions.method.toUpperCase();
914
+ let { data, url } = mergedOptions;
915
+ url = url || window.location.toString();
916
+ const { processData, async, cache, username, password, headers, xhrFields, statusCode, dataType, contentType, timeout, global, } = mergedOptions;
917
+ // 需要发送的数据
918
+ // GET/HEAD 请求和 processData 为 true 时,转换为查询字符串格式,特殊格式不转换
919
+ const isMethodQueryString = isQueryStringData(method);
920
+ if (data &&
921
+ (isMethodQueryString || processData) &&
922
+ !isString(data) &&
923
+ !(data instanceof ArrayBuffer) &&
924
+ !(data instanceof Blob) &&
925
+ !(data instanceof Document) &&
926
+ !(data instanceof FormData)) {
927
+ data = param(data);
928
+ }
929
+ // 对于 GET、HEAD 类型的请求,把 data 数据添加到 URL 中
930
+ if (data && isMethodQueryString) {
931
+ // 查询字符串拼接到 URL 中
932
+ url = appendQuery(url, data);
933
+ data = null;
934
+ }
935
+ /**
936
+ * 触发事件和回调函数
937
+ * @param event
938
+ * @param callback
939
+ * @param args
940
+ */
941
+ const trigger = (event, callback, ...args) => {
942
+ // 触发全局事件
943
+ if (global) {
944
+ $(document).trigger(event, callback === 'success' ? successEventParams : eventParams);
945
+ }
946
+ // 触发 ajax 回调和事件
947
+ let resultGlobal;
948
+ let resultCustom;
949
+ // 全局回调
950
+ if (callback in globalOptions) {
951
+ // @ts-ignore
952
+ resultGlobal = globalOptions[callback](...args);
953
+ }
954
+ // 自定义回调
955
+ if (mergedOptions[callback]) {
956
+ // @ts-ignore
957
+ resultCustom = mergedOptions[callback](...args);
958
+ }
959
+ // beforeSend 回调返回 false 时取消 ajax 请求
960
+ if (callback === 'beforeSend' &&
961
+ [resultGlobal, resultCustom].includes(false)) {
962
+ isCanceled = true;
963
+ }
964
+ };
965
+ // XMLHttpRequest 请求
966
+ const XHR = () => {
967
+ let textStatus;
968
+ return new Promise((resolve, reject) => {
969
+ const doReject = (reason) => {
970
+ return reject(new Error(reason));
971
+ };
972
+ // GET/HEAD 请求的缓存处理
973
+ if (isMethodQueryString && !cache) {
974
+ url = appendQuery(url, `_=${Date.now()}`);
975
+ }
976
+ // 创建 XHR
977
+ const xhr = new XMLHttpRequest();
978
+ xhr.open(method, url, async, username, password);
979
+ if (contentType ||
980
+ (data && !isMethodQueryString && contentType !== false)) {
981
+ xhr.setRequestHeader('Content-Type', contentType);
982
+ }
983
+ // 设置 Accept
984
+ if (dataType === 'json') {
985
+ xhr.setRequestHeader('Accept', 'application/json, text/javascript');
986
+ }
987
+ // 添加 headers
988
+ eachObject(headers, (key, value) => {
989
+ // undefined 值不发送,string 和 null 需要发送
990
+ if (!isUndefined(value)) {
991
+ xhr.setRequestHeader(key, value + ''); // 把 null 转换成字符串
992
+ }
993
+ });
994
+ // 检查是否是跨域请求,跨域请求时不添加 X-Requested-With
995
+ if (!isCrossDomain(url)) {
996
+ xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
997
+ }
998
+ // 设置 xhr 选项
999
+ eachObject(xhrFields, (key, value) => {
1000
+ xhr[key] = value;
1001
+ });
1002
+ eventParams.xhr = successEventParams.xhr = xhr;
1003
+ eventParams.options = successEventParams.options = mergedOptions;
1004
+ let xhrTimeout;
1005
+ xhr.onload = () => {
1006
+ if (xhrTimeout) {
1007
+ clearTimeout(xhrTimeout);
1008
+ }
1009
+ // AJAX 返回的 HTTP 响应码是否表示成功
1010
+ const isSuccess = isHttpStatusSuccess(xhr.status);
1011
+ // @ts-ignore
1012
+ let responseData = undefined;
1013
+ if (isSuccess) {
1014
+ textStatus =
1015
+ xhr.status === 204 || method === 'HEAD'
1016
+ ? 'nocontent'
1017
+ : xhr.status === 304
1018
+ ? 'notmodified'
1019
+ : 'success';
1020
+ if (dataType === 'json' ||
1021
+ (!dataType &&
1022
+ (xhr.getResponseHeader('content-type') || '').includes('json'))) {
1023
+ try {
1024
+ responseData =
1025
+ method === 'HEAD' ? undefined : JSON.parse(xhr.responseText);
1026
+ successEventParams.response = responseData;
1027
+ }
1028
+ catch (err) {
1029
+ textStatus = 'parsererror';
1030
+ trigger(ajaxError, 'error', xhr, textStatus);
1031
+ doReject(textStatus);
1032
+ }
1033
+ if (textStatus !== 'parsererror') {
1034
+ trigger(ajaxSuccess, 'success', responseData, textStatus, xhr);
1035
+ resolve(responseData);
1036
+ }
1037
+ }
1038
+ else {
1039
+ responseData =
1040
+ method === 'HEAD'
1041
+ ? undefined
1042
+ : xhr.responseType === 'text' || xhr.responseType === ''
1043
+ ? xhr.responseText
1044
+ : xhr.response;
1045
+ successEventParams.response = responseData;
1046
+ trigger(ajaxSuccess, 'success', responseData, textStatus, xhr);
1047
+ resolve(responseData);
1048
+ }
1049
+ }
1050
+ else {
1051
+ textStatus = 'error';
1052
+ trigger(ajaxError, 'error', xhr, textStatus);
1053
+ doReject(textStatus);
1054
+ }
1055
+ // statusCode
1056
+ eachArray([globalOptions.statusCode ?? {}, statusCode], (func) => {
1057
+ if (func[xhr.status]) {
1058
+ if (isSuccess) {
1059
+ func[xhr.status](responseData, textStatus, xhr);
1060
+ }
1061
+ else {
1062
+ func[xhr.status](xhr, textStatus);
1063
+ }
1064
+ }
1065
+ });
1066
+ trigger(ajaxComplete, 'complete', xhr, textStatus);
1067
+ };
1068
+ xhr.onerror = () => {
1069
+ if (xhrTimeout) {
1070
+ clearTimeout(xhrTimeout);
1071
+ }
1072
+ trigger(ajaxError, 'error', xhr, xhr.statusText);
1073
+ trigger(ajaxComplete, 'complete', xhr, 'error');
1074
+ doReject(xhr.statusText);
1075
+ };
1076
+ xhr.onabort = () => {
1077
+ let statusText = 'abort';
1078
+ if (xhrTimeout) {
1079
+ statusText = 'timeout';
1080
+ clearTimeout(xhrTimeout);
1081
+ }
1082
+ trigger(ajaxError, 'error', xhr, statusText);
1083
+ trigger(ajaxComplete, 'complete', xhr, statusText);
1084
+ doReject(statusText);
1085
+ };
1086
+ // ajax start 回调
1087
+ trigger(ajaxStart, 'beforeSend', xhr, mergedOptions);
1088
+ if (isCanceled) {
1089
+ return doReject('cancel');
1090
+ }
1091
+ // Timeout
1092
+ if (timeout > 0) {
1093
+ xhrTimeout = window.setTimeout(() => xhr.abort(), timeout);
1094
+ }
1095
+ // 发送 XHR
1096
+ xhr.send(data);
1097
+ });
1098
+ };
1099
+ return XHR();
1100
+ };
1101
+
1102
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1103
+ class MduiElement extends h {
1104
+ /**
1105
+ * 触发自定义事件。若返回 false,表示事件被取消
1106
+ * @param type
1107
+ * @param options 通常只用到 cancelable 和 detail;bubbles、composed 统一不用
1108
+ */
1109
+ emit(type, options) {
1110
+ const event = new CustomEvent(type, Object.assign({
1111
+ bubbles: true,
1112
+ cancelable: false,
1113
+ composed: true,
1114
+ detail: {},
1115
+ }, options));
1116
+ return this.dispatchEvent(event);
1117
+ }
1118
+ }
1119
+
1120
+ /**
1121
+ * 检查指定的 slot 是否存在
1122
+ */
1123
+ class HasSlotController {
1124
+ constructor(host, ...slotNames) {
1125
+ this.slotNames = [];
1126
+ (this.host = host).addController(this);
1127
+ this.slotNames = slotNames;
1128
+ this.onSlotChange = this.onSlotChange.bind(this);
1129
+ }
1130
+ hostConnected() {
1131
+ this.host.shadowRoot.addEventListener('slotchange', this.onSlotChange);
1132
+ if (!isDomReady()) {
1133
+ $(() => {
1134
+ this.host.requestUpdate();
1135
+ });
1136
+ }
1137
+ }
1138
+ hostDisconnected() {
1139
+ this.host.shadowRoot.removeEventListener('slotchange', this.onSlotChange);
1140
+ }
1141
+ test(slotName) {
1142
+ return slotName === '[default]'
1143
+ ? this.hasDefaultSlot()
1144
+ : this.hasNamedSlot(slotName);
1145
+ }
1146
+ hasDefaultSlot() {
1147
+ return [...this.host.childNodes].some((node) => {
1148
+ if (node.nodeType === node.TEXT_NODE && node.textContent.trim() !== '') {
1149
+ return true;
1150
+ }
1151
+ if (node.nodeType === node.ELEMENT_NODE) {
1152
+ const el = node;
1153
+ if (!el.hasAttribute('slot')) {
1154
+ return true;
1155
+ }
1156
+ }
1157
+ return false;
1158
+ });
1159
+ }
1160
+ hasNamedSlot(name) {
1161
+ return this.host.querySelector(`:scope > [slot="${name}"]`) !== null;
1162
+ }
1163
+ onSlotChange(event) {
1164
+ const slot = event.target;
1165
+ if ((this.slotNames.includes('[default]') && !slot.name) ||
1166
+ (slot.name && this.slotNames.includes(slot.name))) {
1167
+ this.host.requestUpdate();
1168
+ }
1169
+ }
1170
+ }
1171
+
1172
+ const componentStyle = i$2 `:host{box-sizing:border-box}:host *,:host ::after,:host ::before{box-sizing:inherit}:host :focus,:host :focus-visible,:host(:focus),:host(:focus-visible){outline:0}[hidden]{display:none!important}`;
1173
+
1174
+ const style$2 = i$2 `:host{display:inline-block;width:1em;height:1em;font-weight:400;font-family:'Material Icons';font-display:block;font-style:normal;line-height:1;direction:ltr;letter-spacing:normal;white-space:nowrap;text-transform:none;word-wrap:normal;-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;-moz-osx-font-smoothing:grayscale;font-size:1.5rem}::slotted(svg),svg{width:100%;height:100%;fill:currentcolor}`;
1175
+
1176
+ /**
1177
+ * @summary 图标组件
1178
+ *
1179
+ * ```html
1180
+ * <mdui-icon name="search"></mdui-icon>
1181
+ * ```
1182
+ *
1183
+ * @slot - `svg` 图标的内容
1184
+ */
1185
+ let Icon = class Icon extends MduiElement {
1186
+ constructor() {
1187
+ super(...arguments);
1188
+ this.hasSlotController = new HasSlotController(this, '[default]');
1189
+ }
1190
+ render() {
1191
+ const renderDefault = () => {
1192
+ if (this.name) {
1193
+ const [name, variant] = this.name.split('--');
1194
+ const familyMap = new Map([
1195
+ ['outlined', 'Material Icons Outlined'],
1196
+ ['filled', 'Material Icons'],
1197
+ ['rounded', 'Material Icons Round'],
1198
+ ['sharp', 'Material Icons Sharp'],
1199
+ ['two-tone', 'Material Icons Two Tone'],
1200
+ ]);
1201
+ return ke `<span style="${se({ fontFamily: familyMap.get(variant) })}">${name}</span>`;
1202
+ }
1203
+ if (this.src) {
1204
+ return ke `${be(ajax({ url: this.src }).then(fe))}`;
1205
+ }
1206
+ return ke ``;
1207
+ };
1208
+ return this.hasSlotController.test('[default]')
1209
+ ? ke `<slot></slot>`
1210
+ : renderDefault();
1211
+ }
1212
+ };
1213
+ Icon.styles = [componentStyle, style$2];
1214
+ __decorate([
1215
+ n({ reflect: true })
1216
+ ], Icon.prototype, "name", void 0);
1217
+ __decorate([
1218
+ n({ reflect: true })
1219
+ ], Icon.prototype, "src", void 0);
1220
+ Icon = __decorate([
1221
+ t$1('mdui-icon')
1222
+ ], Icon);
1223
+
1224
+ /**
1225
+ * @license
1226
+ * Copyright 2018 Google LLC
1227
+ * SPDX-License-Identifier: BSD-3-Clause
1228
+ */const to=t=>t??D;
1229
+
1230
+ function cc(names) {
1231
+ if (typeof names === "string" || typeof names === "number") return "" + names
1232
+
1233
+ let out = "";
1234
+
1235
+ if (Array.isArray(names)) {
1236
+ for (let i = 0, tmp; i < names.length; i++) {
1237
+ if ((tmp = cc(names[i])) !== "") {
1238
+ out += (out && " ") + tmp;
1239
+ }
1240
+ }
1241
+ } else {
1242
+ for (let k in names) {
1243
+ if (names[k]) out += (out && " ") + k;
1244
+ }
1245
+ }
1246
+
1247
+ return out
1248
+ }
1249
+
1250
+ /**
1251
+ * 获取属性值
1252
+ * @param element
1253
+ * @param key 属性键名
1254
+ * @param defaultValue 当 element.getAttribute 为 null 时,默认返回 undefined
1255
+ */
1256
+ const getAttribute = (element, key, defaultValue) => {
1257
+ const value = element.getAttribute(key);
1258
+ return isNull(value) ? defaultValue : value;
1259
+ };
1260
+ /**
1261
+ * 移除属性
1262
+ * @param element
1263
+ * @param key 属性键名
1264
+ */
1265
+ const removeAttribute = (element, key) => {
1266
+ element.removeAttribute(key);
1267
+ };
1268
+ /**
1269
+ * 设置属性值
1270
+ * @param element
1271
+ * @param key 属性键名
1272
+ * @param value 值,若为 null,则调用 removeAttribute
1273
+ */
1274
+ const setAttribute = (element, key, value) => {
1275
+ isNull(value)
1276
+ ? removeAttribute(element, key)
1277
+ : element.setAttribute(key, value);
1278
+ };
1279
+
1280
+ /**
1281
+ * 获取元素的样式值
1282
+ * @param element
1283
+ * @param name
1284
+ */
1285
+ const getComputedStyleValue = (element, name) => {
1286
+ const window = getWindow();
1287
+ return window.getComputedStyle(element).getPropertyValue(toKebabCase(name));
1288
+ };
1289
+ /**
1290
+ * 检查元素的 box-sizing 是否是 border-box
1291
+ * @param element
1292
+ */
1293
+ const isBorderBox = (element) => {
1294
+ return getComputedStyleValue(element, 'box-sizing') === 'border-box';
1295
+ };
1296
+ /**
1297
+ * 获取元素的 padding, border, margin 宽度(两侧宽度的和,单位为px)
1298
+ * @param element
1299
+ * @param direction
1300
+ * @param extra
1301
+ */
1302
+ const getExtraWidth = (element, direction, extra) => {
1303
+ const position = direction === 'width'
1304
+ ? ['Left', 'Right']
1305
+ : ['Top', 'Bottom'];
1306
+ return [0, 1].reduce((prev, _, index) => {
1307
+ let prop = extra + position[index];
1308
+ if (extra === 'border') {
1309
+ prop += 'Width';
1310
+ }
1311
+ return prev + parseFloat(getComputedStyleValue(element, prop) || '0');
1312
+ }, 0);
1313
+ };
1314
+ /**
1315
+ * 获取元素的样式值,对 width 和 height 进行过处理
1316
+ * @param element
1317
+ * @param name
1318
+ */
1319
+ const getStyle = (element, name) => {
1320
+ // width、height 属性使用 getComputedStyle 得到的值不准确,需要使用 getBoundingClientRect 获取
1321
+ if (name === 'width' || name === 'height') {
1322
+ const valueNumber = element.getBoundingClientRect()[name];
1323
+ if (isBorderBox(element)) {
1324
+ return `${valueNumber}px`;
1325
+ }
1326
+ return `${valueNumber -
1327
+ getExtraWidth(element, name, 'border') -
1328
+ getExtraWidth(element, name, 'padding')}px`;
1329
+ }
1330
+ return getComputedStyleValue(element, name);
1331
+ };
1332
+ /**
1333
+ * 数值单位的 CSS 属性
1334
+ */
1335
+ const cssNumber = [
1336
+ 'animation-iteration-count',
1337
+ 'column-count',
1338
+ 'fill-opacity',
1339
+ 'flex-grow',
1340
+ 'flex-shrink',
1341
+ 'font-weight',
1342
+ 'grid-area',
1343
+ 'grid-column',
1344
+ 'grid-column-end',
1345
+ 'grid-column-start',
1346
+ 'grid-row',
1347
+ 'grid-row-end',
1348
+ 'grid-row-start',
1349
+ 'line-height',
1350
+ 'opacity',
1351
+ 'order',
1352
+ 'orphans',
1353
+ 'widows',
1354
+ 'z-index',
1355
+ 'zoom',
1356
+ ];
1357
+
1358
+ eachArray(['attr', 'prop', 'css'], (name, nameIndex) => {
1359
+ // eslint-disable-next-line
1360
+ const set = (element, key, value) => {
1361
+ // 值为 undefined 时,不修改
1362
+ if (isUndefined(value)) {
1363
+ return;
1364
+ }
1365
+ // attr
1366
+ if (nameIndex === 0) {
1367
+ return setAttribute(element, key, value);
1368
+ }
1369
+ // prop
1370
+ if (nameIndex === 1) {
1371
+ // @ts-ignore
1372
+ element[key] = value;
1373
+ return;
1374
+ }
1375
+ // css
1376
+ key = toKebabCase(key);
1377
+ // 获取默认后缀。以 -- 开头的为 CSS 变量,不添加后缀;值为数值类型的不添加后缀
1378
+ const getSuffix = () => key.startsWith('--') || cssNumber.includes(key) ? '' : 'px';
1379
+ element.style.setProperty(key, isNumber(value) ? `${value}${getSuffix()}` : value);
1380
+ };
1381
+ // eslint-disable-next-line
1382
+ const get = (element, key) => {
1383
+ // attr
1384
+ if (nameIndex === 0) {
1385
+ // 属性不存在时,原生 getAttribute 方法返回 null,而 jquery 返回 undefined。这里和 jquery 保持一致
1386
+ return getAttribute(element, key);
1387
+ }
1388
+ // prop
1389
+ if (nameIndex === 1) {
1390
+ // @ts-ignore
1391
+ return element[key];
1392
+ }
1393
+ return getStyle(element, key);
1394
+ };
1395
+ $.fn[name] = function (key,
1396
+ // eslint-disable-next-line
1397
+ value) {
1398
+ if (isObjectLike(key)) {
1399
+ eachObject(key, (k, v) => {
1400
+ // @ts-ignore
1401
+ this[name](k, v);
1402
+ });
1403
+ return this;
1404
+ }
1405
+ if (arguments.length === 1) {
1406
+ const element = this[0];
1407
+ return isElement(element) ? get(element, key) : undefined;
1408
+ }
1409
+ return this.each((i, element) => {
1410
+ set(element, key, isFunction(value) ? value.call(element, i, get(element, key)) : value);
1411
+ });
1412
+ };
1413
+ });
1414
+
1415
+ /**
1416
+ * 使用该 WeakMap 来存储指定表单中所有的 mdui 表单控件
1417
+ * 在每个表单控件的 hostConnected 中添加、hostDisconnected 中移除对应表单的 mdui 表单控件,
1418
+ * 然后在 getFormControls 方法中就能获取到表单中所有的 mdui 表单控件
1419
+ */
1420
+ const formCollections = new WeakMap();
1421
+ /**
1422
+ * 获取表单中的所有表单控件,包含原生和 mdui 表单控件
1423
+ * 原生的 `HTMLFormElement.elements` 仅返回原生表单控件,不包含 mdui 表单控件
1424
+ */
1425
+ const getFormControls = (form) => {
1426
+ const nativeFormControls = [...form.elements];
1427
+ const formControls = formCollections.get(form) || [];
1428
+ const comparePosition = (a, b) => {
1429
+ const position = a.compareDocumentPosition(b);
1430
+ return position & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
1431
+ };
1432
+ // 按 DOM 元素的顺序排序
1433
+ return [...nativeFormControls, ...formControls].sort(comparePosition);
1434
+ };
1435
+
1436
+ /**
1437
+ * 过滤掉数组中的重复元素
1438
+ * @param arr 数组
1439
+ * @example
1440
+ ```js
1441
+ unique([1, 2, 12, 3, 2, 1, 2, 1, 1]);
1442
+ // [1, 2, 12, 3]
1443
+ ```
1444
+ */
1445
+ const unique = (arr) => {
1446
+ return [...new Set(arr)];
1447
+ };
1448
+
1449
+ /**
1450
+ * 判断组件是否定义完成
1451
+ *
1452
+ * 如果需要在组件操作或读取组件外部、或组件 slot 中的原生 DOM 时,则需要在 DOM 就绪时,才能认为组件定义完成
1453
+ * 如果组件需要和其他组件配合使用,则需要等待其他组件定义完成后,才能认为组件定义完成
1454
+ */
1455
+ class DefinedController {
1456
+ constructor(host, options) {
1457
+ /**
1458
+ * 组件是否已定义完成
1459
+ */
1460
+ this.defined = false;
1461
+ (this.host = host).addController(this);
1462
+ this.relatedElements = options.relatedElements;
1463
+ this.needDomReady = options.needDomReady || !!options.relatedElements;
1464
+ this.onSlotChange = this.onSlotChange.bind(this);
1465
+ }
1466
+ hostConnected() {
1467
+ this.host.shadowRoot.addEventListener('slotchange', this.onSlotChange);
1468
+ }
1469
+ hostDisconnected() {
1470
+ this.host.shadowRoot.removeEventListener('slotchange', this.onSlotChange);
1471
+ }
1472
+ /**
1473
+ * 判断组件是否定义完成
1474
+ */
1475
+ isDefined() {
1476
+ if (this.defined) {
1477
+ return true;
1478
+ }
1479
+ this.defined =
1480
+ (!this.needDomReady || isDomReady()) &&
1481
+ !this.getUndefinedLocalNames().length;
1482
+ return this.defined;
1483
+ }
1484
+ /**
1485
+ * 在组件定义完成后,promise 被 resolve
1486
+ */
1487
+ async whenDefined() {
1488
+ if (this.defined) {
1489
+ return Promise.resolve();
1490
+ }
1491
+ const document = getDocument();
1492
+ if (this.needDomReady && !isDomReady(document)) {
1493
+ await new Promise((resolve) => {
1494
+ document.addEventListener('DOMContentLoaded', () => resolve(), {
1495
+ once: true,
1496
+ });
1497
+ });
1498
+ }
1499
+ const undefinedLocalNames = this.getUndefinedLocalNames();
1500
+ if (undefinedLocalNames.length) {
1501
+ const promises = [];
1502
+ undefinedLocalNames.forEach((localName) => {
1503
+ promises.push(customElements.whenDefined(localName));
1504
+ });
1505
+ await Promise.all(promises);
1506
+ }
1507
+ this.defined = true;
1508
+ return;
1509
+ }
1510
+ /**
1511
+ * slot 中的未完成定义的相关 Web components 组件的 CSS 选择器
1512
+ */
1513
+ getScopeLocalNameSelector() {
1514
+ const localNames = this.relatedElements;
1515
+ if (!localNames) {
1516
+ return null;
1517
+ }
1518
+ if (Array.isArray(localNames)) {
1519
+ return localNames
1520
+ .map((localName) => `${localName}:not(:defined)`)
1521
+ .join(',');
1522
+ }
1523
+ return Object.keys(localNames)
1524
+ .filter((localName) => !localNames[localName])
1525
+ .map((localName) => `${localName}:not(:defined)`)
1526
+ .join(',');
1527
+ }
1528
+ /**
1529
+ * 整个页面中的未完成定义的相关 Web components 组件的 CSS 选择器
1530
+ */
1531
+ getGlobalLocalNameSelector() {
1532
+ const localNames = this.relatedElements;
1533
+ if (!localNames || Array.isArray(localNames)) {
1534
+ return null;
1535
+ }
1536
+ return Object.keys(localNames)
1537
+ .filter((localName) => localNames[localName])
1538
+ .map((localName) => `${localName}:not(:defined)`)
1539
+ .join(',');
1540
+ }
1541
+ /**
1542
+ * 获取未完成定义的相关 Web components 组件名
1543
+ */
1544
+ getUndefinedLocalNames() {
1545
+ const scopeSelector = this.getScopeLocalNameSelector();
1546
+ const globalSelector = this.getGlobalLocalNameSelector();
1547
+ const undefinedScopeElements = scopeSelector
1548
+ ? [...this.host.querySelectorAll(scopeSelector)]
1549
+ : [];
1550
+ const undefinedGlobalElements = globalSelector
1551
+ ? [...getDocument().querySelectorAll(globalSelector)]
1552
+ : [];
1553
+ const localNames = [
1554
+ ...undefinedScopeElements,
1555
+ ...undefinedGlobalElements,
1556
+ ].map((element) => element.localName);
1557
+ return unique(localNames);
1558
+ }
1559
+ /**
1560
+ * slot 变更时,若 slot 中包含未完成定义的相关 Web components 组件,则组件未定义完成
1561
+ */
1562
+ onSlotChange() {
1563
+ const selector = this.getScopeLocalNameSelector();
1564
+ if (selector) {
1565
+ const undefinedElements = this.host.querySelectorAll(selector);
1566
+ if (undefinedElements.length) {
1567
+ this.defined = false;
1568
+ }
1569
+ }
1570
+ }
1571
+ }
1572
+
1573
+ /**
1574
+ * 参考:https://github.com/shoelace-style/shoelace/blob/next/src/internal/form.ts
1575
+ */
1576
+ /**
1577
+ * 在执行 `<form>` 元素的 reportValidity() 时,不会执行 mdui 组件的 reportValidity() 方法,
1578
+ * 因此在 mdui 表单控件的 hostConnected 中把 `<form>` 的 reportValidity 替换为自定义方法,
1579
+ * hostDisconnected 中恢复为 原生 reportValidity 方法
1580
+ *
1581
+ * 该 WeakMap 用于存储指定 `<form>` 的原生 reportValidity 方法
1582
+ *
1583
+ * 日后使用 ElementInternals 可不再进行该处理,但当前 safari 浏览器不支持。
1584
+ */
1585
+ const reportValidityOverloads = new WeakMap();
1586
+ /**
1587
+ * 在执行表单的 reset() 方法后,使用该 WeakMap 存储指定表单中所有的表单控件
1588
+ * 在表单控件中监听值变更后,需要从该 WeakMap 中判断是否存在该表单控件,
1589
+ * 若存在,则 invalid 设置为 false(不显示验证不通过样式),同时从 WeakMap 中移除该表单控件
1590
+ */
1591
+ const formResets = new WeakMap();
1592
+ class FormController {
1593
+ constructor(host, options) {
1594
+ (this.host = host).addController(this);
1595
+ this.definedController = new DefinedController(host, {
1596
+ needDomReady: true,
1597
+ });
1598
+ this.options = {
1599
+ form: (control) => {
1600
+ const formId = $(control).attr('form');
1601
+ if (formId) {
1602
+ const root = control.getRootNode();
1603
+ return root.getElementById(formId);
1604
+ }
1605
+ return control.closest('form');
1606
+ },
1607
+ name: (control) => control.name,
1608
+ value: (control) => control.value,
1609
+ defaultValue: (control) => control.defaultValue,
1610
+ setValue: (control, value) => (control.value = value),
1611
+ disabled: (control) => control.disabled,
1612
+ reportValidity: (control) => isFunction(control.reportValidity) ? control.reportValidity() : true,
1613
+ ...options,
1614
+ };
1615
+ this.onFormData = this.onFormData.bind(this);
1616
+ this.onFormSubmit = this.onFormSubmit.bind(this);
1617
+ this.onFormReset = this.onFormReset.bind(this);
1618
+ this.reportFormValidity = this.reportFormValidity.bind(this);
1619
+ }
1620
+ hostConnected() {
1621
+ this.definedController.whenDefined().then(() => {
1622
+ this.form = this.options.form(this.host);
1623
+ if (this.form) {
1624
+ this.attachForm(this.form);
1625
+ }
1626
+ });
1627
+ }
1628
+ hostDisconnected() {
1629
+ this.detachForm();
1630
+ }
1631
+ hostUpdated() {
1632
+ this.definedController.whenDefined().then(() => {
1633
+ const form = this.options.form(this.host);
1634
+ if (!form) {
1635
+ this.detachForm();
1636
+ }
1637
+ if (form && this.form !== form) {
1638
+ this.detachForm();
1639
+ this.attachForm(form);
1640
+ }
1641
+ });
1642
+ }
1643
+ /**
1644
+ * 获取当前表单控件关联的 `<form>` 元素
1645
+ */
1646
+ getForm() {
1647
+ return this.form ?? null;
1648
+ }
1649
+ /**
1650
+ * 重置整个表单,所有表单控件恢复成默认值
1651
+ */
1652
+ reset(invoker) {
1653
+ this.doAction('reset', invoker);
1654
+ }
1655
+ /**
1656
+ * 提交整个表单
1657
+ */
1658
+ submit(invoker) {
1659
+ this.doAction('submit', invoker);
1660
+ }
1661
+ attachForm(form) {
1662
+ if (!form) {
1663
+ this.form = undefined;
1664
+ return;
1665
+ }
1666
+ this.form = form;
1667
+ if (formCollections.has(this.form)) {
1668
+ formCollections.get(this.form).add(this.host);
1669
+ }
1670
+ else {
1671
+ formCollections.set(this.form, new Set([this.host]));
1672
+ }
1673
+ this.form.addEventListener('formdata', this.onFormData);
1674
+ this.form.addEventListener('submit', this.onFormSubmit);
1675
+ this.form.addEventListener('reset', this.onFormReset);
1676
+ if (!reportValidityOverloads.has(this.form)) {
1677
+ reportValidityOverloads.set(this.form, this.form.reportValidity);
1678
+ this.form.reportValidity = () => this.reportFormValidity();
1679
+ }
1680
+ }
1681
+ detachForm() {
1682
+ if (this.form) {
1683
+ formCollections.get(this.form).delete(this.host);
1684
+ this.form.removeEventListener('formdata', this.onFormData);
1685
+ this.form.removeEventListener('submit', this.onFormSubmit);
1686
+ this.form.removeEventListener('reset', this.onFormReset);
1687
+ if (reportValidityOverloads.has(this.form) &&
1688
+ !formCollections.get(this.form).size) {
1689
+ this.form.reportValidity = reportValidityOverloads.get(this.form);
1690
+ reportValidityOverloads.delete(this.form);
1691
+ }
1692
+ }
1693
+ }
1694
+ doAction(type, invoker) {
1695
+ if (!this.form) {
1696
+ return;
1697
+ }
1698
+ const $button = $(`<button type="${type}">`).css({
1699
+ position: 'absolute',
1700
+ width: 0,
1701
+ height: 0,
1702
+ clipPath: 'inset(50%)',
1703
+ overflow: 'hidden',
1704
+ whiteSpace: 'nowrap',
1705
+ });
1706
+ const button = $button[0];
1707
+ if (invoker) {
1708
+ button.name = invoker.name;
1709
+ button.value = invoker.value;
1710
+ [
1711
+ 'formaction',
1712
+ 'formenctype',
1713
+ 'formmethod',
1714
+ 'formnovalidate',
1715
+ 'formtarget',
1716
+ ].forEach((attr) => {
1717
+ $button.attr(attr, $(invoker).attr(attr));
1718
+ });
1719
+ }
1720
+ this.form.append(button);
1721
+ button.click();
1722
+ button.remove();
1723
+ }
1724
+ onFormData(event) {
1725
+ const disabled = this.options.disabled(this.host);
1726
+ const name = this.options.name(this.host);
1727
+ const value = this.options.value(this.host);
1728
+ // 对于按钮,仅在 type="submit" 时,才提交值。已在 doAction() 方法中把 name、value 注入到 <button> 元素上
1729
+ const isButton = [
1730
+ 'mdui-button',
1731
+ 'mdui-button-icon',
1732
+ 'mdui-chip',
1733
+ 'mdui-fab',
1734
+ 'mdui-segmented-button',
1735
+ ].includes(this.host.tagName.toLowerCase());
1736
+ if (!disabled &&
1737
+ !isButton &&
1738
+ isString(name) &&
1739
+ name &&
1740
+ !isUndefined(value)) {
1741
+ if (Array.isArray(value)) {
1742
+ value.forEach((val) => {
1743
+ event.formData.append(name, val.toString());
1744
+ });
1745
+ }
1746
+ else {
1747
+ event.formData.append(name, value.toString());
1748
+ }
1749
+ }
1750
+ }
1751
+ // todo: 当前组件进行验证的顺序,取决于组件的注册顺序,而不会按在 DOM 中的顺序从上到下验证。如何按 DOM 顺序验证?
1752
+ onFormSubmit(event) {
1753
+ const disabled = this.options.disabled(this.host);
1754
+ const reportValidity = this.options.reportValidity;
1755
+ if (this.form &&
1756
+ !this.form.noValidate &&
1757
+ !disabled &&
1758
+ !reportValidity(this.host)) {
1759
+ event.preventDefault();
1760
+ event.stopImmediatePropagation();
1761
+ }
1762
+ }
1763
+ onFormReset() {
1764
+ if (this.form) {
1765
+ this.options.setValue(this.host, this.options.defaultValue(this.host));
1766
+ // 取消 invalid 状态。
1767
+ // 此外,还需要在各个组件内,监听值的变更,判断 formResets 中是否存在当前表单控件。若存在则 invalid 设为 false;不存在则设置为 checkValidity() 的值
1768
+ // @ts-ignore
1769
+ this.host.invalid = false;
1770
+ if (formResets.has(this.form)) {
1771
+ formResets.get(this.form).add(this.host);
1772
+ }
1773
+ else {
1774
+ formResets.set(this.form, new Set([this.host]));
1775
+ }
1776
+ }
1777
+ }
1778
+ reportFormValidity() {
1779
+ if (this.form && !this.form.noValidate) {
1780
+ const elements = getFormControls(this.form);
1781
+ for (const element of elements) {
1782
+ if (isFunction(element.reportValidity) && !element.reportValidity()) {
1783
+ return false;
1784
+ }
1785
+ }
1786
+ }
1787
+ return true;
1788
+ }
1789
+ }
1790
+
1791
+ const AnchorMixin = (superclass) => {
1792
+ class AnchorMixinClass extends superclass {
1793
+ renderAnchor({ id, className, part, content = ke `<slot></slot>`, refDirective, tabIndex, }) {
1794
+ return ke `<a ${refDirective} id="${to(id)}" class="_a ${className ? className : ''}" part="${to(part)}" href="${to(this.href)}" download="${to(this.download)}" target="${to(this.target)}" rel="${to(this.rel)}" tabindex="${to(tabIndex)}">${content}</a>`;
1795
+ }
1796
+ }
1797
+ __decorate([
1798
+ n({ reflect: true })
1799
+ ], AnchorMixinClass.prototype, "href", void 0);
1800
+ __decorate([
1801
+ n({ reflect: true })
1802
+ ], AnchorMixinClass.prototype, "download", void 0);
1803
+ __decorate([
1804
+ n({ reflect: true })
1805
+ ], AnchorMixinClass.prototype, "target", void 0);
1806
+ __decorate([
1807
+ n({ reflect: true })
1808
+ ], AnchorMixinClass.prototype, "rel", void 0);
1809
+ return AnchorMixinClass;
1810
+ };
1811
+
1812
+ $.fn.removeAttr = function (attributeName) {
1813
+ const names = attributeName.split(' ').filter((name) => name);
1814
+ return this.each(function () {
1815
+ eachArray(names, (name) => {
1816
+ removeAttribute(this, name);
1817
+ });
1818
+ });
1819
+ };
1820
+
1821
+ let isClick = true;
1822
+ const document$1 = getDocument();
1823
+ document$1.addEventListener('pointerdown', () => {
1824
+ isClick = true;
1825
+ });
1826
+ document$1.addEventListener('keydown', () => {
1827
+ isClick = false;
1828
+ });
1829
+ /**
1830
+ * 参考:https://github.com/adobe/spectrum-web-components/blob/main/tools/shared/src/focusable.ts
1831
+ */
1832
+ const FocusableMixin = (superclass) => {
1833
+ class FocusableMixinClass extends superclass {
1834
+ constructor() {
1835
+ super(...arguments);
1836
+ /**
1837
+ * 是否在页面加载完成后自动获取焦点
1838
+ */
1839
+ this.autofocus = false;
1840
+ /**
1841
+ * 是否获得了焦点,不管是鼠标点击,还是键盘切换获得的焦点,都会添加该属性
1842
+ * 添加到 :host 元素上,供 CSS 选择器添加样式
1843
+ */
1844
+ this.focused = false;
1845
+ /**
1846
+ * 是否通过键盘切换获得了焦点
1847
+ * 添加到 :host 元素上,供 CSS 选择器添加样式
1848
+ */
1849
+ this.focusVisible = false;
1850
+ this.focusableDefinedController = new DefinedController(this, { relatedElements: [''] });
1851
+ this._manipulatingTabindex = false;
1852
+ this._tabIndex = 0;
1853
+ }
1854
+ /**
1855
+ * 元素在使用 Tab 键切换焦点时的顺序
1856
+ */
1857
+ get tabIndex() {
1858
+ const $this = $(this);
1859
+ if (this.focusElement === this) {
1860
+ return Number($this.attr('tabindex') || -1);
1861
+ }
1862
+ const tabIndexAttribute = Number($this.attr('tabindex') || 0);
1863
+ if (this.focusDisabled || tabIndexAttribute < 0) {
1864
+ return -1;
1865
+ }
1866
+ if (!this.focusElement) {
1867
+ return tabIndexAttribute;
1868
+ }
1869
+ return this.focusElement.tabIndex;
1870
+ }
1871
+ set tabIndex(tabIndex) {
1872
+ if (this._manipulatingTabindex) {
1873
+ this._manipulatingTabindex = false;
1874
+ return;
1875
+ }
1876
+ const $this = $(this);
1877
+ if (this.focusElement === this) {
1878
+ if (tabIndex !== null) {
1879
+ this._tabIndex = tabIndex;
1880
+ }
1881
+ $this.attr('tabindex', this.focusDisabled ? null : tabIndex);
1882
+ return;
1883
+ }
1884
+ const onPointerDown = () => {
1885
+ if (this.tabIndex === -1) {
1886
+ this.tabIndex = 0;
1887
+ this.focus({ preventScroll: true });
1888
+ }
1889
+ };
1890
+ if (tabIndex === -1) {
1891
+ this.addEventListener('pointerdown', onPointerDown);
1892
+ }
1893
+ else {
1894
+ this._manipulatingTabindex = true;
1895
+ this.removeEventListener('pointerdown', onPointerDown);
1896
+ }
1897
+ if (tabIndex === -1 || this.focusDisabled) {
1898
+ $this.attr('tabindex', -1);
1899
+ if (tabIndex !== -1) {
1900
+ this.manageFocusElementTabindex(tabIndex);
1901
+ }
1902
+ return;
1903
+ }
1904
+ if (!this.hasAttribute('tabindex')) {
1905
+ this._manipulatingTabindex = false;
1906
+ }
1907
+ this.manageFocusElementTabindex(tabIndex);
1908
+ }
1909
+ /**
1910
+ * 父类要实现该属性,表示是否禁用 focus 状态
1911
+ */
1912
+ get focusDisabled() {
1913
+ throw new Error('Must implement focusDisabled getter!');
1914
+ }
1915
+ /**
1916
+ * 最终获得焦点的元素
1917
+ */
1918
+ get focusElement() {
1919
+ throw new Error('Must implement focusElement getter!');
1920
+ }
1921
+ connectedCallback() {
1922
+ super.connectedCallback();
1923
+ this.updateComplete.then(() => {
1924
+ requestAnimationFrame(() => {
1925
+ this.manageAutoFocus();
1926
+ });
1927
+ });
1928
+ }
1929
+ /**
1930
+ * 模拟鼠标点击元素
1931
+ */
1932
+ click() {
1933
+ if (this.focusDisabled) {
1934
+ return;
1935
+ }
1936
+ if (this.focusElement !== this) {
1937
+ this.focusElement.click();
1938
+ }
1939
+ else {
1940
+ HTMLElement.prototype.click.apply(this);
1941
+ }
1942
+ }
1943
+ /**
1944
+ * 将焦点设置到当前元素。
1945
+ *
1946
+ * 可以传入一个对象作为参数,该对象的属性包括:
1947
+ *
1948
+ * * `preventScroll`:默认情况下,元素获取焦点后,页面会滚动以将该元素滚动到视图中。如果不希望页面滚动,可以将此属性设置为 `true`。
1949
+ */
1950
+ focus(options) {
1951
+ if (this.focusDisabled || !this.focusElement) {
1952
+ return;
1953
+ }
1954
+ if (this.focusElement !== this) {
1955
+ this.focusElement.focus(options);
1956
+ }
1957
+ else {
1958
+ HTMLElement.prototype.focus.apply(this, [options]);
1959
+ }
1960
+ }
1961
+ /**
1962
+ * 移除当前元素的焦点
1963
+ */
1964
+ blur() {
1965
+ if (this.focusElement !== this) {
1966
+ this.focusElement.blur();
1967
+ }
1968
+ else {
1969
+ HTMLElement.prototype.blur.apply(this);
1970
+ }
1971
+ }
1972
+ firstUpdated(changedProperties) {
1973
+ super.firstUpdated(changedProperties);
1974
+ this.focusElement.addEventListener('focus', () => {
1975
+ this.focused = true;
1976
+ this.focusVisible = !isClick;
1977
+ });
1978
+ this.focusElement.addEventListener('blur', () => {
1979
+ this.focused = false;
1980
+ this.focusVisible = false;
1981
+ });
1982
+ }
1983
+ update(changedProperties) {
1984
+ if (this._lastFocusDisabled === undefined ||
1985
+ this._lastFocusDisabled !== this.focusDisabled) {
1986
+ this._lastFocusDisabled = this.focusDisabled;
1987
+ const $this = $(this);
1988
+ if (this.focusDisabled) {
1989
+ $this.removeAttr('tabindex');
1990
+ }
1991
+ else {
1992
+ if (this.focusElement === this) {
1993
+ this._manipulatingTabindex = true;
1994
+ $this.attr('tabindex', this._tabIndex);
1995
+ }
1996
+ else if (this.tabIndex > -1) {
1997
+ $this.removeAttr('tabindex');
1998
+ }
1999
+ }
2000
+ }
2001
+ super.update(changedProperties);
2002
+ }
2003
+ updated(changedProperties) {
2004
+ super.updated(changedProperties);
2005
+ if (this.focused && this.focusDisabled) {
2006
+ this.blur();
2007
+ }
2008
+ }
2009
+ async manageFocusElementTabindex(tabIndex) {
2010
+ if (!this.focusElement) {
2011
+ await this.updateComplete;
2012
+ }
2013
+ if (tabIndex === null) {
2014
+ this.focusElement.removeAttribute('tabindex');
2015
+ }
2016
+ else {
2017
+ this.focusElement.tabIndex = tabIndex;
2018
+ }
2019
+ }
2020
+ manageAutoFocus() {
2021
+ if (this.autofocus) {
2022
+ this.dispatchEvent(new KeyboardEvent('keydown', {
2023
+ code: 'Tab',
2024
+ }));
2025
+ this.focusElement.focus();
2026
+ }
2027
+ }
2028
+ }
2029
+ __decorate([
2030
+ n({
2031
+ type: Boolean,
2032
+ /**
2033
+ * 哪些属性需要 reflect: true?
2034
+ * 一般所有属性都需要 reflect,但以下情况除外:
2035
+ * 1. 会频繁变更的属性
2036
+ * 2. 属性同步会造成较大性能开销的属性
2037
+ * 3. 复杂类型属性(数组、对象等,仅提供 property,不提供 attribute)
2038
+ */
2039
+ reflect: true,
2040
+ converter: booleanConverter,
2041
+ })
2042
+ ], FocusableMixinClass.prototype, "autofocus", void 0);
2043
+ __decorate([
2044
+ n({
2045
+ type: Boolean,
2046
+ reflect: true,
2047
+ converter: booleanConverter,
2048
+ })
2049
+ ], FocusableMixinClass.prototype, "focused", void 0);
2050
+ __decorate([
2051
+ n({
2052
+ type: Boolean,
2053
+ reflect: true,
2054
+ converter: booleanConverter,
2055
+ attribute: 'focus-visible',
2056
+ })
2057
+ ], FocusableMixinClass.prototype, "focusVisible", void 0);
2058
+ __decorate([
2059
+ n({ type: Number, attribute: 'tabindex' })
2060
+ ], FocusableMixinClass.prototype, "tabIndex", null);
2061
+ return FocusableMixinClass;
2062
+ };
2063
+
2064
+ /**
2065
+ * @license
2066
+ * Copyright 2018 Google LLC
2067
+ * SPDX-License-Identifier: BSD-3-Clause
2068
+ */const Rt=e(class extends i{constructor(s){if(super(s),s.type!==t.ATTRIBUTE||"class"!==s.name||s.strings?.length>2)throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute.")}render(t){return " "+Object.keys(t).filter((s=>t[s])).join(" ")+" "}update(t,[s]){if(void 0===this.st){this.st=new Set,void 0!==t.strings&&(this.nt=new Set(t.strings.join(" ").split(/\s/).filter((t=>""!==t))));for(const t in s)s[t]&&!this.nt?.has(t)&&this.st.add(t);return this.render(s)}const i=t.element.classList;for(const t of this.st)t in s||(i.remove(t),this.st.delete(t));for(const t in s){const r=!!s[t];r===this.st.has(t)||this.nt?.has(t)||(r?(i.add(t),this.st.add(t)):(i.remove(t),this.st.delete(t)));}return R}});
2069
+
2070
+ const style$1 = i$2 `:host{position:relative;display:inline-block;flex-shrink:0;width:2.5rem;height:2.5rem;stroke:rgb(var(--mdui-color-primary))}.progress{position:relative;display:inline-block;width:100%;height:100%;text-align:left;transition:opacity var(--mdui-motion-duration-medium1) var(--mdui-motion-easing-linear)}.determinate svg{transform:rotate(-90deg);fill:transparent}.determinate .track{stroke:transparent}.determinate .circle{stroke:inherit;transition:stroke-dashoffset var(--mdui-motion-duration-long2) var(--mdui-motion-easing-standard)}.indeterminate{font-size:0;letter-spacing:0;white-space:nowrap;animation:mdui-comp-circular-progress-rotate 1568ms var(--mdui-motion-easing-linear) infinite}.indeterminate .circle,.indeterminate .layer{position:absolute;width:100%;height:100%}.indeterminate .layer{animation:mdui-comp-circular-progress-layer-rotate 5332ms var(--mdui-motion-easing-standard) infinite both}.indeterminate .circle{fill:transparent;stroke:inherit}.indeterminate .gap-patch{position:absolute;top:0;left:47.5%;width:5%;height:100%;overflow:hidden}.indeterminate .gap-patch .circle{left:-900%;width:2000%;transform:rotate(180deg)}.indeterminate .clipper{position:relative;display:inline-block;width:50%;height:100%;overflow:hidden}.indeterminate .clipper .circle{width:200%}.indeterminate .clipper.left .circle{animation:mdui-comp-circular-progress-left-spin 1333ms var(--mdui-motion-easing-standard) infinite both}.indeterminate .clipper.right .circle{left:-100%;animation:mdui-comp-circular-progress-right-spin 1333ms var(--mdui-motion-easing-standard) infinite both}@keyframes mdui-comp-circular-progress-rotate{to{transform:rotate(360deg)}}@keyframes mdui-comp-circular-progress-layer-rotate{12.5%{transform:rotate(135deg)}25%{transform:rotate(270deg)}37.5%{transform:rotate(405deg)}50%{transform:rotate(540deg)}62.5%{transform:rotate(675deg)}75%{transform:rotate(810deg)}87.5%{transform:rotate(945deg)}100%{transform:rotate(1080deg)}}@keyframes mdui-comp-circular-progress-left-spin{0%{transform:rotate(265deg)}50%{transform:rotate(130deg)}100%{transform:rotate(265deg)}}@keyframes mdui-comp-circular-progress-right-spin{0%{transform:rotate(-265deg)}50%{transform:rotate(-130deg)}100%{transform:rotate(-265deg)}}`;
2071
+
2072
+ /**
2073
+ * @summary 圆形进度指示器组件
2074
+ *
2075
+ * ```html
2076
+ * <mdui-circular-progress></mdui-circular-progress>
2077
+ * ```
2078
+ */
2079
+ let CircularProgress = class CircularProgress extends MduiElement {
2080
+ constructor() {
2081
+ super(...arguments);
2082
+ /**
2083
+ * 进度指示器的最大值。默认为 `1`
2084
+ */
2085
+ this.max = 1;
2086
+ }
2087
+ render() {
2088
+ const isDeterminate = !isUndefined(this.value);
2089
+ return ke `<div class="progress ${Rt({
2090
+ determinate: isDeterminate,
2091
+ indeterminate: !isDeterminate,
2092
+ })}">${isDeterminate ? this.renderDeterminate() : this.renderInDeterminate()}</div>`;
2093
+ }
2094
+ renderDeterminate() {
2095
+ const value = this.value;
2096
+ const strokeWidth = 4; // 圆环宽度
2097
+ const circleRadius = 18; // 圆环宽度中心点的半径
2098
+ const π = 3.1415926;
2099
+ const center = circleRadius + strokeWidth / 2;
2100
+ const circumference = 2 * π * circleRadius;
2101
+ const determinateStrokeDashOffset = (1 - value / Math.max(this.max ?? value, value)) * circumference;
2102
+ return ke `<svg viewBox="0 0 ${center * 2} ${center * 2}"><circle class="track" cx="${center}" cy="${center}" r="${circleRadius}" stroke-width="${strokeWidth}"></circle><circle class="circle" cx="${center}" cy="${center}" r="${circleRadius}" stroke-dasharray="${2 * π * circleRadius}" stroke-dashoffset="${determinateStrokeDashOffset}" stroke-width="${strokeWidth}"></circle></svg>`;
2103
+ }
2104
+ renderInDeterminate() {
2105
+ const strokeWidth = 4; // 圆环宽度
2106
+ const circleRadius = 18; // 圆环宽度中心点的半径
2107
+ const π = 3.1415926;
2108
+ const center = circleRadius + strokeWidth / 2;
2109
+ const circumference = 2 * π * circleRadius;
2110
+ const halfCircumference = 0.5 * circumference;
2111
+ const circle = (thisStrokeWidth) => ke `<svg class="circle" viewBox="0 0 ${center * 2} ${center * 2}"><circle cx="${center}" cy="${center}" r="${circleRadius}" stroke-dasharray="${circumference}" stroke-dashoffset="${halfCircumference}" stroke-width="${thisStrokeWidth}"></circle></svg>`;
2112
+ return ke `<div class="layer"><div class="clipper left">${circle(strokeWidth)}</div><div class="gap-patch">${circle(strokeWidth * 0.8)}</div><div class="clipper right">${circle(strokeWidth)}</div></div>`;
2113
+ }
2114
+ };
2115
+ CircularProgress.styles = [componentStyle, style$1];
2116
+ __decorate([
2117
+ n({ type: Number, reflect: true })
2118
+ ], CircularProgress.prototype, "max", void 0);
2119
+ __decorate([
2120
+ n({ type: Number })
2121
+ ], CircularProgress.prototype, "value", void 0);
2122
+ CircularProgress = __decorate([
2123
+ t$1('mdui-circular-progress')
2124
+ ], CircularProgress);
2125
+
2126
+ // eslint-disable-next-line
2127
+ $.fn.is = function (selector) {
2128
+ let isMatched = false;
2129
+ if (isFunction(selector)) {
2130
+ this.each((index, element) => {
2131
+ if (selector.call(element, index, element)) {
2132
+ isMatched = true;
2133
+ }
2134
+ });
2135
+ return isMatched;
2136
+ }
2137
+ if (isString(selector)) {
2138
+ this.each((_, element) => {
2139
+ if (isDocument(element) || isWindow(element)) {
2140
+ return;
2141
+ }
2142
+ if (element.matches.call(element, selector)) {
2143
+ isMatched = true;
2144
+ }
2145
+ });
2146
+ return isMatched;
2147
+ }
2148
+ const $compareWith = $(selector);
2149
+ this.each((_, element) => {
2150
+ $compareWith.each((_, compare) => {
2151
+ if (element === compare) {
2152
+ isMatched = true;
2153
+ }
2154
+ });
2155
+ });
2156
+ return isMatched;
2157
+ };
2158
+
2159
+ $.fn.children = function (selector) {
2160
+ const children = [];
2161
+ this.each((_, element) => {
2162
+ eachArray(element.childNodes, (childNode) => {
2163
+ if (!isElement(childNode)) {
2164
+ return;
2165
+ }
2166
+ if (!selector || $(childNode).is(selector)) {
2167
+ children.push(childNode);
2168
+ }
2169
+ });
2170
+ });
2171
+ return new JQ(unique(children));
2172
+ };
2173
+
2174
+ $.fn.slice = function (...args) {
2175
+ return new JQ([].slice.apply(this, args));
2176
+ };
2177
+
2178
+ $.fn.eq = function (index) {
2179
+ const ret = index === -1 ? this.slice(index) : this.slice(index, +index + 1);
2180
+ return new JQ(ret);
2181
+ };
2182
+
2183
+ const dir = ($elements, nameIndex, node,
2184
+ // eslint-disable-next-line
2185
+ selector, filter) => {
2186
+ const ret = [];
2187
+ let target;
2188
+ $elements.each((_, element) => {
2189
+ target = element[node];
2190
+ // 不能包含最顶层的 document 元素
2191
+ while (target && isElement(target)) {
2192
+ // prevUntil, nextUntil, parentsUntil
2193
+ if (nameIndex === 2) {
2194
+ if (selector && $(target).is(selector)) {
2195
+ break;
2196
+ }
2197
+ if (!filter || $(target).is(filter)) {
2198
+ ret.push(target);
2199
+ }
2200
+ }
2201
+ // prev, next, parent
2202
+ else if (nameIndex === 0) {
2203
+ if (!selector || $(target).is(selector)) {
2204
+ ret.push(target);
2205
+ }
2206
+ break;
2207
+ }
2208
+ // prevAll, nextAll, parents
2209
+ else {
2210
+ if (!selector || $(target).is(selector)) {
2211
+ ret.push(target);
2212
+ }
2213
+ }
2214
+ target = target[node];
2215
+ }
2216
+ });
2217
+ return new JQ(unique(ret));
2218
+ };
2219
+
2220
+ eachArray(['', 's', 'sUntil'], (name, nameIndex) => {
2221
+ $.fn[`parent${name}`] = function (
2222
+ // eslint-disable-next-line
2223
+ selector, filter) {
2224
+ // parents、parentsUntil 需要把元素的顺序反向处理,以便和 jQuery 的结果一致
2225
+ const $nodes = !nameIndex ? this : $(this.get().reverse());
2226
+ return dir($nodes, nameIndex, 'parentNode', selector, filter);
2227
+ };
2228
+ });
2229
+
2230
+ // eslint-disable-next-line
2231
+ $.fn.index = function (selector) {
2232
+ if (!arguments.length) {
2233
+ return this.eq(0).parent().children().get().indexOf(this[0]);
2234
+ }
2235
+ if (isString(selector)) {
2236
+ return $(selector).get().indexOf(this[0]);
2237
+ }
2238
+ return this.get().indexOf($(selector)[0]);
2239
+ };
2240
+
2241
+ eachArray(['add', 'remove', 'toggle'], (name) => {
2242
+ $.fn[`${name}Class`] = function (className) {
2243
+ if (name === 'remove' && !arguments.length) {
2244
+ return this.each((_, element) => {
2245
+ setAttribute(element, 'class', '');
2246
+ });
2247
+ }
2248
+ return this.each((i, element) => {
2249
+ if (!isElement(element)) {
2250
+ return;
2251
+ }
2252
+ const classes = (isFunction(className)
2253
+ ? className.call(element, i, getAttribute(element, 'class', ''))
2254
+ : className)
2255
+ .split(' ')
2256
+ .filter((name) => name);
2257
+ eachArray(classes, (cls) => {
2258
+ element.classList[name](cls);
2259
+ });
2260
+ });
2261
+ };
2262
+ });
2263
+
2264
+ const weakMap = new WeakMap();
2265
+ /**
2266
+ * 获取元素上的所有数据
2267
+ * @param element
2268
+ */
2269
+ const getAll = (element) => {
2270
+ return weakMap.get(element) ?? {};
2271
+ };
2272
+ /**
2273
+ * 获取元素上的的一个数据
2274
+ * @param element
2275
+ * @param keyOriginal
2276
+ */
2277
+ const get$2 = (element, keyOriginal) => {
2278
+ const data = getAll(element);
2279
+ const key = toCamelCase(keyOriginal);
2280
+ return key in data ? data[key] : undefined;
2281
+ };
2282
+ /**
2283
+ * 在上设置键值对数据
2284
+ * @param element
2285
+ * @param object
2286
+ */
2287
+ const setAll = (element, object) => {
2288
+ const data = getAll(element);
2289
+ eachObject(object, (keyOriginal, value) => {
2290
+ data[toCamelCase(keyOriginal)] = value;
2291
+ });
2292
+ weakMap.set(element, data);
2293
+ };
2294
+ /**
2295
+ * 在元素上设置一个数据
2296
+ * @param element
2297
+ * @param keyOriginal
2298
+ * @param value
2299
+ */
2300
+ const set$2 = (element, keyOriginal, value) => {
2301
+ setAll(element, { [keyOriginal]: value });
2302
+ };
2303
+ const rbrace = /^(?:{[\w\W]*\}|\[[\w\W]*\])$/;
2304
+ /**
2305
+ * dataset 中的值读取时进行转换
2306
+ * @param value
2307
+ */
2308
+ const stringTransform = (value) => {
2309
+ if (value === 'true') {
2310
+ return true;
2311
+ }
2312
+ if (value === 'false') {
2313
+ return false;
2314
+ }
2315
+ if (value === 'null') {
2316
+ return null;
2317
+ }
2318
+ if (value === +value + '') {
2319
+ return +value;
2320
+ }
2321
+ if (rbrace.test(value)) {
2322
+ return JSON.parse(value);
2323
+ }
2324
+ return value;
2325
+ };
2326
+ // 若 value 不存在,则从 `dataset` 中获取值。key 需要自行转为驼峰法
2327
+ const dataAttr = (element, key, value) => {
2328
+ if (isUndefined(value) && element.nodeType === 1) {
2329
+ value = element.dataset[key];
2330
+ if (isString(value)) {
2331
+ try {
2332
+ value = stringTransform(value);
2333
+ }
2334
+ catch (e) { }
2335
+ }
2336
+ }
2337
+ return value;
2338
+ };
2339
+
2340
+ // eslint-disable-next-line
2341
+ $.fn.data = function (key, value) {
2342
+ // 获取所有值
2343
+ if (isUndefined(key)) {
2344
+ if (!this.length) {
2345
+ return undefined;
2346
+ }
2347
+ const element = this[0];
2348
+ const resultData = getAll(element);
2349
+ // window, document 上不存在 `dataset`
2350
+ if (element.nodeType !== 1) {
2351
+ return resultData;
2352
+ }
2353
+ // 若值未通过 data 方法设置,则从 `dataset` 中获取值。dataset 中读取的 key 会自动转为驼峰法
2354
+ eachObject(element.dataset, (key) => {
2355
+ resultData[key] = dataAttr(element, key, resultData[key]);
2356
+ });
2357
+ return resultData;
2358
+ }
2359
+ // 同时设置多个值
2360
+ if (isObjectLike(key)) {
2361
+ return this.each(function () {
2362
+ setAll(this, key);
2363
+ });
2364
+ }
2365
+ // value 传入了 undefined
2366
+ if (arguments.length === 2 && isUndefined(value)) {
2367
+ return this;
2368
+ }
2369
+ // 设置值
2370
+ if (!isUndefined(value)) {
2371
+ return this.each(function () {
2372
+ set$2(this, key, value);
2373
+ });
2374
+ }
2375
+ // 获取值
2376
+ if (!this.length) {
2377
+ return undefined;
2378
+ }
2379
+ return dataAttr(this[0], toCamelCase(key), get$2(this[0], key));
2380
+ };
2381
+
2382
+ // eslint-disable-next-line
2383
+ function each(target, callback) {
2384
+ // eachArray 回调函数是 value, key,这里的 each 函数是 key, value
2385
+ return isArrayLike(target)
2386
+ ? eachArray(target, (value, index) => {
2387
+ return callback.call(value, index, value);
2388
+ })
2389
+ : eachObject(target, callback);
2390
+ }
2391
+
2392
+ // eslint-disable-next-line
2393
+ function map(elements, callback) {
2394
+ const window = getWindow();
2395
+ let value;
2396
+ const ret = [];
2397
+ each(elements, (i, element) => {
2398
+ value = callback.call(window, element, i);
2399
+ if (value != null) {
2400
+ ret.push(value);
2401
+ }
2402
+ });
2403
+ return [].concat(...ret);
2404
+ }
2405
+
2406
+ // eslint-disable-next-line
2407
+ $.fn.map = function (callback) {
2408
+ return new JQ(map(this, (element, i) => {
2409
+ return callback.call(element, i, element);
2410
+ }));
2411
+ };
2412
+
2413
+ // eslint-disable-next-line
2414
+ $.fn.filter = function (selector) {
2415
+ if (isFunction(selector)) {
2416
+ return this.map((index, element) => {
2417
+ return selector.call(element, index, element) ? element : undefined;
2418
+ });
2419
+ }
2420
+ if (isString(selector)) {
2421
+ return this.map((_, element) => {
2422
+ return $(element).is(selector) ? element : undefined;
2423
+ });
2424
+ }
2425
+ const $selector = $(selector);
2426
+ return this.map((_, element) => {
2427
+ return $selector.get().includes(element) ? element : undefined;
2428
+ });
2429
+ };
2430
+
2431
+ /**
2432
+ * 值上面的 padding、border、margin 处理
2433
+ * @param element
2434
+ * @param name
2435
+ * @param value
2436
+ * @param funcIndex
2437
+ * @param includeMargin
2438
+ * @param multiply
2439
+ */
2440
+ const handleExtraWidth = (element, name, value, funcIndex, includeMargin, multiply) => {
2441
+ // 获取元素的 padding, border, margin 宽度(两侧宽度的和)
2442
+ const getExtraWidthValue = (extra) => {
2443
+ return (getExtraWidth(element, name.toLowerCase(), extra) *
2444
+ multiply);
2445
+ };
2446
+ if (funcIndex === 2 && includeMargin) {
2447
+ value += getExtraWidthValue('margin');
2448
+ }
2449
+ if (isBorderBox(element)) {
2450
+ if (funcIndex === 0) {
2451
+ value -= getExtraWidthValue('border');
2452
+ }
2453
+ if (funcIndex === 1) {
2454
+ value -= getExtraWidthValue('border');
2455
+ value -= getExtraWidthValue('padding');
2456
+ }
2457
+ }
2458
+ else {
2459
+ if (funcIndex === 0) {
2460
+ value += getExtraWidthValue('padding');
2461
+ }
2462
+ if (funcIndex === 2) {
2463
+ value += getExtraWidthValue('border');
2464
+ value += getExtraWidthValue('padding');
2465
+ }
2466
+ }
2467
+ return value;
2468
+ };
2469
+ /**
2470
+ * 获取元素的样式值
2471
+ * @param element
2472
+ * @param name
2473
+ * @param funcIndex 0: innerWidth, innerHeight; 1: width, height; 2: outerWidth, outerHeight
2474
+ * @param includeMargin
2475
+ */
2476
+ const get$1 = (element, name, funcIndex, includeMargin) => {
2477
+ const document = getDocument();
2478
+ const clientProp = `client${name}`;
2479
+ const scrollProp = `scroll${name}`;
2480
+ const offsetProp = `offset${name}`;
2481
+ const innerProp = `inner${name}`;
2482
+ // $(window).width()
2483
+ if (isWindow(element)) {
2484
+ // outerWidth, outerHeight 需要包含滚动条的宽度
2485
+ return funcIndex === 2
2486
+ ? element[innerProp]
2487
+ : toElement(document)[clientProp];
2488
+ }
2489
+ // $(document).width()
2490
+ if (isDocument(element)) {
2491
+ const doc = toElement(element);
2492
+ return Math.max(
2493
+ // @ts-ignore
2494
+ element.body[scrollProp], doc[scrollProp],
2495
+ // @ts-ignore
2496
+ element.body[offsetProp], doc[offsetProp], doc[clientProp]);
2497
+ }
2498
+ const value = parseFloat(getComputedStyleValue(element, name.toLowerCase()) || '0');
2499
+ return handleExtraWidth(element, name, value, funcIndex, includeMargin, 1);
2500
+ };
2501
+ /**
2502
+ * 设置元素的样式值
2503
+ * @param element
2504
+ * @param elementIndex
2505
+ * @param name
2506
+ * @param funcIndex 0: innerWidth, innerHeight; 1: width, height; 2: outerWidth, outerHeight
2507
+ * @param includeMargin
2508
+ * @param value
2509
+ */
2510
+ const set$1 = (element, elementIndex, name, funcIndex, includeMargin, value) => {
2511
+ let computedValue = isFunction(value)
2512
+ ? value.call(element, elementIndex, get$1(element, name, funcIndex, includeMargin))
2513
+ : value;
2514
+ if (computedValue == null) {
2515
+ return;
2516
+ }
2517
+ const $element = $(element);
2518
+ const dimension = name.toLowerCase();
2519
+ // 特殊的值,不需要计算 padding、border、margin
2520
+ if (isString(computedValue) &&
2521
+ ['auto', 'inherit', ''].includes(computedValue)) {
2522
+ $element.css(dimension, computedValue);
2523
+ return;
2524
+ }
2525
+ // 其他值保留原始单位。注意:如果不使用 px 作为单位,则算出的值一般是不准确的
2526
+ const suffix = computedValue.toString().replace(/\b[0-9.]*/, '');
2527
+ const numerical = parseFloat(computedValue);
2528
+ computedValue =
2529
+ handleExtraWidth(element, name, numerical, funcIndex, includeMargin, -1) +
2530
+ (suffix || 'px');
2531
+ $element.css(dimension, computedValue);
2532
+ };
2533
+ eachArray(['Width', 'Height'], (name) => {
2534
+ eachArray([`inner${name}`, name.toLowerCase(), `outer${name}`], (funcName, funcIndex) => {
2535
+ $.fn[funcName] = function (
2536
+ // eslint-disable-next-line
2537
+ margin,
2538
+ // eslint-disable-next-line
2539
+ value) {
2540
+ // 是否是赋值操作
2541
+ const isSet = arguments.length && (funcIndex < 2 || !isBoolean(margin));
2542
+ const includeMargin = margin === true || value === true;
2543
+ // 获取第一个元素的值
2544
+ if (!isSet) {
2545
+ return this.length
2546
+ ? get$1(this[0], name, funcIndex, includeMargin)
2547
+ : undefined;
2548
+ }
2549
+ // 设置每个元素的值
2550
+ return this.each((index, element) => {
2551
+ return set$1(element, index, name, funcIndex, includeMargin, margin);
2552
+ });
2553
+ };
2554
+ });
2555
+ });
2556
+
2557
+ /**
2558
+ * 返回最近的用于定位的父元素
2559
+ */
2560
+ $.fn.offsetParent = function () {
2561
+ const document = getDocument();
2562
+ return this.map(function () {
2563
+ let offsetParent = this.offsetParent;
2564
+ while (offsetParent && $(offsetParent).css('position') === 'static') {
2565
+ offsetParent = offsetParent.offsetParent;
2566
+ }
2567
+ return offsetParent || document.documentElement;
2568
+ });
2569
+ };
2570
+
2571
+ const floatStyle = ($element, name) => {
2572
+ return parseFloat($element.css(name));
2573
+ };
2574
+ // @ts-ignore
2575
+ $.fn.position = function () {
2576
+ if (!this.length) {
2577
+ return undefined;
2578
+ }
2579
+ const $element = this.eq(0);
2580
+ let currentOffset;
2581
+ let parentOffset = {
2582
+ left: 0,
2583
+ top: 0,
2584
+ };
2585
+ if ($element.css('position') === 'fixed') {
2586
+ currentOffset = $element[0].getBoundingClientRect();
2587
+ }
2588
+ else {
2589
+ currentOffset = $element.offset();
2590
+ const $offsetParent = $element.offsetParent();
2591
+ parentOffset = $offsetParent.offset();
2592
+ parentOffset.top += floatStyle($offsetParent, 'border-top-width');
2593
+ parentOffset.left += floatStyle($offsetParent, 'border-left-width');
2594
+ }
2595
+ return {
2596
+ top: currentOffset.top - parentOffset.top - floatStyle($element, 'margin-top'),
2597
+ left: currentOffset.left -
2598
+ parentOffset.left -
2599
+ floatStyle($element, 'margin-left'),
2600
+ };
2601
+ };
2602
+
2603
+ const get = (element) => {
2604
+ if (!element.getClientRects().length) {
2605
+ return { top: 0, left: 0 };
2606
+ }
2607
+ const { top, left } = element.getBoundingClientRect();
2608
+ const { pageYOffset, pageXOffset } = element.ownerDocument
2609
+ .defaultView;
2610
+ return {
2611
+ top: top + pageYOffset,
2612
+ left: left + pageXOffset,
2613
+ };
2614
+ };
2615
+ const set = (element, value, index) => {
2616
+ const $element = $(element);
2617
+ const position = $element.css('position');
2618
+ if (position === 'static') {
2619
+ $element.css('position', 'relative');
2620
+ }
2621
+ const currentOffset = get(element);
2622
+ const currentTopString = $element.css('top');
2623
+ const currentLeftString = $element.css('left');
2624
+ let currentTop;
2625
+ let currentLeft;
2626
+ const calculatePosition = (position === 'absolute' || position === 'fixed') &&
2627
+ (currentTopString + currentLeftString).includes('auto');
2628
+ if (calculatePosition) {
2629
+ const currentPosition = $element.position();
2630
+ currentTop = currentPosition.top;
2631
+ currentLeft = currentPosition.left;
2632
+ }
2633
+ else {
2634
+ currentTop = parseFloat(currentTopString);
2635
+ currentLeft = parseFloat(currentLeftString);
2636
+ }
2637
+ const computedValue = isFunction(value)
2638
+ ? value.call(element, index, extend({}, currentOffset))
2639
+ : value;
2640
+ $element.css({
2641
+ top: computedValue.top != null
2642
+ ? computedValue.top - currentOffset.top + currentTop
2643
+ : undefined,
2644
+ left: computedValue.left != null
2645
+ ? computedValue.left - currentOffset.left + currentLeft
2646
+ : undefined,
2647
+ });
2648
+ };
2649
+ // eslint-disable-next-line
2650
+ $.fn.offset = function (value) {
2651
+ // 获取坐标
2652
+ if (!arguments.length) {
2653
+ if (!this.length) {
2654
+ return undefined;
2655
+ }
2656
+ return get(this[0]);
2657
+ }
2658
+ // 设置坐标
2659
+ return this.each(function (index) {
2660
+ set(this, value, index);
2661
+ });
2662
+ };
2663
+
2664
+ $.fn.off = function (types,
2665
+ // eslint-disable-next-line
2666
+ selector,
2667
+ // eslint-disable-next-line
2668
+ callback) {
2669
+ // types 是对象
2670
+ if (isObjectLike(types)) {
2671
+ eachObject(types, (type, fn) => {
2672
+ // this.off('click', undefined, function () {})
2673
+ // this.off('click', '.box', function () {})
2674
+ this.off(type, selector, fn);
2675
+ });
2676
+ return this;
2677
+ }
2678
+ // selector 不存在
2679
+ if (selector === false || isFunction(selector)) {
2680
+ callback = selector;
2681
+ selector = undefined;
2682
+ // this.off('click', undefined, function () {})
2683
+ }
2684
+ // callback 传入 `false`,相当于 `return false`
2685
+ if (callback === false) {
2686
+ callback = returnFalse;
2687
+ }
2688
+ return this.each(function () {
2689
+ remove(this, types, callback, selector);
2690
+ });
2691
+ };
2692
+
2693
+ $.fn.on = function (
2694
+ // eslint-disable-next-line
2695
+ types,
2696
+ // eslint-disable-next-line
2697
+ selector,
2698
+ // eslint-disable-next-line
2699
+ data,
2700
+ // eslint-disable-next-line
2701
+ callback, one) {
2702
+ // types 可以是 type/func 对象
2703
+ if (isObjectLike(types)) {
2704
+ // (types-Object, selector, data)
2705
+ if (!isString(selector)) {
2706
+ // (types-Object, data)
2707
+ data = data || selector;
2708
+ selector = undefined;
2709
+ }
2710
+ eachObject(types, (type, fn) => {
2711
+ // selector 和 data 都可能是 undefined
2712
+ // @ts-ignore
2713
+ this.on(type, selector, data, fn, one);
2714
+ });
2715
+ return this;
2716
+ }
2717
+ if (data == null && callback == null) {
2718
+ // (types, fn)
2719
+ callback = selector;
2720
+ data = selector = undefined;
2721
+ }
2722
+ else if (callback == null) {
2723
+ if (isString(selector)) {
2724
+ // (types, selector, fn)
2725
+ callback = data;
2726
+ data = undefined;
2727
+ }
2728
+ else {
2729
+ // (types, data, fn)
2730
+ callback = data;
2731
+ data = selector;
2732
+ selector = undefined;
2733
+ }
2734
+ }
2735
+ if (callback === false) {
2736
+ callback = returnFalse;
2737
+ }
2738
+ else if (!callback) {
2739
+ return this;
2740
+ }
2741
+ // $().one()
2742
+ if (one) {
2743
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
2744
+ const _this = this;
2745
+ const origCallback = callback;
2746
+ callback = function (event, ...dataN) {
2747
+ _this.off(event.type, selector, callback);
2748
+ return origCallback.call(this, event, ...dataN);
2749
+ };
2750
+ }
2751
+ return this.each(function () {
2752
+ add(this, types, callback, data, selector);
2753
+ });
2754
+ };
2755
+
2756
+ eachArray(['insertBefore', 'insertAfter'], (name, nameIndex) => {
2757
+ // eslint-disable-next-line
2758
+ $.fn[name] = function (target) {
2759
+ const $element = nameIndex ? $(this.get().reverse()) : this; // 顺序和 jQuery 保持一致
2760
+ const $target = $(target);
2761
+ const result = [];
2762
+ $target.each((index, target) => {
2763
+ if (!target.parentNode) {
2764
+ return;
2765
+ }
2766
+ $element.each((_, element) => {
2767
+ const newItem = index
2768
+ ? element.cloneNode(true)
2769
+ : element;
2770
+ const existingItem = nameIndex ? target.nextSibling : target;
2771
+ result.push(newItem);
2772
+ target.parentNode.insertBefore(newItem, existingItem);
2773
+ });
2774
+ });
2775
+ return $(nameIndex ? result.reverse() : result);
2776
+ };
2777
+ });
2778
+
2779
+ $.fn.remove = function (selector) {
2780
+ return this.each((_, element) => {
2781
+ if (!selector || $(element).is(selector)) {
2782
+ removeChild(element);
2783
+ }
2784
+ });
2785
+ };
2786
+
2787
+ eachArray(['appendTo', 'prependTo'], (name, nameIndex) => {
2788
+ // eslint-disable-next-line
2789
+ $.fn[name] = function (target) {
2790
+ const extraChilds = [];
2791
+ const $target = $(target).map((_, element) => {
2792
+ const childNodes = element.childNodes;
2793
+ const childLength = childNodes.length;
2794
+ if (childLength) {
2795
+ return childNodes[nameIndex ? 0 : childLength - 1];
2796
+ }
2797
+ const child = createElement('div');
2798
+ appendChild(element, child);
2799
+ extraChilds.push(child);
2800
+ return child;
2801
+ });
2802
+ const $result = this[nameIndex ? 'insertBefore' : 'insertAfter']($target);
2803
+ $(extraChilds).remove();
2804
+ return $result;
2805
+ };
2806
+ });
2807
+
2808
+ const style = i$2 `:host{position:absolute;top:0;left:0;display:block;width:100%;height:100%;overflow:hidden;pointer-events:none}.surface{position:absolute;top:0;left:0;width:100%;height:100%;transition-duration:280ms;transition-property:background-color;pointer-events:none;transition-timing-function:var(--mdui-motion-easing-standard)}.hover{background-color:rgba(var(--mdui-comp-ripple-state-layer-color,var(--mdui-color-on-surface)),var(--mdui-state-layer-hover))}:host-context([focus-visible]) .focused{background-color:rgba(var(--mdui-comp-ripple-state-layer-color,var(--mdui-color-on-surface)),var(--mdui-state-layer-focus))}.dragged{background-color:rgba(var(--mdui-comp-ripple-state-layer-color,var(--mdui-color-on-surface)),var(--mdui-state-layer-dragged))}.wave{position:absolute;z-index:1;background-color:rgb(var(--mdui-comp-ripple-state-layer-color,var(--mdui-color-on-surface)));border-radius:50%;transform:translate3d(0,0,0) scale(.4);opacity:0;animation:225ms ease 0s 1 normal forwards running mdui-comp-ripple-radius-in,75ms ease 0s 1 normal forwards running mdui-comp-ripple-opacity-in;pointer-events:none}.out{transform:translate3d(var(--mdui-comp-ripple-transition-x,0),var(--mdui-comp-ripple-transition-y,0),0) scale(1);animation:150ms ease 0s 1 normal none running mdui-comp-ripple-opacity-out}@keyframes mdui-comp-ripple-radius-in{from{transform:translate3d(0,0,0) scale(.4);animation-timing-function:var(--mdui-motion-easing-standard)}to{transform:translate3d(var(--mdui-comp-ripple-transition-x,0),var(--mdui-comp-ripple-transition-y,0),0) scale(1)}}@keyframes mdui-comp-ripple-opacity-in{from{opacity:0;animation-timing-function:linear}to{opacity:var(--mdui-state-layer-pressed)}}@keyframes mdui-comp-ripple-opacity-out{from{animation-timing-function:linear;opacity:var(--mdui-state-layer-pressed)}to{opacity:0}}`;
2809
+
2810
+ /**
2811
+ * 处理点击时的涟漪动画;及添加 hover、focused、dragged 的背景色
2812
+ * 背景色通过在 .surface 元素上添加对应的 class 实现
2813
+ * 阴影在 ripple-mixin 中处理,通过在 :host 元素上添加 attribute 供 CSS 选择器添加样式
2814
+ */
2815
+ let Ripple = class Ripple extends MduiElement {
2816
+ constructor() {
2817
+ super(...arguments);
2818
+ /**
2819
+ * 是否禁用涟漪动画
2820
+ */
2821
+ this.noRipple = false;
2822
+ this.hover = false;
2823
+ this.focused = false;
2824
+ this.dragged = false;
2825
+ this.surfaceRef = ii();
2826
+ }
2827
+ startPress(event) {
2828
+ if (this.noRipple) {
2829
+ return;
2830
+ }
2831
+ const $surface = $(this.surfaceRef.value);
2832
+ const surfaceHeight = $surface.innerHeight();
2833
+ const surfaceWidth = $surface.innerWidth();
2834
+ // 点击位置坐标
2835
+ let touchStartX;
2836
+ let touchStartY;
2837
+ if (!event) {
2838
+ // 未传入事件对象,涟漪从中间扩散
2839
+ touchStartX = surfaceWidth / 2;
2840
+ touchStartY = surfaceHeight / 2;
2841
+ }
2842
+ else {
2843
+ // 传入了事件对象,涟漪从点击位置扩散
2844
+ const touchPosition = typeof TouchEvent !== 'undefined' &&
2845
+ event instanceof TouchEvent &&
2846
+ event.touches.length
2847
+ ? event.touches[0]
2848
+ : event;
2849
+ const offset = $surface.offset();
2850
+ // 点击位置不在 surface 内,不执行
2851
+ if (touchPosition.pageX < offset.left ||
2852
+ touchPosition.pageX > offset.left + surfaceWidth ||
2853
+ touchPosition.pageY < offset.top ||
2854
+ touchPosition.pageY > offset.top + surfaceHeight) {
2855
+ return;
2856
+ }
2857
+ touchStartX = touchPosition.pageX - offset.left;
2858
+ touchStartY = touchPosition.pageY - offset.top;
2859
+ }
2860
+ // 涟漪直径
2861
+ const diameter = Math.max(Math.pow(Math.pow(surfaceHeight, 2) + Math.pow(surfaceWidth, 2), 0.5), 48);
2862
+ // 涟漪扩散动画
2863
+ const translateX = `${-touchStartX + surfaceWidth / 2}px`;
2864
+ const translateY = `${-touchStartY + surfaceHeight / 2}px`;
2865
+ const translate = `translate3d(${translateX}, ${translateY}, 0) scale(1)`;
2866
+ // 涟漪 DOM 元素
2867
+ $('<div class="wave"></div>')
2868
+ .css({
2869
+ width: diameter,
2870
+ height: diameter,
2871
+ marginTop: -diameter / 2,
2872
+ marginLeft: -diameter / 2,
2873
+ left: touchStartX,
2874
+ top: touchStartY,
2875
+ })
2876
+ .each((_, wave) => {
2877
+ wave.style.setProperty('--mdui-comp-ripple-transition-x', translateX);
2878
+ wave.style.setProperty('--mdui-comp-ripple-transition-y', translateY);
2879
+ })
2880
+ .prependTo(this.surfaceRef.value)
2881
+ .each((_, wave) => wave.clientLeft) // 重绘
2882
+ .css('transform', translate)
2883
+ .on('animationend', function (e) {
2884
+ const event = e;
2885
+ if (event.animationName === 'mdui-comp-ripple-radius-in') {
2886
+ $(this).data('filled', true); // 扩散动画完成后,添加标记
2887
+ }
2888
+ });
2889
+ }
2890
+ endPress() {
2891
+ const $waves = $(this.surfaceRef.value)
2892
+ .children()
2893
+ .filter((_, wave) => !$(wave).data('removing'))
2894
+ .data('removing', true);
2895
+ const hideAndRemove = ($waves) => {
2896
+ $waves
2897
+ .addClass('out')
2898
+ .each((_, wave) => wave.clientLeft) // 重绘
2899
+ .on('animationend', function () {
2900
+ $(this).remove();
2901
+ });
2902
+ };
2903
+ // 扩散动画未完成,先完成扩散,再隐藏并移除
2904
+ $waves
2905
+ .filter((_, wave) => !$(wave).data('filled'))
2906
+ .on('animationend', function (e) {
2907
+ const event = e;
2908
+ if (event.animationName === 'mdui-comp-ripple-radius-in') {
2909
+ hideAndRemove($(this));
2910
+ }
2911
+ });
2912
+ // 扩散动画已完成,直接隐藏并移除
2913
+ hideAndRemove($waves.filter((_, wave) => !!$(wave).data('filled')));
2914
+ }
2915
+ startHover() {
2916
+ this.hover = true;
2917
+ }
2918
+ endHover() {
2919
+ this.hover = false;
2920
+ }
2921
+ startFocus() {
2922
+ this.focused = true;
2923
+ }
2924
+ endFocus() {
2925
+ this.focused = false;
2926
+ }
2927
+ startDrag() {
2928
+ this.dragged = true;
2929
+ }
2930
+ endDrag() {
2931
+ this.dragged = false;
2932
+ }
2933
+ render() {
2934
+ return ke `<div ${Kt(this.surfaceRef)} class="surface ${Rt({
2935
+ hover: this.hover,
2936
+ focused: this.focused,
2937
+ dragged: this.dragged,
2938
+ })}"></div>`;
2939
+ }
2940
+ };
2941
+ Ripple.styles = [componentStyle, style];
2942
+ __decorate([
2943
+ n({
2944
+ type: Boolean,
2945
+ reflect: true,
2946
+ converter: booleanConverter,
2947
+ attribute: 'no-ripple',
2948
+ })
2949
+ ], Ripple.prototype, "noRipple", void 0);
2950
+ __decorate([
2951
+ r()
2952
+ ], Ripple.prototype, "hover", void 0);
2953
+ __decorate([
2954
+ r()
2955
+ ], Ripple.prototype, "focused", void 0);
2956
+ __decorate([
2957
+ r()
2958
+ ], Ripple.prototype, "dragged", void 0);
2959
+ Ripple = __decorate([
2960
+ t$1('mdui-ripple')
2961
+ ], Ripple);
2962
+
2963
+ /**
2964
+ * hover, pressed, dragged 三个属性用于添加到 rippleTarget 属性指定的元素上,供 CSS 选择题添加样式
2965
+ *
2966
+ * TODO: dragged 功能
2967
+ *
2968
+ * NOTE:
2969
+ * 不支持触控的屏幕上事件顺序为:pointerdown -> (8ms) -> mousedown -> pointerup -> (1ms) -> mouseup -> (1ms) -> click
2970
+ *
2971
+ * 支持触控的屏幕上事件顺序为:pointerdown -> (8ms) -> touchstart -> pointerup -> (1ms) -> touchend -> (5ms) -> mousedown -> mouseup -> click
2972
+ * pointermove 比较灵敏,有可能触发了 pointermove 但没有触发 touchmove
2973
+ *
2974
+ * 支持触摸笔的屏幕上事件顺序为:todo
2975
+ */
2976
+ const RippleMixin = (superclass) => {
2977
+ class Mixin extends superclass {
2978
+ constructor() {
2979
+ super(...arguments);
2980
+ /**
2981
+ * 是否禁用涟漪动画
2982
+ */
2983
+ this.noRipple = false;
2984
+ /**
2985
+ * 当前激活的是第几个 <mdui-ripple>。仅一个组件中有多个 <mdui-ripple> 时可以使用该属性
2986
+ * 若值为 undefined,则组件中所有 <mdui-ripple> 都激活
2987
+ */
2988
+ this.rippleIndex = undefined;
2989
+ /**
2990
+ * 获取当前激活的是第几个 <mdui-ripple>。仅一个组件中有多个 <mdui-ripple> 时可以使用该属性
2991
+ * 若值为 undefined,则组件中所有 <mdui-ripple> 都激活
2992
+ * 可在子类中手动指定该方法,指定需要激活的 ripple
2993
+ */
2994
+ this.getRippleIndex = () => this.rippleIndex;
2995
+ }
2996
+ /**
2997
+ * 子类要添加该属性,指向 <mdui-ripple> 元素
2998
+ * 如果一个组件中包含多个 <mdui-ripple> 元素,则这里可以是一个数组或 NodeList
2999
+ */
3000
+ get rippleElement() {
3001
+ throw new Error('Must implement rippleElement getter!');
3002
+ }
3003
+ /**
3004
+ * 子类要实现该属性,表示是否禁用 ripple
3005
+ * 如果一个组件中包含多个 <mdui-ripple> 元素,则这里可以是一个数组;也可以是单个值,同时控制多个 <mdui-ripple> 元素
3006
+ */
3007
+ get rippleDisabled() {
3008
+ throw new Error('Must implement rippleDisabled getter!');
3009
+ }
3010
+ /**
3011
+ * 当前 <mdui-ripple> 元素相对于哪个元素存在,即 hover、pressed、dragged 属性要添加到哪个元素上,默认为 :host
3012
+ * 如果需要修改该属性,则子类可以实现该属性
3013
+ * 如果一个组件中包含多个 <mdui-ripple> 元素,则这里可以是一个数组;也可以是单个值,同时控制多个 <mdui-ripple> 元素
3014
+ */
3015
+ get rippleTarget() {
3016
+ return this;
3017
+ }
3018
+ firstUpdated(changedProperties) {
3019
+ super.firstUpdated(changedProperties);
3020
+ const $rippleTarget = $(this.rippleTarget);
3021
+ // 监听到事件时,是在第几个 <mdui-ripple> 上触发的事件,记录到 this.rippleIndex 中
3022
+ const setRippleIndex = (event) => {
3023
+ if (isArrayLike(this.rippleTarget)) {
3024
+ this.rippleIndex = $rippleTarget.index(event.target);
3025
+ }
3026
+ };
3027
+ const rippleTargetArr = isArrayLike(this.rippleTarget)
3028
+ ? this.rippleTarget
3029
+ : [this.rippleTarget];
3030
+ rippleTargetArr.forEach((rippleTarget) => {
3031
+ rippleTarget.addEventListener('pointerdown', (event) => {
3032
+ setRippleIndex(event);
3033
+ this.startPress(event);
3034
+ });
3035
+ rippleTarget.addEventListener('pointerenter', (event) => {
3036
+ setRippleIndex(event);
3037
+ this.startHover(event);
3038
+ });
3039
+ rippleTarget.addEventListener('pointerleave', (event) => {
3040
+ setRippleIndex(event);
3041
+ this.endHover(event);
3042
+ });
3043
+ rippleTarget.addEventListener('focus', (event) => {
3044
+ setRippleIndex(event);
3045
+ this.startFocus();
3046
+ });
3047
+ rippleTarget.addEventListener('blur', (event) => {
3048
+ setRippleIndex(event);
3049
+ this.endFocus();
3050
+ });
3051
+ });
3052
+ }
3053
+ /**
3054
+ * 若存在多个 <mdui-ripple>,但 rippleTarget 为同一个,则 hover 状态无法在多个 <mdui-ripple> 之间切换
3055
+ * 所以把 startHover 和 endHover 设置为 protected,供子类调用
3056
+ * 子类中,在 getRippleIndex() 的返回值变更前调用 endHover(event),变更后调用 startHover(event)
3057
+ */
3058
+ startHover(event) {
3059
+ if (event.pointerType !== 'mouse' || this.isRippleDisabled()) {
3060
+ return;
3061
+ }
3062
+ this.getRippleTarget().setAttribute('hover', '');
3063
+ this.getRippleElement().startHover();
3064
+ }
3065
+ endHover(event) {
3066
+ if (event.pointerType !== 'mouse' || this.isRippleDisabled()) {
3067
+ return;
3068
+ }
3069
+ this.getRippleTarget().removeAttribute('hover');
3070
+ this.getRippleElement().endHover();
3071
+ }
3072
+ /**
3073
+ * 当前激活的 <mdui-ripple> 元素是否被禁用
3074
+ */
3075
+ isRippleDisabled() {
3076
+ const disabled = this.rippleDisabled;
3077
+ if (!Array.isArray(disabled)) {
3078
+ return disabled;
3079
+ }
3080
+ const rippleIndex = this.getRippleIndex();
3081
+ if (rippleIndex !== undefined) {
3082
+ return disabled[rippleIndex];
3083
+ }
3084
+ return disabled.length ? disabled[0] : false;
3085
+ }
3086
+ /**
3087
+ * 获取当前激活的 <mdui-ripple> 元素实例
3088
+ */
3089
+ getRippleElement() {
3090
+ const ripple = this.rippleElement;
3091
+ if (!isArrayLike(ripple)) {
3092
+ return ripple;
3093
+ }
3094
+ const rippleIndex = this.getRippleIndex();
3095
+ if (rippleIndex !== undefined) {
3096
+ return ripple[rippleIndex];
3097
+ }
3098
+ return ripple[0];
3099
+ }
3100
+ /**
3101
+ * 获取当前激活的 <mdui-ripple> 元素相对于哪个元素存在
3102
+ */
3103
+ getRippleTarget() {
3104
+ const target = this.rippleTarget;
3105
+ if (!isArrayLike(target)) {
3106
+ return target;
3107
+ }
3108
+ const rippleIndex = this.getRippleIndex();
3109
+ if (rippleIndex !== undefined) {
3110
+ return target[rippleIndex];
3111
+ }
3112
+ return target[0];
3113
+ }
3114
+ startFocus() {
3115
+ if (this.isRippleDisabled()) {
3116
+ return;
3117
+ }
3118
+ this.getRippleElement().startFocus();
3119
+ }
3120
+ endFocus() {
3121
+ if (this.isRippleDisabled()) {
3122
+ return;
3123
+ }
3124
+ this.getRippleElement().endFocus();
3125
+ }
3126
+ startPress(event) {
3127
+ // 为鼠标时操作,仅响应鼠标左键点击
3128
+ if (this.isRippleDisabled() || event.button) {
3129
+ return;
3130
+ }
3131
+ const target = this.getRippleTarget();
3132
+ target.setAttribute('pressed', '');
3133
+ // 手指触摸触发涟漪
3134
+ if (['touch', 'pen'].includes(event.pointerType)) {
3135
+ let hidden = false;
3136
+ // 手指触摸后,延迟一段时间触发涟漪,避免手指滑动时也触发涟漪
3137
+ let timer = setTimeout(() => {
3138
+ timer = 0;
3139
+ this.getRippleElement().startPress(event);
3140
+ }, 70);
3141
+ const hideRipple = () => {
3142
+ // 如果手指没有移动,且涟漪动画还没有开始,则开始涟漪动画
3143
+ if (timer) {
3144
+ clearTimeout(timer);
3145
+ timer = 0;
3146
+ this.getRippleElement().startPress(event);
3147
+ }
3148
+ if (!hidden) {
3149
+ hidden = true;
3150
+ this.endPress();
3151
+ }
3152
+ target.removeEventListener('pointerup', hideRipple);
3153
+ target.removeEventListener('pointercancel', hideRipple);
3154
+ };
3155
+ // 手指移动后,移除涟漪动画
3156
+ const touchMove = () => {
3157
+ if (timer) {
3158
+ clearTimeout(timer);
3159
+ timer = 0;
3160
+ }
3161
+ target.removeEventListener('touchmove', touchMove);
3162
+ };
3163
+ // pointermove 事件过于灵敏,可能在未触发 touchmove 的情况下,触发了 pointermove 事件,导致正常的点击操作没有显示涟漪
3164
+ // 因此这里监听 touchmove 事件
3165
+ target.addEventListener('touchmove', touchMove);
3166
+ target.addEventListener('pointerup', hideRipple);
3167
+ target.addEventListener('pointercancel', hideRipple);
3168
+ }
3169
+ // 鼠标点击触发涟漪,点击后立即触发涟漪(仅鼠标左键能触发涟漪)
3170
+ if (event.pointerType === 'mouse' && event.button === 0) {
3171
+ const hideRipple = () => {
3172
+ this.endPress();
3173
+ target.removeEventListener('pointerup', hideRipple);
3174
+ target.removeEventListener('pointercancel', hideRipple);
3175
+ target.removeEventListener('pointerleave', hideRipple);
3176
+ };
3177
+ this.getRippleElement().startPress(event);
3178
+ target.addEventListener('pointerup', hideRipple);
3179
+ target.addEventListener('pointercancel', hideRipple);
3180
+ target.addEventListener('pointerleave', hideRipple);
3181
+ }
3182
+ }
3183
+ endPress() {
3184
+ if (this.isRippleDisabled()) {
3185
+ return;
3186
+ }
3187
+ this.getRippleTarget().removeAttribute('pressed');
3188
+ this.getRippleElement().endPress();
3189
+ }
3190
+ startDrag() {
3191
+ if (this.isRippleDisabled()) {
3192
+ return;
3193
+ }
3194
+ this.getRippleElement().startDrag();
3195
+ }
3196
+ endDrag() {
3197
+ if (this.isRippleDisabled()) {
3198
+ return;
3199
+ }
3200
+ this.getRippleElement().endDrag();
3201
+ }
3202
+ }
3203
+ __decorate([
3204
+ n({
3205
+ type: Boolean,
3206
+ reflect: true,
3207
+ converter: booleanConverter,
3208
+ attribute: 'no-ripple',
3209
+ })
3210
+ ], Mixin.prototype, "noRipple", void 0);
3211
+ return Mixin;
3212
+ };
3213
+
3214
+ const buttonBaseStyle = i$2 `.button{position:relative;display:inline-flex;align-items:center;justify-content:center;height:100%;padding:0;overflow:hidden;color:inherit;font-size:inherit;font-family:inherit;font-weight:inherit;letter-spacing:inherit;white-space:nowrap;text-align:center;text-decoration:none;vertical-align:middle;background:0 0;border:none;outline:0;cursor:inherit;-webkit-user-select:none;user-select:none;touch-action:manipulation;zoom:1;-webkit-user-drag:none}`;
3215
+
3216
+ class ButtonBase extends AnchorMixin(RippleMixin(FocusableMixin(MduiElement))) {
3217
+ constructor() {
3218
+ super(...arguments);
3219
+ /**
3220
+ * 是否禁用
3221
+ */
3222
+ this.disabled = false;
3223
+ /**
3224
+ * 是否处于加载中状态
3225
+ */
3226
+ this.loading = false;
3227
+ /**
3228
+ * 按钮的名称,将与表单数据一起提交。
3229
+ *
3230
+ * **Note**:仅在未设置 `href` 属性时,此属性才有效。
3231
+ */
3232
+ this.name = '';
3233
+ /**
3234
+ * 按钮的初始值,将与表单数据一起提交。
3235
+ *
3236
+ * **Note**:仅在未设置 `href` 属性时,此属性才有效。
3237
+ */
3238
+ this.value = '';
3239
+ /**
3240
+ * 按钮的类型。默认类型为 `button`。可选类型包括:
3241
+ *
3242
+ * * `submit`:点击按钮会提交表单数据到服务器
3243
+ * * `reset`:点击按钮会将表单中的所有字段重置为初始值
3244
+ * * `button`:此类型的按钮没有默认行为
3245
+ *
3246
+ * **Note**:仅在未指定 `href` 属性时,此属性才有效。
3247
+ */
3248
+ this.type = 'button';
3249
+ /**
3250
+ * 如果设置了此属性,表单提交时将不执行表单验证。
3251
+ *
3252
+ * 如果设置了此属性,将覆盖 `<form>` 元素的 `novalidate` 属性。
3253
+ *
3254
+ * **Note**:仅在未设置 `href` 属性且 `type="submit"` 时,此属性才有效。
3255
+ */
3256
+ this.formNoValidate = false;
3257
+ this.formController = new FormController(this);
3258
+ }
3259
+ /**
3260
+ * 表单验证状态对象,具体参见 [`ValidityState`](https://developer.mozilla.org/zh-CN/docs/Web/API/ValidityState)
3261
+ */
3262
+ get validity() {
3263
+ if (this.isButton()) {
3264
+ return this.focusElement.validity;
3265
+ }
3266
+ }
3267
+ /**
3268
+ * 如果表单验证未通过,此属性将包含提示信息。如果验证通过,此属性将为空字符串
3269
+ */
3270
+ get validationMessage() {
3271
+ if (this.isButton()) {
3272
+ return this.focusElement.validationMessage;
3273
+ }
3274
+ }
3275
+ get rippleDisabled() {
3276
+ return this.disabled || this.loading;
3277
+ }
3278
+ get focusElement() {
3279
+ return this.isButton()
3280
+ ? this.renderRoot?.querySelector('._button')
3281
+ : !this.focusDisabled
3282
+ ? this.renderRoot?.querySelector('._a')
3283
+ : this;
3284
+ }
3285
+ get focusDisabled() {
3286
+ return this.disabled || this.loading;
3287
+ }
3288
+ /**
3289
+ * 检查表单字段是否通过验证。如果未通过,返回 `false` 并触发 `invalid` 事件;如果通过,返回 `true`
3290
+ */
3291
+ checkValidity() {
3292
+ if (this.isButton()) {
3293
+ const valid = this.focusElement.checkValidity();
3294
+ if (!valid) {
3295
+ // @ts-ignore
3296
+ this.emit('invalid', {
3297
+ bubbles: false,
3298
+ cancelable: true,
3299
+ composed: false,
3300
+ });
3301
+ }
3302
+ return valid;
3303
+ }
3304
+ return true;
3305
+ }
3306
+ /**
3307
+ * 检查表单字段是否通过验证。如果未通过,返回 `false` 并触发 `invalid` 事件;如果通过,返回 `true`。
3308
+ *
3309
+ * 如果验证未通过,还会在组件上显示验证失败的提示。
3310
+ */
3311
+ reportValidity() {
3312
+ if (this.isButton()) {
3313
+ const invalid = !this.focusElement.reportValidity();
3314
+ if (invalid) {
3315
+ // @ts-ignore
3316
+ this.emit('invalid', {
3317
+ bubbles: false,
3318
+ cancelable: true,
3319
+ composed: false,
3320
+ });
3321
+ // todo 考虑是否要支持 preventDefault() 方法,当前 invalid 状态没有样式
3322
+ }
3323
+ return !invalid;
3324
+ }
3325
+ return true;
3326
+ }
3327
+ /**
3328
+ * 设置自定义的错误提示文本。只要这个文本不为空,就表示字段未通过验证
3329
+ *
3330
+ * @param message 自定义的错误提示文本
3331
+ */
3332
+ setCustomValidity(message) {
3333
+ if (this.isButton()) {
3334
+ this.focusElement.setCustomValidity(message);
3335
+ }
3336
+ }
3337
+ firstUpdated(_changedProperties) {
3338
+ super.firstUpdated(_changedProperties);
3339
+ this.addEventListener('click', () => {
3340
+ if (this.type === 'submit') {
3341
+ this.formController.submit(this);
3342
+ }
3343
+ if (this.type === 'reset') {
3344
+ this.formController.reset(this);
3345
+ }
3346
+ });
3347
+ }
3348
+ renderLoading() {
3349
+ return this.loading
3350
+ ? ke `<mdui-circular-progress part="loading"></mdui-circular-progress>`
3351
+ : nothingTemplate;
3352
+ }
3353
+ renderButton({ id, className, part, content = ke `<slot></slot>`, }) {
3354
+ return ke `<button id="${to(id)}" class="${cc(['_button', className])}" part="${to(part)}" ?disabled="${this.rippleDisabled || this.focusDisabled}">${content}</button>`;
3355
+ }
3356
+ isButton() {
3357
+ return !this.href;
3358
+ }
3359
+ }
3360
+ ButtonBase.styles = [
3361
+ componentStyle,
3362
+ buttonBaseStyle,
3363
+ ];
3364
+ __decorate([
3365
+ n({
3366
+ type: Boolean,
3367
+ reflect: true,
3368
+ converter: booleanConverter,
3369
+ })
3370
+ ], ButtonBase.prototype, "disabled", void 0);
3371
+ __decorate([
3372
+ n({
3373
+ type: Boolean,
3374
+ reflect: true,
3375
+ converter: booleanConverter,
3376
+ })
3377
+ ], ButtonBase.prototype, "loading", void 0);
3378
+ __decorate([
3379
+ n({ reflect: true })
3380
+ ], ButtonBase.prototype, "name", void 0);
3381
+ __decorate([
3382
+ n({ reflect: true })
3383
+ ], ButtonBase.prototype, "value", void 0);
3384
+ __decorate([
3385
+ n({ reflect: true })
3386
+ ], ButtonBase.prototype, "type", void 0);
3387
+ __decorate([
3388
+ n({ reflect: true })
3389
+ ], ButtonBase.prototype, "form", void 0);
3390
+ __decorate([
3391
+ n({ reflect: true, attribute: 'formaction' })
3392
+ ], ButtonBase.prototype, "formAction", void 0);
3393
+ __decorate([
3394
+ n({ reflect: true, attribute: 'formenctype' })
3395
+ ], ButtonBase.prototype, "formEnctype", void 0);
3396
+ __decorate([
3397
+ n({ reflect: true, attribute: 'formmethod' })
3398
+ ], ButtonBase.prototype, "formMethod", void 0);
3399
+ __decorate([
3400
+ n({
3401
+ type: Boolean,
3402
+ reflect: true,
3403
+ converter: booleanConverter,
3404
+ attribute: 'formnovalidate',
3405
+ })
3406
+ ], ButtonBase.prototype, "formNoValidate", void 0);
3407
+ __decorate([
3408
+ n({ reflect: true, attribute: 'formtarget' })
3409
+ ], ButtonBase.prototype, "formTarget", void 0);
3410
+
3411
+ exports.ButtonBase = ButtonBase;
3412
+ exports.HasSlotController = HasSlotController;
3413
+ exports.Kt = Kt;
3414
+ exports.__decorate = __decorate;
3415
+ exports.booleanConverter = booleanConverter;
3416
+ exports.i = i$2;
3417
+ exports.ii = ii;
3418
+ exports.ke = ke;
3419
+ exports.n = n;
3420
+ exports.nothingTemplate = nothingTemplate;
3421
+ exports.t = t$1;
3422
+
3423
+ //# sourceMappingURL=button-base-f4219018.js.map