@everymatrix/helper-filters 0.1.23 → 1.13.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/helper-filters_2.cjs.entry.js +1680 -986
- package/dist/collection/components/helper-filters/helper-filters.js +2 -0
- package/dist/components/helper-filters.js +1680 -986
- package/dist/esm/helper-filters_2.entry.js +1680 -986
- package/dist/helper-filters/helper-filters.esm.js +1 -1
- package/dist/helper-filters/{p-13c0b3c4.entry.js → p-144654ad.entry.js} +148 -172
- package/package.json +1 -1
- /package/dist/types/Users/{dragos.bodea/Documents/everymatrix-prjs → adrian.pripon/Documents/Work}/stencil/widgets-stencil/packages/helper-filters/.stencil/packages/helper-filters/stencil.config.d.ts +0 -0
|
@@ -65,9 +65,16 @@ const translate$1 = (key, customLang) => {
|
|
|
65
65
|
* Copyright (c) 2017 - 2022 Vaadin Ltd.
|
|
66
66
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
67
67
|
*/
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Dummy custom element used for collecting
|
|
71
|
+
* development time usage statistics.
|
|
72
|
+
*
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
68
75
|
class Lumo extends HTMLElement {
|
|
69
76
|
static get version() {
|
|
70
|
-
return '23.
|
|
77
|
+
return '23.3.14';
|
|
71
78
|
}
|
|
72
79
|
}
|
|
73
80
|
|
|
@@ -84,20 +91,20 @@ const t$1=window,e$2=t$1.ShadowRoot&&(void 0===t$1.ShadyCSS||t$1.ShadyCSS.native
|
|
|
84
91
|
* @license
|
|
85
92
|
* Copyright 2017 Google LLC
|
|
86
93
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
87
|
-
*/var s$2;const e$1=window,r$1=e$1.trustedTypes,h$1=r$1?r$1.emptyScript:"",o$2=e$1.reactiveElementPolyfillSupport,n$2={toAttribute(t,i){switch(i){case Boolean:t=t?h$1:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t);}return t},fromAttribute(t,i){let s=t;switch(i){case Boolean:s=null!==t;break;case Number:s=null===t?null:Number(t);break;case Object:case Array:try{s=JSON.parse(t);}catch(t){s=null;}}return s}},a$1=(t,i)=>i!==t&&(i==i||t==t),l$2={attribute:!0,type:String,converter:n$2,reflect:!1,hasChanged:a$1};class d$1 extends HTMLElement{constructor(){super(),this._$Ei=new Map,this.isUpdatePending=!1,this.hasUpdated=!1,this._$El=null,this.u();}static addInitializer(t){var i;null!==(i=this.h)&&void 0!==i
|
|
94
|
+
*/var s$2;const e$1=window,r$1=e$1.trustedTypes,h$1=r$1?r$1.emptyScript:"",o$2=e$1.reactiveElementPolyfillSupport,n$2={toAttribute(t,i){switch(i){case Boolean:t=t?h$1:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t);}return t},fromAttribute(t,i){let s=t;switch(i){case Boolean:s=null!==t;break;case Number:s=null===t?null:Number(t);break;case Object:case Array:try{s=JSON.parse(t);}catch(t){s=null;}}return s}},a$1=(t,i)=>i!==t&&(i==i||t==t),l$2={attribute:!0,type:String,converter:n$2,reflect:!1,hasChanged:a$1};class d$1 extends HTMLElement{constructor(){super(),this._$Ei=new Map,this.isUpdatePending=!1,this.hasUpdated=!1,this._$El=null,this.u();}static addInitializer(t){var i;this.finalize(),(null!==(i=this.h)&&void 0!==i?i:this.h=[]).push(t);}static get observedAttributes(){this.finalize();const t=[];return this.elementProperties.forEach(((i,s)=>{const e=this._$Ep(s,i);void 0!==e&&(this._$Ev.set(e,s),t.push(e));})),t}static createProperty(t,i=l$2){if(i.state&&(i.attribute=!1),this.finalize(),this.elementProperties.set(t,i),!i.noAccessor&&!this.prototype.hasOwnProperty(t)){const s="symbol"==typeof t?Symbol():"__"+t,e=this.getPropertyDescriptor(t,s,i);void 0!==e&&Object.defineProperty(this.prototype,t,e);}}static getPropertyDescriptor(t,i,s){return {get(){return this[i]},set(e){const r=this[t];this[i]=e,this.requestUpdate(t,r,s);},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)||l$2}static finalize(){if(this.hasOwnProperty("finalized"))return !1;this.finalized=!0;const t=Object.getPrototypeOf(this);if(t.finalize(),void 0!==t.h&&(this.h=[...t.h]),this.elementProperties=new Map(t.elementProperties),this._$Ev=new Map,this.hasOwnProperty("properties")){const t=this.properties,i=[...Object.getOwnPropertyNames(t),...Object.getOwnPropertySymbols(t)];for(const s of i)this.createProperty(s,t[s]);}return this.elementStyles=this.finalizeStyles(this.styles),!0}static finalizeStyles(i){const s=[];if(Array.isArray(i)){const e=new Set(i.flat(1/0).reverse());for(const i of e)s.unshift(c$1(i));}else void 0!==i&&s.push(c$1(i));return s}static _$Ep(t,i){const s=i.attribute;return !1===s?void 0:"string"==typeof s?s:"string"==typeof t?t.toLowerCase():void 0}u(){var t;this._$E_=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$Eg(),this.requestUpdate(),null===(t=this.constructor.h)||void 0===t||t.forEach((t=>t(this)));}addController(t){var i,s;(null!==(i=this._$ES)&&void 0!==i?i:this._$ES=[]).push(t),void 0!==this.renderRoot&&this.isConnected&&(null===(s=t.hostConnected)||void 0===s||s.call(t));}removeController(t){var i;null===(i=this._$ES)||void 0===i||i.splice(this._$ES.indexOf(t)>>>0,1);}_$Eg(){this.constructor.elementProperties.forEach(((t,i)=>{this.hasOwnProperty(i)&&(this._$Ei.set(i,this[i]),delete this[i]);}));}createRenderRoot(){var t;const s=null!==(t=this.shadowRoot)&&void 0!==t?t:this.attachShadow(this.constructor.shadowRootOptions);return S$1(s,this.constructor.elementStyles),s}connectedCallback(){var t;void 0===this.renderRoot&&(this.renderRoot=this.createRenderRoot()),this.enableUpdating(!0),null===(t=this._$ES)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostConnected)||void 0===i?void 0:i.call(t)}));}enableUpdating(t){}disconnectedCallback(){var t;null===(t=this._$ES)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostDisconnected)||void 0===i?void 0:i.call(t)}));}attributeChangedCallback(t,i,s){this._$AK(t,s);}_$EO(t,i,s=l$2){var e;const r=this.constructor._$Ep(t,s);if(void 0!==r&&!0===s.reflect){const h=(void 0!==(null===(e=s.converter)||void 0===e?void 0:e.toAttribute)?s.converter:n$2).toAttribute(i,s.type);this._$El=t,null==h?this.removeAttribute(r):this.setAttribute(r,h),this._$El=null;}}_$AK(t,i){var s;const e=this.constructor,r=e._$Ev.get(t);if(void 0!==r&&this._$El!==r){const t=e.getPropertyOptions(r),h="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==(null===(s=t.converter)||void 0===s?void 0:s.fromAttribute)?t.converter:n$2;this._$El=r,this[r]=h.fromAttribute(i,t.type),this._$El=null;}}requestUpdate(t,i,s){let e=!0;void 0!==t&&(((s=s||this.constructor.getPropertyOptions(t)).hasChanged||a$1)(this[t],i)?(this._$AL.has(t)||this._$AL.set(t,i),!0===s.reflect&&this._$El!==t&&(void 0===this._$EC&&(this._$EC=new Map),this._$EC.set(t,s))):e=!1),!this.isUpdatePending&&e&&(this._$E_=this._$Ej());}async _$Ej(){this.isUpdatePending=!0;try{await this._$E_;}catch(t){Promise.reject(t);}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){var t;if(!this.isUpdatePending)return;this._$Ei&&(this._$Ei.forEach(((t,i)=>this[i]=t)),this._$Ei=void 0);let i=!1;const s=this._$AL;try{i=this.shouldUpdate(s),i?(this.willUpdate(s),null===(t=this._$ES)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostUpdate)||void 0===i?void 0:i.call(t)})),this.update(s)):this._$Ek();}catch(t){throw i=!1,this._$Ek(),t}i&&this._$AE(s);}willUpdate(t){}_$AE(t){var i;null===(i=this._$ES)||void 0===i||i.forEach((t=>{var i;return null===(i=t.hostUpdated)||void 0===i?void 0:i.call(t)})),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t);}_$Ek(){this._$AL=new Map,this.isUpdatePending=!1;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$E_}shouldUpdate(t){return !0}update(t){void 0!==this._$EC&&(this._$EC.forEach(((t,i)=>this._$EO(i,this[i],t))),this._$EC=void 0),this._$Ek();}updated(t){}firstUpdated(t){}}d$1.finalized=!0,d$1.elementProperties=new Map,d$1.elementStyles=[],d$1.shadowRootOptions={mode:"open"},null==o$2||o$2({ReactiveElement:d$1}),(null!==(s$2=e$1.reactiveElementVersions)&&void 0!==s$2?s$2:e$1.reactiveElementVersions=[]).push("1.6.1");
|
|
88
95
|
|
|
89
96
|
/**
|
|
90
97
|
* @license
|
|
91
98
|
* Copyright 2017 Google LLC
|
|
92
99
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
93
100
|
*/
|
|
94
|
-
var t;const i=window,s$1=i.trustedTypes,e=s$1?s$1.createPolicy("lit-html",{createHTML:t=>t}):void 0,o$1=`lit$${(Math.random()+"").slice(9)}$`,
|
|
101
|
+
var t;const i=window,s$1=i.trustedTypes,e=s$1?s$1.createPolicy("lit-html",{createHTML:t=>t}):void 0,o$1="$lit$",n$1=`lit$${(Math.random()+"").slice(9)}$`,l$1="?"+n$1,h=`<${l$1}>`,r=document,d=()=>r.createComment(""),u=t=>null===t||"object"!=typeof t&&"function"!=typeof t,c=Array.isArray,v=t=>c(t)||"function"==typeof(null==t?void 0:t[Symbol.iterator]),a="[ \t\n\f\r]",f=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,_=/-->/g,m=/>/g,p=RegExp(`>|${a}(?:([^\\s"'>=/]+)(${a}*=${a}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),g=/'/g,$=/"/g,y=/^(?:script|style|textarea|title)$/i,T=Symbol.for("lit-noChange"),A=Symbol.for("lit-nothing"),E=new WeakMap,C=r.createTreeWalker(r,129,null,!1),P=(t,i)=>{const s=t.length-1,l=[];let r,d=2===i?"<svg>":"",u=f;for(let i=0;i<s;i++){const s=t[i];let e,c,v=-1,a=0;for(;a<s.length&&(u.lastIndex=a,c=u.exec(s),null!==c);)a=u.lastIndex,u===f?"!--"===c[1]?u=_:void 0!==c[1]?u=m:void 0!==c[2]?(y.test(c[2])&&(r=RegExp("</"+c[2],"g")),u=p):void 0!==c[3]&&(u=p):u===p?">"===c[0]?(u=null!=r?r:f,v=-1):void 0===c[1]?v=-2:(v=u.lastIndex-c[2].length,e=c[1],u=void 0===c[3]?p:'"'===c[3]?$:g):u===$||u===g?u=p:u===_||u===m?u=f:(u=p,r=void 0);const w=u===p&&t[i+1].startsWith("/>")?" ":"";d+=u===f?s+h:v>=0?(l.push(e),s.slice(0,v)+o$1+s.slice(v)+n$1+w):s+n$1+(-2===v?(l.push(void 0),i):w);}const c=d+(t[s]||"<?>")+(2===i?"</svg>":"");if(!Array.isArray(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return [void 0!==e?e.createHTML(c):c,l]};class V{constructor({strings:t,_$litType$:i},e){let h;this.parts=[];let r=0,u=0;const c=t.length-1,v=this.parts,[a,f]=P(t,i);if(this.el=V.createElement(a,e),C.currentNode=this.el.content,2===i){const t=this.el.content,i=t.firstChild;i.remove(),t.append(...i.childNodes);}for(;null!==(h=C.nextNode())&&v.length<c;){if(1===h.nodeType){if(h.hasAttributes()){const t=[];for(const i of h.getAttributeNames())if(i.endsWith(o$1)||i.startsWith(n$1)){const s=f[u++];if(t.push(i),void 0!==s){const t=h.getAttribute(s.toLowerCase()+o$1).split(n$1),i=/([.?@])?(.*)/.exec(s);v.push({type:1,index:r,name:i[2],strings:t,ctor:"."===i[1]?k:"?"===i[1]?I:"@"===i[1]?L:R});}else v.push({type:6,index:r});}for(const i of t)h.removeAttribute(i);}if(y.test(h.tagName)){const t=h.textContent.split(n$1),i=t.length-1;if(i>0){h.textContent=s$1?s$1.emptyScript:"";for(let s=0;s<i;s++)h.append(t[s],d()),C.nextNode(),v.push({type:2,index:++r});h.append(t[i],d());}}}else if(8===h.nodeType)if(h.data===l$1)v.push({type:2,index:r});else {let t=-1;for(;-1!==(t=h.data.indexOf(n$1,t+1));)v.push({type:7,index:r}),t+=n$1.length-1;}r++;}}static createElement(t,i){const s=r.createElement("template");return s.innerHTML=t,s}}function N(t,i,s=t,e){var o,n,l,h;if(i===T)return i;let r=void 0!==e?null===(o=s._$Co)||void 0===o?void 0:o[e]:s._$Cl;const d=u(i)?void 0:i._$litDirective$;return (null==r?void 0:r.constructor)!==d&&(null===(n=null==r?void 0:r._$AO)||void 0===n||n.call(r,!1),void 0===d?r=void 0:(r=new d(t),r._$AT(t,s,e)),void 0!==e?(null!==(l=(h=s)._$Co)&&void 0!==l?l:h._$Co=[])[e]=r:s._$Cl=r),void 0!==r&&(i=N(t,r._$AS(t,i.values),r,e)),i}class S{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){var i;const{el:{content:s},parts:e}=this._$AD,o=(null!==(i=null==t?void 0:t.creationScope)&&void 0!==i?i:r).importNode(s,!0);C.currentNode=o;let n=C.nextNode(),l=0,h=0,d=e[0];for(;void 0!==d;){if(l===d.index){let i;2===d.type?i=new M(n,n.nextSibling,this,t):1===d.type?i=new d.ctor(n,d.name,d.strings,this,t):6===d.type&&(i=new z(n,this,t)),this._$AV.push(i),d=e[++h];}l!==(null==d?void 0:d.index)&&(n=C.nextNode(),l++);}return C.currentNode=r,o}v(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 M{constructor(t,i,s,e){var o;this.type=2,this._$AH=A,this._$AN=void 0,this._$AA=t,this._$AB=i,this._$AM=s,this.options=e,this._$Cp=null===(o=null==e?void 0:e.isConnected)||void 0===o||o;}get _$AU(){var t,i;return null!==(i=null===(t=this._$AM)||void 0===t?void 0:t._$AU)&&void 0!==i?i:this._$Cp}get parentNode(){let t=this._$AA.parentNode;const i=this._$AM;return void 0!==i&&11===(null==t?void 0:t.nodeType)&&(t=i.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,i=this){t=N(this,t,i),u(t)?t===A||null==t||""===t?(this._$AH!==A&&this._$AR(),this._$AH=A):t!==this._$AH&&t!==T&&this._(t):void 0!==t._$litType$?this.g(t):void 0!==t.nodeType?this.$(t):v(t)?this.T(t):this._(t);}k(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}$(t){this._$AH!==t&&(this._$AR(),this._$AH=this.k(t));}_(t){this._$AH!==A&&u(this._$AH)?this._$AA.nextSibling.data=t:this.$(r.createTextNode(t)),this._$AH=t;}g(t){var i;const{values:s,_$litType$:e}=t,o="number"==typeof e?this._$AC(t):(void 0===e.el&&(e.el=V.createElement(e.h,this.options)),e);if((null===(i=this._$AH)||void 0===i?void 0:i._$AD)===o)this._$AH.v(s);else {const t=new S(o,this),i=t.u(this.options);t.v(s),this.$(i),this._$AH=t;}}_$AC(t){let i=E.get(t.strings);return void 0===i&&E.set(t.strings,i=new V(t)),i}T(t){c(this._$AH)||(this._$AH=[],this._$AR());const i=this._$AH;let s,e=0;for(const o of t)e===i.length?i.push(s=new M(this.k(d()),this.k(d()),this,this.options)):s=i[e],s._$AI(o),e++;e<i.length&&(this._$AR(s&&s._$AB.nextSibling,e),i.length=e);}_$AR(t=this._$AA.nextSibling,i){var s;for(null===(s=this._$AP)||void 0===s||s.call(this,!1,!0,i);t&&t!==this._$AB;){const i=t.nextSibling;t.remove(),t=i;}}setConnected(t){var i;void 0===this._$AM&&(this._$Cp=t,null===(i=this._$AP)||void 0===i||i.call(this,t));}}class R{constructor(t,i,s,e,o){this.type=1,this._$AH=A,this._$AN=void 0,this.element=t,this.name=i,this._$AM=e,this.options=o,s.length>2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=A;}get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}_$AI(t,i=this,s,e){const o=this.strings;let n=!1;if(void 0===o)t=N(this,t,i,0),n=!u(t)||t!==this._$AH&&t!==T,n&&(this._$AH=t);else {const e=t;let l,h;for(t=o[0],l=0;l<o.length-1;l++)h=N(this,e[s+l],i,l),h===T&&(h=this._$AH[l]),n||(n=!u(h)||h!==this._$AH[l]),h===A?t=A:t!==A&&(t+=(null!=h?h:"")+o[l+1]),this._$AH[l]=h;}n&&!e&&this.j(t);}j(t){t===A?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,null!=t?t:"");}}class k extends R{constructor(){super(...arguments),this.type=3;}j(t){this.element[this.name]=t===A?void 0:t;}}const H=s$1?s$1.emptyScript:"";class I extends R{constructor(){super(...arguments),this.type=4;}j(t){t&&t!==A?this.element.setAttribute(this.name,H):this.element.removeAttribute(this.name);}}class L extends R{constructor(t,i,s,e,o){super(t,i,s,e,o),this.type=5;}_$AI(t,i=this){var s;if((t=null!==(s=N(this,t,i,0))&&void 0!==s?s:A)===T)return;const e=this._$AH,o=t===A&&e!==A||t.capture!==e.capture||t.once!==e.once||t.passive!==e.passive,n=t!==A&&(e===A||o);o&&this.element.removeEventListener(this.name,this,e),n&&this.element.addEventListener(this.name,this,t),this._$AH=t;}handleEvent(t){var i,s;"function"==typeof this._$AH?this._$AH.call(null!==(s=null===(i=this.options)||void 0===i?void 0:i.host)&&void 0!==s?s:this.element,t):this._$AH.handleEvent(t);}}class z{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){N(this,t);}}const j=i.litHtmlPolyfillSupport;null==j||j(V,M),(null!==(t=i.litHtmlVersions)&&void 0!==t?t:i.litHtmlVersions=[]).push("2.7.4");const B=(t,i,s)=>{var e,o;const n=null!==(e=null==s?void 0:s.renderBefore)&&void 0!==e?e:i;let l=n._$litPart$;if(void 0===l){const t=null!==(o=null==s?void 0:s.renderBefore)&&void 0!==o?o:null;n._$litPart$=l=new M(i.insertBefore(d(),t),t,void 0,null!=s?s:{});}return l._$AI(t),l};
|
|
95
102
|
|
|
96
103
|
/**
|
|
97
104
|
* @license
|
|
98
105
|
* Copyright 2017 Google LLC
|
|
99
106
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
100
|
-
*/var l,o;class s extends d$1{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0;}createRenderRoot(){var t,e;const i=super.createRenderRoot();return null!==(t=(e=this.renderOptions).renderBefore)&&void 0!==t||(e.renderBefore=i.firstChild),i}update(t){const i=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=
|
|
107
|
+
*/var l,o;class s extends d$1{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0;}createRenderRoot(){var t,e;const i=super.createRenderRoot();return null!==(t=(e=this.renderOptions).renderBefore)&&void 0!==t||(e.renderBefore=i.firstChild),i}update(t){const i=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=B(i,this.renderRoot,this.renderOptions);}connectedCallback(){var t;super.connectedCallback(),null===(t=this._$Do)||void 0===t||t.setConnected(!0);}disconnectedCallback(){var t;super.disconnectedCallback(),null===(t=this._$Do)||void 0===t||t.setConnected(!1);}render(){return T}}s.finalized=!0,s._$litElement$=!0,null===(l=globalThis.litElementHydrateSupport)||void 0===l||l.call(globalThis,{LitElement:s});const n=globalThis.litElementPolyfillSupport;null==n||n({LitElement:s});(null!==(o=globalThis.litElementVersions)&&void 0!==o?o:globalThis.litElementVersions=[]).push("3.3.2");
|
|
101
108
|
|
|
102
109
|
/**
|
|
103
110
|
* @license
|
|
@@ -123,7 +130,7 @@ const ThemePropertyMixin = (superClass) =>
|
|
|
123
130
|
* **NOTE:** Extending the mixin only provides the property for binding,
|
|
124
131
|
* and does not make the propagation alone.
|
|
125
132
|
*
|
|
126
|
-
* See [Styling Components: Sub-components](https://vaadin.com/docs/latest/
|
|
133
|
+
* See [Styling Components: Sub-components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components/#sub-components).
|
|
127
134
|
* page for more information.
|
|
128
135
|
*
|
|
129
136
|
* @deprecated The `theme` property is not supposed for public use and will be dropped in Vaadin 24.
|
|
@@ -148,7 +155,7 @@ const ThemePropertyMixin = (superClass) =>
|
|
|
148
155
|
* **NOTE:** Extending the mixin only provides the property for binding,
|
|
149
156
|
* and does not make the propagation alone.
|
|
150
157
|
*
|
|
151
|
-
* See [Styling Components: Sub-components](https://vaadin.com/docs/latest/
|
|
158
|
+
* See [Styling Components: Sub-components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components/#sub-components).
|
|
152
159
|
* page for more information.
|
|
153
160
|
*
|
|
154
161
|
* @protected
|
|
@@ -253,9 +260,9 @@ function matchesThemeFor(themeFor, tagName) {
|
|
|
253
260
|
*/
|
|
254
261
|
function getIncludePriority(moduleName = '') {
|
|
255
262
|
let includePriority = 0;
|
|
256
|
-
if (moduleName.
|
|
263
|
+
if (moduleName.startsWith('lumo-') || moduleName.startsWith('material-')) {
|
|
257
264
|
includePriority = 1;
|
|
258
|
-
} else if (moduleName.
|
|
265
|
+
} else if (moduleName.startsWith('vaadin-')) {
|
|
259
266
|
includePriority = 2;
|
|
260
267
|
}
|
|
261
268
|
return includePriority;
|
|
@@ -489,9 +496,9 @@ const colorBase = i$1`
|
|
|
489
496
|
}
|
|
490
497
|
`;
|
|
491
498
|
|
|
492
|
-
const $tpl$
|
|
493
|
-
$tpl$
|
|
494
|
-
document.head.appendChild($tpl$
|
|
499
|
+
const $tpl$4 = document.createElement('template');
|
|
500
|
+
$tpl$4.innerHTML = `<style>${colorBase.toString().replace(':host', 'html')}</style>`;
|
|
501
|
+
document.head.appendChild($tpl$4.content);
|
|
495
502
|
|
|
496
503
|
const color = i$1`
|
|
497
504
|
[theme~='dark'] {
|
|
@@ -638,9 +645,9 @@ const sizing = i$1`
|
|
|
638
645
|
}
|
|
639
646
|
`;
|
|
640
647
|
|
|
641
|
-
const $tpl$
|
|
642
|
-
$tpl$
|
|
643
|
-
document.head.appendChild($tpl$
|
|
648
|
+
const $tpl$3 = document.createElement('template');
|
|
649
|
+
$tpl$3.innerHTML = `<style>${sizing.toString().replace(':host', 'html')}</style>`;
|
|
650
|
+
document.head.appendChild($tpl$3.content);
|
|
644
651
|
|
|
645
652
|
/**
|
|
646
653
|
* @license
|
|
@@ -668,9 +675,19 @@ const style = i$1`
|
|
|
668
675
|
}
|
|
669
676
|
`;
|
|
670
677
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
678
|
+
/**
|
|
679
|
+
* Default values for component-specific custom properties.
|
|
680
|
+
*/
|
|
681
|
+
i$1`
|
|
682
|
+
html {
|
|
683
|
+
--vaadin-checkbox-size: calc(var(--lumo-size-m) / 2);
|
|
684
|
+
--vaadin-radio-button-size: calc(var(--lumo-size-m) / 2);
|
|
685
|
+
}
|
|
686
|
+
`;
|
|
687
|
+
|
|
688
|
+
const $tpl$2 = document.createElement('template');
|
|
689
|
+
$tpl$2.innerHTML = `<style>${style.toString().replace(':host', 'html')}$</style>`;
|
|
690
|
+
document.head.appendChild($tpl$2.content);
|
|
674
691
|
|
|
675
692
|
/**
|
|
676
693
|
* @license
|
|
@@ -807,9 +824,9 @@ const typography = i$1`
|
|
|
807
824
|
|
|
808
825
|
registerStyles('', typography, { moduleId: 'lumo-typography' });
|
|
809
826
|
|
|
810
|
-
const $tpl$
|
|
811
|
-
$tpl$
|
|
812
|
-
document.head.appendChild($tpl$
|
|
827
|
+
const $tpl$1 = document.createElement('template');
|
|
828
|
+
$tpl$1.innerHTML = `<style>${font.toString().replace(':host', 'html')}</style>`;
|
|
829
|
+
document.head.appendChild($tpl$1.content);
|
|
813
830
|
|
|
814
831
|
registerStyles(
|
|
815
832
|
'vaadin-input-container',
|
|
@@ -8101,6 +8118,7 @@ class DirHelper {
|
|
|
8101
8118
|
* Array of Vaadin custom element classes that have been subscribed to the dir changes.
|
|
8102
8119
|
*/
|
|
8103
8120
|
const directionSubscribers = [];
|
|
8121
|
+
|
|
8104
8122
|
function directionUpdater() {
|
|
8105
8123
|
const documentDir = getDocumentDir();
|
|
8106
8124
|
directionSubscribers.forEach((element) => {
|
|
@@ -8166,7 +8184,7 @@ const DirMixin = (superClass) =>
|
|
|
8166
8184
|
connectedCallback() {
|
|
8167
8185
|
super.connectedCallback();
|
|
8168
8186
|
|
|
8169
|
-
if (!this.hasAttribute('dir')) {
|
|
8187
|
+
if (!this.hasAttribute('dir') || this.__restoreSubscription) {
|
|
8170
8188
|
this.__subscribe();
|
|
8171
8189
|
alignDirs(this, getDocumentDir(), null);
|
|
8172
8190
|
}
|
|
@@ -8192,15 +8210,15 @@ const DirMixin = (superClass) =>
|
|
|
8192
8210
|
this.__subscribe();
|
|
8193
8211
|
alignDirs(this, documentDir, newValue);
|
|
8194
8212
|
} else if (newDiffValue) {
|
|
8195
|
-
this.
|
|
8213
|
+
this.__unsubscribe();
|
|
8196
8214
|
}
|
|
8197
8215
|
}
|
|
8198
8216
|
|
|
8199
8217
|
/** @protected */
|
|
8200
8218
|
disconnectedCallback() {
|
|
8201
8219
|
super.disconnectedCallback();
|
|
8202
|
-
this.
|
|
8203
|
-
this.
|
|
8220
|
+
this.__restoreSubscription = directionSubscribers.includes(this);
|
|
8221
|
+
this.__unsubscribe();
|
|
8204
8222
|
}
|
|
8205
8223
|
|
|
8206
8224
|
/** @protected */
|
|
@@ -8225,12 +8243,15 @@ const DirMixin = (superClass) =>
|
|
|
8225
8243
|
}
|
|
8226
8244
|
|
|
8227
8245
|
/** @private */
|
|
8228
|
-
__subscribe(
|
|
8229
|
-
if (
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8246
|
+
__subscribe() {
|
|
8247
|
+
if (!directionSubscribers.includes(this)) {
|
|
8248
|
+
directionSubscribers.push(this);
|
|
8249
|
+
}
|
|
8250
|
+
}
|
|
8251
|
+
|
|
8252
|
+
/** @private */
|
|
8253
|
+
__unsubscribe() {
|
|
8254
|
+
if (directionSubscribers.includes(this)) {
|
|
8234
8255
|
directionSubscribers.splice(directionSubscribers.indexOf(this), 1);
|
|
8235
8256
|
}
|
|
8236
8257
|
}
|
|
@@ -8308,7 +8329,6 @@ class InputContainer extends ThemableMixin(DirMixin(PolymerElement)) {
|
|
|
8308
8329
|
::slotted(:is(input, textarea))::placeholder {
|
|
8309
8330
|
/* Use ::slotted(input:placeholder-shown) in themes to style the placeholder. */
|
|
8310
8331
|
/* because ::slotted(...)::placeholder does not work in Safari. */
|
|
8311
|
-
/* See the workaround at the end of this file. */
|
|
8312
8332
|
font: inherit;
|
|
8313
8333
|
color: inherit;
|
|
8314
8334
|
/* Override default opacity in Firefox */
|
|
@@ -8375,18 +8395,6 @@ class InputContainer extends ThemableMixin(DirMixin(PolymerElement)) {
|
|
|
8375
8395
|
|
|
8376
8396
|
customElements.define(InputContainer.is, InputContainer);
|
|
8377
8397
|
|
|
8378
|
-
const placeholderStyleWorkaround = i$1`
|
|
8379
|
-
/* Needed for Safari, where ::slotted(...)::placeholder does not work */
|
|
8380
|
-
:is(input[slot='input'], textarea[slot='textarea'])::placeholder {
|
|
8381
|
-
font: inherit;
|
|
8382
|
-
color: inherit;
|
|
8383
|
-
}
|
|
8384
|
-
`;
|
|
8385
|
-
|
|
8386
|
-
const $tpl$1 = document.createElement('template');
|
|
8387
|
-
$tpl$1.innerHTML = `<style>${placeholderStyleWorkaround.toString()}</style>`;
|
|
8388
|
-
document.head.appendChild($tpl$1.content);
|
|
8389
|
-
|
|
8390
8398
|
/**
|
|
8391
8399
|
* @license
|
|
8392
8400
|
* Copyright (c) 2017 - 2022 Vaadin Ltd.
|
|
@@ -10140,6 +10148,38 @@ const ControllerMixin = dedupingMixin(
|
|
|
10140
10148
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
10141
10149
|
*/
|
|
10142
10150
|
|
|
10151
|
+
// We consider the keyboard to be active if the window has received a keydown
|
|
10152
|
+
// event since the last mousedown event.
|
|
10153
|
+
let keyboardActive = false;
|
|
10154
|
+
|
|
10155
|
+
// Listen for top-level keydown and mousedown events.
|
|
10156
|
+
// Use capture phase so we detect events even if they're handled.
|
|
10157
|
+
window.addEventListener(
|
|
10158
|
+
'keydown',
|
|
10159
|
+
() => {
|
|
10160
|
+
keyboardActive = true;
|
|
10161
|
+
},
|
|
10162
|
+
{ capture: true },
|
|
10163
|
+
);
|
|
10164
|
+
|
|
10165
|
+
window.addEventListener(
|
|
10166
|
+
'mousedown',
|
|
10167
|
+
() => {
|
|
10168
|
+
keyboardActive = false;
|
|
10169
|
+
},
|
|
10170
|
+
{ capture: true },
|
|
10171
|
+
);
|
|
10172
|
+
|
|
10173
|
+
/**
|
|
10174
|
+
* Returns true if the window has received a keydown
|
|
10175
|
+
* event since the last mousedown event.
|
|
10176
|
+
*
|
|
10177
|
+
* @return {boolean}
|
|
10178
|
+
*/
|
|
10179
|
+
function isKeyboardActive() {
|
|
10180
|
+
return keyboardActive;
|
|
10181
|
+
}
|
|
10182
|
+
|
|
10143
10183
|
/**
|
|
10144
10184
|
* Returns true if the element is hidden directly with `display: none` or `visibility: hidden`,
|
|
10145
10185
|
* false otherwise.
|
|
@@ -10580,7 +10620,7 @@ class FocusTrapController {
|
|
|
10580
10620
|
* ---|---|---
|
|
10581
10621
|
* `--vaadin-overlay-viewport-bottom` | Bottom offset of the visible viewport area | `0` or detected offset
|
|
10582
10622
|
*
|
|
10583
|
-
* See [Styling Components](https://vaadin.com/docs/latest/
|
|
10623
|
+
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
|
|
10584
10624
|
*
|
|
10585
10625
|
* @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
|
|
10586
10626
|
* @fires {CustomEvent} vaadin-overlay-open - Fired after the overlay is opened.
|
|
@@ -10594,7 +10634,7 @@ class FocusTrapController {
|
|
|
10594
10634
|
* @mixes DirMixin
|
|
10595
10635
|
* @mixes ControllerMixin
|
|
10596
10636
|
*/
|
|
10597
|
-
class
|
|
10637
|
+
class Overlay extends ThemableMixin(DirMixin(ControllerMixin(PolymerElement))) {
|
|
10598
10638
|
static get template() {
|
|
10599
10639
|
return html`
|
|
10600
10640
|
<style>
|
|
@@ -10894,7 +10934,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
10894
10934
|
* @protected
|
|
10895
10935
|
*/
|
|
10896
10936
|
_setTemplateFromNodes(nodes) {
|
|
10897
|
-
this.template = nodes.
|
|
10937
|
+
this.template = nodes.find((node) => node.localName && node.localName === 'template') || this.template;
|
|
10898
10938
|
}
|
|
10899
10939
|
|
|
10900
10940
|
/**
|
|
@@ -11221,7 +11261,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11221
11261
|
*/
|
|
11222
11262
|
static get __attachedInstances() {
|
|
11223
11263
|
return Array.from(document.body.children)
|
|
11224
|
-
.filter((el) => el instanceof
|
|
11264
|
+
.filter((el) => el instanceof Overlay && !el.hasAttribute('closing'))
|
|
11225
11265
|
.sort((a, b) => a.__zIndex - b.__zIndex || 0);
|
|
11226
11266
|
}
|
|
11227
11267
|
|
|
@@ -11231,7 +11271,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11231
11271
|
* @protected
|
|
11232
11272
|
*/
|
|
11233
11273
|
get _last() {
|
|
11234
|
-
return this ===
|
|
11274
|
+
return this === Overlay.__attachedInstances.pop();
|
|
11235
11275
|
}
|
|
11236
11276
|
|
|
11237
11277
|
/** @private */
|
|
@@ -11266,7 +11306,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11266
11306
|
}
|
|
11267
11307
|
|
|
11268
11308
|
// Disable pointer events in other attached overlays
|
|
11269
|
-
|
|
11309
|
+
Overlay.__attachedInstances.forEach((el) => {
|
|
11270
11310
|
if (el !== this) {
|
|
11271
11311
|
el.shadowRoot.querySelector('[part="overlay"]').style.pointerEvents = 'none';
|
|
11272
11312
|
}
|
|
@@ -11289,7 +11329,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11289
11329
|
}
|
|
11290
11330
|
|
|
11291
11331
|
// Restore pointer events in the previous overlay(s)
|
|
11292
|
-
const instances =
|
|
11332
|
+
const instances = Overlay.__attachedInstances;
|
|
11293
11333
|
let el;
|
|
11294
11334
|
// Use instances.pop() to ensure the reverse order
|
|
11295
11335
|
while ((el = instances.pop())) {
|
|
@@ -11468,7 +11508,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11468
11508
|
*/
|
|
11469
11509
|
bringToFront() {
|
|
11470
11510
|
let zIndex = '';
|
|
11471
|
-
const frontmost =
|
|
11511
|
+
const frontmost = Overlay.__attachedInstances.filter((o) => o !== this).pop();
|
|
11472
11512
|
if (frontmost) {
|
|
11473
11513
|
const frontmostZIndex = frontmost.__zIndex;
|
|
11474
11514
|
zIndex = frontmostZIndex + 1;
|
|
@@ -11478,7 +11518,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11478
11518
|
}
|
|
11479
11519
|
}
|
|
11480
11520
|
|
|
11481
|
-
customElements.define(
|
|
11521
|
+
customElements.define(Overlay.is, Overlay);
|
|
11482
11522
|
|
|
11483
11523
|
/**
|
|
11484
11524
|
* @license
|
|
@@ -11664,7 +11704,7 @@ const button = i$1`
|
|
|
11664
11704
|
-moz-osx-font-smoothing: grayscale;
|
|
11665
11705
|
}
|
|
11666
11706
|
|
|
11667
|
-
/* Set only for the internal parts so we don
|
|
11707
|
+
/* Set only for the internal parts so we don't affect the host vertical alignment */
|
|
11668
11708
|
[part='label'],
|
|
11669
11709
|
[part='prefix'],
|
|
11670
11710
|
[part='suffix'] {
|
|
@@ -11900,7 +11940,7 @@ const button = i$1`
|
|
|
11900
11940
|
registerStyles('vaadin-button', button, { moduleId: 'lumo-button' });
|
|
11901
11941
|
|
|
11902
11942
|
const DEV_MODE_CODE_REGEXP =
|
|
11903
|
-
|
|
11943
|
+
/\/\*[\*!]\s+vaadin-dev-mode:start([\s\S]*)vaadin-dev-mode:end\s+\*\*\//i;
|
|
11904
11944
|
|
|
11905
11945
|
const FlowClients = window.Vaadin && window.Vaadin.Flow && window.Vaadin.Flow.clients;
|
|
11906
11946
|
|
|
@@ -12850,7 +12890,7 @@ const registered = new Set();
|
|
|
12850
12890
|
const ElementMixin = (superClass) =>
|
|
12851
12891
|
class VaadinElementMixin extends DirMixin(superClass) {
|
|
12852
12892
|
static get version() {
|
|
12853
|
-
return '23.
|
|
12893
|
+
return '23.3.14';
|
|
12854
12894
|
}
|
|
12855
12895
|
|
|
12856
12896
|
/** @protected */
|
|
@@ -12885,174 +12925,553 @@ const ElementMixin = (superClass) =>
|
|
|
12885
12925
|
};
|
|
12886
12926
|
|
|
12887
12927
|
/**
|
|
12888
|
-
@license
|
|
12889
|
-
Copyright (c)
|
|
12890
|
-
|
|
12891
|
-
|
|
12892
|
-
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
|
12893
|
-
Code distributed by Google as part of the polymer project is also
|
|
12894
|
-
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
|
12895
|
-
*/
|
|
12896
|
-
|
|
12897
|
-
const passiveTouchGestures = false;
|
|
12898
|
-
const wrap = (node) => node;
|
|
12899
|
-
|
|
12900
|
-
// Detect native touch action support
|
|
12901
|
-
const HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
|
|
12902
|
-
const GESTURE_KEY = '__polymerGestures';
|
|
12903
|
-
const HANDLED_OBJ = '__polymerGesturesHandled';
|
|
12904
|
-
const TOUCH_ACTION = '__polymerGesturesTouchAction';
|
|
12905
|
-
// Radius for tap and track
|
|
12906
|
-
const TAP_DISTANCE = 25;
|
|
12907
|
-
const TRACK_DISTANCE = 5;
|
|
12908
|
-
// Number of last N track positions to keep
|
|
12909
|
-
const TRACK_LENGTH = 2;
|
|
12928
|
+
* @license
|
|
12929
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
12930
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
12931
|
+
*/
|
|
12910
12932
|
|
|
12911
|
-
|
|
12912
|
-
// An array of bitmask values for mapping MouseEvent.which to MouseEvent.buttons
|
|
12913
|
-
const MOUSE_WHICH_TO_BUTTONS = [0, 1, 4, 2];
|
|
12914
|
-
const MOUSE_HAS_BUTTONS = (function () {
|
|
12915
|
-
try {
|
|
12916
|
-
return new MouseEvent('test', { buttons: 1 }).buttons === 1;
|
|
12917
|
-
} catch (e) {
|
|
12918
|
-
return false;
|
|
12919
|
-
}
|
|
12920
|
-
})();
|
|
12933
|
+
let uniqueId = 0;
|
|
12921
12934
|
|
|
12922
12935
|
/**
|
|
12923
|
-
*
|
|
12924
|
-
*
|
|
12936
|
+
* Returns a unique integer id.
|
|
12937
|
+
*
|
|
12938
|
+
* @return {number}
|
|
12925
12939
|
*/
|
|
12926
|
-
function
|
|
12927
|
-
|
|
12940
|
+
function generateUniqueId() {
|
|
12941
|
+
// eslint-disable-next-line no-plusplus
|
|
12942
|
+
return uniqueId++;
|
|
12928
12943
|
}
|
|
12929
12944
|
|
|
12930
|
-
|
|
12931
|
-
|
|
12932
|
-
|
|
12933
|
-
|
|
12934
|
-
|
|
12935
|
-
const opts = Object.defineProperty({}, 'passive', {
|
|
12936
|
-
// eslint-disable-next-line getter-return
|
|
12937
|
-
get() {
|
|
12938
|
-
supportsPassive = true;
|
|
12939
|
-
},
|
|
12940
|
-
});
|
|
12941
|
-
window.addEventListener('test', null, opts);
|
|
12942
|
-
window.removeEventListener('test', null, opts);
|
|
12943
|
-
} catch (e) {}
|
|
12944
|
-
})();
|
|
12945
|
+
/**
|
|
12946
|
+
* @license
|
|
12947
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
12948
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
12949
|
+
*/
|
|
12945
12950
|
|
|
12946
12951
|
/**
|
|
12947
|
-
*
|
|
12948
|
-
*
|
|
12949
|
-
* @param {string} eventName Event name to determine if `{passive}` option is
|
|
12950
|
-
* needed
|
|
12951
|
-
* @return {{passive: boolean} | undefined} Options to use for addEventListener
|
|
12952
|
-
* and removeEventListener
|
|
12952
|
+
* A controller for providing content to slot element and observing changes.
|
|
12953
12953
|
*/
|
|
12954
|
-
|
|
12955
|
-
|
|
12956
|
-
|
|
12957
|
-
|
|
12958
|
-
|
|
12959
|
-
|
|
12954
|
+
class SlotController extends EventTarget {
|
|
12955
|
+
/**
|
|
12956
|
+
* Ensure that every instance has unique ID.
|
|
12957
|
+
*
|
|
12958
|
+
* @param {string} slotName
|
|
12959
|
+
* @param {HTMLElement} host
|
|
12960
|
+
* @return {string}
|
|
12961
|
+
* @protected
|
|
12962
|
+
*/
|
|
12963
|
+
static generateId(slotName, host) {
|
|
12964
|
+
const prefix = slotName || 'default';
|
|
12965
|
+
return `${prefix}-${host.localName}-${generateUniqueId()}`;
|
|
12960
12966
|
}
|
|
12961
|
-
}
|
|
12962
12967
|
|
|
12963
|
-
|
|
12964
|
-
|
|
12968
|
+
constructor(host, slotName, slotFactory, slotInitializer, useUniqueId) {
|
|
12969
|
+
super();
|
|
12965
12970
|
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
command: true,
|
|
12971
|
-
fieldset: true,
|
|
12972
|
-
input: true,
|
|
12973
|
-
keygen: true,
|
|
12974
|
-
optgroup: true,
|
|
12975
|
-
option: true,
|
|
12976
|
-
select: true,
|
|
12977
|
-
textarea: true,
|
|
12978
|
-
};
|
|
12971
|
+
this.host = host;
|
|
12972
|
+
this.slotName = slotName;
|
|
12973
|
+
this.slotFactory = slotFactory;
|
|
12974
|
+
this.slotInitializer = slotInitializer;
|
|
12979
12975
|
|
|
12980
|
-
|
|
12981
|
-
|
|
12982
|
-
|
|
12983
|
-
*/
|
|
12984
|
-
function hasLeftMouseButton(ev) {
|
|
12985
|
-
const type = ev.type;
|
|
12986
|
-
// Exit early if the event is not a mouse event
|
|
12987
|
-
if (!isMouseEvent(type)) {
|
|
12988
|
-
return false;
|
|
12989
|
-
}
|
|
12990
|
-
// Ev.button is not reliable for mousemove (0 is overloaded as both left button and no buttons)
|
|
12991
|
-
// instead we use ev.buttons (bitmask of buttons) or fall back to ev.which (deprecated, 0 for no buttons, 1 for left button)
|
|
12992
|
-
if (type === 'mousemove') {
|
|
12993
|
-
// Allow undefined for testing events
|
|
12994
|
-
let buttons = ev.buttons === undefined ? 1 : ev.buttons;
|
|
12995
|
-
if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {
|
|
12996
|
-
buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;
|
|
12976
|
+
// Only generate the default ID if requested by the controller.
|
|
12977
|
+
if (useUniqueId) {
|
|
12978
|
+
this.defaultId = SlotController.generateId(slotName, host);
|
|
12997
12979
|
}
|
|
12998
|
-
// Buttons is a bitmask, check that the left button bit is set (1)
|
|
12999
|
-
return Boolean(buttons & 1);
|
|
13000
12980
|
}
|
|
13001
|
-
// Allow undefined for testing events
|
|
13002
|
-
const button = ev.button === undefined ? 0 : ev.button;
|
|
13003
|
-
// Ev.button is 0 in mousedown/mouseup/click for left button activation
|
|
13004
|
-
return button === 0;
|
|
13005
|
-
}
|
|
13006
12981
|
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
|
|
13010
|
-
if (ev.detail === 0) {
|
|
13011
|
-
return true;
|
|
13012
|
-
}
|
|
13013
|
-
// In the worst case, check that the x/y position of the click is within
|
|
13014
|
-
// the bounding box of the target of the event
|
|
13015
|
-
// Thanks IE 10 >:(
|
|
13016
|
-
const t = _findOriginalTarget(ev);
|
|
13017
|
-
// Make sure the target of the event is an element so we can use getBoundingClientRect,
|
|
13018
|
-
// if not, just assume it is a synthetic click
|
|
13019
|
-
if (!t.nodeType || /** @type {Element} */ (t).nodeType !== Node.ELEMENT_NODE) {
|
|
13020
|
-
return true;
|
|
13021
|
-
}
|
|
13022
|
-
const bcr = /** @type {Element} */ (t).getBoundingClientRect();
|
|
13023
|
-
// Use page x/y to account for scrolling
|
|
13024
|
-
const x = ev.pageX,
|
|
13025
|
-
y = ev.pageY;
|
|
13026
|
-
// Ev is a synthetic click if the position is outside the bounding box of the target
|
|
13027
|
-
return !(x >= bcr.left && x <= bcr.right && y >= bcr.top && y <= bcr.bottom);
|
|
13028
|
-
}
|
|
13029
|
-
return false;
|
|
13030
|
-
}
|
|
12982
|
+
hostConnected() {
|
|
12983
|
+
if (!this.initialized) {
|
|
12984
|
+
let node = this.getSlotChild();
|
|
13031
12985
|
|
|
13032
|
-
|
|
13033
|
-
|
|
13034
|
-
|
|
13035
|
-
|
|
13036
|
-
|
|
13037
|
-
|
|
13038
|
-
x: 0,
|
|
13039
|
-
y: 0,
|
|
13040
|
-
id: -1,
|
|
13041
|
-
scrollDecided: false,
|
|
13042
|
-
},
|
|
13043
|
-
};
|
|
12986
|
+
if (!node) {
|
|
12987
|
+
node = this.attachDefaultNode();
|
|
12988
|
+
} else {
|
|
12989
|
+
this.node = node;
|
|
12990
|
+
this.initCustomNode(node);
|
|
12991
|
+
}
|
|
13044
12992
|
|
|
13045
|
-
|
|
13046
|
-
|
|
13047
|
-
|
|
13048
|
-
|
|
13049
|
-
|
|
13050
|
-
|
|
13051
|
-
|
|
13052
|
-
|
|
12993
|
+
this.initNode(node);
|
|
12994
|
+
|
|
12995
|
+
// TODO: Consider making this behavior opt-in to improve performance.
|
|
12996
|
+
this.observe();
|
|
12997
|
+
|
|
12998
|
+
this.initialized = true;
|
|
12999
|
+
}
|
|
13000
|
+
}
|
|
13001
|
+
|
|
13002
|
+
/**
|
|
13003
|
+
* Create and attach default node using the slot factory.
|
|
13004
|
+
* @return {Node | undefined}
|
|
13005
|
+
* @protected
|
|
13006
|
+
*/
|
|
13007
|
+
attachDefaultNode() {
|
|
13008
|
+
const { host, slotName, slotFactory } = this;
|
|
13009
|
+
|
|
13010
|
+
// Check if the node was created previously and if so, reuse it.
|
|
13011
|
+
let node = this.defaultNode;
|
|
13012
|
+
|
|
13013
|
+
// Slot factory is optional, some slots don't have default content.
|
|
13014
|
+
if (!node && slotFactory) {
|
|
13015
|
+
node = slotFactory(host);
|
|
13016
|
+
if (node instanceof Element) {
|
|
13017
|
+
if (slotName !== '') {
|
|
13018
|
+
node.setAttribute('slot', slotName);
|
|
13019
|
+
}
|
|
13020
|
+
this.node = node;
|
|
13021
|
+
this.defaultNode = node;
|
|
13022
|
+
}
|
|
13023
|
+
}
|
|
13024
|
+
|
|
13025
|
+
if (node) {
|
|
13026
|
+
host.appendChild(node);
|
|
13027
|
+
}
|
|
13028
|
+
|
|
13029
|
+
return node;
|
|
13030
|
+
}
|
|
13031
|
+
|
|
13032
|
+
/**
|
|
13033
|
+
* Return a reference to the node managed by the controller.
|
|
13034
|
+
* @return {Node}
|
|
13035
|
+
*/
|
|
13036
|
+
getSlotChild() {
|
|
13037
|
+
const { slotName } = this;
|
|
13038
|
+
return Array.from(this.host.childNodes).find((node) => {
|
|
13039
|
+
// Either an element (any slot) or a text node (only un-named slot).
|
|
13040
|
+
return (
|
|
13041
|
+
(node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) ||
|
|
13042
|
+
(node.nodeType === Node.TEXT_NODE && node.textContent.trim() && slotName === '')
|
|
13043
|
+
);
|
|
13044
|
+
});
|
|
13045
|
+
}
|
|
13046
|
+
|
|
13047
|
+
/**
|
|
13048
|
+
* @param {Node} node
|
|
13049
|
+
* @protected
|
|
13050
|
+
*/
|
|
13051
|
+
initNode(node) {
|
|
13052
|
+
const { slotInitializer } = this;
|
|
13053
|
+
// Don't try to bind `this` to initializer (normally it's arrow function).
|
|
13054
|
+
// Instead, pass the host as a first argument to access component's state.
|
|
13055
|
+
if (slotInitializer) {
|
|
13056
|
+
slotInitializer(this.host, node);
|
|
13057
|
+
}
|
|
13058
|
+
}
|
|
13059
|
+
|
|
13060
|
+
/**
|
|
13061
|
+
* Override to initialize the newly added custom node.
|
|
13062
|
+
*
|
|
13063
|
+
* @param {Node} _node
|
|
13064
|
+
* @protected
|
|
13065
|
+
*/
|
|
13066
|
+
initCustomNode(_node) {}
|
|
13067
|
+
|
|
13068
|
+
/**
|
|
13069
|
+
* Override to teardown slotted node when it's removed.
|
|
13070
|
+
*
|
|
13071
|
+
* @param {Node} _node
|
|
13072
|
+
* @protected
|
|
13073
|
+
*/
|
|
13074
|
+
teardownNode(_node) {}
|
|
13075
|
+
|
|
13076
|
+
/**
|
|
13077
|
+
* Setup the observer to manage slot content changes.
|
|
13078
|
+
* @protected
|
|
13079
|
+
*/
|
|
13080
|
+
observe() {
|
|
13081
|
+
const { slotName } = this;
|
|
13082
|
+
const selector = slotName === '' ? 'slot:not([name])' : `slot[name=${slotName}]`;
|
|
13083
|
+
const slot = this.host.shadowRoot.querySelector(selector);
|
|
13084
|
+
|
|
13085
|
+
this.__slotObserver = new FlattenedNodesObserver(slot, (info) => {
|
|
13086
|
+
// TODO: support default slot with multiple nodes (e.g. confirm-dialog)
|
|
13087
|
+
const current = this.node;
|
|
13088
|
+
const newNode = info.addedNodes.find((node) => node !== current);
|
|
13089
|
+
|
|
13090
|
+
if (info.removedNodes.length) {
|
|
13091
|
+
info.removedNodes.forEach((node) => {
|
|
13092
|
+
this.teardownNode(node);
|
|
13093
|
+
});
|
|
13094
|
+
}
|
|
13095
|
+
|
|
13096
|
+
if (newNode) {
|
|
13097
|
+
// Custom node is added, remove the current one.
|
|
13098
|
+
if (current && current.isConnected) {
|
|
13099
|
+
this.host.removeChild(current);
|
|
13100
|
+
}
|
|
13101
|
+
|
|
13102
|
+
this.node = newNode;
|
|
13103
|
+
|
|
13104
|
+
if (newNode !== this.defaultNode) {
|
|
13105
|
+
this.initCustomNode(newNode);
|
|
13106
|
+
|
|
13107
|
+
this.initNode(newNode);
|
|
13108
|
+
}
|
|
13109
|
+
}
|
|
13110
|
+
});
|
|
13111
|
+
}
|
|
13112
|
+
}
|
|
13113
|
+
|
|
13114
|
+
/**
|
|
13115
|
+
* @license
|
|
13116
|
+
* Copyright (c) 2022 Vaadin Ltd.
|
|
13117
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
13118
|
+
*/
|
|
13119
|
+
|
|
13120
|
+
/**
|
|
13121
|
+
* A controller that manages the slotted tooltip element.
|
|
13122
|
+
*/
|
|
13123
|
+
class TooltipController extends SlotController {
|
|
13124
|
+
constructor(host) {
|
|
13125
|
+
// Do not provide slot factory to create tooltip lazily.
|
|
13126
|
+
super(host, 'tooltip');
|
|
13127
|
+
|
|
13128
|
+
this.setTarget(host);
|
|
13129
|
+
}
|
|
13130
|
+
|
|
13131
|
+
/**
|
|
13132
|
+
* Override to initialize the newly added custom tooltip.
|
|
13133
|
+
*
|
|
13134
|
+
* @param {Node} tooltipNode
|
|
13135
|
+
* @protected
|
|
13136
|
+
* @override
|
|
13137
|
+
*/
|
|
13138
|
+
initCustomNode(tooltipNode) {
|
|
13139
|
+
tooltipNode.target = this.target;
|
|
13140
|
+
|
|
13141
|
+
if (this.context !== undefined) {
|
|
13142
|
+
tooltipNode.context = this.context;
|
|
13143
|
+
}
|
|
13144
|
+
|
|
13145
|
+
if (this.manual !== undefined) {
|
|
13146
|
+
tooltipNode.manual = this.manual;
|
|
13147
|
+
}
|
|
13148
|
+
|
|
13149
|
+
if (this.opened !== undefined) {
|
|
13150
|
+
tooltipNode.opened = this.opened;
|
|
13151
|
+
}
|
|
13152
|
+
|
|
13153
|
+
if (this.position !== undefined) {
|
|
13154
|
+
tooltipNode._position = this.position;
|
|
13155
|
+
}
|
|
13156
|
+
|
|
13157
|
+
if (this.shouldShow !== undefined) {
|
|
13158
|
+
tooltipNode.shouldShow = this.shouldShow;
|
|
13159
|
+
}
|
|
13160
|
+
}
|
|
13161
|
+
|
|
13162
|
+
/**
|
|
13163
|
+
* Set a context object to be used by generator.
|
|
13164
|
+
* @param {object} context
|
|
13165
|
+
*/
|
|
13166
|
+
setContext(context) {
|
|
13167
|
+
this.context = context;
|
|
13168
|
+
|
|
13169
|
+
const tooltipNode = this.node;
|
|
13170
|
+
if (tooltipNode) {
|
|
13171
|
+
tooltipNode.context = context;
|
|
13172
|
+
}
|
|
13173
|
+
}
|
|
13174
|
+
|
|
13175
|
+
/**
|
|
13176
|
+
* Toggle manual state on the slotted tooltip.
|
|
13177
|
+
* @param {boolean} manual
|
|
13178
|
+
*/
|
|
13179
|
+
setManual(manual) {
|
|
13180
|
+
this.manual = manual;
|
|
13181
|
+
|
|
13182
|
+
const tooltipNode = this.node;
|
|
13183
|
+
if (tooltipNode) {
|
|
13184
|
+
tooltipNode.manual = manual;
|
|
13185
|
+
}
|
|
13186
|
+
}
|
|
13187
|
+
|
|
13188
|
+
/**
|
|
13189
|
+
* Toggle opened state on the slotted tooltip.
|
|
13190
|
+
* @param {boolean} opened
|
|
13191
|
+
*/
|
|
13192
|
+
setOpened(opened) {
|
|
13193
|
+
this.opened = opened;
|
|
13194
|
+
|
|
13195
|
+
const tooltipNode = this.node;
|
|
13196
|
+
if (tooltipNode) {
|
|
13197
|
+
tooltipNode.opened = opened;
|
|
13198
|
+
}
|
|
13199
|
+
}
|
|
13200
|
+
|
|
13201
|
+
/**
|
|
13202
|
+
* Set default position for the slotted tooltip.
|
|
13203
|
+
* This can be overridden by setting the position
|
|
13204
|
+
* using corresponding property or attribute.
|
|
13205
|
+
* @param {string} position
|
|
13206
|
+
*/
|
|
13207
|
+
setPosition(position) {
|
|
13208
|
+
this.position = position;
|
|
13209
|
+
|
|
13210
|
+
const tooltipNode = this.node;
|
|
13211
|
+
if (tooltipNode) {
|
|
13212
|
+
tooltipNode._position = position;
|
|
13213
|
+
}
|
|
13214
|
+
}
|
|
13215
|
+
|
|
13216
|
+
/**
|
|
13217
|
+
* Set function used to detect whether to show
|
|
13218
|
+
* the tooltip based on a condition.
|
|
13219
|
+
* @param {Function} shouldShow
|
|
13220
|
+
*/
|
|
13221
|
+
setShouldShow(shouldShow) {
|
|
13222
|
+
this.shouldShow = shouldShow;
|
|
13223
|
+
|
|
13224
|
+
const tooltipNode = this.node;
|
|
13225
|
+
if (tooltipNode) {
|
|
13226
|
+
tooltipNode.shouldShow = shouldShow;
|
|
13227
|
+
}
|
|
13228
|
+
}
|
|
13229
|
+
|
|
13230
|
+
/**
|
|
13231
|
+
* Set an HTML element to attach the tooltip to.
|
|
13232
|
+
* @param {HTMLElement} target
|
|
13233
|
+
*/
|
|
13234
|
+
setTarget(target) {
|
|
13235
|
+
this.target = target;
|
|
13236
|
+
|
|
13237
|
+
const tooltipNode = this.node;
|
|
13238
|
+
if (tooltipNode) {
|
|
13239
|
+
tooltipNode.target = target;
|
|
13053
13240
|
}
|
|
13054
13241
|
}
|
|
13055
|
-
|
|
13242
|
+
}
|
|
13243
|
+
|
|
13244
|
+
/**
|
|
13245
|
+
* @license
|
|
13246
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
13247
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
13248
|
+
*/
|
|
13249
|
+
|
|
13250
|
+
/**
|
|
13251
|
+
* A mixin to provide disabled property for field components.
|
|
13252
|
+
*
|
|
13253
|
+
* @polymerMixin
|
|
13254
|
+
*/
|
|
13255
|
+
const DisabledMixin = dedupingMixin(
|
|
13256
|
+
(superclass) =>
|
|
13257
|
+
class DisabledMixinClass extends superclass {
|
|
13258
|
+
static get properties() {
|
|
13259
|
+
return {
|
|
13260
|
+
/**
|
|
13261
|
+
* If true, the user cannot interact with this element.
|
|
13262
|
+
*/
|
|
13263
|
+
disabled: {
|
|
13264
|
+
type: Boolean,
|
|
13265
|
+
value: false,
|
|
13266
|
+
observer: '_disabledChanged',
|
|
13267
|
+
reflectToAttribute: true,
|
|
13268
|
+
},
|
|
13269
|
+
};
|
|
13270
|
+
}
|
|
13271
|
+
|
|
13272
|
+
/**
|
|
13273
|
+
* @param {boolean} disabled
|
|
13274
|
+
* @protected
|
|
13275
|
+
*/
|
|
13276
|
+
_disabledChanged(disabled) {
|
|
13277
|
+
this._setAriaDisabled(disabled);
|
|
13278
|
+
}
|
|
13279
|
+
|
|
13280
|
+
/**
|
|
13281
|
+
* @param {boolean} disabled
|
|
13282
|
+
* @protected
|
|
13283
|
+
*/
|
|
13284
|
+
_setAriaDisabled(disabled) {
|
|
13285
|
+
if (disabled) {
|
|
13286
|
+
this.setAttribute('aria-disabled', 'true');
|
|
13287
|
+
} else {
|
|
13288
|
+
this.removeAttribute('aria-disabled');
|
|
13289
|
+
}
|
|
13290
|
+
}
|
|
13291
|
+
|
|
13292
|
+
/**
|
|
13293
|
+
* Overrides the default element `click` method in order to prevent
|
|
13294
|
+
* firing the `click` event when the element is disabled.
|
|
13295
|
+
* @protected
|
|
13296
|
+
* @override
|
|
13297
|
+
*/
|
|
13298
|
+
click() {
|
|
13299
|
+
if (!this.disabled) {
|
|
13300
|
+
super.click();
|
|
13301
|
+
}
|
|
13302
|
+
}
|
|
13303
|
+
},
|
|
13304
|
+
);
|
|
13305
|
+
|
|
13306
|
+
/**
|
|
13307
|
+
@license
|
|
13308
|
+
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
|
13309
|
+
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
|
13310
|
+
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
|
13311
|
+
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
|
13312
|
+
Code distributed by Google as part of the polymer project is also
|
|
13313
|
+
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
|
13314
|
+
*/
|
|
13315
|
+
|
|
13316
|
+
const passiveTouchGestures = false;
|
|
13317
|
+
const wrap = (node) => node;
|
|
13318
|
+
|
|
13319
|
+
// Detect native touch action support
|
|
13320
|
+
const HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
|
|
13321
|
+
const GESTURE_KEY = '__polymerGestures';
|
|
13322
|
+
const HANDLED_OBJ = '__polymerGesturesHandled';
|
|
13323
|
+
const TOUCH_ACTION = '__polymerGesturesTouchAction';
|
|
13324
|
+
// Radius for tap and track
|
|
13325
|
+
const TAP_DISTANCE = 25;
|
|
13326
|
+
const TRACK_DISTANCE = 5;
|
|
13327
|
+
// Number of last N track positions to keep
|
|
13328
|
+
const TRACK_LENGTH = 2;
|
|
13329
|
+
|
|
13330
|
+
const MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'click'];
|
|
13331
|
+
// An array of bitmask values for mapping MouseEvent.which to MouseEvent.buttons
|
|
13332
|
+
const MOUSE_WHICH_TO_BUTTONS = [0, 1, 4, 2];
|
|
13333
|
+
const MOUSE_HAS_BUTTONS = (function () {
|
|
13334
|
+
try {
|
|
13335
|
+
return new MouseEvent('test', { buttons: 1 }).buttons === 1;
|
|
13336
|
+
} catch (e) {
|
|
13337
|
+
return false;
|
|
13338
|
+
}
|
|
13339
|
+
})();
|
|
13340
|
+
|
|
13341
|
+
/**
|
|
13342
|
+
* @param {string} name Possible mouse event name
|
|
13343
|
+
* @return {boolean} true if mouse event, false if not
|
|
13344
|
+
*/
|
|
13345
|
+
function isMouseEvent(name) {
|
|
13346
|
+
return MOUSE_EVENTS.indexOf(name) > -1;
|
|
13347
|
+
}
|
|
13348
|
+
|
|
13349
|
+
/* eslint no-empty: ["error", { "allowEmptyCatch": true }] */
|
|
13350
|
+
// check for passive event listeners
|
|
13351
|
+
let supportsPassive = false;
|
|
13352
|
+
(function () {
|
|
13353
|
+
try {
|
|
13354
|
+
const opts = Object.defineProperty({}, 'passive', {
|
|
13355
|
+
// eslint-disable-next-line getter-return
|
|
13356
|
+
get() {
|
|
13357
|
+
supportsPassive = true;
|
|
13358
|
+
},
|
|
13359
|
+
});
|
|
13360
|
+
window.addEventListener('test', null, opts);
|
|
13361
|
+
window.removeEventListener('test', null, opts);
|
|
13362
|
+
} catch (e) {}
|
|
13363
|
+
})();
|
|
13364
|
+
|
|
13365
|
+
/**
|
|
13366
|
+
* Generate settings for event listeners, dependant on `passiveTouchGestures`
|
|
13367
|
+
*
|
|
13368
|
+
* @param {string} eventName Event name to determine if `{passive}` option is
|
|
13369
|
+
* needed
|
|
13370
|
+
* @return {{passive: boolean} | undefined} Options to use for addEventListener
|
|
13371
|
+
* and removeEventListener
|
|
13372
|
+
*/
|
|
13373
|
+
function PASSIVE_TOUCH(eventName) {
|
|
13374
|
+
if (isMouseEvent(eventName) || eventName === 'touchend') {
|
|
13375
|
+
return;
|
|
13376
|
+
}
|
|
13377
|
+
if (HAS_NATIVE_TA && supportsPassive && passiveTouchGestures) {
|
|
13378
|
+
return { passive: true };
|
|
13379
|
+
}
|
|
13380
|
+
}
|
|
13381
|
+
|
|
13382
|
+
// Check for touch-only devices
|
|
13383
|
+
const IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);
|
|
13384
|
+
|
|
13385
|
+
// Defined at https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute
|
|
13386
|
+
/** @type {!Object<boolean>} */
|
|
13387
|
+
const canBeDisabled = {
|
|
13388
|
+
button: true,
|
|
13389
|
+
command: true,
|
|
13390
|
+
fieldset: true,
|
|
13391
|
+
input: true,
|
|
13392
|
+
keygen: true,
|
|
13393
|
+
optgroup: true,
|
|
13394
|
+
option: true,
|
|
13395
|
+
select: true,
|
|
13396
|
+
textarea: true,
|
|
13397
|
+
};
|
|
13398
|
+
|
|
13399
|
+
/**
|
|
13400
|
+
* @param {MouseEvent} ev event to test for left mouse button down
|
|
13401
|
+
* @return {boolean} has left mouse button down
|
|
13402
|
+
*/
|
|
13403
|
+
function hasLeftMouseButton(ev) {
|
|
13404
|
+
const type = ev.type;
|
|
13405
|
+
// Exit early if the event is not a mouse event
|
|
13406
|
+
if (!isMouseEvent(type)) {
|
|
13407
|
+
return false;
|
|
13408
|
+
}
|
|
13409
|
+
// Ev.button is not reliable for mousemove (0 is overloaded as both left button and no buttons)
|
|
13410
|
+
// instead we use ev.buttons (bitmask of buttons) or fall back to ev.which (deprecated, 0 for no buttons, 1 for left button)
|
|
13411
|
+
if (type === 'mousemove') {
|
|
13412
|
+
// Allow undefined for testing events
|
|
13413
|
+
let buttons = ev.buttons === undefined ? 1 : ev.buttons;
|
|
13414
|
+
if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {
|
|
13415
|
+
buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;
|
|
13416
|
+
}
|
|
13417
|
+
// Buttons is a bitmask, check that the left button bit is set (1)
|
|
13418
|
+
return Boolean(buttons & 1);
|
|
13419
|
+
}
|
|
13420
|
+
// Allow undefined for testing events
|
|
13421
|
+
const button = ev.button === undefined ? 0 : ev.button;
|
|
13422
|
+
// Ev.button is 0 in mousedown/mouseup/click for left button activation
|
|
13423
|
+
return button === 0;
|
|
13424
|
+
}
|
|
13425
|
+
|
|
13426
|
+
function isSyntheticClick(ev) {
|
|
13427
|
+
if (ev.type === 'click') {
|
|
13428
|
+
// Ev.detail is 0 for HTMLElement.click in most browsers
|
|
13429
|
+
if (ev.detail === 0) {
|
|
13430
|
+
return true;
|
|
13431
|
+
}
|
|
13432
|
+
// In the worst case, check that the x/y position of the click is within
|
|
13433
|
+
// the bounding box of the target of the event
|
|
13434
|
+
// Thanks IE 10 >:(
|
|
13435
|
+
const t = _findOriginalTarget(ev);
|
|
13436
|
+
// Make sure the target of the event is an element so we can use getBoundingClientRect,
|
|
13437
|
+
// if not, just assume it is a synthetic click
|
|
13438
|
+
if (!t.nodeType || /** @type {Element} */ (t).nodeType !== Node.ELEMENT_NODE) {
|
|
13439
|
+
return true;
|
|
13440
|
+
}
|
|
13441
|
+
const bcr = /** @type {Element} */ (t).getBoundingClientRect();
|
|
13442
|
+
// Use page x/y to account for scrolling
|
|
13443
|
+
const x = ev.pageX,
|
|
13444
|
+
y = ev.pageY;
|
|
13445
|
+
// Ev is a synthetic click if the position is outside the bounding box of the target
|
|
13446
|
+
return !(x >= bcr.left && x <= bcr.right && y >= bcr.top && y <= bcr.bottom);
|
|
13447
|
+
}
|
|
13448
|
+
return false;
|
|
13449
|
+
}
|
|
13450
|
+
|
|
13451
|
+
const POINTERSTATE = {
|
|
13452
|
+
mouse: {
|
|
13453
|
+
target: null,
|
|
13454
|
+
mouseIgnoreJob: null,
|
|
13455
|
+
},
|
|
13456
|
+
touch: {
|
|
13457
|
+
x: 0,
|
|
13458
|
+
y: 0,
|
|
13459
|
+
id: -1,
|
|
13460
|
+
scrollDecided: false,
|
|
13461
|
+
},
|
|
13462
|
+
};
|
|
13463
|
+
|
|
13464
|
+
function firstTouchAction(ev) {
|
|
13465
|
+
let ta = 'auto';
|
|
13466
|
+
const path = getComposedPath(ev);
|
|
13467
|
+
for (let i = 0, n; i < path.length; i++) {
|
|
13468
|
+
n = path[i];
|
|
13469
|
+
if (n[TOUCH_ACTION]) {
|
|
13470
|
+
ta = n[TOUCH_ACTION];
|
|
13471
|
+
break;
|
|
13472
|
+
}
|
|
13473
|
+
}
|
|
13474
|
+
return ta;
|
|
13056
13475
|
}
|
|
13057
13476
|
|
|
13058
13477
|
function trackDocument(stateObj, movefn, upfn) {
|
|
@@ -13148,7 +13567,7 @@ function _handleNative(ev) {
|
|
|
13148
13567
|
}
|
|
13149
13568
|
if (!ev[HANDLED_OBJ]) {
|
|
13150
13569
|
ev[HANDLED_OBJ] = {};
|
|
13151
|
-
if (type.
|
|
13570
|
+
if (type.startsWith('touch')) {
|
|
13152
13571
|
const t = ev.changedTouches[0];
|
|
13153
13572
|
if (type === 'touchstart') {
|
|
13154
13573
|
// Only handle the first finger
|
|
@@ -13719,100 +14138,38 @@ register({
|
|
|
13719
14138
|
* @param {TouchEvent} e
|
|
13720
14139
|
* @return {void}
|
|
13721
14140
|
*/
|
|
13722
|
-
touchend(e) {
|
|
13723
|
-
trackForward(this.info, e.changedTouches[0], e);
|
|
13724
|
-
},
|
|
13725
|
-
});
|
|
13726
|
-
|
|
13727
|
-
/**
|
|
13728
|
-
* @param {!GestureInfo} info
|
|
13729
|
-
* @param {Event | Touch} e
|
|
13730
|
-
* @param {Event=} preventer
|
|
13731
|
-
* @return {void}
|
|
13732
|
-
*/
|
|
13733
|
-
function trackForward(info, e, preventer) {
|
|
13734
|
-
const dx = Math.abs(e.clientX - info.x);
|
|
13735
|
-
const dy = Math.abs(e.clientY - info.y);
|
|
13736
|
-
// Find original target from `preventer` for TouchEvents, or `e` for MouseEvents
|
|
13737
|
-
const t = _findOriginalTarget(preventer || e);
|
|
13738
|
-
if (!t || (canBeDisabled[/** @type {!HTMLElement} */ (t).localName] && t.hasAttribute('disabled'))) {
|
|
13739
|
-
return;
|
|
13740
|
-
}
|
|
13741
|
-
// Dx,dy can be NaN if `click` has been simulated and there was no `down` for `start`
|
|
13742
|
-
if (isNaN(dx) || isNaN(dy) || (dx <= TAP_DISTANCE && dy <= TAP_DISTANCE) || isSyntheticClick(e)) {
|
|
13743
|
-
// Prevent taps from being generated if an event has canceled them
|
|
13744
|
-
if (!info.prevent) {
|
|
13745
|
-
_fire(t, 'tap', {
|
|
13746
|
-
x: e.clientX,
|
|
13747
|
-
y: e.clientY,
|
|
13748
|
-
sourceEvent: e,
|
|
13749
|
-
preventer,
|
|
13750
|
-
});
|
|
13751
|
-
}
|
|
13752
|
-
}
|
|
13753
|
-
}
|
|
13754
|
-
|
|
13755
|
-
/**
|
|
13756
|
-
* @license
|
|
13757
|
-
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
13758
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
13759
|
-
*/
|
|
13760
|
-
|
|
13761
|
-
/**
|
|
13762
|
-
* A mixin to provide disabled property for field components.
|
|
13763
|
-
*
|
|
13764
|
-
* @polymerMixin
|
|
13765
|
-
*/
|
|
13766
|
-
const DisabledMixin = dedupingMixin(
|
|
13767
|
-
(superclass) =>
|
|
13768
|
-
class DisabledMixinClass extends superclass {
|
|
13769
|
-
static get properties() {
|
|
13770
|
-
return {
|
|
13771
|
-
/**
|
|
13772
|
-
* If true, the user cannot interact with this element.
|
|
13773
|
-
*/
|
|
13774
|
-
disabled: {
|
|
13775
|
-
type: Boolean,
|
|
13776
|
-
value: false,
|
|
13777
|
-
observer: '_disabledChanged',
|
|
13778
|
-
reflectToAttribute: true,
|
|
13779
|
-
},
|
|
13780
|
-
};
|
|
13781
|
-
}
|
|
13782
|
-
|
|
13783
|
-
/**
|
|
13784
|
-
* @param {boolean} disabled
|
|
13785
|
-
* @protected
|
|
13786
|
-
*/
|
|
13787
|
-
_disabledChanged(disabled) {
|
|
13788
|
-
this._setAriaDisabled(disabled);
|
|
13789
|
-
}
|
|
13790
|
-
|
|
13791
|
-
/**
|
|
13792
|
-
* @param {boolean} disabled
|
|
13793
|
-
* @protected
|
|
13794
|
-
*/
|
|
13795
|
-
_setAriaDisabled(disabled) {
|
|
13796
|
-
if (disabled) {
|
|
13797
|
-
this.setAttribute('aria-disabled', 'true');
|
|
13798
|
-
} else {
|
|
13799
|
-
this.removeAttribute('aria-disabled');
|
|
13800
|
-
}
|
|
13801
|
-
}
|
|
14141
|
+
touchend(e) {
|
|
14142
|
+
trackForward(this.info, e.changedTouches[0], e);
|
|
14143
|
+
},
|
|
14144
|
+
});
|
|
13802
14145
|
|
|
13803
|
-
|
|
13804
|
-
|
|
13805
|
-
|
|
13806
|
-
|
|
13807
|
-
|
|
13808
|
-
|
|
13809
|
-
|
|
13810
|
-
|
|
13811
|
-
|
|
13812
|
-
|
|
13813
|
-
|
|
13814
|
-
|
|
13815
|
-
|
|
14146
|
+
/**
|
|
14147
|
+
* @param {!GestureInfo} info
|
|
14148
|
+
* @param {Event | Touch} e
|
|
14149
|
+
* @param {Event=} preventer
|
|
14150
|
+
* @return {void}
|
|
14151
|
+
*/
|
|
14152
|
+
function trackForward(info, e, preventer) {
|
|
14153
|
+
const dx = Math.abs(e.clientX - info.x);
|
|
14154
|
+
const dy = Math.abs(e.clientY - info.y);
|
|
14155
|
+
// Find original target from `preventer` for TouchEvents, or `e` for MouseEvents
|
|
14156
|
+
const t = _findOriginalTarget(preventer || e);
|
|
14157
|
+
if (!t || (canBeDisabled[/** @type {!HTMLElement} */ (t).localName] && t.hasAttribute('disabled'))) {
|
|
14158
|
+
return;
|
|
14159
|
+
}
|
|
14160
|
+
// Dx,dy can be NaN if `click` has been simulated and there was no `down` for `start`
|
|
14161
|
+
if (isNaN(dx) || isNaN(dy) || (dx <= TAP_DISTANCE && dy <= TAP_DISTANCE) || isSyntheticClick(e)) {
|
|
14162
|
+
// Prevent taps from being generated if an event has canceled them
|
|
14163
|
+
if (!info.prevent) {
|
|
14164
|
+
_fire(t, 'tap', {
|
|
14165
|
+
x: e.clientX,
|
|
14166
|
+
y: e.clientY,
|
|
14167
|
+
sourceEvent: e,
|
|
14168
|
+
preventer,
|
|
14169
|
+
});
|
|
14170
|
+
}
|
|
14171
|
+
}
|
|
14172
|
+
}
|
|
13816
14173
|
|
|
13817
14174
|
/**
|
|
13818
14175
|
* @license
|
|
@@ -14007,28 +14364,6 @@ const ActiveMixin = (superclass) =>
|
|
|
14007
14364
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
14008
14365
|
*/
|
|
14009
14366
|
|
|
14010
|
-
// We consider the keyboard to be active if the window has received a keydown
|
|
14011
|
-
// event since the last mousedown event.
|
|
14012
|
-
let keyboardActive = false;
|
|
14013
|
-
|
|
14014
|
-
// Listen for top-level keydown and mousedown events.
|
|
14015
|
-
// Use capture phase so we detect events even if they're handled.
|
|
14016
|
-
window.addEventListener(
|
|
14017
|
-
'keydown',
|
|
14018
|
-
() => {
|
|
14019
|
-
keyboardActive = true;
|
|
14020
|
-
},
|
|
14021
|
-
{ capture: true },
|
|
14022
|
-
);
|
|
14023
|
-
|
|
14024
|
-
window.addEventListener(
|
|
14025
|
-
'mousedown',
|
|
14026
|
-
() => {
|
|
14027
|
-
keyboardActive = false;
|
|
14028
|
-
},
|
|
14029
|
-
{ capture: true },
|
|
14030
|
-
);
|
|
14031
|
-
|
|
14032
14367
|
/**
|
|
14033
14368
|
* A mixin to handle `focused` and `focus-ring` attributes based on focus.
|
|
14034
14369
|
*
|
|
@@ -14042,7 +14377,7 @@ const FocusMixin = dedupingMixin(
|
|
|
14042
14377
|
* @return {boolean}
|
|
14043
14378
|
*/
|
|
14044
14379
|
get _keyboardActive() {
|
|
14045
|
-
return
|
|
14380
|
+
return isKeyboardActive();
|
|
14046
14381
|
}
|
|
14047
14382
|
|
|
14048
14383
|
/** @protected */
|
|
@@ -14306,14 +14641,15 @@ const ButtonMixin = (superClass) =>
|
|
|
14306
14641
|
* `focus-ring` | Set when the button is focused using the keyboard.
|
|
14307
14642
|
* `focused` | Set when the button is focused.
|
|
14308
14643
|
*
|
|
14309
|
-
* See [Styling Components](https://vaadin.com/docs/latest/
|
|
14644
|
+
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
|
|
14310
14645
|
*
|
|
14311
14646
|
* @extends HTMLElement
|
|
14312
14647
|
* @mixes ButtonMixin
|
|
14648
|
+
* @mixes ControllerMixin
|
|
14313
14649
|
* @mixes ElementMixin
|
|
14314
14650
|
* @mixes ThemableMixin
|
|
14315
14651
|
*/
|
|
14316
|
-
class Button extends ButtonMixin(ElementMixin(ThemableMixin(PolymerElement))) {
|
|
14652
|
+
class Button extends ButtonMixin(ElementMixin(ThemableMixin(ControllerMixin(PolymerElement)))) {
|
|
14317
14653
|
static get is() {
|
|
14318
14654
|
return 'vaadin-button';
|
|
14319
14655
|
}
|
|
@@ -14367,18 +14703,27 @@ class Button extends ButtonMixin(ElementMixin(ThemableMixin(PolymerElement))) {
|
|
|
14367
14703
|
}
|
|
14368
14704
|
</style>
|
|
14369
14705
|
<div class="vaadin-button-container">
|
|
14370
|
-
<span part="prefix">
|
|
14706
|
+
<span part="prefix" aria-hidden="true">
|
|
14371
14707
|
<slot name="prefix"></slot>
|
|
14372
14708
|
</span>
|
|
14373
14709
|
<span part="label">
|
|
14374
14710
|
<slot></slot>
|
|
14375
14711
|
</span>
|
|
14376
|
-
<span part="suffix">
|
|
14712
|
+
<span part="suffix" aria-hidden="true">
|
|
14377
14713
|
<slot name="suffix"></slot>
|
|
14378
14714
|
</span>
|
|
14379
14715
|
</div>
|
|
14716
|
+
<slot name="tooltip"></slot>
|
|
14380
14717
|
`;
|
|
14381
14718
|
}
|
|
14719
|
+
|
|
14720
|
+
/** @protected */
|
|
14721
|
+
ready() {
|
|
14722
|
+
super.ready();
|
|
14723
|
+
|
|
14724
|
+
this._tooltipController = new TooltipController(this);
|
|
14725
|
+
this.addController(this._tooltipController);
|
|
14726
|
+
}
|
|
14382
14727
|
}
|
|
14383
14728
|
|
|
14384
14729
|
customElements.define(Button.is, Button);
|
|
@@ -14388,7 +14733,6 @@ registerStyles(
|
|
|
14388
14733
|
i$1`
|
|
14389
14734
|
:host {
|
|
14390
14735
|
position: relative;
|
|
14391
|
-
background-color: transparent;
|
|
14392
14736
|
/* Background for the year scroller, placed here as we are using a mask image on the actual years part */
|
|
14393
14737
|
background-image: linear-gradient(var(--lumo-shade-5pct), var(--lumo-shade-5pct));
|
|
14394
14738
|
background-size: 57px 100%;
|
|
@@ -14414,7 +14758,7 @@ registerStyles(
|
|
|
14414
14758
|
+ var(--lumo-size-m) * 6
|
|
14415
14759
|
+ var(--lumo-space-s)
|
|
14416
14760
|
);
|
|
14417
|
-
--vaadin-infinite-scroller-buffer-offset:
|
|
14761
|
+
--vaadin-infinite-scroller-buffer-offset: 10%;
|
|
14418
14762
|
-webkit-mask-image: linear-gradient(transparent, #000 10%, #000 85%, transparent);
|
|
14419
14763
|
mask-image: linear-gradient(transparent, #000 10%, #000 85%, transparent);
|
|
14420
14764
|
position: relative;
|
|
@@ -14496,17 +14840,10 @@ registerStyles(
|
|
|
14496
14840
|
|
|
14497
14841
|
[part='toolbar'] {
|
|
14498
14842
|
padding: var(--lumo-space-s);
|
|
14499
|
-
box-shadow: 0 -1px 0 0 var(--lumo-contrast-10pct);
|
|
14500
14843
|
border-bottom-left-radius: var(--lumo-border-radius-l);
|
|
14501
14844
|
margin-right: 57px;
|
|
14502
14845
|
}
|
|
14503
14846
|
|
|
14504
|
-
@supports (mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000)) {
|
|
14505
|
-
[part='toolbar'] {
|
|
14506
|
-
box-shadow: none;
|
|
14507
|
-
}
|
|
14508
|
-
}
|
|
14509
|
-
|
|
14510
14847
|
/* Today and Cancel buttons */
|
|
14511
14848
|
|
|
14512
14849
|
[part='toolbar'] [part\$='button'] {
|
|
@@ -14539,8 +14876,6 @@ registerStyles(
|
|
|
14539
14876
|
/* Very narrow screen (year scroller initially hidden) */
|
|
14540
14877
|
|
|
14541
14878
|
[part='years-toggle-button'] {
|
|
14542
|
-
position: relative;
|
|
14543
|
-
right: auto;
|
|
14544
14879
|
display: flex;
|
|
14545
14880
|
align-items: center;
|
|
14546
14881
|
height: var(--lumo-size-s);
|
|
@@ -14558,11 +14893,7 @@ registerStyles(
|
|
|
14558
14893
|
color: var(--lumo-primary-contrast-color);
|
|
14559
14894
|
}
|
|
14560
14895
|
|
|
14561
|
-
|
|
14562
|
-
content: none;
|
|
14563
|
-
}
|
|
14564
|
-
|
|
14565
|
-
/* TODO magic number (same as used for iron-media-query in vaadin-date-picker-overlay-content) */
|
|
14896
|
+
/* TODO magic number (same as used for media-query in vaadin-date-picker-overlay-content) */
|
|
14566
14897
|
@media screen and (max-width: 374px) {
|
|
14567
14898
|
:host {
|
|
14568
14899
|
background-image: none;
|
|
@@ -14737,9 +15068,9 @@ registerStyles(
|
|
|
14737
15068
|
{ moduleId: 'lumo-month-calendar' },
|
|
14738
15069
|
);
|
|
14739
15070
|
|
|
14740
|
-
const $
|
|
15071
|
+
const template$1 = document.createElement('template');
|
|
14741
15072
|
|
|
14742
|
-
$
|
|
15073
|
+
template$1.innerHTML = `
|
|
14743
15074
|
<style>
|
|
14744
15075
|
@keyframes vaadin-date-picker-month-calendar-focus-date {
|
|
14745
15076
|
50% {
|
|
@@ -14749,7 +15080,7 @@ $_documentContainer$1.innerHTML = `
|
|
|
14749
15080
|
</style>
|
|
14750
15081
|
`;
|
|
14751
15082
|
|
|
14752
|
-
document.head.appendChild($
|
|
15083
|
+
document.head.appendChild(template$1.content);
|
|
14753
15084
|
|
|
14754
15085
|
/**
|
|
14755
15086
|
* @license
|
|
@@ -14757,9 +15088,9 @@ document.head.appendChild($_documentContainer$1.content);
|
|
|
14757
15088
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
14758
15089
|
*/
|
|
14759
15090
|
|
|
14760
|
-
const
|
|
15091
|
+
const template = document.createElement('template');
|
|
14761
15092
|
|
|
14762
|
-
|
|
15093
|
+
template.innerHTML = `
|
|
14763
15094
|
<style>
|
|
14764
15095
|
@font-face {
|
|
14765
15096
|
font-family: 'lumo-icons';
|
|
@@ -14815,7 +15146,7 @@ $_documentContainer.innerHTML = `
|
|
|
14815
15146
|
</style>
|
|
14816
15147
|
`;
|
|
14817
15148
|
|
|
14818
|
-
document.head.appendChild(
|
|
15149
|
+
document.head.appendChild(template.content);
|
|
14819
15150
|
|
|
14820
15151
|
/**
|
|
14821
15152
|
* @license
|
|
@@ -14929,6 +15260,10 @@ const requiredField = i$1`
|
|
|
14929
15260
|
line-height: 1;
|
|
14930
15261
|
padding-right: 1em;
|
|
14931
15262
|
padding-bottom: 0.5em;
|
|
15263
|
+
/* As a workaround for diacritics being cut off, add a top padding and a
|
|
15264
|
+
negative margin to compensate */
|
|
15265
|
+
padding-top: 0.25em;
|
|
15266
|
+
margin-top: -0.25em;
|
|
14932
15267
|
overflow: hidden;
|
|
14933
15268
|
white-space: nowrap;
|
|
14934
15269
|
text-overflow: ellipsis;
|
|
@@ -14949,6 +15284,10 @@ const requiredField = i$1`
|
|
|
14949
15284
|
padding-top: var(--lumo-space-m);
|
|
14950
15285
|
}
|
|
14951
15286
|
|
|
15287
|
+
:host([has-label]) ::slotted([slot='tooltip']) {
|
|
15288
|
+
--vaadin-tooltip-offset-bottom: calc((var(--lumo-space-m) - var(--lumo-space-xs)) * -1);
|
|
15289
|
+
}
|
|
15290
|
+
|
|
14952
15291
|
:host([required]) [part='required-indicator']::after {
|
|
14953
15292
|
content: var(--lumo-required-field-indicator, '•');
|
|
14954
15293
|
transition: opacity 0.2s;
|
|
@@ -15382,6 +15721,57 @@ function getAncestorRootNodes(node) {
|
|
|
15382
15721
|
return result;
|
|
15383
15722
|
}
|
|
15384
15723
|
|
|
15724
|
+
/**
|
|
15725
|
+
* @param {string} value
|
|
15726
|
+
* @return {Set<string>}
|
|
15727
|
+
*/
|
|
15728
|
+
function deserializeAttributeValue(value) {
|
|
15729
|
+
if (!value) {
|
|
15730
|
+
return new Set();
|
|
15731
|
+
}
|
|
15732
|
+
|
|
15733
|
+
return new Set(value.split(' '));
|
|
15734
|
+
}
|
|
15735
|
+
|
|
15736
|
+
/**
|
|
15737
|
+
* @param {Set<string>} values
|
|
15738
|
+
* @return {string}
|
|
15739
|
+
*/
|
|
15740
|
+
function serializeAttributeValue(values) {
|
|
15741
|
+
return [...values].join(' ');
|
|
15742
|
+
}
|
|
15743
|
+
|
|
15744
|
+
/**
|
|
15745
|
+
* Adds a value to an attribute containing space-delimited values.
|
|
15746
|
+
*
|
|
15747
|
+
* @param {HTMLElement} element
|
|
15748
|
+
* @param {string} attr
|
|
15749
|
+
* @param {string} value
|
|
15750
|
+
*/
|
|
15751
|
+
function addValueToAttribute(element, attr, value) {
|
|
15752
|
+
const values = deserializeAttributeValue(element.getAttribute(attr));
|
|
15753
|
+
values.add(value);
|
|
15754
|
+
element.setAttribute(attr, serializeAttributeValue(values));
|
|
15755
|
+
}
|
|
15756
|
+
|
|
15757
|
+
/**
|
|
15758
|
+
* Removes a value from an attribute containing space-delimited values.
|
|
15759
|
+
* If the value is the last one, the whole attribute is removed.
|
|
15760
|
+
*
|
|
15761
|
+
* @param {HTMLElement} element
|
|
15762
|
+
* @param {string} attr
|
|
15763
|
+
* @param {string} value
|
|
15764
|
+
*/
|
|
15765
|
+
function removeValueFromAttribute(element, attr, value) {
|
|
15766
|
+
const values = deserializeAttributeValue(element.getAttribute(attr));
|
|
15767
|
+
values.delete(value);
|
|
15768
|
+
if (values.size === 0) {
|
|
15769
|
+
element.removeAttribute(attr);
|
|
15770
|
+
return;
|
|
15771
|
+
}
|
|
15772
|
+
element.setAttribute(attr, serializeAttributeValue(values));
|
|
15773
|
+
}
|
|
15774
|
+
|
|
15385
15775
|
/**
|
|
15386
15776
|
* @license
|
|
15387
15777
|
* Copyright (c) 2017 - 2022 Vaadin Ltd.
|
|
@@ -15398,6 +15788,16 @@ const PROP_NAMES_HORIZONTAL = {
|
|
|
15398
15788
|
end: 'right',
|
|
15399
15789
|
};
|
|
15400
15790
|
|
|
15791
|
+
const targetResizeObserver = new ResizeObserver((entries) => {
|
|
15792
|
+
setTimeout(() => {
|
|
15793
|
+
entries.forEach((entry) => {
|
|
15794
|
+
if (entry.target.__overlay) {
|
|
15795
|
+
entry.target.__overlay._updatePosition();
|
|
15796
|
+
}
|
|
15797
|
+
});
|
|
15798
|
+
});
|
|
15799
|
+
});
|
|
15800
|
+
|
|
15401
15801
|
/**
|
|
15402
15802
|
* @polymerMixin
|
|
15403
15803
|
*/
|
|
@@ -15423,6 +15823,8 @@ const PositionMixin = (superClass) =>
|
|
|
15423
15823
|
* RTL is taken into account when interpreting the value.
|
|
15424
15824
|
* The overlay is automatically flipped to the opposite side when it doesn't fit into
|
|
15425
15825
|
* the default side defined by this property.
|
|
15826
|
+
*
|
|
15827
|
+
* @attr {start|end} horizontal-align
|
|
15426
15828
|
*/
|
|
15427
15829
|
horizontalAlign: {
|
|
15428
15830
|
type: String,
|
|
@@ -15435,6 +15837,8 @@ const PositionMixin = (superClass) =>
|
|
|
15435
15837
|
* Possible values are `top` and `bottom`.
|
|
15436
15838
|
* The overlay is automatically flipped to the opposite side when it doesn't fit into
|
|
15437
15839
|
* the default side defined by this property.
|
|
15840
|
+
*
|
|
15841
|
+
* @attr {top|bottom} vertical-align
|
|
15438
15842
|
*/
|
|
15439
15843
|
verticalAlign: {
|
|
15440
15844
|
type: String,
|
|
@@ -15444,6 +15848,8 @@ const PositionMixin = (superClass) =>
|
|
|
15444
15848
|
/**
|
|
15445
15849
|
* When `positionTarget` is set, this property defines whether the overlay should overlap
|
|
15446
15850
|
* the target element in the x-axis, or be positioned right next to it.
|
|
15851
|
+
*
|
|
15852
|
+
* @attr {boolean} no-horizontal-overlap
|
|
15447
15853
|
*/
|
|
15448
15854
|
noHorizontalOverlap: {
|
|
15449
15855
|
type: Boolean,
|
|
@@ -15453,17 +15859,32 @@ const PositionMixin = (superClass) =>
|
|
|
15453
15859
|
/**
|
|
15454
15860
|
* When `positionTarget` is set, this property defines whether the overlay should overlap
|
|
15455
15861
|
* the target element in the y-axis, or be positioned right above/below it.
|
|
15862
|
+
*
|
|
15863
|
+
* @attr {boolean} no-vertical-overlap
|
|
15456
15864
|
*/
|
|
15457
15865
|
noVerticalOverlap: {
|
|
15458
15866
|
type: Boolean,
|
|
15459
15867
|
value: false,
|
|
15460
15868
|
},
|
|
15869
|
+
|
|
15870
|
+
/**
|
|
15871
|
+
* If the overlay content has no intrinsic height, this property can be used to set
|
|
15872
|
+
* the minimum vertical space (in pixels) required by the overlay. Setting a value to
|
|
15873
|
+
* the property effectively disables the content measurement in favor of using this
|
|
15874
|
+
* fixed value for determining the open direction.
|
|
15875
|
+
*
|
|
15876
|
+
* @attr {number} required-vertical-space
|
|
15877
|
+
*/
|
|
15878
|
+
requiredVerticalSpace: {
|
|
15879
|
+
type: Number,
|
|
15880
|
+
value: 0,
|
|
15881
|
+
},
|
|
15461
15882
|
};
|
|
15462
15883
|
}
|
|
15463
15884
|
|
|
15464
15885
|
static get observers() {
|
|
15465
15886
|
return [
|
|
15466
|
-
'__positionSettingsChanged(horizontalAlign, verticalAlign, noHorizontalOverlap, noVerticalOverlap)',
|
|
15887
|
+
'__positionSettingsChanged(horizontalAlign, verticalAlign, noHorizontalOverlap, noVerticalOverlap, requiredVerticalSpace)',
|
|
15467
15888
|
'__overlayOpenedChanged(opened, positionTarget)',
|
|
15468
15889
|
];
|
|
15469
15890
|
}
|
|
@@ -15471,6 +15892,7 @@ const PositionMixin = (superClass) =>
|
|
|
15471
15892
|
constructor() {
|
|
15472
15893
|
super();
|
|
15473
15894
|
|
|
15895
|
+
this.__onScroll = this.__onScroll.bind(this);
|
|
15474
15896
|
this._updatePosition = this._updatePosition.bind(this);
|
|
15475
15897
|
}
|
|
15476
15898
|
|
|
@@ -15495,7 +15917,7 @@ const PositionMixin = (superClass) =>
|
|
|
15495
15917
|
|
|
15496
15918
|
this.__positionTargetAncestorRootNodes = getAncestorRootNodes(this.positionTarget);
|
|
15497
15919
|
this.__positionTargetAncestorRootNodes.forEach((node) => {
|
|
15498
|
-
node.addEventListener('scroll', this.
|
|
15920
|
+
node.addEventListener('scroll', this.__onScroll, true);
|
|
15499
15921
|
});
|
|
15500
15922
|
}
|
|
15501
15923
|
|
|
@@ -15505,7 +15927,7 @@ const PositionMixin = (superClass) =>
|
|
|
15505
15927
|
|
|
15506
15928
|
if (this.__positionTargetAncestorRootNodes) {
|
|
15507
15929
|
this.__positionTargetAncestorRootNodes.forEach((node) => {
|
|
15508
|
-
node.removeEventListener('scroll', this.
|
|
15930
|
+
node.removeEventListener('scroll', this.__onScroll, true);
|
|
15509
15931
|
});
|
|
15510
15932
|
this.__positionTargetAncestorRootNodes = null;
|
|
15511
15933
|
}
|
|
@@ -15515,8 +15937,15 @@ const PositionMixin = (superClass) =>
|
|
|
15515
15937
|
__overlayOpenedChanged(opened, positionTarget) {
|
|
15516
15938
|
this.__removeUpdatePositionEventListeners();
|
|
15517
15939
|
|
|
15518
|
-
if (
|
|
15519
|
-
|
|
15940
|
+
if (positionTarget) {
|
|
15941
|
+
positionTarget.__overlay = null;
|
|
15942
|
+
targetResizeObserver.unobserve(positionTarget);
|
|
15943
|
+
|
|
15944
|
+
if (opened) {
|
|
15945
|
+
this.__addUpdatePositionEventListeners();
|
|
15946
|
+
positionTarget.__overlay = this;
|
|
15947
|
+
targetResizeObserver.observe(positionTarget);
|
|
15948
|
+
}
|
|
15520
15949
|
}
|
|
15521
15950
|
|
|
15522
15951
|
if (opened) {
|
|
@@ -15543,6 +15972,14 @@ const PositionMixin = (superClass) =>
|
|
|
15543
15972
|
this._updatePosition();
|
|
15544
15973
|
}
|
|
15545
15974
|
|
|
15975
|
+
/** @private */
|
|
15976
|
+
__onScroll(e) {
|
|
15977
|
+
// If the scroll event occurred inside the overlay, ignore it.
|
|
15978
|
+
if (!this.contains(e.target)) {
|
|
15979
|
+
this._updatePosition();
|
|
15980
|
+
}
|
|
15981
|
+
}
|
|
15982
|
+
|
|
15546
15983
|
_updatePosition() {
|
|
15547
15984
|
if (!this.positionTarget || !this.opened) {
|
|
15548
15985
|
return;
|
|
@@ -15615,7 +16052,8 @@ const PositionMixin = (superClass) =>
|
|
|
15615
16052
|
__shouldAlignStartVertically(targetRect) {
|
|
15616
16053
|
// Using previous size to fix a case where window resize may cause the overlay to be squeezed
|
|
15617
16054
|
// smaller than its current space before the fit-calculations.
|
|
15618
|
-
const contentHeight =
|
|
16055
|
+
const contentHeight =
|
|
16056
|
+
this.requiredVerticalSpace || Math.max(this.__oldContentHeight || 0, this.$.overlay.offsetHeight);
|
|
15619
16057
|
this.__oldContentHeight = this.$.overlay.offsetHeight;
|
|
15620
16058
|
|
|
15621
16059
|
const viewportHeight = Math.min(window.innerHeight, document.documentElement.clientHeight);
|
|
@@ -15647,9 +16085,47 @@ const PositionMixin = (superClass) =>
|
|
|
15647
16085
|
return defaultAlignStart === shouldGoToDefaultSide;
|
|
15648
16086
|
}
|
|
15649
16087
|
|
|
16088
|
+
/**
|
|
16089
|
+
* Returns an adjusted value after resizing the browser window,
|
|
16090
|
+
* to avoid wrong calculations when e.g. previously set `bottom`
|
|
16091
|
+
* CSS property value is larger than the updated viewport height.
|
|
16092
|
+
* See https://github.com/vaadin/web-components/issues/4604
|
|
16093
|
+
*/
|
|
16094
|
+
__adjustBottomProperty(cssPropNameToSet, propNames, currentValue) {
|
|
16095
|
+
let adjustedProp;
|
|
16096
|
+
|
|
16097
|
+
if (cssPropNameToSet === propNames.end) {
|
|
16098
|
+
// Adjust horizontally
|
|
16099
|
+
if (propNames.end === PROP_NAMES_VERTICAL.end) {
|
|
16100
|
+
const viewportHeight = Math.min(window.innerHeight, document.documentElement.clientHeight);
|
|
16101
|
+
|
|
16102
|
+
if (currentValue > viewportHeight && this.__oldViewportHeight) {
|
|
16103
|
+
const heightDiff = this.__oldViewportHeight - viewportHeight;
|
|
16104
|
+
adjustedProp = currentValue - heightDiff;
|
|
16105
|
+
}
|
|
16106
|
+
|
|
16107
|
+
this.__oldViewportHeight = viewportHeight;
|
|
16108
|
+
}
|
|
16109
|
+
|
|
16110
|
+
// Adjust vertically
|
|
16111
|
+
if (propNames.end === PROP_NAMES_HORIZONTAL.end) {
|
|
16112
|
+
const viewportWidth = Math.min(window.innerWidth, document.documentElement.clientWidth);
|
|
16113
|
+
|
|
16114
|
+
if (currentValue > viewportWidth && this.__oldViewportWidth) {
|
|
16115
|
+
const widthDiff = this.__oldViewportWidth - viewportWidth;
|
|
16116
|
+
adjustedProp = currentValue - widthDiff;
|
|
16117
|
+
}
|
|
16118
|
+
|
|
16119
|
+
this.__oldViewportWidth = viewportWidth;
|
|
16120
|
+
}
|
|
16121
|
+
}
|
|
16122
|
+
|
|
16123
|
+
return adjustedProp;
|
|
16124
|
+
}
|
|
16125
|
+
|
|
15650
16126
|
/**
|
|
15651
16127
|
* Returns an object with CSS position properties to set,
|
|
15652
|
-
* e.g. { top: "100px"
|
|
16128
|
+
* e.g. { top: "100px" }
|
|
15653
16129
|
*/
|
|
15654
16130
|
// eslint-disable-next-line max-params
|
|
15655
16131
|
__calculatePositionInOneDimension(targetRect, overlayRect, noOverlap, propNames, overlay, shouldAlignStart) {
|
|
@@ -15657,13 +16133,18 @@ const PositionMixin = (superClass) =>
|
|
|
15657
16133
|
const cssPropNameToClear = shouldAlignStart ? propNames.end : propNames.start;
|
|
15658
16134
|
|
|
15659
16135
|
const currentValue = parseFloat(overlay.style[cssPropNameToSet] || getComputedStyle(overlay)[cssPropNameToSet]);
|
|
16136
|
+
const adjustedValue = this.__adjustBottomProperty(cssPropNameToSet, propNames, currentValue);
|
|
15660
16137
|
|
|
15661
16138
|
const diff =
|
|
15662
16139
|
overlayRect[shouldAlignStart ? propNames.start : propNames.end] -
|
|
15663
16140
|
targetRect[noOverlap === shouldAlignStart ? propNames.end : propNames.start];
|
|
15664
16141
|
|
|
16142
|
+
const valueToSet = adjustedValue
|
|
16143
|
+
? `${adjustedValue}px`
|
|
16144
|
+
: `${currentValue + diff * (shouldAlignStart ? -1 : 1)}px`;
|
|
16145
|
+
|
|
15665
16146
|
return {
|
|
15666
|
-
[cssPropNameToSet]:
|
|
16147
|
+
[cssPropNameToSet]: valueToSet,
|
|
15667
16148
|
[cssPropNameToClear]: '',
|
|
15668
16149
|
};
|
|
15669
16150
|
}
|
|
@@ -15680,11 +16161,6 @@ const datePickerStyles = i$1`
|
|
|
15680
16161
|
direction: ltr;
|
|
15681
16162
|
}
|
|
15682
16163
|
|
|
15683
|
-
:host([dir='rtl']) [part='value']::placeholder {
|
|
15684
|
-
direction: rtl;
|
|
15685
|
-
text-align: left;
|
|
15686
|
-
}
|
|
15687
|
-
|
|
15688
16164
|
:host([dir='rtl']) [part='input-field'] ::slotted(input)::placeholder {
|
|
15689
16165
|
direction: rtl;
|
|
15690
16166
|
text-align: left;
|
|
@@ -15717,10 +16193,10 @@ let memoizedTemplate;
|
|
|
15717
16193
|
/**
|
|
15718
16194
|
* An element used internally by `<vaadin-date-picker>`. Not intended to be used separately.
|
|
15719
16195
|
*
|
|
15720
|
-
* @extends
|
|
16196
|
+
* @extends Overlay
|
|
15721
16197
|
* @private
|
|
15722
16198
|
*/
|
|
15723
|
-
class DatePickerOverlay extends DisableUpgradeMixin(PositionMixin(
|
|
16199
|
+
class DatePickerOverlay extends DisableUpgradeMixin(PositionMixin(Overlay)) {
|
|
15724
16200
|
static get is() {
|
|
15725
16201
|
return 'vaadin-date-picker-overlay';
|
|
15726
16202
|
}
|
|
@@ -16860,6 +17336,53 @@ function extractDateParts(date) {
|
|
|
16860
17336
|
};
|
|
16861
17337
|
}
|
|
16862
17338
|
|
|
17339
|
+
/**
|
|
17340
|
+
* Calculate the year of the date based on the provided reference date.
|
|
17341
|
+
* Gets a two-digit year and returns a full year.
|
|
17342
|
+
* @param {!Date} referenceDate The date to act as basis in the calculation
|
|
17343
|
+
* @param {!number} year Should be in the range of [0, 99]
|
|
17344
|
+
* @param {number} month
|
|
17345
|
+
* @param {number} day
|
|
17346
|
+
* @return {!number} Adjusted year value
|
|
17347
|
+
*/
|
|
17348
|
+
function getAdjustedYear(referenceDate, year, month = 0, day = 1) {
|
|
17349
|
+
if (year > 99) {
|
|
17350
|
+
throw new Error('The provided year cannot have more than 2 digits.');
|
|
17351
|
+
}
|
|
17352
|
+
if (year < 0) {
|
|
17353
|
+
throw new Error('The provided year cannot be negative.');
|
|
17354
|
+
}
|
|
17355
|
+
// Year values up to 2 digits are parsed based on the reference date.
|
|
17356
|
+
let adjustedYear = year + Math.floor(referenceDate.getFullYear() / 100) * 100;
|
|
17357
|
+
if (referenceDate < new Date(adjustedYear - 50, month, day)) {
|
|
17358
|
+
adjustedYear -= 100;
|
|
17359
|
+
} else if (referenceDate > new Date(adjustedYear + 50, month, day)) {
|
|
17360
|
+
adjustedYear += 100;
|
|
17361
|
+
}
|
|
17362
|
+
return adjustedYear;
|
|
17363
|
+
}
|
|
17364
|
+
|
|
17365
|
+
/**
|
|
17366
|
+
* Parse date string of one of the following date formats:
|
|
17367
|
+
* - ISO 8601 `"YYYY-MM-DD"`
|
|
17368
|
+
* - 6-digit extended ISO 8601 `"+YYYYYY-MM-DD"`, `"-YYYYYY-MM-DD"`
|
|
17369
|
+
* @param {!string} str Date string to parse
|
|
17370
|
+
* @return {Date} Parsed date
|
|
17371
|
+
*/
|
|
17372
|
+
function parseDate(str) {
|
|
17373
|
+
// Parsing with RegExp to ensure correct format
|
|
17374
|
+
const parts = /^([-+]\d{1}|\d{2,4}|[-+]\d{6})-(\d{1,2})-(\d{1,2})$/.exec(str);
|
|
17375
|
+
if (!parts) {
|
|
17376
|
+
return undefined;
|
|
17377
|
+
}
|
|
17378
|
+
|
|
17379
|
+
const date = new Date(0, 0); // Wrong date (1900-01-01), but with midnight in local time
|
|
17380
|
+
date.setFullYear(parseInt(parts[1], 10));
|
|
17381
|
+
date.setMonth(parseInt(parts[2], 10) - 1);
|
|
17382
|
+
date.setDate(parseInt(parts[3], 10));
|
|
17383
|
+
return date;
|
|
17384
|
+
}
|
|
17385
|
+
|
|
16863
17386
|
/**
|
|
16864
17387
|
* @license
|
|
16865
17388
|
* Copyright (c) 2016 - 2022 Vaadin Ltd.
|
|
@@ -16936,7 +17459,9 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
16936
17459
|
is="dom-repeat"
|
|
16937
17460
|
items="[[_getWeekDayNames(i18n.weekdays, i18n.weekdaysShort, showWeekNumbers, i18n.firstDayOfWeek)]]"
|
|
16938
17461
|
>
|
|
16939
|
-
<th role="columnheader" part="weekday" scope="col" abbr$="[[item.weekDay]]">
|
|
17462
|
+
<th role="columnheader" part="weekday" scope="col" abbr$="[[item.weekDay]]" aria-hidden="true">
|
|
17463
|
+
[[item.weekDayShort]]
|
|
17464
|
+
</th>
|
|
16940
17465
|
</template>
|
|
16941
17466
|
</tr>
|
|
16942
17467
|
</thead>
|
|
@@ -17106,7 +17631,9 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
17106
17631
|
|
|
17107
17632
|
_onMonthGridTouchStart() {
|
|
17108
17633
|
this._notTapping = false;
|
|
17109
|
-
setTimeout(() =>
|
|
17634
|
+
setTimeout(() => {
|
|
17635
|
+
this._notTapping = true;
|
|
17636
|
+
}, 300);
|
|
17110
17637
|
}
|
|
17111
17638
|
|
|
17112
17639
|
_dateAdd(date, delta) {
|
|
@@ -17280,12 +17807,6 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
17280
17807
|
|
|
17281
17808
|
return '-1';
|
|
17282
17809
|
}
|
|
17283
|
-
|
|
17284
|
-
__getWeekNumbers(dates) {
|
|
17285
|
-
return dates
|
|
17286
|
-
.map((date) => this.__getWeekNumber(date, dates))
|
|
17287
|
-
.filter((week, index, arr) => arr.indexOf(week) === index);
|
|
17288
|
-
}
|
|
17289
17810
|
}
|
|
17290
17811
|
|
|
17291
17812
|
customElements.define(MonthCalendar.is, MonthCalendar);
|
|
@@ -17375,6 +17896,7 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17375
17896
|
/**
|
|
17376
17897
|
* The amount of initial scroll top. Needed in order for the
|
|
17377
17898
|
* user to be able to scroll backwards.
|
|
17899
|
+
* @private
|
|
17378
17900
|
*/
|
|
17379
17901
|
_initialScroll: {
|
|
17380
17902
|
value: 500000,
|
|
@@ -17382,17 +17904,22 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17382
17904
|
|
|
17383
17905
|
/**
|
|
17384
17906
|
* The index/position mapped at _initialScroll point.
|
|
17907
|
+
* @private
|
|
17385
17908
|
*/
|
|
17386
17909
|
_initialIndex: {
|
|
17387
17910
|
value: 0,
|
|
17388
17911
|
},
|
|
17389
17912
|
|
|
17913
|
+
/** @private */
|
|
17390
17914
|
_buffers: Array,
|
|
17391
17915
|
|
|
17916
|
+
/** @private */
|
|
17392
17917
|
_preventScrollEvent: Boolean,
|
|
17393
17918
|
|
|
17919
|
+
/** @private */
|
|
17394
17920
|
_mayHaveMomentum: Boolean,
|
|
17395
17921
|
|
|
17922
|
+
/** @private */
|
|
17396
17923
|
_initialized: Boolean,
|
|
17397
17924
|
|
|
17398
17925
|
active: {
|
|
@@ -17402,10 +17929,11 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17402
17929
|
};
|
|
17403
17930
|
}
|
|
17404
17931
|
|
|
17932
|
+
/** @protected */
|
|
17405
17933
|
ready() {
|
|
17406
17934
|
super.ready();
|
|
17407
17935
|
|
|
17408
|
-
this._buffers =
|
|
17936
|
+
this._buffers = [...this.shadowRoot.querySelectorAll('.buffer')];
|
|
17409
17937
|
|
|
17410
17938
|
this.$.fullHeight.style.height = `${this._initialScroll * 2}px`;
|
|
17411
17939
|
|
|
@@ -17414,8 +17942,8 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17414
17942
|
forwardHostProp(prop, value) {
|
|
17415
17943
|
if (prop !== 'index') {
|
|
17416
17944
|
this._buffers.forEach((buffer) => {
|
|
17417
|
-
[].forEach
|
|
17418
|
-
|
|
17945
|
+
[...buffer.children].forEach((slot) => {
|
|
17946
|
+
slot._itemWrapper.instance[prop] = value;
|
|
17419
17947
|
});
|
|
17420
17948
|
});
|
|
17421
17949
|
}
|
|
@@ -17429,6 +17957,19 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17429
17957
|
}
|
|
17430
17958
|
}
|
|
17431
17959
|
|
|
17960
|
+
/**
|
|
17961
|
+
* Force the scroller to update clones after a reset, without
|
|
17962
|
+
* waiting for the debouncer to resolve.
|
|
17963
|
+
*/
|
|
17964
|
+
forceUpdate() {
|
|
17965
|
+
if (this._debouncerUpdateClones) {
|
|
17966
|
+
this._buffers[0].updated = this._buffers[1].updated = false;
|
|
17967
|
+
this._updateClones();
|
|
17968
|
+
this._debouncerUpdateClones.cancel();
|
|
17969
|
+
}
|
|
17970
|
+
}
|
|
17971
|
+
|
|
17972
|
+
/** @private */
|
|
17432
17973
|
_activated(active) {
|
|
17433
17974
|
if (active && !this._initialized) {
|
|
17434
17975
|
this._createPool();
|
|
@@ -17436,12 +17977,15 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17436
17977
|
}
|
|
17437
17978
|
}
|
|
17438
17979
|
|
|
17980
|
+
/** @private */
|
|
17439
17981
|
_finishInit() {
|
|
17440
17982
|
if (!this._initDone) {
|
|
17441
17983
|
// Once the first set of items start fading in, stamp the rest
|
|
17442
17984
|
this._buffers.forEach((buffer) => {
|
|
17443
|
-
[].forEach
|
|
17444
|
-
|
|
17985
|
+
[...buffer.children].forEach((slot) => {
|
|
17986
|
+
this._ensureStampedInstance(slot._itemWrapper);
|
|
17987
|
+
});
|
|
17988
|
+
});
|
|
17445
17989
|
|
|
17446
17990
|
if (!this._buffers[0].translateY) {
|
|
17447
17991
|
this._reset();
|
|
@@ -17451,6 +17995,7 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17451
17995
|
}
|
|
17452
17996
|
}
|
|
17453
17997
|
|
|
17998
|
+
/** @private */
|
|
17454
17999
|
_translateBuffer(up) {
|
|
17455
18000
|
const index = up ? 1 : 0;
|
|
17456
18001
|
this._buffers[index].translateY = this._buffers[index ? 0 : 1].translateY + this._bufferHeight * (index ? -1 : 1);
|
|
@@ -17459,6 +18004,7 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17459
18004
|
this._buffers.reverse();
|
|
17460
18005
|
}
|
|
17461
18006
|
|
|
18007
|
+
/** @private */
|
|
17462
18008
|
_scroll() {
|
|
17463
18009
|
if (this._scrollDisabled) {
|
|
17464
18010
|
return;
|
|
@@ -17555,10 +18101,12 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17555
18101
|
return this._itemHeightVal;
|
|
17556
18102
|
}
|
|
17557
18103
|
|
|
18104
|
+
/** @private */
|
|
17558
18105
|
get _bufferHeight() {
|
|
17559
18106
|
return this.itemHeight * this.bufferSize;
|
|
17560
18107
|
}
|
|
17561
18108
|
|
|
18109
|
+
/** @private */
|
|
17562
18110
|
_reset() {
|
|
17563
18111
|
this._scrollDisabled = true;
|
|
17564
18112
|
this.$.scroller.scrollTop = this._initialScroll;
|
|
@@ -17578,6 +18126,7 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17578
18126
|
this._scrollDisabled = false;
|
|
17579
18127
|
}
|
|
17580
18128
|
|
|
18129
|
+
/** @private */
|
|
17581
18130
|
_createPool() {
|
|
17582
18131
|
const container = this.getBoundingClientRect();
|
|
17583
18132
|
this._buffers.forEach((buffer) => {
|
|
@@ -17589,10 +18138,10 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17589
18138
|
const contentId = (InfiniteScroller._contentIndex = InfiniteScroller._contentIndex + 1 || 0);
|
|
17590
18139
|
const slotName = `vaadin-infinite-scroller-item-content-${contentId}`;
|
|
17591
18140
|
|
|
17592
|
-
const
|
|
17593
|
-
|
|
17594
|
-
|
|
17595
|
-
buffer.appendChild(
|
|
18141
|
+
const slot = document.createElement('slot');
|
|
18142
|
+
slot.setAttribute('name', slotName);
|
|
18143
|
+
slot._itemWrapper = itemWrapper;
|
|
18144
|
+
buffer.appendChild(slot);
|
|
17596
18145
|
|
|
17597
18146
|
itemWrapper.setAttribute('slot', slotName);
|
|
17598
18147
|
this.appendChild(itemWrapper);
|
|
@@ -17604,13 +18153,14 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17604
18153
|
}
|
|
17605
18154
|
}, 1); // Wait for first reset
|
|
17606
18155
|
}
|
|
17607
|
-
}
|
|
18156
|
+
});
|
|
17608
18157
|
|
|
17609
18158
|
setTimeout(() => {
|
|
17610
18159
|
afterNextRender(this, this._finishInit.bind(this));
|
|
17611
18160
|
}, 1);
|
|
17612
18161
|
}
|
|
17613
18162
|
|
|
18163
|
+
/** @private */
|
|
17614
18164
|
_ensureStampedInstance(itemWrapper) {
|
|
17615
18165
|
if (itemWrapper.firstElementChild) {
|
|
17616
18166
|
return;
|
|
@@ -17626,6 +18176,7 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17626
18176
|
});
|
|
17627
18177
|
}
|
|
17628
18178
|
|
|
18179
|
+
/** @private */
|
|
17629
18180
|
_updateClones(viewPortOnly) {
|
|
17630
18181
|
this._firstIndex = ~~((this._buffers[0].translateY - this._initialScroll) / this.itemHeight) + this._initialIndex;
|
|
17631
18182
|
|
|
@@ -17634,17 +18185,18 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17634
18185
|
if (!buffer.updated) {
|
|
17635
18186
|
const firstIndex = this._firstIndex + this.bufferSize * bufferIndex;
|
|
17636
18187
|
|
|
17637
|
-
[].forEach
|
|
17638
|
-
const itemWrapper =
|
|
18188
|
+
[...buffer.children].forEach((slot, index) => {
|
|
18189
|
+
const itemWrapper = slot._itemWrapper;
|
|
17639
18190
|
if (!viewPortOnly || this._isVisible(itemWrapper, scrollerRect)) {
|
|
17640
18191
|
itemWrapper.instance.index = firstIndex + index;
|
|
17641
18192
|
}
|
|
17642
18193
|
});
|
|
17643
18194
|
buffer.updated = true;
|
|
17644
18195
|
}
|
|
17645
|
-
}
|
|
18196
|
+
});
|
|
17646
18197
|
}
|
|
17647
18198
|
|
|
18199
|
+
/** @private */
|
|
17648
18200
|
_isVisible(element, container) {
|
|
17649
18201
|
const rect = element.getBoundingClientRect();
|
|
17650
18202
|
return rect.bottom > container.top && rect.top < container.bottom;
|
|
@@ -17741,7 +18293,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
17741
18293
|
height: 100%;
|
|
17742
18294
|
width: 100%;
|
|
17743
18295
|
outline: none;
|
|
17744
|
-
background: #fff;
|
|
17745
18296
|
}
|
|
17746
18297
|
|
|
17747
18298
|
[part='overlay-header'] {
|
|
@@ -17759,22 +18310,14 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
17759
18310
|
flex-grow: 1;
|
|
17760
18311
|
}
|
|
17761
18312
|
|
|
17762
|
-
[
|
|
17763
|
-
display: none;
|
|
18313
|
+
[hidden] {
|
|
18314
|
+
display: none !important;
|
|
17764
18315
|
}
|
|
17765
18316
|
|
|
17766
18317
|
[part='years-toggle-button'] {
|
|
17767
18318
|
display: flex;
|
|
17768
18319
|
}
|
|
17769
18320
|
|
|
17770
|
-
[part='years-toggle-button'][desktop] {
|
|
17771
|
-
display: none;
|
|
17772
|
-
}
|
|
17773
|
-
|
|
17774
|
-
:host(:not([years-visible])) [part='years-toggle-button']::before {
|
|
17775
|
-
transform: rotate(180deg);
|
|
17776
|
-
}
|
|
17777
|
-
|
|
17778
18321
|
#scrollers {
|
|
17779
18322
|
display: flex;
|
|
17780
18323
|
height: 100%;
|
|
@@ -17848,27 +18391,14 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
17848
18391
|
z-index: 2;
|
|
17849
18392
|
flex-shrink: 0;
|
|
17850
18393
|
}
|
|
17851
|
-
|
|
17852
|
-
[part~='overlay-header']:not([desktop]) {
|
|
17853
|
-
padding-bottom: 40px;
|
|
17854
|
-
}
|
|
17855
|
-
|
|
17856
|
-
[part~='years-toggle-button'] {
|
|
17857
|
-
position: absolute;
|
|
17858
|
-
top: auto;
|
|
17859
|
-
right: 8px;
|
|
17860
|
-
bottom: 0;
|
|
17861
|
-
z-index: 1;
|
|
17862
|
-
padding: 8px;
|
|
17863
|
-
}
|
|
17864
18394
|
</style>
|
|
17865
18395
|
|
|
17866
18396
|
<div part="overlay-header" on-touchend="_preventDefault" desktop$="[[_desktopMode]]" aria-hidden="true">
|
|
17867
18397
|
<div part="label">[[_formatDisplayed(selectedDate, i18n.formatDate, label)]]</div>
|
|
17868
|
-
<div part="clear-button"
|
|
18398
|
+
<div part="clear-button" hidden$="[[!selectedDate]]"></div>
|
|
17869
18399
|
<div part="toggle-button"></div>
|
|
17870
18400
|
|
|
17871
|
-
<div part="years-toggle-button"
|
|
18401
|
+
<div part="years-toggle-button" hidden$="[[_desktopMode]]" aria-hidden="true">
|
|
17872
18402
|
[[_yearAfterXMonths(_visibleMonthIndex)]]
|
|
17873
18403
|
</div>
|
|
17874
18404
|
</div>
|
|
@@ -17954,6 +18484,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
17954
18484
|
*/
|
|
17955
18485
|
selectedDate: {
|
|
17956
18486
|
type: Date,
|
|
18487
|
+
value: null,
|
|
17957
18488
|
},
|
|
17958
18489
|
|
|
17959
18490
|
/**
|
|
@@ -18029,10 +18560,24 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18029
18560
|
return this.getAttribute('dir') === 'rtl';
|
|
18030
18561
|
}
|
|
18031
18562
|
|
|
18563
|
+
/**
|
|
18564
|
+
* Whether to scroll to a sub-month position when scrolling to a date.
|
|
18565
|
+
* This is active if the month scroller is not large enough to fit a
|
|
18566
|
+
* full month. In that case we want to scroll to a position between
|
|
18567
|
+
* two months in order to have the focused date in the visible area.
|
|
18568
|
+
* @returns {boolean} whether to use sub-month scrolling
|
|
18569
|
+
* @private
|
|
18570
|
+
*/
|
|
18571
|
+
get __useSubMonthScrolling() {
|
|
18572
|
+
return this.$.monthScroller.clientHeight < this.$.monthScroller.itemHeight + this.$.monthScroller.bufferOffset;
|
|
18573
|
+
}
|
|
18574
|
+
|
|
18575
|
+
get calendars() {
|
|
18576
|
+
return [...this.shadowRoot.querySelectorAll('vaadin-month-calendar')];
|
|
18577
|
+
}
|
|
18578
|
+
|
|
18032
18579
|
get focusableDateElement() {
|
|
18033
|
-
return
|
|
18034
|
-
.map((calendar) => calendar.focusableDateElement)
|
|
18035
|
-
.find(Boolean);
|
|
18580
|
+
return this.calendars.map((calendar) => calendar.focusableDateElement).find(Boolean);
|
|
18036
18581
|
}
|
|
18037
18582
|
|
|
18038
18583
|
ready() {
|
|
@@ -18040,7 +18585,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18040
18585
|
|
|
18041
18586
|
this.setAttribute('role', 'dialog');
|
|
18042
18587
|
|
|
18043
|
-
addListener(this, 'tap', this._stopPropagation);
|
|
18044
18588
|
addListener(this.$.scrollers, 'track', this._track.bind(this));
|
|
18045
18589
|
addListener(this.shadowRoot.querySelector('[part="clear-button"]'), 'tap', this._clear.bind(this));
|
|
18046
18590
|
addListener(this.shadowRoot.querySelector('[part="today-button"]'), 'tap', this._onTodayTap.bind(this));
|
|
@@ -18085,7 +18629,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18085
18629
|
* Scrolls the list to the given Date.
|
|
18086
18630
|
*/
|
|
18087
18631
|
scrollToDate(date, animate) {
|
|
18088
|
-
this.
|
|
18632
|
+
const offset = this.__useSubMonthScrolling ? this._calculateWeekScrollOffset(date) : 0;
|
|
18633
|
+
this._scrollToPosition(this._differenceInMonths(date, this._originDate) + offset, animate);
|
|
18634
|
+
this.$.monthScroller.forceUpdate();
|
|
18089
18635
|
}
|
|
18090
18636
|
|
|
18091
18637
|
/**
|
|
@@ -18117,23 +18663,63 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18117
18663
|
* Scrolls the month and year scrollers enough to reveal the given date.
|
|
18118
18664
|
*/
|
|
18119
18665
|
revealDate(date, animate = true) {
|
|
18120
|
-
if (date) {
|
|
18121
|
-
|
|
18122
|
-
|
|
18666
|
+
if (!date) {
|
|
18667
|
+
return;
|
|
18668
|
+
}
|
|
18669
|
+
const diff = this._differenceInMonths(date, this._originDate);
|
|
18670
|
+
// If scroll area does not fit the full month, then always scroll with an offset to
|
|
18671
|
+
// approximately display the week of the date
|
|
18672
|
+
if (this.__useSubMonthScrolling) {
|
|
18673
|
+
const offset = this._calculateWeekScrollOffset(date);
|
|
18674
|
+
this._scrollToPosition(diff + offset, animate);
|
|
18675
|
+
return;
|
|
18676
|
+
}
|
|
18123
18677
|
|
|
18124
|
-
|
|
18125
|
-
|
|
18126
|
-
|
|
18127
|
-
|
|
18128
|
-
|
|
18129
|
-
|
|
18678
|
+
// Otherwise determine if we need to scroll to make the month of the date visible
|
|
18679
|
+
const scrolledAboveViewport = this.$.monthScroller.position > diff;
|
|
18680
|
+
|
|
18681
|
+
const visibleArea = Math.max(
|
|
18682
|
+
this.$.monthScroller.itemHeight,
|
|
18683
|
+
this.$.monthScroller.clientHeight - this.$.monthScroller.bufferOffset * 2,
|
|
18684
|
+
);
|
|
18685
|
+
const visibleItems = visibleArea / this.$.monthScroller.itemHeight;
|
|
18686
|
+
const scrolledBelowViewport = this.$.monthScroller.position + visibleItems - 1 < diff;
|
|
18130
18687
|
|
|
18131
|
-
|
|
18132
|
-
|
|
18133
|
-
|
|
18134
|
-
|
|
18688
|
+
if (scrolledAboveViewport) {
|
|
18689
|
+
this._scrollToPosition(diff, animate);
|
|
18690
|
+
} else if (scrolledBelowViewport) {
|
|
18691
|
+
this._scrollToPosition(diff - visibleItems + 1, animate);
|
|
18692
|
+
}
|
|
18693
|
+
}
|
|
18694
|
+
|
|
18695
|
+
/**
|
|
18696
|
+
* Calculates an offset to be added to the month scroll position
|
|
18697
|
+
* when using sub-month scrolling, in order ensure that the week
|
|
18698
|
+
* that the date is in is visible even for small scroll areas.
|
|
18699
|
+
* As the month scroller uses a month as minimal scroll unit
|
|
18700
|
+
* (a value of `1` equals one month), we can not exactly identify
|
|
18701
|
+
* the position of a specific week. This is a best effort
|
|
18702
|
+
* implementation based on manual testing.
|
|
18703
|
+
* @param date the date for which to calculate the offset
|
|
18704
|
+
* @returns {number} the offset
|
|
18705
|
+
* @private
|
|
18706
|
+
*/
|
|
18707
|
+
_calculateWeekScrollOffset(date) {
|
|
18708
|
+
// Get first day of month
|
|
18709
|
+
const temp = new Date(0, 0);
|
|
18710
|
+
temp.setFullYear(date.getFullYear());
|
|
18711
|
+
temp.setMonth(date.getMonth());
|
|
18712
|
+
temp.setDate(1);
|
|
18713
|
+
// Determine week (=row index) of date within the month
|
|
18714
|
+
let week = 0;
|
|
18715
|
+
while (temp.getDate() < date.getDate()) {
|
|
18716
|
+
temp.setDate(temp.getDate() + 1);
|
|
18717
|
+
if (temp.getDay() === this.i18n.firstDayOfWeek) {
|
|
18718
|
+
week += 1;
|
|
18135
18719
|
}
|
|
18136
18720
|
}
|
|
18721
|
+
// Calculate magic number that approximately keeps the week visible
|
|
18722
|
+
return week / 6;
|
|
18137
18723
|
}
|
|
18138
18724
|
|
|
18139
18725
|
_initialPositionChanged(initialPosition) {
|
|
@@ -18162,7 +18748,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18162
18748
|
|
|
18163
18749
|
_onYearScrollTouchStart() {
|
|
18164
18750
|
this._notTapping = false;
|
|
18165
|
-
setTimeout(() =>
|
|
18751
|
+
setTimeout(() => {
|
|
18752
|
+
this._notTapping = true;
|
|
18753
|
+
}, 300);
|
|
18166
18754
|
|
|
18167
18755
|
this._repositionMonthScroller();
|
|
18168
18756
|
}
|
|
@@ -18173,7 +18761,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18173
18761
|
|
|
18174
18762
|
_doIgnoreTaps() {
|
|
18175
18763
|
this._ignoreTaps = true;
|
|
18176
|
-
this._debouncer = Debouncer$1.debounce(this._debouncer, timeOut.after(300), () =>
|
|
18764
|
+
this._debouncer = Debouncer$1.debounce(this._debouncer, timeOut.after(300), () => {
|
|
18765
|
+
this._ignoreTaps = false;
|
|
18766
|
+
});
|
|
18177
18767
|
}
|
|
18178
18768
|
|
|
18179
18769
|
_formatDisplayed(date, formatDate, label) {
|
|
@@ -18204,10 +18794,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18204
18794
|
this.scrollToDate(new Date(), true);
|
|
18205
18795
|
}
|
|
18206
18796
|
|
|
18207
|
-
_showClear(selectedDate) {
|
|
18208
|
-
return !!selectedDate;
|
|
18209
|
-
}
|
|
18210
|
-
|
|
18211
18797
|
_onYearTap(e) {
|
|
18212
18798
|
if (!this._ignoreTaps && !this._notTapping) {
|
|
18213
18799
|
const scrollDelta =
|
|
@@ -18233,6 +18819,11 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18233
18819
|
|
|
18234
18820
|
this._targetPosition = targetPosition;
|
|
18235
18821
|
|
|
18822
|
+
let revealResolve;
|
|
18823
|
+
this._revealPromise = new Promise((resolve) => {
|
|
18824
|
+
revealResolve = resolve;
|
|
18825
|
+
});
|
|
18826
|
+
|
|
18236
18827
|
// http://gizma.com/easing/
|
|
18237
18828
|
const easingFunction = (t, b, c, d) => {
|
|
18238
18829
|
t /= d / 2;
|
|
@@ -18273,7 +18864,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18273
18864
|
|
|
18274
18865
|
this.$.monthScroller.position = this._targetPosition;
|
|
18275
18866
|
this._targetPosition = undefined;
|
|
18276
|
-
|
|
18867
|
+
|
|
18868
|
+
revealResolve();
|
|
18869
|
+
this._revealPromise = undefined;
|
|
18277
18870
|
}
|
|
18278
18871
|
|
|
18279
18872
|
setTimeout(this._repositionYearScroller.bind(this), 1);
|
|
@@ -18389,10 +18982,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18389
18982
|
return months - date2.getMonth() + date1.getMonth();
|
|
18390
18983
|
}
|
|
18391
18984
|
|
|
18392
|
-
_differenceInYears(date1, date2) {
|
|
18393
|
-
return this._differenceInMonths(date1, date2) / 12;
|
|
18394
|
-
}
|
|
18395
|
-
|
|
18396
18985
|
_clear() {
|
|
18397
18986
|
this._selectDate('');
|
|
18398
18987
|
}
|
|
@@ -18483,51 +19072,44 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18483
19072
|
switch (section) {
|
|
18484
19073
|
case 'calendar':
|
|
18485
19074
|
if (event.shiftKey) {
|
|
18486
|
-
// Return focus back to the input field.
|
|
18487
19075
|
event.preventDefault();
|
|
18488
|
-
|
|
19076
|
+
|
|
19077
|
+
if (this.hasAttribute('fullscreen')) {
|
|
19078
|
+
// Trap focus in the overlay
|
|
19079
|
+
this.$.cancelButton.focus();
|
|
19080
|
+
} else {
|
|
19081
|
+
this.__focusInput();
|
|
19082
|
+
}
|
|
18489
19083
|
}
|
|
18490
19084
|
break;
|
|
18491
19085
|
case 'today':
|
|
18492
19086
|
if (event.shiftKey) {
|
|
18493
|
-
|
|
18494
|
-
|
|
18495
|
-
setTimeout(() => this.revealDate(this.focusedDate), 1);
|
|
19087
|
+
event.preventDefault();
|
|
19088
|
+
this.focusDateElement();
|
|
18496
19089
|
}
|
|
18497
19090
|
break;
|
|
18498
19091
|
case 'cancel':
|
|
18499
19092
|
if (!event.shiftKey) {
|
|
18500
|
-
// Return focus back to the input field.
|
|
18501
19093
|
event.preventDefault();
|
|
18502
|
-
|
|
19094
|
+
|
|
19095
|
+
if (this.hasAttribute('fullscreen')) {
|
|
19096
|
+
// Trap focus in the overlay
|
|
19097
|
+
this.focusDateElement();
|
|
19098
|
+
} else {
|
|
19099
|
+
this.__focusInput();
|
|
19100
|
+
}
|
|
18503
19101
|
}
|
|
18504
19102
|
break;
|
|
18505
19103
|
}
|
|
18506
19104
|
}
|
|
18507
19105
|
|
|
18508
19106
|
__onTodayButtonKeyDown(event) {
|
|
18509
|
-
if (this.hasAttribute('fullscreen')) {
|
|
18510
|
-
// Do not prevent closing on Esc
|
|
18511
|
-
if (event.key !== 'Escape') {
|
|
18512
|
-
event.stopPropagation();
|
|
18513
|
-
}
|
|
18514
|
-
return;
|
|
18515
|
-
}
|
|
18516
|
-
|
|
18517
19107
|
if (event.key === 'Tab') {
|
|
18518
19108
|
this._onTabKeyDown(event, 'today');
|
|
18519
19109
|
}
|
|
18520
19110
|
}
|
|
18521
19111
|
|
|
18522
19112
|
__onCancelButtonKeyDown(event) {
|
|
18523
|
-
if (this.hasAttribute('fullscreen')) {
|
|
18524
|
-
// Do not prevent closing on Esc
|
|
18525
|
-
if (event.key !== 'Escape') {
|
|
18526
|
-
event.stopPropagation();
|
|
18527
|
-
}
|
|
18528
|
-
return;
|
|
18529
|
-
}
|
|
18530
|
-
|
|
18531
19113
|
if (event.key === 'Tab') {
|
|
18532
19114
|
this._onTabKeyDown(event, 'cancel');
|
|
18533
19115
|
}
|
|
@@ -18556,15 +19138,29 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18556
19138
|
if (!keepMonth) {
|
|
18557
19139
|
this._focusedMonthDate = dateToFocus.getDate();
|
|
18558
19140
|
}
|
|
18559
|
-
await this.focusDateElement();
|
|
19141
|
+
await this.focusDateElement(false);
|
|
18560
19142
|
}
|
|
18561
19143
|
|
|
18562
|
-
async focusDateElement() {
|
|
19144
|
+
async focusDateElement(reveal = true) {
|
|
18563
19145
|
this.__pendingDateFocus = this.focusedDate;
|
|
18564
19146
|
|
|
18565
|
-
|
|
18566
|
-
|
|
18567
|
-
|
|
19147
|
+
// Wait for `vaadin-month-calendar` elements to be rendered
|
|
19148
|
+
if (!this.calendars.length) {
|
|
19149
|
+
await new Promise((resolve) => {
|
|
19150
|
+
setTimeout(resolve);
|
|
19151
|
+
});
|
|
19152
|
+
}
|
|
19153
|
+
|
|
19154
|
+
// Reveal focused date unless it has been just set,
|
|
19155
|
+
// which triggers `revealDate()` in the observer.
|
|
19156
|
+
if (reveal) {
|
|
19157
|
+
this.revealDate(this.focusedDate);
|
|
19158
|
+
}
|
|
19159
|
+
|
|
19160
|
+
if (this._revealPromise) {
|
|
19161
|
+
// Wait for focused date to be scrolled into view.
|
|
19162
|
+
await this._revealPromise;
|
|
19163
|
+
}
|
|
18568
19164
|
|
|
18569
19165
|
this.__tryFocusDate();
|
|
18570
19166
|
}
|
|
@@ -18662,10 +19258,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18662
19258
|
todayMidnight.setDate(today.getDate());
|
|
18663
19259
|
return this._dateAllowed(todayMidnight, min, max);
|
|
18664
19260
|
}
|
|
18665
|
-
|
|
18666
|
-
_stopPropagation(e) {
|
|
18667
|
-
e.stopPropagation();
|
|
18668
|
-
}
|
|
18669
19261
|
}
|
|
18670
19262
|
|
|
18671
19263
|
customElements.define(DatePickerOverlayContent.is, DatePickerOverlayContent);
|
|
@@ -18796,277 +19388,105 @@ const DelegateFocusMixin = dedupingMixin(
|
|
|
18796
19388
|
* @param {HTMLElement} element
|
|
18797
19389
|
* @protected
|
|
18798
19390
|
*/
|
|
18799
|
-
_addFocusListeners(element) {
|
|
18800
|
-
element.addEventListener('blur', this._boundOnBlur);
|
|
18801
|
-
element.addEventListener('focus', this._boundOnFocus);
|
|
18802
|
-
}
|
|
18803
|
-
|
|
18804
|
-
/**
|
|
18805
|
-
* @param {HTMLElement} element
|
|
18806
|
-
* @protected
|
|
18807
|
-
*/
|
|
18808
|
-
_removeFocusListeners(element) {
|
|
18809
|
-
element.removeEventListener('blur', this._boundOnBlur);
|
|
18810
|
-
element.removeEventListener('focus', this._boundOnFocus);
|
|
18811
|
-
}
|
|
18812
|
-
|
|
18813
|
-
/**
|
|
18814
|
-
* Focus event does not bubble, so we dispatch it manually
|
|
18815
|
-
* on the host element to support adding focus listeners
|
|
18816
|
-
* when the focusable element is placed in light DOM.
|
|
18817
|
-
* @param {FocusEvent} event
|
|
18818
|
-
* @protected
|
|
18819
|
-
*/
|
|
18820
|
-
_onFocus(event) {
|
|
18821
|
-
event.stopPropagation();
|
|
18822
|
-
this.dispatchEvent(new Event('focus'));
|
|
18823
|
-
}
|
|
18824
|
-
|
|
18825
|
-
/**
|
|
18826
|
-
* Blur event does not bubble, so we dispatch it manually
|
|
18827
|
-
* on the host element to support adding blur listeners
|
|
18828
|
-
* when the focusable element is placed in light DOM.
|
|
18829
|
-
* @param {FocusEvent} event
|
|
18830
|
-
* @protected
|
|
18831
|
-
*/
|
|
18832
|
-
_onBlur(event) {
|
|
18833
|
-
event.stopPropagation();
|
|
18834
|
-
this.dispatchEvent(new Event('blur'));
|
|
18835
|
-
}
|
|
18836
|
-
|
|
18837
|
-
/**
|
|
18838
|
-
* @param {Event} event
|
|
18839
|
-
* @return {boolean}
|
|
18840
|
-
* @protected
|
|
18841
|
-
* @override
|
|
18842
|
-
*/
|
|
18843
|
-
_shouldSetFocus(event) {
|
|
18844
|
-
return event.target === this.focusElement;
|
|
18845
|
-
}
|
|
18846
|
-
|
|
18847
|
-
/**
|
|
18848
|
-
* @param {boolean} disabled
|
|
18849
|
-
* @param {boolean} oldDisabled
|
|
18850
|
-
* @protected
|
|
18851
|
-
* @override
|
|
18852
|
-
*/
|
|
18853
|
-
_disabledChanged(disabled, oldDisabled) {
|
|
18854
|
-
super._disabledChanged(disabled, oldDisabled);
|
|
18855
|
-
|
|
18856
|
-
if (this.focusElement) {
|
|
18857
|
-
this.focusElement.disabled = disabled;
|
|
18858
|
-
}
|
|
18859
|
-
|
|
18860
|
-
if (disabled) {
|
|
18861
|
-
this.blur();
|
|
18862
|
-
}
|
|
18863
|
-
}
|
|
18864
|
-
|
|
18865
|
-
/**
|
|
18866
|
-
* Override an observer from `TabindexMixin`.
|
|
18867
|
-
* Do not call super to remove tabindex attribute
|
|
18868
|
-
* from the host after it has been forwarded.
|
|
18869
|
-
* @param {string} tabindex
|
|
18870
|
-
* @protected
|
|
18871
|
-
* @override
|
|
18872
|
-
*/
|
|
18873
|
-
_tabindexChanged(tabindex) {
|
|
18874
|
-
this.__forwardTabIndex(tabindex);
|
|
18875
|
-
}
|
|
18876
|
-
|
|
18877
|
-
/** @private */
|
|
18878
|
-
__forwardTabIndex(tabindex) {
|
|
18879
|
-
if (tabindex !== undefined && this.focusElement) {
|
|
18880
|
-
this.focusElement.tabIndex = tabindex;
|
|
18881
|
-
|
|
18882
|
-
// Preserve tabindex="-1" on the host element
|
|
18883
|
-
if (tabindex !== -1) {
|
|
18884
|
-
this.tabindex = undefined;
|
|
18885
|
-
}
|
|
18886
|
-
}
|
|
18887
|
-
|
|
18888
|
-
if (this.disabled && tabindex) {
|
|
18889
|
-
// If tabindex attribute was changed while component was disabled
|
|
18890
|
-
if (tabindex !== -1) {
|
|
18891
|
-
this._lastTabIndex = tabindex;
|
|
18892
|
-
}
|
|
18893
|
-
this.tabindex = undefined;
|
|
18894
|
-
}
|
|
18895
|
-
}
|
|
18896
|
-
},
|
|
18897
|
-
);
|
|
18898
|
-
|
|
18899
|
-
/**
|
|
18900
|
-
* @license
|
|
18901
|
-
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
18902
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
18903
|
-
*/
|
|
18904
|
-
|
|
18905
|
-
/**
|
|
18906
|
-
* A controller for providing content to slot element and observing changes.
|
|
18907
|
-
*/
|
|
18908
|
-
class SlotController extends EventTarget {
|
|
18909
|
-
/**
|
|
18910
|
-
* Ensure that every instance has unique ID.
|
|
18911
|
-
*
|
|
18912
|
-
* @param {string} slotName
|
|
18913
|
-
* @param {HTMLElement} host
|
|
18914
|
-
* @return {string}
|
|
18915
|
-
* @protected
|
|
18916
|
-
*/
|
|
18917
|
-
static generateId(slotName, host) {
|
|
18918
|
-
const prefix = slotName || 'default';
|
|
18919
|
-
|
|
18920
|
-
// Support dash-case slot names e.g. "error-message"
|
|
18921
|
-
const field = `${dashToCamelCase(prefix)}Id`;
|
|
18922
|
-
|
|
18923
|
-
// Maintain the unique ID counter for a given prefix.
|
|
18924
|
-
this[field] = 1 + this[field] || 0;
|
|
18925
|
-
|
|
18926
|
-
return `${prefix}-${host.localName}-${this[field]}`;
|
|
18927
|
-
}
|
|
18928
|
-
|
|
18929
|
-
constructor(host, slotName, slotFactory, slotInitializer) {
|
|
18930
|
-
super();
|
|
18931
|
-
|
|
18932
|
-
this.host = host;
|
|
18933
|
-
this.slotName = slotName;
|
|
18934
|
-
this.slotFactory = slotFactory;
|
|
18935
|
-
this.slotInitializer = slotInitializer;
|
|
18936
|
-
this.defaultId = SlotController.generateId(slotName, host);
|
|
18937
|
-
}
|
|
18938
|
-
|
|
18939
|
-
hostConnected() {
|
|
18940
|
-
if (!this.initialized) {
|
|
18941
|
-
let node = this.getSlotChild();
|
|
18942
|
-
|
|
18943
|
-
if (!node) {
|
|
18944
|
-
node = this.attachDefaultNode();
|
|
18945
|
-
} else {
|
|
18946
|
-
this.node = node;
|
|
18947
|
-
this.initCustomNode(node);
|
|
18948
|
-
}
|
|
18949
|
-
|
|
18950
|
-
this.initNode(node);
|
|
18951
|
-
|
|
18952
|
-
// TODO: Consider making this behavior opt-in to improve performance.
|
|
18953
|
-
this.observe();
|
|
18954
|
-
|
|
18955
|
-
this.initialized = true;
|
|
18956
|
-
}
|
|
18957
|
-
}
|
|
18958
|
-
|
|
18959
|
-
/**
|
|
18960
|
-
* Create and attach default node using the slot factory.
|
|
18961
|
-
* @return {Node | undefined}
|
|
18962
|
-
* @protected
|
|
18963
|
-
*/
|
|
18964
|
-
attachDefaultNode() {
|
|
18965
|
-
const { host, slotName, slotFactory } = this;
|
|
18966
|
-
|
|
18967
|
-
// Check if the node was created previously and if so, reuse it.
|
|
18968
|
-
let node = this.defaultNode;
|
|
18969
|
-
|
|
18970
|
-
// Slot factory is optional, some slots don't have default content.
|
|
18971
|
-
if (!node && slotFactory) {
|
|
18972
|
-
node = slotFactory(host);
|
|
18973
|
-
if (node instanceof Element) {
|
|
18974
|
-
if (slotName !== '') {
|
|
18975
|
-
node.setAttribute('slot', slotName);
|
|
18976
|
-
}
|
|
18977
|
-
this.node = node;
|
|
18978
|
-
this.defaultNode = node;
|
|
18979
|
-
}
|
|
18980
|
-
}
|
|
18981
|
-
|
|
18982
|
-
if (node) {
|
|
18983
|
-
host.appendChild(node);
|
|
18984
|
-
}
|
|
18985
|
-
|
|
18986
|
-
return node;
|
|
18987
|
-
}
|
|
18988
|
-
|
|
18989
|
-
/**
|
|
18990
|
-
* Return a reference to the node managed by the controller.
|
|
18991
|
-
* @return {Node}
|
|
18992
|
-
*/
|
|
18993
|
-
getSlotChild() {
|
|
18994
|
-
const { slotName } = this;
|
|
18995
|
-
return Array.from(this.host.childNodes).find((node) => {
|
|
18996
|
-
// Either an element (any slot) or a text node (only un-named slot).
|
|
18997
|
-
return (
|
|
18998
|
-
(node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) ||
|
|
18999
|
-
(node.nodeType === Node.TEXT_NODE && node.textContent.trim() && slotName === '')
|
|
19000
|
-
);
|
|
19001
|
-
});
|
|
19002
|
-
}
|
|
19003
|
-
|
|
19004
|
-
/**
|
|
19005
|
-
* @param {Node} node
|
|
19006
|
-
* @protected
|
|
19007
|
-
*/
|
|
19008
|
-
initNode(node) {
|
|
19009
|
-
const { slotInitializer } = this;
|
|
19010
|
-
// Don't try to bind `this` to initializer (normally it's arrow function).
|
|
19011
|
-
// Instead, pass the host as a first argument to access component's state.
|
|
19012
|
-
if (slotInitializer) {
|
|
19013
|
-
slotInitializer(this.host, node);
|
|
19014
|
-
}
|
|
19015
|
-
}
|
|
19016
|
-
|
|
19017
|
-
/**
|
|
19018
|
-
* Override to initialize the newly added custom node.
|
|
19019
|
-
*
|
|
19020
|
-
* @param {Node} _node
|
|
19021
|
-
* @protected
|
|
19022
|
-
*/
|
|
19023
|
-
initCustomNode(_node) {}
|
|
19391
|
+
_addFocusListeners(element) {
|
|
19392
|
+
element.addEventListener('blur', this._boundOnBlur);
|
|
19393
|
+
element.addEventListener('focus', this._boundOnFocus);
|
|
19394
|
+
}
|
|
19024
19395
|
|
|
19025
|
-
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
19396
|
+
/**
|
|
19397
|
+
* @param {HTMLElement} element
|
|
19398
|
+
* @protected
|
|
19399
|
+
*/
|
|
19400
|
+
_removeFocusListeners(element) {
|
|
19401
|
+
element.removeEventListener('blur', this._boundOnBlur);
|
|
19402
|
+
element.removeEventListener('focus', this._boundOnFocus);
|
|
19403
|
+
}
|
|
19032
19404
|
|
|
19033
|
-
|
|
19034
|
-
|
|
19035
|
-
|
|
19036
|
-
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19405
|
+
/**
|
|
19406
|
+
* Focus event does not bubble, so we dispatch it manually
|
|
19407
|
+
* on the host element to support adding focus listeners
|
|
19408
|
+
* when the focusable element is placed in light DOM.
|
|
19409
|
+
* @param {FocusEvent} event
|
|
19410
|
+
* @protected
|
|
19411
|
+
*/
|
|
19412
|
+
_onFocus(event) {
|
|
19413
|
+
event.stopPropagation();
|
|
19414
|
+
this.dispatchEvent(new Event('focus'));
|
|
19415
|
+
}
|
|
19041
19416
|
|
|
19042
|
-
|
|
19043
|
-
|
|
19044
|
-
|
|
19045
|
-
|
|
19417
|
+
/**
|
|
19418
|
+
* Blur event does not bubble, so we dispatch it manually
|
|
19419
|
+
* on the host element to support adding blur listeners
|
|
19420
|
+
* when the focusable element is placed in light DOM.
|
|
19421
|
+
* @param {FocusEvent} event
|
|
19422
|
+
* @protected
|
|
19423
|
+
*/
|
|
19424
|
+
_onBlur(event) {
|
|
19425
|
+
event.stopPropagation();
|
|
19426
|
+
this.dispatchEvent(new Event('blur'));
|
|
19427
|
+
}
|
|
19046
19428
|
|
|
19047
|
-
|
|
19048
|
-
|
|
19049
|
-
|
|
19050
|
-
|
|
19429
|
+
/**
|
|
19430
|
+
* @param {Event} event
|
|
19431
|
+
* @return {boolean}
|
|
19432
|
+
* @protected
|
|
19433
|
+
* @override
|
|
19434
|
+
*/
|
|
19435
|
+
_shouldSetFocus(event) {
|
|
19436
|
+
return event.target === this.focusElement;
|
|
19051
19437
|
}
|
|
19052
19438
|
|
|
19053
|
-
|
|
19054
|
-
|
|
19055
|
-
|
|
19056
|
-
|
|
19439
|
+
/**
|
|
19440
|
+
* @param {boolean} disabled
|
|
19441
|
+
* @param {boolean} oldDisabled
|
|
19442
|
+
* @protected
|
|
19443
|
+
* @override
|
|
19444
|
+
*/
|
|
19445
|
+
_disabledChanged(disabled, oldDisabled) {
|
|
19446
|
+
super._disabledChanged(disabled, oldDisabled);
|
|
19447
|
+
|
|
19448
|
+
if (this.focusElement) {
|
|
19449
|
+
this.focusElement.disabled = disabled;
|
|
19057
19450
|
}
|
|
19058
19451
|
|
|
19059
|
-
|
|
19452
|
+
if (disabled) {
|
|
19453
|
+
this.blur();
|
|
19454
|
+
}
|
|
19455
|
+
}
|
|
19060
19456
|
|
|
19061
|
-
|
|
19062
|
-
|
|
19457
|
+
/**
|
|
19458
|
+
* Override an observer from `TabindexMixin`.
|
|
19459
|
+
* Do not call super to remove tabindex attribute
|
|
19460
|
+
* from the host after it has been forwarded.
|
|
19461
|
+
* @param {string} tabindex
|
|
19462
|
+
* @protected
|
|
19463
|
+
* @override
|
|
19464
|
+
*/
|
|
19465
|
+
_tabindexChanged(tabindex) {
|
|
19466
|
+
this.__forwardTabIndex(tabindex);
|
|
19467
|
+
}
|
|
19063
19468
|
|
|
19064
|
-
|
|
19469
|
+
/** @private */
|
|
19470
|
+
__forwardTabIndex(tabindex) {
|
|
19471
|
+
if (tabindex !== undefined && this.focusElement) {
|
|
19472
|
+
this.focusElement.tabIndex = tabindex;
|
|
19473
|
+
|
|
19474
|
+
// Preserve tabindex="-1" on the host element
|
|
19475
|
+
if (tabindex !== -1) {
|
|
19476
|
+
this.tabindex = undefined;
|
|
19477
|
+
}
|
|
19478
|
+
}
|
|
19479
|
+
|
|
19480
|
+
if (this.disabled && tabindex) {
|
|
19481
|
+
// If tabindex attribute was changed while component was disabled
|
|
19482
|
+
if (tabindex !== -1) {
|
|
19483
|
+
this._lastTabIndex = tabindex;
|
|
19484
|
+
}
|
|
19485
|
+
this.tabindex = undefined;
|
|
19065
19486
|
}
|
|
19066
19487
|
}
|
|
19067
|
-
}
|
|
19068
|
-
|
|
19069
|
-
}
|
|
19488
|
+
},
|
|
19489
|
+
);
|
|
19070
19490
|
|
|
19071
19491
|
/**
|
|
19072
19492
|
* @license
|
|
@@ -19088,6 +19508,7 @@ class ErrorController extends SlotController {
|
|
|
19088
19508
|
|
|
19089
19509
|
this.__updateHasError();
|
|
19090
19510
|
},
|
|
19511
|
+
true,
|
|
19091
19512
|
);
|
|
19092
19513
|
}
|
|
19093
19514
|
|
|
@@ -19123,7 +19544,7 @@ class ErrorController extends SlotController {
|
|
|
19123
19544
|
}
|
|
19124
19545
|
|
|
19125
19546
|
/**
|
|
19126
|
-
* Override to initialize the newly added custom
|
|
19547
|
+
* Override to initialize the newly added custom error message.
|
|
19127
19548
|
*
|
|
19128
19549
|
* @param {Node} errorNode
|
|
19129
19550
|
* @protected
|
|
@@ -19141,7 +19562,7 @@ class ErrorController extends SlotController {
|
|
|
19141
19562
|
}
|
|
19142
19563
|
|
|
19143
19564
|
/**
|
|
19144
|
-
* Override to cleanup
|
|
19565
|
+
* Override to cleanup error message node when it's removed.
|
|
19145
19566
|
*
|
|
19146
19567
|
* @param {Node} node
|
|
19147
19568
|
* @protected
|
|
@@ -19154,7 +19575,7 @@ class ErrorController extends SlotController {
|
|
|
19154
19575
|
if (!errorNode && node !== this.defaultNode) {
|
|
19155
19576
|
errorNode = this.attachDefaultNode();
|
|
19156
19577
|
|
|
19157
|
-
// Run initializer to update default
|
|
19578
|
+
// Run initializer to update default error message ID.
|
|
19158
19579
|
this.initNode(errorNode);
|
|
19159
19580
|
}
|
|
19160
19581
|
|
|
@@ -19202,63 +19623,6 @@ class ErrorController extends SlotController {
|
|
|
19202
19623
|
}
|
|
19203
19624
|
}
|
|
19204
19625
|
|
|
19205
|
-
/**
|
|
19206
|
-
* @license
|
|
19207
|
-
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
19208
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
19209
|
-
*/
|
|
19210
|
-
|
|
19211
|
-
/**
|
|
19212
|
-
* @param {string} value
|
|
19213
|
-
* @return {Set<string>}
|
|
19214
|
-
*/
|
|
19215
|
-
function deserializeAttributeValue(value) {
|
|
19216
|
-
if (!value) {
|
|
19217
|
-
return new Set();
|
|
19218
|
-
}
|
|
19219
|
-
|
|
19220
|
-
return new Set(value.split(' '));
|
|
19221
|
-
}
|
|
19222
|
-
|
|
19223
|
-
/**
|
|
19224
|
-
* @param {Set<string>} values
|
|
19225
|
-
* @return {string}
|
|
19226
|
-
*/
|
|
19227
|
-
function serializeAttributeValue(values) {
|
|
19228
|
-
return [...values].join(' ');
|
|
19229
|
-
}
|
|
19230
|
-
|
|
19231
|
-
/**
|
|
19232
|
-
* Adds a value to an attribute containing space-delimited values.
|
|
19233
|
-
*
|
|
19234
|
-
* @param {HTMLElement} element
|
|
19235
|
-
* @param {string} attr
|
|
19236
|
-
* @param {string} value
|
|
19237
|
-
*/
|
|
19238
|
-
function addValueToAttribute(element, attr, value) {
|
|
19239
|
-
const values = deserializeAttributeValue(element.getAttribute(attr));
|
|
19240
|
-
values.add(value);
|
|
19241
|
-
element.setAttribute(attr, serializeAttributeValue(values));
|
|
19242
|
-
}
|
|
19243
|
-
|
|
19244
|
-
/**
|
|
19245
|
-
* Removes a value from an attribute containing space-delimited values.
|
|
19246
|
-
* If the value is the last one, the whole attribute is removed.
|
|
19247
|
-
*
|
|
19248
|
-
* @param {HTMLElement} element
|
|
19249
|
-
* @param {string} attr
|
|
19250
|
-
* @param {string} value
|
|
19251
|
-
*/
|
|
19252
|
-
function removeValueFromAttribute(element, attr, value) {
|
|
19253
|
-
const values = deserializeAttributeValue(element.getAttribute(attr));
|
|
19254
|
-
values.delete(value);
|
|
19255
|
-
if (values.size === 0) {
|
|
19256
|
-
element.removeAttribute(attr);
|
|
19257
|
-
return;
|
|
19258
|
-
}
|
|
19259
|
-
element.setAttribute(attr, serializeAttributeValue(values));
|
|
19260
|
-
}
|
|
19261
|
-
|
|
19262
19626
|
/**
|
|
19263
19627
|
* @license
|
|
19264
19628
|
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
@@ -19433,7 +19797,7 @@ class FieldAriaController {
|
|
|
19433
19797
|
|
|
19434
19798
|
/**
|
|
19435
19799
|
* @license
|
|
19436
|
-
* Copyright (c) 2021 Vaadin Ltd.
|
|
19800
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
19437
19801
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
19438
19802
|
*/
|
|
19439
19803
|
|
|
@@ -19443,7 +19807,7 @@ class FieldAriaController {
|
|
|
19443
19807
|
class HelperController extends SlotController {
|
|
19444
19808
|
constructor(host) {
|
|
19445
19809
|
// Do not provide slot factory, as only create helper lazily.
|
|
19446
|
-
super(host, 'helper');
|
|
19810
|
+
super(host, 'helper', null, null, true);
|
|
19447
19811
|
}
|
|
19448
19812
|
|
|
19449
19813
|
get helperId() {
|
|
@@ -19514,7 +19878,11 @@ class HelperController extends SlotController {
|
|
|
19514
19878
|
return false;
|
|
19515
19879
|
}
|
|
19516
19880
|
|
|
19517
|
-
return
|
|
19881
|
+
return (
|
|
19882
|
+
helperNode.children.length > 0 ||
|
|
19883
|
+
(helperNode.nodeType === Node.ELEMENT_NODE && customElements.get(helperNode.localName)) ||
|
|
19884
|
+
this.__isNotEmpty(helperNode.textContent)
|
|
19885
|
+
);
|
|
19518
19886
|
}
|
|
19519
19887
|
|
|
19520
19888
|
/**
|
|
@@ -19640,6 +20008,7 @@ class LabelController extends SlotController {
|
|
|
19640
20008
|
|
|
19641
20009
|
this.__observeLabel(node);
|
|
19642
20010
|
},
|
|
20011
|
+
true,
|
|
19643
20012
|
);
|
|
19644
20013
|
}
|
|
19645
20014
|
|
|
@@ -19814,7 +20183,7 @@ class LabelController extends SlotController {
|
|
|
19814
20183
|
* A mixin to provide label via corresponding property or named slot.
|
|
19815
20184
|
*
|
|
19816
20185
|
* @polymerMixin
|
|
19817
|
-
* @mixes
|
|
20186
|
+
* @mixes ControllerMixin
|
|
19818
20187
|
*/
|
|
19819
20188
|
const LabelMixin = dedupingMixin(
|
|
19820
20189
|
(superclass) =>
|
|
@@ -19846,6 +20215,12 @@ const LabelMixin = dedupingMixin(
|
|
|
19846
20215
|
super();
|
|
19847
20216
|
|
|
19848
20217
|
this._labelController = new LabelController(this);
|
|
20218
|
+
}
|
|
20219
|
+
|
|
20220
|
+
/** @protected */
|
|
20221
|
+
ready() {
|
|
20222
|
+
super.ready();
|
|
20223
|
+
|
|
19849
20224
|
this.addController(this._labelController);
|
|
19850
20225
|
}
|
|
19851
20226
|
|
|
@@ -19893,12 +20268,17 @@ const ValidateMixin = dedupingMixin(
|
|
|
19893
20268
|
}
|
|
19894
20269
|
|
|
19895
20270
|
/**
|
|
19896
|
-
*
|
|
20271
|
+
* Validates the field and sets the `invalid` property based on the result.
|
|
20272
|
+
*
|
|
20273
|
+
* The method fires a `validated` event with the result of the validation.
|
|
19897
20274
|
*
|
|
19898
20275
|
* @return {boolean} True if the value is valid.
|
|
19899
20276
|
*/
|
|
19900
20277
|
validate() {
|
|
19901
|
-
|
|
20278
|
+
const isValid = this.checkValidity();
|
|
20279
|
+
this._setInvalid(!isValid);
|
|
20280
|
+
this.dispatchEvent(new CustomEvent('validated', { detail: { valid: isValid } }));
|
|
20281
|
+
return isValid;
|
|
19902
20282
|
}
|
|
19903
20283
|
|
|
19904
20284
|
/**
|
|
@@ -19909,6 +20289,35 @@ const ValidateMixin = dedupingMixin(
|
|
|
19909
20289
|
checkValidity() {
|
|
19910
20290
|
return !this.required || !!this.value;
|
|
19911
20291
|
}
|
|
20292
|
+
|
|
20293
|
+
/**
|
|
20294
|
+
* @param {boolean} invalid
|
|
20295
|
+
* @protected
|
|
20296
|
+
*/
|
|
20297
|
+
_setInvalid(invalid) {
|
|
20298
|
+
if (this._shouldSetInvalid(invalid)) {
|
|
20299
|
+
this.invalid = invalid;
|
|
20300
|
+
}
|
|
20301
|
+
}
|
|
20302
|
+
|
|
20303
|
+
/**
|
|
20304
|
+
* Override this method to define whether the given `invalid` state should be set.
|
|
20305
|
+
*
|
|
20306
|
+
* @param {boolean} _invalid
|
|
20307
|
+
* @return {boolean}
|
|
20308
|
+
* @protected
|
|
20309
|
+
*/
|
|
20310
|
+
_shouldSetInvalid(_invalid) {
|
|
20311
|
+
return true;
|
|
20312
|
+
}
|
|
20313
|
+
|
|
20314
|
+
/**
|
|
20315
|
+
* Fired whenever the field is validated.
|
|
20316
|
+
*
|
|
20317
|
+
* @event validated
|
|
20318
|
+
* @param {Object} detail
|
|
20319
|
+
* @param {boolean} detail.valid the result of the validation.
|
|
20320
|
+
*/
|
|
19912
20321
|
},
|
|
19913
20322
|
);
|
|
19914
20323
|
|
|
@@ -19997,10 +20406,6 @@ const FieldMixin = (superclass) =>
|
|
|
19997
20406
|
this._helperController = new HelperController(this);
|
|
19998
20407
|
this._errorController = new ErrorController(this);
|
|
19999
20408
|
|
|
20000
|
-
this.addController(this._fieldAriaController);
|
|
20001
|
-
this.addController(this._helperController);
|
|
20002
|
-
this.addController(this._errorController);
|
|
20003
|
-
|
|
20004
20409
|
this._labelController.addEventListener('label-changed', (event) => {
|
|
20005
20410
|
const { hasLabel, node } = event.detail;
|
|
20006
20411
|
this.__labelChanged(hasLabel, node);
|
|
@@ -20012,6 +20417,15 @@ const FieldMixin = (superclass) =>
|
|
|
20012
20417
|
});
|
|
20013
20418
|
}
|
|
20014
20419
|
|
|
20420
|
+
/** @protected */
|
|
20421
|
+
ready() {
|
|
20422
|
+
super.ready();
|
|
20423
|
+
|
|
20424
|
+
this.addController(this._fieldAriaController);
|
|
20425
|
+
this.addController(this._helperController);
|
|
20426
|
+
this.addController(this._errorController);
|
|
20427
|
+
}
|
|
20428
|
+
|
|
20015
20429
|
/** @private */
|
|
20016
20430
|
__helperChanged(hasHelper, helperNode) {
|
|
20017
20431
|
if (hasHelper) {
|
|
@@ -20067,7 +20481,7 @@ const FieldMixin = (superclass) =>
|
|
|
20067
20481
|
}
|
|
20068
20482
|
|
|
20069
20483
|
/**
|
|
20070
|
-
* @param {boolean}
|
|
20484
|
+
* @param {boolean} invalid
|
|
20071
20485
|
* @protected
|
|
20072
20486
|
*/
|
|
20073
20487
|
_invalidChanged(invalid) {
|
|
@@ -20267,13 +20681,23 @@ const InputMixin = dedupingMixin(
|
|
|
20267
20681
|
observer: '_valueChanged',
|
|
20268
20682
|
notify: true,
|
|
20269
20683
|
},
|
|
20684
|
+
|
|
20685
|
+
/**
|
|
20686
|
+
* When true, the input element has a non-empty value entered by the user.
|
|
20687
|
+
* @protected
|
|
20688
|
+
*/
|
|
20689
|
+
_hasInputValue: {
|
|
20690
|
+
type: Boolean,
|
|
20691
|
+
value: false,
|
|
20692
|
+
observer: '_hasInputValueChanged',
|
|
20693
|
+
},
|
|
20270
20694
|
};
|
|
20271
20695
|
}
|
|
20272
20696
|
|
|
20273
20697
|
constructor() {
|
|
20274
20698
|
super();
|
|
20275
20699
|
|
|
20276
|
-
this._boundOnInput = this.
|
|
20700
|
+
this._boundOnInput = this.__onInput.bind(this);
|
|
20277
20701
|
this._boundOnChange = this._onChange.bind(this);
|
|
20278
20702
|
}
|
|
20279
20703
|
|
|
@@ -20288,6 +20712,7 @@ const InputMixin = dedupingMixin(
|
|
|
20288
20712
|
* Add event listeners to the input element instance.
|
|
20289
20713
|
* Override this method to add custom listeners.
|
|
20290
20714
|
* @param {!HTMLElement} input
|
|
20715
|
+
* @protected
|
|
20291
20716
|
*/
|
|
20292
20717
|
_addInputListeners(input) {
|
|
20293
20718
|
input.addEventListener('input', this._boundOnInput);
|
|
@@ -20297,6 +20722,7 @@ const InputMixin = dedupingMixin(
|
|
|
20297
20722
|
/**
|
|
20298
20723
|
* Remove event listeners from the input element instance.
|
|
20299
20724
|
* @param {!HTMLElement} input
|
|
20725
|
+
* @protected
|
|
20300
20726
|
*/
|
|
20301
20727
|
_removeInputListeners(input) {
|
|
20302
20728
|
input.removeEventListener('input', this._boundOnInput);
|
|
@@ -20310,7 +20736,6 @@ const InputMixin = dedupingMixin(
|
|
|
20310
20736
|
* for example to skip this in certain conditions.
|
|
20311
20737
|
* @param {string} value
|
|
20312
20738
|
* @protected
|
|
20313
|
-
* @override
|
|
20314
20739
|
*/
|
|
20315
20740
|
_forwardInputValue(value) {
|
|
20316
20741
|
// Value might be set before an input element is initialized.
|
|
@@ -20327,7 +20752,11 @@ const InputMixin = dedupingMixin(
|
|
|
20327
20752
|
}
|
|
20328
20753
|
}
|
|
20329
20754
|
|
|
20330
|
-
/**
|
|
20755
|
+
/**
|
|
20756
|
+
* @param {HTMLElement | undefined} input
|
|
20757
|
+
* @param {HTMLElement | undefined} oldInput
|
|
20758
|
+
* @protected
|
|
20759
|
+
*/
|
|
20331
20760
|
_inputElementChanged(input, oldInput) {
|
|
20332
20761
|
if (input) {
|
|
20333
20762
|
this._addInputListeners(input);
|
|
@@ -20336,17 +20765,43 @@ const InputMixin = dedupingMixin(
|
|
|
20336
20765
|
}
|
|
20337
20766
|
}
|
|
20338
20767
|
|
|
20768
|
+
/**
|
|
20769
|
+
* Observer to notify about the change of private property.
|
|
20770
|
+
*
|
|
20771
|
+
* @private
|
|
20772
|
+
*/
|
|
20773
|
+
_hasInputValueChanged(hasValue, oldHasValue) {
|
|
20774
|
+
if (hasValue || oldHasValue) {
|
|
20775
|
+
this.dispatchEvent(new CustomEvent('has-input-value-changed'));
|
|
20776
|
+
}
|
|
20777
|
+
}
|
|
20778
|
+
|
|
20779
|
+
/**
|
|
20780
|
+
* An input event listener used to update `_hasInputValue` property.
|
|
20781
|
+
* Do not override this method.
|
|
20782
|
+
*
|
|
20783
|
+
* @param {Event} event
|
|
20784
|
+
* @private
|
|
20785
|
+
*/
|
|
20786
|
+
__onInput(event) {
|
|
20787
|
+
this._setHasInputValue(event);
|
|
20788
|
+
this._onInput(event);
|
|
20789
|
+
}
|
|
20790
|
+
|
|
20339
20791
|
/**
|
|
20340
20792
|
* An input event listener used to update the field value.
|
|
20341
|
-
*
|
|
20342
|
-
* @param {Event}
|
|
20793
|
+
*
|
|
20794
|
+
* @param {Event} event
|
|
20343
20795
|
* @protected
|
|
20344
|
-
* @override
|
|
20345
20796
|
*/
|
|
20346
20797
|
_onInput(event) {
|
|
20798
|
+
// In the case a custom web component is passed as `inputElement`,
|
|
20799
|
+
// the actual native input element, on which the event occurred,
|
|
20800
|
+
// can be inside shadow trees.
|
|
20801
|
+
const target = event.composedPath()[0];
|
|
20347
20802
|
// Ignore fake input events e.g. used by clear button.
|
|
20348
20803
|
this.__userInput = event.isTrusted;
|
|
20349
|
-
this.value =
|
|
20804
|
+
this.value = target.value;
|
|
20350
20805
|
this.__userInput = false;
|
|
20351
20806
|
}
|
|
20352
20807
|
|
|
@@ -20355,12 +20810,12 @@ const InputMixin = dedupingMixin(
|
|
|
20355
20810
|
* Override this method with an actual implementation.
|
|
20356
20811
|
* @param {Event} _event
|
|
20357
20812
|
* @protected
|
|
20358
|
-
* @override
|
|
20359
20813
|
*/
|
|
20360
20814
|
_onChange(_event) {}
|
|
20361
20815
|
|
|
20362
20816
|
/**
|
|
20363
20817
|
* Toggle the has-value attribute based on the value property.
|
|
20818
|
+
*
|
|
20364
20819
|
* @param {boolean} hasValue
|
|
20365
20820
|
* @protected
|
|
20366
20821
|
*/
|
|
@@ -20373,10 +20828,9 @@ const InputMixin = dedupingMixin(
|
|
|
20373
20828
|
* @param {string | undefined} newVal
|
|
20374
20829
|
* @param {string | undefined} oldVal
|
|
20375
20830
|
* @protected
|
|
20376
|
-
* @override
|
|
20377
20831
|
*/
|
|
20378
20832
|
_valueChanged(newVal, oldVal) {
|
|
20379
|
-
this._toggleHasValue(
|
|
20833
|
+
this._toggleHasValue(this._hasValue);
|
|
20380
20834
|
|
|
20381
20835
|
// Setting initial value to empty string, do nothing.
|
|
20382
20836
|
if (newVal === '' && oldVal === undefined) {
|
|
@@ -20391,6 +20845,30 @@ const InputMixin = dedupingMixin(
|
|
|
20391
20845
|
// Setting a value programmatically, sync it to input element.
|
|
20392
20846
|
this._forwardInputValue(newVal);
|
|
20393
20847
|
}
|
|
20848
|
+
|
|
20849
|
+
/**
|
|
20850
|
+
* Indicates whether the value is different from the default one.
|
|
20851
|
+
* Override if the `value` property has a type other than `string`.
|
|
20852
|
+
*
|
|
20853
|
+
* @protected
|
|
20854
|
+
*/
|
|
20855
|
+
get _hasValue() {
|
|
20856
|
+
return this.value != null && this.value !== '';
|
|
20857
|
+
}
|
|
20858
|
+
|
|
20859
|
+
/**
|
|
20860
|
+
* Sets the `_hasInputValue` property based on the `input` event.
|
|
20861
|
+
*
|
|
20862
|
+
* @param {InputEvent} event
|
|
20863
|
+
* @protected
|
|
20864
|
+
*/
|
|
20865
|
+
_setHasInputValue(event) {
|
|
20866
|
+
// In the case a custom web component is passed as `inputElement`,
|
|
20867
|
+
// the actual native input element, on which the event occurred,
|
|
20868
|
+
// can be inside shadow trees.
|
|
20869
|
+
const target = event.composedPath()[0];
|
|
20870
|
+
this._hasInputValue = target.value.length > 0;
|
|
20871
|
+
}
|
|
20394
20872
|
},
|
|
20395
20873
|
);
|
|
20396
20874
|
|
|
@@ -20462,26 +20940,32 @@ const InputConstraintsMixin = dedupingMixin(
|
|
|
20462
20940
|
_createConstraintsObserver() {
|
|
20463
20941
|
// This complex observer needs to be added dynamically instead of using `static get observers()`
|
|
20464
20942
|
// to make it possible to tweak this behavior in classes that apply this mixin.
|
|
20465
|
-
this._createMethodObserver(`_constraintsChanged(${this.constructor.constraints.join(', ')})`);
|
|
20943
|
+
this._createMethodObserver(`_constraintsChanged(stateTarget, ${this.constructor.constraints.join(', ')})`);
|
|
20466
20944
|
}
|
|
20467
20945
|
|
|
20468
20946
|
/**
|
|
20469
20947
|
* Override this method to implement custom validation constraints.
|
|
20948
|
+
* @param {HTMLElement | undefined} stateTarget
|
|
20470
20949
|
* @param {unknown[]} constraints
|
|
20471
20950
|
* @protected
|
|
20472
20951
|
*/
|
|
20473
|
-
_constraintsChanged(...constraints) {
|
|
20474
|
-
//
|
|
20475
|
-
//
|
|
20476
|
-
if (!
|
|
20952
|
+
_constraintsChanged(stateTarget, ...constraints) {
|
|
20953
|
+
// The input element's validity cannot be determined until
|
|
20954
|
+
// all the necessary constraint attributes aren't set on it.
|
|
20955
|
+
if (!stateTarget) {
|
|
20477
20956
|
return;
|
|
20478
20957
|
}
|
|
20479
20958
|
|
|
20480
|
-
|
|
20959
|
+
const hasConstraints = this._hasValidConstraints(constraints);
|
|
20960
|
+
const isLastConstraintRemoved = this.__previousHasConstraints && !hasConstraints;
|
|
20961
|
+
|
|
20962
|
+
if ((this._hasValue || this.invalid) && hasConstraints) {
|
|
20481
20963
|
this.validate();
|
|
20482
|
-
} else {
|
|
20483
|
-
this.
|
|
20964
|
+
} else if (isLastConstraintRemoved) {
|
|
20965
|
+
this._setInvalid(false);
|
|
20484
20966
|
}
|
|
20967
|
+
|
|
20968
|
+
this.__previousHasConstraints = hasConstraints;
|
|
20485
20969
|
}
|
|
20486
20970
|
|
|
20487
20971
|
/**
|
|
@@ -20516,6 +21000,82 @@ const InputConstraintsMixin = dedupingMixin(
|
|
|
20516
21000
|
},
|
|
20517
21001
|
);
|
|
20518
21002
|
|
|
21003
|
+
/**
|
|
21004
|
+
* @license
|
|
21005
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
21006
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
21007
|
+
*/
|
|
21008
|
+
|
|
21009
|
+
const stylesMap = new WeakMap();
|
|
21010
|
+
|
|
21011
|
+
/**
|
|
21012
|
+
* Get all the styles inserted into root.
|
|
21013
|
+
* @param {DocumentOrShadowRoot} root
|
|
21014
|
+
* @return {Set<string>}
|
|
21015
|
+
*/
|
|
21016
|
+
function getRootStyles(root) {
|
|
21017
|
+
if (!stylesMap.has(root)) {
|
|
21018
|
+
stylesMap.set(root, new Set());
|
|
21019
|
+
}
|
|
21020
|
+
|
|
21021
|
+
return stylesMap.get(root);
|
|
21022
|
+
}
|
|
21023
|
+
|
|
21024
|
+
/**
|
|
21025
|
+
* Insert styles into the root.
|
|
21026
|
+
* @param {string} styles
|
|
21027
|
+
* @param {DocumentOrShadowRoot} root
|
|
21028
|
+
*/
|
|
21029
|
+
function insertStyles(styles, root) {
|
|
21030
|
+
const style = document.createElement('style');
|
|
21031
|
+
style.textContent = styles;
|
|
21032
|
+
|
|
21033
|
+
if (root === document) {
|
|
21034
|
+
document.head.appendChild(style);
|
|
21035
|
+
} else {
|
|
21036
|
+
root.insertBefore(style, root.firstChild);
|
|
21037
|
+
}
|
|
21038
|
+
}
|
|
21039
|
+
|
|
21040
|
+
/**
|
|
21041
|
+
* Mixin to insert styles into the outer scope to handle slotted components.
|
|
21042
|
+
* This is useful e.g. to hide native `<input type="number">` controls.
|
|
21043
|
+
*
|
|
21044
|
+
* @polymerMixin
|
|
21045
|
+
*/
|
|
21046
|
+
const SlotStylesMixin = dedupingMixin(
|
|
21047
|
+
(superclass) =>
|
|
21048
|
+
class SlotStylesMixinClass extends superclass {
|
|
21049
|
+
/**
|
|
21050
|
+
* List of styles to insert into root.
|
|
21051
|
+
* @protected
|
|
21052
|
+
*/
|
|
21053
|
+
get slotStyles() {
|
|
21054
|
+
return {};
|
|
21055
|
+
}
|
|
21056
|
+
|
|
21057
|
+
/** @protected */
|
|
21058
|
+
connectedCallback() {
|
|
21059
|
+
super.connectedCallback();
|
|
21060
|
+
|
|
21061
|
+
this.__applySlotStyles();
|
|
21062
|
+
}
|
|
21063
|
+
|
|
21064
|
+
/** @private */
|
|
21065
|
+
__applySlotStyles() {
|
|
21066
|
+
const root = this.getRootNode();
|
|
21067
|
+
const rootStyles = getRootStyles(root);
|
|
21068
|
+
|
|
21069
|
+
this.slotStyles.forEach((styles) => {
|
|
21070
|
+
if (!rootStyles.has(styles)) {
|
|
21071
|
+
insertStyles(styles, root);
|
|
21072
|
+
rootStyles.add(styles);
|
|
21073
|
+
}
|
|
21074
|
+
});
|
|
21075
|
+
}
|
|
21076
|
+
},
|
|
21077
|
+
);
|
|
21078
|
+
|
|
20519
21079
|
/**
|
|
20520
21080
|
* @license
|
|
20521
21081
|
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
@@ -20530,13 +21090,31 @@ const InputConstraintsMixin = dedupingMixin(
|
|
|
20530
21090
|
* @mixes FieldMixin
|
|
20531
21091
|
* @mixes InputConstraintsMixin
|
|
20532
21092
|
* @mixes KeyboardMixin
|
|
21093
|
+
* @mixes SlotStylesMixin
|
|
20533
21094
|
*/
|
|
20534
21095
|
const InputControlMixin = (superclass) =>
|
|
20535
|
-
class InputControlMixinClass extends
|
|
20536
|
-
InputConstraintsMixin(FieldMixin(KeyboardMixin(superclass))),
|
|
21096
|
+
class InputControlMixinClass extends SlotStylesMixin(
|
|
21097
|
+
DelegateFocusMixin(InputConstraintsMixin(FieldMixin(KeyboardMixin(superclass)))),
|
|
20537
21098
|
) {
|
|
20538
21099
|
static get properties() {
|
|
20539
21100
|
return {
|
|
21101
|
+
/**
|
|
21102
|
+
* A pattern matched against individual characters the user inputs.
|
|
21103
|
+
*
|
|
21104
|
+
* When set, the field will prevent:
|
|
21105
|
+
* - `keydown` events if the entered key doesn't match `/^allowedCharPattern$/`
|
|
21106
|
+
* - `paste` events if the pasted text doesn't match `/^allowedCharPattern*$/`
|
|
21107
|
+
* - `drop` events if the dropped text doesn't match `/^allowedCharPattern*$/`
|
|
21108
|
+
*
|
|
21109
|
+
* For example, to allow entering only numbers and minus signs, use:
|
|
21110
|
+
* `allowedCharPattern = "[\\d-]"`
|
|
21111
|
+
* @attr {string} allowed-char-pattern
|
|
21112
|
+
*/
|
|
21113
|
+
allowedCharPattern: {
|
|
21114
|
+
type: String,
|
|
21115
|
+
observer: '_allowedCharPatternChanged',
|
|
21116
|
+
},
|
|
21117
|
+
|
|
20540
21118
|
/**
|
|
20541
21119
|
* If true, the input text gets fully selected when the field is focused using click or touch / tap.
|
|
20542
21120
|
*/
|
|
@@ -20594,6 +21172,14 @@ const InputControlMixin = (superclass) =>
|
|
|
20594
21172
|
return [...super.delegateAttrs, 'name', 'type', 'placeholder', 'readonly', 'invalid', 'title'];
|
|
20595
21173
|
}
|
|
20596
21174
|
|
|
21175
|
+
constructor() {
|
|
21176
|
+
super();
|
|
21177
|
+
|
|
21178
|
+
this._boundOnPaste = this._onPaste.bind(this);
|
|
21179
|
+
this._boundOnDrop = this._onDrop.bind(this);
|
|
21180
|
+
this._boundOnBeforeInput = this._onBeforeInput.bind(this);
|
|
21181
|
+
}
|
|
21182
|
+
|
|
20597
21183
|
/**
|
|
20598
21184
|
* Any element extending this mixin is required to implement this getter.
|
|
20599
21185
|
* It returns the reference to the clear button element.
|
|
@@ -20605,6 +21191,19 @@ const InputControlMixin = (superclass) =>
|
|
|
20605
21191
|
return null;
|
|
20606
21192
|
}
|
|
20607
21193
|
|
|
21194
|
+
/** @protected */
|
|
21195
|
+
get slotStyles() {
|
|
21196
|
+
// Needed for Safari, where ::slotted(...)::placeholder does not work
|
|
21197
|
+
return [
|
|
21198
|
+
`
|
|
21199
|
+
:is(input[slot='input'], textarea[slot='textarea'])::placeholder {
|
|
21200
|
+
font: inherit;
|
|
21201
|
+
color: inherit;
|
|
21202
|
+
}
|
|
21203
|
+
`,
|
|
21204
|
+
];
|
|
21205
|
+
}
|
|
21206
|
+
|
|
20608
21207
|
/** @protected */
|
|
20609
21208
|
ready() {
|
|
20610
21209
|
super.ready();
|
|
@@ -20686,6 +21285,115 @@ const InputControlMixin = (superclass) =>
|
|
|
20686
21285
|
this.inputElement.dispatchEvent(new Event('change', { bubbles: true }));
|
|
20687
21286
|
}
|
|
20688
21287
|
|
|
21288
|
+
/**
|
|
21289
|
+
* Override a method from `InputMixin`.
|
|
21290
|
+
* @param {!HTMLElement} input
|
|
21291
|
+
* @protected
|
|
21292
|
+
* @override
|
|
21293
|
+
*/
|
|
21294
|
+
_addInputListeners(input) {
|
|
21295
|
+
super._addInputListeners(input);
|
|
21296
|
+
|
|
21297
|
+
input.addEventListener('paste', this._boundOnPaste);
|
|
21298
|
+
input.addEventListener('drop', this._boundOnDrop);
|
|
21299
|
+
input.addEventListener('beforeinput', this._boundOnBeforeInput);
|
|
21300
|
+
}
|
|
21301
|
+
|
|
21302
|
+
/**
|
|
21303
|
+
* Override a method from `InputMixin`.
|
|
21304
|
+
* @param {!HTMLElement} input
|
|
21305
|
+
* @protected
|
|
21306
|
+
* @override
|
|
21307
|
+
*/
|
|
21308
|
+
_removeInputListeners(input) {
|
|
21309
|
+
super._removeInputListeners(input);
|
|
21310
|
+
|
|
21311
|
+
input.removeEventListener('paste', this._boundOnPaste);
|
|
21312
|
+
input.removeEventListener('drop', this._boundOnDrop);
|
|
21313
|
+
input.removeEventListener('beforeinput', this._boundOnBeforeInput);
|
|
21314
|
+
}
|
|
21315
|
+
|
|
21316
|
+
/**
|
|
21317
|
+
* Override an event listener from `KeyboardMixin`.
|
|
21318
|
+
* @param {!KeyboardEvent} event
|
|
21319
|
+
* @protected
|
|
21320
|
+
* @override
|
|
21321
|
+
*/
|
|
21322
|
+
_onKeyDown(event) {
|
|
21323
|
+
super._onKeyDown(event);
|
|
21324
|
+
|
|
21325
|
+
if (this.allowedCharPattern && !this.__shouldAcceptKey(event)) {
|
|
21326
|
+
event.preventDefault();
|
|
21327
|
+
this._markInputPrevented();
|
|
21328
|
+
}
|
|
21329
|
+
}
|
|
21330
|
+
|
|
21331
|
+
/** @protected */
|
|
21332
|
+
_markInputPrevented() {
|
|
21333
|
+
// Add input-prevented attribute for 200ms
|
|
21334
|
+
this.setAttribute('input-prevented', '');
|
|
21335
|
+
this._preventInputDebouncer = Debouncer$1.debounce(this._preventInputDebouncer, timeOut.after(200), () => {
|
|
21336
|
+
this.removeAttribute('input-prevented');
|
|
21337
|
+
});
|
|
21338
|
+
}
|
|
21339
|
+
|
|
21340
|
+
/** @private */
|
|
21341
|
+
__shouldAcceptKey(event) {
|
|
21342
|
+
return (
|
|
21343
|
+
event.metaKey ||
|
|
21344
|
+
event.ctrlKey ||
|
|
21345
|
+
!event.key || // Allow typing anything if event.key is not supported
|
|
21346
|
+
event.key.length !== 1 || // Allow "Backspace", "ArrowLeft" etc.
|
|
21347
|
+
this.__allowedCharRegExp.test(event.key)
|
|
21348
|
+
);
|
|
21349
|
+
}
|
|
21350
|
+
|
|
21351
|
+
/** @private */
|
|
21352
|
+
_onPaste(e) {
|
|
21353
|
+
if (this.allowedCharPattern) {
|
|
21354
|
+
const pastedText = e.clipboardData.getData('text');
|
|
21355
|
+
if (!this.__allowedTextRegExp.test(pastedText)) {
|
|
21356
|
+
e.preventDefault();
|
|
21357
|
+
this._markInputPrevented();
|
|
21358
|
+
}
|
|
21359
|
+
}
|
|
21360
|
+
}
|
|
21361
|
+
|
|
21362
|
+
/** @private */
|
|
21363
|
+
_onDrop(e) {
|
|
21364
|
+
if (this.allowedCharPattern) {
|
|
21365
|
+
const draggedText = e.dataTransfer.getData('text');
|
|
21366
|
+
if (!this.__allowedTextRegExp.test(draggedText)) {
|
|
21367
|
+
e.preventDefault();
|
|
21368
|
+
this._markInputPrevented();
|
|
21369
|
+
}
|
|
21370
|
+
}
|
|
21371
|
+
}
|
|
21372
|
+
|
|
21373
|
+
/** @private */
|
|
21374
|
+
_onBeforeInput(e) {
|
|
21375
|
+
// The `beforeinput` event covers all the cases for `allowedCharPattern`: keyboard, pasting and dropping,
|
|
21376
|
+
// but it is still experimental technology so we can't rely on it. It's used here just as an additional check,
|
|
21377
|
+
// because it seems to be the only way to detect and prevent specific keys on mobile devices.
|
|
21378
|
+
// See https://github.com/vaadin/vaadin-text-field/issues/429
|
|
21379
|
+
if (this.allowedCharPattern && e.data && !this.__allowedTextRegExp.test(e.data)) {
|
|
21380
|
+
e.preventDefault();
|
|
21381
|
+
this._markInputPrevented();
|
|
21382
|
+
}
|
|
21383
|
+
}
|
|
21384
|
+
|
|
21385
|
+
/** @private */
|
|
21386
|
+
_allowedCharPatternChanged(charPattern) {
|
|
21387
|
+
if (charPattern) {
|
|
21388
|
+
try {
|
|
21389
|
+
this.__allowedCharRegExp = new RegExp(`^${charPattern}$`);
|
|
21390
|
+
this.__allowedTextRegExp = new RegExp(`^${charPattern}*$`);
|
|
21391
|
+
} catch (e) {
|
|
21392
|
+
console.error(e);
|
|
21393
|
+
}
|
|
21394
|
+
}
|
|
21395
|
+
}
|
|
21396
|
+
|
|
20689
21397
|
/**
|
|
20690
21398
|
* Fired when the user commits a value change.
|
|
20691
21399
|
*
|
|
@@ -20724,14 +21432,13 @@ class InputController extends SlotController {
|
|
|
20724
21432
|
}
|
|
20725
21433
|
|
|
20726
21434
|
// Ensure every instance has unique ID
|
|
20727
|
-
|
|
20728
|
-
host._inputId = `${host.localName}-${uniqueId}`;
|
|
20729
|
-
node.id = host._inputId;
|
|
21435
|
+
node.id = this.defaultId;
|
|
20730
21436
|
|
|
20731
21437
|
if (typeof callback === 'function') {
|
|
20732
21438
|
callback(node);
|
|
20733
21439
|
}
|
|
20734
21440
|
},
|
|
21441
|
+
true,
|
|
20735
21442
|
);
|
|
20736
21443
|
}
|
|
20737
21444
|
}
|
|
@@ -20913,7 +21620,9 @@ class VirtualKeyboardController {
|
|
|
20913
21620
|
* @param {function(new:HTMLElement)} subclass
|
|
20914
21621
|
*/
|
|
20915
21622
|
const DatePickerMixin = (subclass) =>
|
|
20916
|
-
class VaadinDatePickerMixin extends ControllerMixin(
|
|
21623
|
+
class VaadinDatePickerMixin extends ControllerMixin(
|
|
21624
|
+
DelegateFocusMixin(InputConstraintsMixin(KeyboardMixin(subclass))),
|
|
21625
|
+
) {
|
|
20917
21626
|
static get properties() {
|
|
20918
21627
|
return {
|
|
20919
21628
|
/**
|
|
@@ -20942,7 +21651,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
20942
21651
|
*/
|
|
20943
21652
|
value: {
|
|
20944
21653
|
type: String,
|
|
20945
|
-
observer: '_valueChanged',
|
|
20946
21654
|
notify: true,
|
|
20947
21655
|
value: '',
|
|
20948
21656
|
},
|
|
@@ -20998,13 +21706,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
20998
21706
|
value: '(max-width: 420px), (max-height: 420px)',
|
|
20999
21707
|
},
|
|
21000
21708
|
|
|
21001
|
-
/**
|
|
21002
|
-
* An array of ancestor elements whose -webkit-overflow-scrolling is forced from value
|
|
21003
|
-
* 'touch' to value 'auto' in order to prevent them from clipping the dropdown. iOS only.
|
|
21004
|
-
* @private
|
|
21005
|
-
*/
|
|
21006
|
-
_touchPrevented: Array,
|
|
21007
|
-
|
|
21008
21709
|
/**
|
|
21009
21710
|
* The object used to localize this component.
|
|
21010
21711
|
* To change the default localization, replace the entire
|
|
@@ -21060,6 +21761,16 @@ const DatePickerMixin = (subclass) =>
|
|
|
21060
21761
|
* // Translation of the Cancel button text.
|
|
21061
21762
|
* cancel: 'Cancel',
|
|
21062
21763
|
*
|
|
21764
|
+
* // Used for adjusting the year value when parsing dates with short years.
|
|
21765
|
+
* // The year values between 0 and 99 are evaluated and adjusted.
|
|
21766
|
+
* // Example: for a referenceDate of 1970-10-30;
|
|
21767
|
+
* // dateToBeParsed: 40-10-30, result: 1940-10-30
|
|
21768
|
+
* // dateToBeParsed: 80-10-30, result: 1980-10-30
|
|
21769
|
+
* // dateToBeParsed: 10-10-30, result: 2010-10-30
|
|
21770
|
+
* // Supported date format: ISO 8601 `"YYYY-MM-DD"` (default)
|
|
21771
|
+
* // The default value is the current date.
|
|
21772
|
+
* referenceDate: '',
|
|
21773
|
+
*
|
|
21063
21774
|
* // A function to format given `Object` as
|
|
21064
21775
|
* // date string. Object is in the format `{ day: ..., month: ..., year: ... }`
|
|
21065
21776
|
* // Note: The argument month is 0-based. This means that January = 0 and December = 11.
|
|
@@ -21113,11 +21824,12 @@ const DatePickerMixin = (subclass) =>
|
|
|
21113
21824
|
calendar: 'Calendar',
|
|
21114
21825
|
today: 'Today',
|
|
21115
21826
|
cancel: 'Cancel',
|
|
21116
|
-
|
|
21827
|
+
referenceDate: '',
|
|
21828
|
+
formatDate(d) {
|
|
21117
21829
|
const yearStr = String(d.year).replace(/\d+/, (y) => '0000'.substr(y.length) + y);
|
|
21118
21830
|
return [d.month + 1, d.day, yearStr].join('/');
|
|
21119
21831
|
},
|
|
21120
|
-
parseDate
|
|
21832
|
+
parseDate(text) {
|
|
21121
21833
|
const parts = text.split('/');
|
|
21122
21834
|
const today = new Date();
|
|
21123
21835
|
let date,
|
|
@@ -21125,12 +21837,13 @@ const DatePickerMixin = (subclass) =>
|
|
|
21125
21837
|
year = today.getFullYear();
|
|
21126
21838
|
|
|
21127
21839
|
if (parts.length === 3) {
|
|
21840
|
+
month = parseInt(parts[0]) - 1;
|
|
21841
|
+
date = parseInt(parts[1]);
|
|
21128
21842
|
year = parseInt(parts[2]);
|
|
21129
21843
|
if (parts[2].length < 3 && year >= 0) {
|
|
21130
|
-
|
|
21844
|
+
const usedReferenceDate = this.referenceDate ? parseDate(this.referenceDate) : new Date();
|
|
21845
|
+
year = getAdjustedYear(usedReferenceDate, year, month, date);
|
|
21131
21846
|
}
|
|
21132
|
-
month = parseInt(parts[0]) - 1;
|
|
21133
|
-
date = parseInt(parts[1]);
|
|
21134
21847
|
} else if (parts.length === 2) {
|
|
21135
21848
|
month = parseInt(parts[0]) - 1;
|
|
21136
21849
|
date = parseInt(parts[1]);
|
|
@@ -21160,7 +21873,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21160
21873
|
*/
|
|
21161
21874
|
min: {
|
|
21162
21875
|
type: String,
|
|
21163
|
-
observer: '_minChanged',
|
|
21164
21876
|
},
|
|
21165
21877
|
|
|
21166
21878
|
/**
|
|
@@ -21174,28 +21886,26 @@ const DatePickerMixin = (subclass) =>
|
|
|
21174
21886
|
*/
|
|
21175
21887
|
max: {
|
|
21176
21888
|
type: String,
|
|
21177
|
-
observer: '_maxChanged',
|
|
21178
21889
|
},
|
|
21179
21890
|
|
|
21180
21891
|
/**
|
|
21181
21892
|
* The earliest date that can be selected. All earlier dates will be disabled.
|
|
21182
|
-
* @type {Date |
|
|
21893
|
+
* @type {Date | undefined}
|
|
21183
21894
|
* @protected
|
|
21184
21895
|
*/
|
|
21185
21896
|
_minDate: {
|
|
21186
21897
|
type: Date,
|
|
21187
|
-
|
|
21188
|
-
value: '',
|
|
21898
|
+
computed: '__computeMinOrMaxDate(min)',
|
|
21189
21899
|
},
|
|
21190
21900
|
|
|
21191
21901
|
/**
|
|
21192
21902
|
* The latest date that can be selected. All later dates will be disabled.
|
|
21193
|
-
* @type {Date |
|
|
21903
|
+
* @type {Date | undefined}
|
|
21194
21904
|
* @protected
|
|
21195
21905
|
*/
|
|
21196
21906
|
_maxDate: {
|
|
21197
21907
|
type: Date,
|
|
21198
|
-
|
|
21908
|
+
computed: '__computeMinOrMaxDate(max)',
|
|
21199
21909
|
},
|
|
21200
21910
|
|
|
21201
21911
|
/** @private */
|
|
@@ -21210,12 +21920,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21210
21920
|
value: isIOS,
|
|
21211
21921
|
},
|
|
21212
21922
|
|
|
21213
|
-
/** @private */
|
|
21214
|
-
_webkitOverflowScroll: {
|
|
21215
|
-
type: Boolean,
|
|
21216
|
-
value: document.createElement('div').style.webkitOverflowScrolling === '',
|
|
21217
|
-
},
|
|
21218
|
-
|
|
21219
21923
|
/** @private */
|
|
21220
21924
|
_focusOverlayOnOpen: Boolean,
|
|
21221
21925
|
|
|
@@ -21231,6 +21935,10 @@ const DatePickerMixin = (subclass) =>
|
|
|
21231
21935
|
];
|
|
21232
21936
|
}
|
|
21233
21937
|
|
|
21938
|
+
static get constraints() {
|
|
21939
|
+
return [...super.constraints, 'min', 'max'];
|
|
21940
|
+
}
|
|
21941
|
+
|
|
21234
21942
|
/**
|
|
21235
21943
|
* Override a getter from `InputControlMixin` to make it optional
|
|
21236
21944
|
* and to prevent warning when a clear button is missing,
|
|
@@ -21291,18 +21999,13 @@ const DatePickerMixin = (subclass) =>
|
|
|
21291
21999
|
|
|
21292
22000
|
if (!this.opened) {
|
|
21293
22001
|
if (this.autoOpenDisabled) {
|
|
21294
|
-
|
|
21295
|
-
if (this._isValidDate(parsedDate)) {
|
|
21296
|
-
this._selectDate(parsedDate);
|
|
21297
|
-
}
|
|
22002
|
+
this._selectParsedOrFocusedDate();
|
|
21298
22003
|
}
|
|
21299
22004
|
|
|
21300
|
-
|
|
21301
|
-
|
|
22005
|
+
this.validate();
|
|
22006
|
+
|
|
22007
|
+
if (this._inputValue === '' && this.value !== '') {
|
|
21302
22008
|
this.value = '';
|
|
21303
|
-
this.__dispatchChange = false;
|
|
21304
|
-
} else {
|
|
21305
|
-
this.validate();
|
|
21306
22009
|
}
|
|
21307
22010
|
}
|
|
21308
22011
|
}
|
|
@@ -21371,14 +22074,19 @@ const DatePickerMixin = (subclass) =>
|
|
|
21371
22074
|
this.$.overlay.removeAttribute('disable-upgrade');
|
|
21372
22075
|
this._overlayInitialized = true;
|
|
21373
22076
|
|
|
21374
|
-
this.$.overlay.addEventListener('opened-changed', (e) =>
|
|
22077
|
+
this.$.overlay.addEventListener('opened-changed', (e) => {
|
|
22078
|
+
this.opened = e.detail.value;
|
|
22079
|
+
});
|
|
21375
22080
|
|
|
21376
22081
|
this.$.overlay.addEventListener('vaadin-overlay-escape-press', () => {
|
|
21377
22082
|
this._focusedDate = this._selectedDate;
|
|
21378
22083
|
this._close();
|
|
21379
22084
|
});
|
|
21380
22085
|
|
|
21381
|
-
this._overlayContent.addEventListener('close',
|
|
22086
|
+
this._overlayContent.addEventListener('close', () => {
|
|
22087
|
+
this._close();
|
|
22088
|
+
});
|
|
22089
|
+
|
|
21382
22090
|
this._overlayContent.addEventListener('focus-input', this._focusAndSelect.bind(this));
|
|
21383
22091
|
|
|
21384
22092
|
// User confirmed selected date by clicking the calendar.
|
|
@@ -21387,34 +22095,29 @@ const DatePickerMixin = (subclass) =>
|
|
|
21387
22095
|
|
|
21388
22096
|
this._selectDate(e.detail.date);
|
|
21389
22097
|
|
|
21390
|
-
this._close(
|
|
22098
|
+
this._close();
|
|
21391
22099
|
});
|
|
21392
22100
|
|
|
21393
|
-
// User confirmed selected date by pressing Enter or Today.
|
|
22101
|
+
// User confirmed selected date by pressing Enter, Space, or Today.
|
|
21394
22102
|
this._overlayContent.addEventListener('date-selected', (e) => {
|
|
21395
|
-
|
|
22103
|
+
// Reset if a date is deselected.
|
|
22104
|
+
this.__userConfirmedDate = !!e.detail.date;
|
|
21396
22105
|
|
|
21397
22106
|
this._selectDate(e.detail.date);
|
|
21398
22107
|
});
|
|
21399
22108
|
|
|
21400
|
-
//
|
|
22109
|
+
// Set focus-ring attribute when moving focus to the overlay
|
|
22110
|
+
// by pressing Tab or arrow key, after opening it on click.
|
|
21401
22111
|
this._overlayContent.addEventListener('focusin', () => {
|
|
21402
|
-
this.
|
|
22112
|
+
if (this._keyboardActive) {
|
|
22113
|
+
this._setFocused(true);
|
|
22114
|
+
}
|
|
21403
22115
|
});
|
|
21404
22116
|
|
|
21405
22117
|
this.addEventListener('mousedown', () => this.__bringToFront());
|
|
21406
22118
|
this.addEventListener('touchstart', () => this.__bringToFront());
|
|
21407
22119
|
}
|
|
21408
22120
|
|
|
21409
|
-
/**
|
|
21410
|
-
* Returns true if `value` is valid, and sets the `invalid` flag appropriately.
|
|
21411
|
-
*
|
|
21412
|
-
* @return {boolean} True if the value is valid and sets the `invalid` flag appropriately
|
|
21413
|
-
*/
|
|
21414
|
-
validate() {
|
|
21415
|
-
return !(this.invalid = !this.checkValidity());
|
|
21416
|
-
}
|
|
21417
|
-
|
|
21418
22121
|
/**
|
|
21419
22122
|
* Returns true if the current input value satisfies all constraints (if any)
|
|
21420
22123
|
*
|
|
@@ -21425,7 +22128,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21425
22128
|
checkValidity() {
|
|
21426
22129
|
const inputValid =
|
|
21427
22130
|
!this._inputValue ||
|
|
21428
|
-
(this._selectedDate && this._inputValue === this._getFormattedDate(this.i18n.formatDate, this._selectedDate));
|
|
22131
|
+
(!!this._selectedDate && this._inputValue === this._getFormattedDate(this.i18n.formatDate, this._selectedDate));
|
|
21429
22132
|
const minMaxValid = !this._selectedDate || dateAllowed(this._selectedDate, this._minDate, this._maxDate);
|
|
21430
22133
|
|
|
21431
22134
|
let inputValidity = true;
|
|
@@ -21441,6 +22144,51 @@ const DatePickerMixin = (subclass) =>
|
|
|
21441
22144
|
return inputValid && minMaxValid && inputValidity;
|
|
21442
22145
|
}
|
|
21443
22146
|
|
|
22147
|
+
/**
|
|
22148
|
+
* Override method inherited from `FocusMixin`
|
|
22149
|
+
* to not call `_setFocused(true)` when focus
|
|
22150
|
+
* is restored after closing overlay on click,
|
|
22151
|
+
* and to avoid removing `focus-ring` attribute.
|
|
22152
|
+
*
|
|
22153
|
+
* @param {!FocusEvent} _event
|
|
22154
|
+
* @return {boolean}
|
|
22155
|
+
* @protected
|
|
22156
|
+
* @override
|
|
22157
|
+
*/
|
|
22158
|
+
_shouldSetFocus(_event) {
|
|
22159
|
+
return !this._shouldKeepFocusRing;
|
|
22160
|
+
}
|
|
22161
|
+
|
|
22162
|
+
/**
|
|
22163
|
+
* Override method inherited from `FocusMixin`
|
|
22164
|
+
* to prevent removing the `focused` attribute:
|
|
22165
|
+
* - when moving focus to the overlay content,
|
|
22166
|
+
* - when closing on date click / outside click.
|
|
22167
|
+
*
|
|
22168
|
+
* @param {!FocusEvent} _event
|
|
22169
|
+
* @return {boolean}
|
|
22170
|
+
* @protected
|
|
22171
|
+
* @override
|
|
22172
|
+
*/
|
|
22173
|
+
_shouldRemoveFocus(_event) {
|
|
22174
|
+
return !this.opened;
|
|
22175
|
+
}
|
|
22176
|
+
|
|
22177
|
+
/**
|
|
22178
|
+
* Override method inherited from `FocusMixin`
|
|
22179
|
+
* to store the `focus-ring` state to restore
|
|
22180
|
+
* it later when closing on outside click.
|
|
22181
|
+
*
|
|
22182
|
+
* @param {boolean} focused
|
|
22183
|
+
* @protected
|
|
22184
|
+
* @override
|
|
22185
|
+
*/
|
|
22186
|
+
_setFocused(focused) {
|
|
22187
|
+
super._setFocused(focused);
|
|
22188
|
+
|
|
22189
|
+
this._shouldKeepFocusRing = focused && this._keyboardActive;
|
|
22190
|
+
}
|
|
22191
|
+
|
|
21444
22192
|
/**
|
|
21445
22193
|
* Select date on user interaction and set the flag
|
|
21446
22194
|
* to fire change event if necessary.
|
|
@@ -21460,10 +22208,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21460
22208
|
}
|
|
21461
22209
|
|
|
21462
22210
|
/** @private */
|
|
21463
|
-
_close(
|
|
21464
|
-
if (e) {
|
|
21465
|
-
e.stopPropagation();
|
|
21466
|
-
}
|
|
22211
|
+
_close() {
|
|
21467
22212
|
this._focus();
|
|
21468
22213
|
this.close();
|
|
21469
22214
|
}
|
|
@@ -21475,21 +22220,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21475
22220
|
});
|
|
21476
22221
|
}
|
|
21477
22222
|
|
|
21478
|
-
/** @private */
|
|
21479
|
-
_parseDate(str) {
|
|
21480
|
-
// Parsing with RegExp to ensure correct format
|
|
21481
|
-
const parts = /^([-+]\d{1}|\d{2,4}|[-+]\d{6})-(\d{1,2})-(\d{1,2})$/.exec(str);
|
|
21482
|
-
if (!parts) {
|
|
21483
|
-
return;
|
|
21484
|
-
}
|
|
21485
|
-
|
|
21486
|
-
const date = new Date(0, 0); // Wrong date (1900-01-01), but with midnight in local time
|
|
21487
|
-
date.setFullYear(parseInt(parts[1], 10));
|
|
21488
|
-
date.setMonth(parseInt(parts[2], 10) - 1);
|
|
21489
|
-
date.setDate(parseInt(parts[3], 10));
|
|
21490
|
-
return date;
|
|
21491
|
-
}
|
|
21492
|
-
|
|
21493
22223
|
/** @private */
|
|
21494
22224
|
// eslint-disable-next-line max-params
|
|
21495
22225
|
_isNoInput(inputElement, fullscreen, ios, i18n, opened, autoOpenDisabled) {
|
|
@@ -21592,48 +22322,47 @@ const DatePickerMixin = (subclass) =>
|
|
|
21592
22322
|
}
|
|
21593
22323
|
}
|
|
21594
22324
|
|
|
21595
|
-
/**
|
|
21596
|
-
|
|
21597
|
-
|
|
21598
|
-
|
|
21599
|
-
|
|
21600
|
-
|
|
22325
|
+
/**
|
|
22326
|
+
* Override the value observer from `InputMixin` to implement custom
|
|
22327
|
+
* handling of the `value` property. The date-picker doesn't forward
|
|
22328
|
+
* the value directly to the input like the default implementation of `InputMixin`.
|
|
22329
|
+
* Instead, it parses the value into a date, puts it in `_selectedDate` which
|
|
22330
|
+
* is then displayed in the input with respect to the specified date format.
|
|
22331
|
+
*
|
|
22332
|
+
* @param {string | undefined} value
|
|
22333
|
+
* @param {string | undefined} oldValue
|
|
22334
|
+
* @protected
|
|
22335
|
+
* @override
|
|
22336
|
+
*/
|
|
22337
|
+
_valueChanged(value, oldValue) {
|
|
22338
|
+
const newDate = parseDate(value);
|
|
21601
22339
|
|
|
21602
|
-
|
|
21603
|
-
|
|
22340
|
+
if (value && !newDate) {
|
|
22341
|
+
// The new value cannot be parsed, revert the old value.
|
|
21604
22342
|
this.value = oldValue;
|
|
21605
22343
|
return;
|
|
21606
22344
|
}
|
|
21607
|
-
if (!dateEquals(this[property], date)) {
|
|
21608
|
-
this[property] = date;
|
|
21609
|
-
if (this.value) {
|
|
21610
|
-
this.validate();
|
|
21611
|
-
}
|
|
21612
|
-
}
|
|
21613
|
-
}
|
|
21614
|
-
|
|
21615
|
-
/** @private */
|
|
21616
|
-
_valueChanged(value, oldValue) {
|
|
21617
|
-
this._handleDateChange('_selectedDate', value, oldValue);
|
|
21618
22345
|
|
|
21619
|
-
|
|
21620
|
-
|
|
22346
|
+
if (value) {
|
|
22347
|
+
if (!dateEquals(this._selectedDate, newDate)) {
|
|
22348
|
+
// Update the date instance only if the date has actually changed.
|
|
22349
|
+
this._selectedDate = newDate;
|
|
21621
22350
|
|
|
21622
|
-
|
|
21623
|
-
|
|
21624
|
-
|
|
21625
|
-
|
|
22351
|
+
if (oldValue !== undefined) {
|
|
22352
|
+
// Validate only if `value` changes after initialization.
|
|
22353
|
+
this.validate();
|
|
22354
|
+
}
|
|
22355
|
+
}
|
|
22356
|
+
} else {
|
|
22357
|
+
this._selectedDate = null;
|
|
22358
|
+
}
|
|
21626
22359
|
|
|
21627
|
-
|
|
21628
|
-
_maxChanged(value, oldValue) {
|
|
21629
|
-
this._handleDateChange('_maxDate', value, oldValue);
|
|
22360
|
+
this._toggleHasValue(this._hasValue);
|
|
21630
22361
|
}
|
|
21631
22362
|
|
|
21632
22363
|
/** @protected */
|
|
21633
22364
|
_onOverlayOpened() {
|
|
21634
|
-
|
|
21635
|
-
|
|
21636
|
-
const parsedInitialPosition = this._parseDate(this.initialPosition);
|
|
22365
|
+
const parsedInitialPosition = parseDate(this.initialPosition);
|
|
21637
22366
|
|
|
21638
22367
|
const initialPosition =
|
|
21639
22368
|
this._selectedDate || this._overlayContent.initialPosition || parsedInitialPosition || new Date();
|
|
@@ -21652,10 +22381,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21652
22381
|
|
|
21653
22382
|
window.addEventListener('scroll', this._boundOnScroll, true);
|
|
21654
22383
|
|
|
21655
|
-
if (this._webkitOverflowScroll) {
|
|
21656
|
-
this._touchPrevented = this._preventWebkitOverflowScrollingTouch(this.parentElement);
|
|
21657
|
-
}
|
|
21658
|
-
|
|
21659
22384
|
if (this._focusOverlayOnOpen) {
|
|
21660
22385
|
this._overlayContent.focusDateElement();
|
|
21661
22386
|
this._focusOverlayOnOpen = false;
|
|
@@ -21669,25 +22394,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21669
22394
|
}
|
|
21670
22395
|
}
|
|
21671
22396
|
|
|
21672
|
-
// A hack needed for iOS to prevent dropdown from being clipped in an
|
|
21673
|
-
// ancestor container with -webkit-overflow-scrolling: touch;
|
|
21674
|
-
/** @private */
|
|
21675
|
-
_preventWebkitOverflowScrollingTouch(element) {
|
|
21676
|
-
const result = [];
|
|
21677
|
-
while (element) {
|
|
21678
|
-
if (window.getComputedStyle(element).webkitOverflowScrolling === 'touch') {
|
|
21679
|
-
const oldInlineValue = element.style.webkitOverflowScrolling;
|
|
21680
|
-
element.style.webkitOverflowScrolling = 'auto';
|
|
21681
|
-
result.push({
|
|
21682
|
-
element,
|
|
21683
|
-
oldInlineValue,
|
|
21684
|
-
});
|
|
21685
|
-
}
|
|
21686
|
-
element = element.parentElement;
|
|
21687
|
-
}
|
|
21688
|
-
return result;
|
|
21689
|
-
}
|
|
21690
|
-
|
|
21691
22397
|
/** @private */
|
|
21692
22398
|
_selectParsedOrFocusedDate() {
|
|
21693
22399
|
// Select the parsed input or focused date
|
|
@@ -21714,13 +22420,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21714
22420
|
_onOverlayClosed() {
|
|
21715
22421
|
window.removeEventListener('scroll', this._boundOnScroll, true);
|
|
21716
22422
|
|
|
21717
|
-
if (this._touchPrevented) {
|
|
21718
|
-
this._touchPrevented.forEach(
|
|
21719
|
-
(prevented) => (prevented.element.style.webkitOverflowScrolling = prevented.oldInlineValue),
|
|
21720
|
-
);
|
|
21721
|
-
this._touchPrevented = [];
|
|
21722
|
-
}
|
|
21723
|
-
|
|
21724
22423
|
// No need to select date on close if it was confirmed by the user.
|
|
21725
22424
|
if (this.__userConfirmedDate) {
|
|
21726
22425
|
this.__userConfirmedDate = false;
|
|
@@ -21736,11 +22435,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21736
22435
|
if (!this.value) {
|
|
21737
22436
|
this.validate();
|
|
21738
22437
|
}
|
|
21739
|
-
|
|
21740
|
-
// If the input isn't focused when overlay closes (fullscreen mode), clear focused state
|
|
21741
|
-
if (this.getRootNode().activeElement !== this.inputElement) {
|
|
21742
|
-
this._setFocused(false);
|
|
21743
|
-
}
|
|
21744
22438
|
}
|
|
21745
22439
|
|
|
21746
22440
|
/** @private */
|
|
@@ -21793,10 +22487,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21793
22487
|
_onChange(event) {
|
|
21794
22488
|
// For change event on the native <input> blur, after the input is cleared,
|
|
21795
22489
|
// we schedule change event to be dispatched on date-picker blur.
|
|
21796
|
-
if (
|
|
21797
|
-
this.inputElement.value === '' &&
|
|
21798
|
-
!(event.detail && event.detail.sourceEvent && event.detail.sourceEvent.__fromClearButton)
|
|
21799
|
-
) {
|
|
22490
|
+
if (this._inputValue === '') {
|
|
21800
22491
|
this.__dispatchChange = true;
|
|
21801
22492
|
}
|
|
21802
22493
|
|
|
@@ -21883,7 +22574,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21883
22574
|
if (e.shiftKey) {
|
|
21884
22575
|
this._overlayContent.focusCancel();
|
|
21885
22576
|
} else {
|
|
21886
|
-
this._overlayContent.
|
|
22577
|
+
this._overlayContent.focusDateElement();
|
|
21887
22578
|
}
|
|
21888
22579
|
}
|
|
21889
22580
|
break;
|
|
@@ -21898,21 +22589,15 @@ const DatePickerMixin = (subclass) =>
|
|
|
21898
22589
|
* @override
|
|
21899
22590
|
*/
|
|
21900
22591
|
_onEnter(_event) {
|
|
21901
|
-
const
|
|
21902
|
-
const isValidDate = this._isValidDate(parsedDate);
|
|
22592
|
+
const oldValue = this.value;
|
|
21903
22593
|
if (this.opened) {
|
|
21904
|
-
|
|
21905
|
-
this._selectDate(this._overlayContent.focusedDate);
|
|
21906
|
-
}
|
|
22594
|
+
// Closing will implicitly select parsed or focused date
|
|
21907
22595
|
this.close();
|
|
21908
|
-
} else if (!isValidDate && this.inputElement.value !== '') {
|
|
21909
|
-
this.validate();
|
|
21910
22596
|
} else {
|
|
21911
|
-
const oldValue = this.value;
|
|
21912
22597
|
this._selectParsedOrFocusedDate();
|
|
21913
|
-
|
|
21914
|
-
|
|
21915
|
-
|
|
22598
|
+
}
|
|
22599
|
+
if (oldValue === this.value) {
|
|
22600
|
+
this.validate();
|
|
21916
22601
|
}
|
|
21917
22602
|
}
|
|
21918
22603
|
|
|
@@ -21954,7 +22639,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21954
22639
|
/** @private */
|
|
21955
22640
|
_getParsedDate(inputValue = this._inputValue) {
|
|
21956
22641
|
const dateObject = this.i18n.parseDate && this.i18n.parseDate(inputValue);
|
|
21957
|
-
const parsedDate = dateObject &&
|
|
22642
|
+
const parsedDate = dateObject && parseDate(`${dateObject.year}-${dateObject.month + 1}-${dateObject.day}`);
|
|
21958
22643
|
return parsedDate;
|
|
21959
22644
|
}
|
|
21960
22645
|
|
|
@@ -21976,7 +22661,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21976
22661
|
|
|
21977
22662
|
/** @private */
|
|
21978
22663
|
_userInputValueChanged() {
|
|
21979
|
-
if (this.
|
|
22664
|
+
if (this._inputValue) {
|
|
21980
22665
|
const parsedDate = this._getParsedDate();
|
|
21981
22666
|
|
|
21982
22667
|
if (this._isValidDate(parsedDate)) {
|
|
@@ -21994,6 +22679,11 @@ const DatePickerMixin = (subclass) =>
|
|
|
21994
22679
|
return this.$.overlay.content.querySelector('#overlay-content');
|
|
21995
22680
|
}
|
|
21996
22681
|
|
|
22682
|
+
/** @private */
|
|
22683
|
+
__computeMinOrMaxDate(dateString) {
|
|
22684
|
+
return parseDate(dateString);
|
|
22685
|
+
}
|
|
22686
|
+
|
|
21997
22687
|
/**
|
|
21998
22688
|
* Fired when the user commits a value change.
|
|
21999
22689
|
*
|
|
@@ -22105,12 +22795,13 @@ registerStyles('vaadin-date-picker', [inputFieldShared, datePickerStyles], { mod
|
|
|
22105
22795
|
* Note: the `theme` attribute value set on `<vaadin-date-picker>` is
|
|
22106
22796
|
* propagated to the internal components listed above.
|
|
22107
22797
|
*
|
|
22108
|
-
* See [Styling Components](https://vaadin.com/docs/latest/
|
|
22798
|
+
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
|
|
22109
22799
|
*
|
|
22110
22800
|
* @fires {Event} change - Fired when the user commits a value change.
|
|
22111
22801
|
* @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
|
|
22112
22802
|
* @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
|
|
22113
22803
|
* @fires {CustomEvent} value-changed - Fired when the `value` property changes.
|
|
22804
|
+
* @fires {CustomEvent} validated - Fired whenever the field is validated.
|
|
22114
22805
|
*
|
|
22115
22806
|
* @extends HTMLElement
|
|
22116
22807
|
* @mixes ElementMixin
|
|
@@ -22164,7 +22855,7 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
|
|
|
22164
22855
|
fullscreen$="[[_fullscreen]]"
|
|
22165
22856
|
theme$="[[__getOverlayTheme(_theme, _overlayInitialized)]]"
|
|
22166
22857
|
on-vaadin-overlay-open="_onOverlayOpened"
|
|
22167
|
-
on-vaadin-overlay-
|
|
22858
|
+
on-vaadin-overlay-closing="_onOverlayClosed"
|
|
22168
22859
|
restore-focus-on-close
|
|
22169
22860
|
restore-focus-node="[[inputElement]]"
|
|
22170
22861
|
disable-upgrade
|
|
@@ -22185,6 +22876,8 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
|
|
|
22185
22876
|
></vaadin-date-picker-overlay-content>
|
|
22186
22877
|
</template>
|
|
22187
22878
|
</vaadin-date-picker-overlay>
|
|
22879
|
+
|
|
22880
|
+
<slot name="tooltip"></slot>
|
|
22188
22881
|
`;
|
|
22189
22882
|
}
|
|
22190
22883
|
|
|
@@ -22211,6 +22904,11 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
|
|
|
22211
22904
|
);
|
|
22212
22905
|
this.addController(new LabelledInputController(this.inputElement, this._labelController));
|
|
22213
22906
|
|
|
22907
|
+
this._tooltipController = new TooltipController(this);
|
|
22908
|
+
this.addController(this._tooltipController);
|
|
22909
|
+
this._tooltipController.setPosition('top');
|
|
22910
|
+
this._tooltipController.setShouldShow((target) => !target.opened);
|
|
22911
|
+
|
|
22214
22912
|
const toggleButton = this.shadowRoot.querySelector('[part="toggle-button"]');
|
|
22215
22913
|
toggleButton.addEventListener('mousedown', (e) => e.preventDefault());
|
|
22216
22914
|
}
|
|
@@ -22224,11 +22922,6 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
|
|
|
22224
22922
|
|
|
22225
22923
|
/** @private */
|
|
22226
22924
|
_onVaadinOverlayClose(e) {
|
|
22227
|
-
if (this._openedWithFocusRing && this.hasAttribute('focused')) {
|
|
22228
|
-
this.setAttribute('focus-ring', '');
|
|
22229
|
-
} else if (!this.hasAttribute('focused')) {
|
|
22230
|
-
this.blur();
|
|
22231
|
-
}
|
|
22232
22925
|
if (e.detail.sourceEvent && e.detail.sourceEvent.composedPath().includes(this)) {
|
|
22233
22926
|
e.preventDefault();
|
|
22234
22927
|
}
|
|
@@ -22358,6 +23051,7 @@ const HelperFilters$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLEleme
|
|
|
22358
23051
|
this.modalCloseEvent();
|
|
22359
23052
|
this.showClearButton = true;
|
|
22360
23053
|
this.filterSelectionHandler(this.filterData);
|
|
23054
|
+
console.log(this.showClearButton);
|
|
22361
23055
|
}
|
|
22362
23056
|
resetSearch() {
|
|
22363
23057
|
this.showClearButton = false;
|
|
@@ -22374,7 +23068,7 @@ const HelperFilters$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLEleme
|
|
|
22374
23068
|
this.filterData.filterToCalendar = new Date(event.target.value).toISOString();
|
|
22375
23069
|
}
|
|
22376
23070
|
render() {
|
|
22377
|
-
return (h$2("div", { class: "HelperFilters", ref: el => this.stylingContainer = el }, h$2("div", { class: "FilterButtonsWrapper" }, h$2("button", { class: "FilterOpen", onClick: () => this.toggleFilterModal() }, translate$1('filterOpen', this.language)), (this.showClearButton || this.quickFiltersActive) ?
|
|
23071
|
+
return (h$2("div", { class: "HelperFilters", ref: el => this.stylingContainer = el }, h$2("div", { class: "FilterButtonsWrapper" }, h$2("button", { class: "FilterOpen", onClick: () => this.toggleFilterModal() }, translate$1('filterOpen', this.language)), console.log('in filter Open', this.showClearButton, this.quickFiltersActive), (this.showClearButton || this.quickFiltersActive) ?
|
|
22378
23072
|
h$2("button", { class: "FilterClear", onClick: () => this.resetSearch() }, translate$1('filterClear', this.language))
|
|
22379
23073
|
:
|
|
22380
23074
|
null), h$2("helper-modal", { "title-modal": "Filter Modal", visible: this.showFilterModal, "client-styling": this.clientStyling, "client-styling-url-content": this.clientStylingUrlContent }, h$2("div", { class: "FilterModalHeader" }, h$2("h3", { class: "FilterModalTitle" }, this.activateTicketSearch ? translate$1('filterModalTicketTitle', this.language) : translate$1('filterModalDrawTitle', this.language))), h$2("div", { class: "FilterModalBody" }, h$2("input", { id: "FilterById", type: "text", value: this.filterData.ticketDrawId, onInput: (event) => this.handleTicketDrawId(event), class: "FilterModalSearch", placeholder: this.activateTicketSearch ? translate$1('filterTicketPlaceholder', this.language) : translate$1('filterDrawPlaceholder', this.language) }), h$2("p", null, translate$1('filterOrDate', this.language)), h$2("div", { class: "FilterCalendarWrapper" }, h$2("vaadin-date-picker", { value: this.filterData.filterFromCalendar, onChange: (event) => this.handleFilterFrom(event), placeholder: translate$1('filterFromCalendar', this.language), class: "VaadinDatePicker" }), h$2("vaadin-date-picker", { value: this.filterData.filterToCalendar, onChange: (event) => this.handleFilterTo(event), placeholder: translate$1('filterToCalendar', this.language), class: "VaadinDatePicker" }))), h$2("div", { class: "FilterModalFooter" }, h$2("button", { class: "FilterModalButton", onClick: () => this.filterSearch() }, translate$1('filterModalButton', this.language))))));
|