@everymatrix/helper-filters 0.1.24 → 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
|
@@ -68,9 +68,16 @@ const translate$1 = (key, customLang) => {
|
|
|
68
68
|
* Copyright (c) 2017 - 2022 Vaadin Ltd.
|
|
69
69
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
70
70
|
*/
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Dummy custom element used for collecting
|
|
74
|
+
* development time usage statistics.
|
|
75
|
+
*
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
71
78
|
class Lumo extends HTMLElement {
|
|
72
79
|
static get version() {
|
|
73
|
-
return '23.
|
|
80
|
+
return '23.3.14';
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
|
|
@@ -87,20 +94,20 @@ const t$1=window,e$2=t$1.ShadowRoot&&(void 0===t$1.ShadyCSS||t$1.ShadyCSS.native
|
|
|
87
94
|
* @license
|
|
88
95
|
* Copyright 2017 Google LLC
|
|
89
96
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
90
|
-
*/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
|
|
97
|
+
*/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");
|
|
91
98
|
|
|
92
99
|
/**
|
|
93
100
|
* @license
|
|
94
101
|
* Copyright 2017 Google LLC
|
|
95
102
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
96
103
|
*/
|
|
97
|
-
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)}$`,
|
|
104
|
+
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};
|
|
98
105
|
|
|
99
106
|
/**
|
|
100
107
|
* @license
|
|
101
108
|
* Copyright 2017 Google LLC
|
|
102
109
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
103
|
-
*/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=
|
|
110
|
+
*/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");
|
|
104
111
|
|
|
105
112
|
/**
|
|
106
113
|
* @license
|
|
@@ -126,7 +133,7 @@ const ThemePropertyMixin = (superClass) =>
|
|
|
126
133
|
* **NOTE:** Extending the mixin only provides the property for binding,
|
|
127
134
|
* and does not make the propagation alone.
|
|
128
135
|
*
|
|
129
|
-
* See [Styling Components: Sub-components](https://vaadin.com/docs/latest/
|
|
136
|
+
* See [Styling Components: Sub-components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components/#sub-components).
|
|
130
137
|
* page for more information.
|
|
131
138
|
*
|
|
132
139
|
* @deprecated The `theme` property is not supposed for public use and will be dropped in Vaadin 24.
|
|
@@ -151,7 +158,7 @@ const ThemePropertyMixin = (superClass) =>
|
|
|
151
158
|
* **NOTE:** Extending the mixin only provides the property for binding,
|
|
152
159
|
* and does not make the propagation alone.
|
|
153
160
|
*
|
|
154
|
-
* See [Styling Components: Sub-components](https://vaadin.com/docs/latest/
|
|
161
|
+
* See [Styling Components: Sub-components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components/#sub-components).
|
|
155
162
|
* page for more information.
|
|
156
163
|
*
|
|
157
164
|
* @protected
|
|
@@ -256,9 +263,9 @@ function matchesThemeFor(themeFor, tagName) {
|
|
|
256
263
|
*/
|
|
257
264
|
function getIncludePriority(moduleName = '') {
|
|
258
265
|
let includePriority = 0;
|
|
259
|
-
if (moduleName.
|
|
266
|
+
if (moduleName.startsWith('lumo-') || moduleName.startsWith('material-')) {
|
|
260
267
|
includePriority = 1;
|
|
261
|
-
} else if (moduleName.
|
|
268
|
+
} else if (moduleName.startsWith('vaadin-')) {
|
|
262
269
|
includePriority = 2;
|
|
263
270
|
}
|
|
264
271
|
return includePriority;
|
|
@@ -492,9 +499,9 @@ const colorBase = i$1`
|
|
|
492
499
|
}
|
|
493
500
|
`;
|
|
494
501
|
|
|
495
|
-
const $tpl$
|
|
496
|
-
$tpl$
|
|
497
|
-
document.head.appendChild($tpl$
|
|
502
|
+
const $tpl$4 = document.createElement('template');
|
|
503
|
+
$tpl$4.innerHTML = `<style>${colorBase.toString().replace(':host', 'html')}</style>`;
|
|
504
|
+
document.head.appendChild($tpl$4.content);
|
|
498
505
|
|
|
499
506
|
const color = i$1`
|
|
500
507
|
[theme~='dark'] {
|
|
@@ -641,9 +648,9 @@ const sizing = i$1`
|
|
|
641
648
|
}
|
|
642
649
|
`;
|
|
643
650
|
|
|
644
|
-
const $tpl$
|
|
645
|
-
$tpl$
|
|
646
|
-
document.head.appendChild($tpl$
|
|
651
|
+
const $tpl$3 = document.createElement('template');
|
|
652
|
+
$tpl$3.innerHTML = `<style>${sizing.toString().replace(':host', 'html')}</style>`;
|
|
653
|
+
document.head.appendChild($tpl$3.content);
|
|
647
654
|
|
|
648
655
|
/**
|
|
649
656
|
* @license
|
|
@@ -671,9 +678,19 @@ const style = i$1`
|
|
|
671
678
|
}
|
|
672
679
|
`;
|
|
673
680
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
681
|
+
/**
|
|
682
|
+
* Default values for component-specific custom properties.
|
|
683
|
+
*/
|
|
684
|
+
i$1`
|
|
685
|
+
html {
|
|
686
|
+
--vaadin-checkbox-size: calc(var(--lumo-size-m) / 2);
|
|
687
|
+
--vaadin-radio-button-size: calc(var(--lumo-size-m) / 2);
|
|
688
|
+
}
|
|
689
|
+
`;
|
|
690
|
+
|
|
691
|
+
const $tpl$2 = document.createElement('template');
|
|
692
|
+
$tpl$2.innerHTML = `<style>${style.toString().replace(':host', 'html')}$</style>`;
|
|
693
|
+
document.head.appendChild($tpl$2.content);
|
|
677
694
|
|
|
678
695
|
/**
|
|
679
696
|
* @license
|
|
@@ -810,9 +827,9 @@ const typography = i$1`
|
|
|
810
827
|
|
|
811
828
|
registerStyles('', typography, { moduleId: 'lumo-typography' });
|
|
812
829
|
|
|
813
|
-
const $tpl$
|
|
814
|
-
$tpl$
|
|
815
|
-
document.head.appendChild($tpl$
|
|
830
|
+
const $tpl$1 = document.createElement('template');
|
|
831
|
+
$tpl$1.innerHTML = `<style>${font.toString().replace(':host', 'html')}</style>`;
|
|
832
|
+
document.head.appendChild($tpl$1.content);
|
|
816
833
|
|
|
817
834
|
registerStyles(
|
|
818
835
|
'vaadin-input-container',
|
|
@@ -8104,6 +8121,7 @@ class DirHelper {
|
|
|
8104
8121
|
* Array of Vaadin custom element classes that have been subscribed to the dir changes.
|
|
8105
8122
|
*/
|
|
8106
8123
|
const directionSubscribers = [];
|
|
8124
|
+
|
|
8107
8125
|
function directionUpdater() {
|
|
8108
8126
|
const documentDir = getDocumentDir();
|
|
8109
8127
|
directionSubscribers.forEach((element) => {
|
|
@@ -8169,7 +8187,7 @@ const DirMixin = (superClass) =>
|
|
|
8169
8187
|
connectedCallback() {
|
|
8170
8188
|
super.connectedCallback();
|
|
8171
8189
|
|
|
8172
|
-
if (!this.hasAttribute('dir')) {
|
|
8190
|
+
if (!this.hasAttribute('dir') || this.__restoreSubscription) {
|
|
8173
8191
|
this.__subscribe();
|
|
8174
8192
|
alignDirs(this, getDocumentDir(), null);
|
|
8175
8193
|
}
|
|
@@ -8195,15 +8213,15 @@ const DirMixin = (superClass) =>
|
|
|
8195
8213
|
this.__subscribe();
|
|
8196
8214
|
alignDirs(this, documentDir, newValue);
|
|
8197
8215
|
} else if (newDiffValue) {
|
|
8198
|
-
this.
|
|
8216
|
+
this.__unsubscribe();
|
|
8199
8217
|
}
|
|
8200
8218
|
}
|
|
8201
8219
|
|
|
8202
8220
|
/** @protected */
|
|
8203
8221
|
disconnectedCallback() {
|
|
8204
8222
|
super.disconnectedCallback();
|
|
8205
|
-
this.
|
|
8206
|
-
this.
|
|
8223
|
+
this.__restoreSubscription = directionSubscribers.includes(this);
|
|
8224
|
+
this.__unsubscribe();
|
|
8207
8225
|
}
|
|
8208
8226
|
|
|
8209
8227
|
/** @protected */
|
|
@@ -8228,12 +8246,15 @@ const DirMixin = (superClass) =>
|
|
|
8228
8246
|
}
|
|
8229
8247
|
|
|
8230
8248
|
/** @private */
|
|
8231
|
-
__subscribe(
|
|
8232
|
-
if (
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
|
|
8249
|
+
__subscribe() {
|
|
8250
|
+
if (!directionSubscribers.includes(this)) {
|
|
8251
|
+
directionSubscribers.push(this);
|
|
8252
|
+
}
|
|
8253
|
+
}
|
|
8254
|
+
|
|
8255
|
+
/** @private */
|
|
8256
|
+
__unsubscribe() {
|
|
8257
|
+
if (directionSubscribers.includes(this)) {
|
|
8237
8258
|
directionSubscribers.splice(directionSubscribers.indexOf(this), 1);
|
|
8238
8259
|
}
|
|
8239
8260
|
}
|
|
@@ -8311,7 +8332,6 @@ class InputContainer extends ThemableMixin(DirMixin(PolymerElement)) {
|
|
|
8311
8332
|
::slotted(:is(input, textarea))::placeholder {
|
|
8312
8333
|
/* Use ::slotted(input:placeholder-shown) in themes to style the placeholder. */
|
|
8313
8334
|
/* because ::slotted(...)::placeholder does not work in Safari. */
|
|
8314
|
-
/* See the workaround at the end of this file. */
|
|
8315
8335
|
font: inherit;
|
|
8316
8336
|
color: inherit;
|
|
8317
8337
|
/* Override default opacity in Firefox */
|
|
@@ -8378,18 +8398,6 @@ class InputContainer extends ThemableMixin(DirMixin(PolymerElement)) {
|
|
|
8378
8398
|
|
|
8379
8399
|
customElements.define(InputContainer.is, InputContainer);
|
|
8380
8400
|
|
|
8381
|
-
const placeholderStyleWorkaround = i$1`
|
|
8382
|
-
/* Needed for Safari, where ::slotted(...)::placeholder does not work */
|
|
8383
|
-
:is(input[slot='input'], textarea[slot='textarea'])::placeholder {
|
|
8384
|
-
font: inherit;
|
|
8385
|
-
color: inherit;
|
|
8386
|
-
}
|
|
8387
|
-
`;
|
|
8388
|
-
|
|
8389
|
-
const $tpl$1 = document.createElement('template');
|
|
8390
|
-
$tpl$1.innerHTML = `<style>${placeholderStyleWorkaround.toString()}</style>`;
|
|
8391
|
-
document.head.appendChild($tpl$1.content);
|
|
8392
|
-
|
|
8393
8401
|
/**
|
|
8394
8402
|
* @license
|
|
8395
8403
|
* Copyright (c) 2017 - 2022 Vaadin Ltd.
|
|
@@ -10143,6 +10151,38 @@ const ControllerMixin = dedupingMixin(
|
|
|
10143
10151
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
10144
10152
|
*/
|
|
10145
10153
|
|
|
10154
|
+
// We consider the keyboard to be active if the window has received a keydown
|
|
10155
|
+
// event since the last mousedown event.
|
|
10156
|
+
let keyboardActive = false;
|
|
10157
|
+
|
|
10158
|
+
// Listen for top-level keydown and mousedown events.
|
|
10159
|
+
// Use capture phase so we detect events even if they're handled.
|
|
10160
|
+
window.addEventListener(
|
|
10161
|
+
'keydown',
|
|
10162
|
+
() => {
|
|
10163
|
+
keyboardActive = true;
|
|
10164
|
+
},
|
|
10165
|
+
{ capture: true },
|
|
10166
|
+
);
|
|
10167
|
+
|
|
10168
|
+
window.addEventListener(
|
|
10169
|
+
'mousedown',
|
|
10170
|
+
() => {
|
|
10171
|
+
keyboardActive = false;
|
|
10172
|
+
},
|
|
10173
|
+
{ capture: true },
|
|
10174
|
+
);
|
|
10175
|
+
|
|
10176
|
+
/**
|
|
10177
|
+
* Returns true if the window has received a keydown
|
|
10178
|
+
* event since the last mousedown event.
|
|
10179
|
+
*
|
|
10180
|
+
* @return {boolean}
|
|
10181
|
+
*/
|
|
10182
|
+
function isKeyboardActive() {
|
|
10183
|
+
return keyboardActive;
|
|
10184
|
+
}
|
|
10185
|
+
|
|
10146
10186
|
/**
|
|
10147
10187
|
* Returns true if the element is hidden directly with `display: none` or `visibility: hidden`,
|
|
10148
10188
|
* false otherwise.
|
|
@@ -10583,7 +10623,7 @@ class FocusTrapController {
|
|
|
10583
10623
|
* ---|---|---
|
|
10584
10624
|
* `--vaadin-overlay-viewport-bottom` | Bottom offset of the visible viewport area | `0` or detected offset
|
|
10585
10625
|
*
|
|
10586
|
-
* See [Styling Components](https://vaadin.com/docs/latest/
|
|
10626
|
+
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
|
|
10587
10627
|
*
|
|
10588
10628
|
* @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
|
|
10589
10629
|
* @fires {CustomEvent} vaadin-overlay-open - Fired after the overlay is opened.
|
|
@@ -10597,7 +10637,7 @@ class FocusTrapController {
|
|
|
10597
10637
|
* @mixes DirMixin
|
|
10598
10638
|
* @mixes ControllerMixin
|
|
10599
10639
|
*/
|
|
10600
|
-
class
|
|
10640
|
+
class Overlay extends ThemableMixin(DirMixin(ControllerMixin(PolymerElement))) {
|
|
10601
10641
|
static get template() {
|
|
10602
10642
|
return html`
|
|
10603
10643
|
<style>
|
|
@@ -10897,7 +10937,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
10897
10937
|
* @protected
|
|
10898
10938
|
*/
|
|
10899
10939
|
_setTemplateFromNodes(nodes) {
|
|
10900
|
-
this.template = nodes.
|
|
10940
|
+
this.template = nodes.find((node) => node.localName && node.localName === 'template') || this.template;
|
|
10901
10941
|
}
|
|
10902
10942
|
|
|
10903
10943
|
/**
|
|
@@ -11224,7 +11264,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11224
11264
|
*/
|
|
11225
11265
|
static get __attachedInstances() {
|
|
11226
11266
|
return Array.from(document.body.children)
|
|
11227
|
-
.filter((el) => el instanceof
|
|
11267
|
+
.filter((el) => el instanceof Overlay && !el.hasAttribute('closing'))
|
|
11228
11268
|
.sort((a, b) => a.__zIndex - b.__zIndex || 0);
|
|
11229
11269
|
}
|
|
11230
11270
|
|
|
@@ -11234,7 +11274,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11234
11274
|
* @protected
|
|
11235
11275
|
*/
|
|
11236
11276
|
get _last() {
|
|
11237
|
-
return this ===
|
|
11277
|
+
return this === Overlay.__attachedInstances.pop();
|
|
11238
11278
|
}
|
|
11239
11279
|
|
|
11240
11280
|
/** @private */
|
|
@@ -11269,7 +11309,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11269
11309
|
}
|
|
11270
11310
|
|
|
11271
11311
|
// Disable pointer events in other attached overlays
|
|
11272
|
-
|
|
11312
|
+
Overlay.__attachedInstances.forEach((el) => {
|
|
11273
11313
|
if (el !== this) {
|
|
11274
11314
|
el.shadowRoot.querySelector('[part="overlay"]').style.pointerEvents = 'none';
|
|
11275
11315
|
}
|
|
@@ -11292,7 +11332,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11292
11332
|
}
|
|
11293
11333
|
|
|
11294
11334
|
// Restore pointer events in the previous overlay(s)
|
|
11295
|
-
const instances =
|
|
11335
|
+
const instances = Overlay.__attachedInstances;
|
|
11296
11336
|
let el;
|
|
11297
11337
|
// Use instances.pop() to ensure the reverse order
|
|
11298
11338
|
while ((el = instances.pop())) {
|
|
@@ -11471,7 +11511,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11471
11511
|
*/
|
|
11472
11512
|
bringToFront() {
|
|
11473
11513
|
let zIndex = '';
|
|
11474
|
-
const frontmost =
|
|
11514
|
+
const frontmost = Overlay.__attachedInstances.filter((o) => o !== this).pop();
|
|
11475
11515
|
if (frontmost) {
|
|
11476
11516
|
const frontmostZIndex = frontmost.__zIndex;
|
|
11477
11517
|
zIndex = frontmostZIndex + 1;
|
|
@@ -11481,7 +11521,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
|
|
|
11481
11521
|
}
|
|
11482
11522
|
}
|
|
11483
11523
|
|
|
11484
|
-
customElements.define(
|
|
11524
|
+
customElements.define(Overlay.is, Overlay);
|
|
11485
11525
|
|
|
11486
11526
|
/**
|
|
11487
11527
|
* @license
|
|
@@ -11667,7 +11707,7 @@ const button = i$1`
|
|
|
11667
11707
|
-moz-osx-font-smoothing: grayscale;
|
|
11668
11708
|
}
|
|
11669
11709
|
|
|
11670
|
-
/* Set only for the internal parts so we don
|
|
11710
|
+
/* Set only for the internal parts so we don't affect the host vertical alignment */
|
|
11671
11711
|
[part='label'],
|
|
11672
11712
|
[part='prefix'],
|
|
11673
11713
|
[part='suffix'] {
|
|
@@ -11903,7 +11943,7 @@ const button = i$1`
|
|
|
11903
11943
|
registerStyles('vaadin-button', button, { moduleId: 'lumo-button' });
|
|
11904
11944
|
|
|
11905
11945
|
const DEV_MODE_CODE_REGEXP =
|
|
11906
|
-
|
|
11946
|
+
/\/\*[\*!]\s+vaadin-dev-mode:start([\s\S]*)vaadin-dev-mode:end\s+\*\*\//i;
|
|
11907
11947
|
|
|
11908
11948
|
const FlowClients = window.Vaadin && window.Vaadin.Flow && window.Vaadin.Flow.clients;
|
|
11909
11949
|
|
|
@@ -12853,7 +12893,7 @@ const registered = new Set();
|
|
|
12853
12893
|
const ElementMixin = (superClass) =>
|
|
12854
12894
|
class VaadinElementMixin extends DirMixin(superClass) {
|
|
12855
12895
|
static get version() {
|
|
12856
|
-
return '23.
|
|
12896
|
+
return '23.3.14';
|
|
12857
12897
|
}
|
|
12858
12898
|
|
|
12859
12899
|
/** @protected */
|
|
@@ -12888,174 +12928,553 @@ const ElementMixin = (superClass) =>
|
|
|
12888
12928
|
};
|
|
12889
12929
|
|
|
12890
12930
|
/**
|
|
12891
|
-
@license
|
|
12892
|
-
Copyright (c)
|
|
12893
|
-
|
|
12894
|
-
|
|
12895
|
-
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
|
12896
|
-
Code distributed by Google as part of the polymer project is also
|
|
12897
|
-
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
|
12898
|
-
*/
|
|
12899
|
-
|
|
12900
|
-
const passiveTouchGestures = false;
|
|
12901
|
-
const wrap = (node) => node;
|
|
12902
|
-
|
|
12903
|
-
// Detect native touch action support
|
|
12904
|
-
const HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
|
|
12905
|
-
const GESTURE_KEY = '__polymerGestures';
|
|
12906
|
-
const HANDLED_OBJ = '__polymerGesturesHandled';
|
|
12907
|
-
const TOUCH_ACTION = '__polymerGesturesTouchAction';
|
|
12908
|
-
// Radius for tap and track
|
|
12909
|
-
const TAP_DISTANCE = 25;
|
|
12910
|
-
const TRACK_DISTANCE = 5;
|
|
12911
|
-
// Number of last N track positions to keep
|
|
12912
|
-
const TRACK_LENGTH = 2;
|
|
12931
|
+
* @license
|
|
12932
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
12933
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
12934
|
+
*/
|
|
12913
12935
|
|
|
12914
|
-
|
|
12915
|
-
// An array of bitmask values for mapping MouseEvent.which to MouseEvent.buttons
|
|
12916
|
-
const MOUSE_WHICH_TO_BUTTONS = [0, 1, 4, 2];
|
|
12917
|
-
const MOUSE_HAS_BUTTONS = (function () {
|
|
12918
|
-
try {
|
|
12919
|
-
return new MouseEvent('test', { buttons: 1 }).buttons === 1;
|
|
12920
|
-
} catch (e) {
|
|
12921
|
-
return false;
|
|
12922
|
-
}
|
|
12923
|
-
})();
|
|
12936
|
+
let uniqueId = 0;
|
|
12924
12937
|
|
|
12925
12938
|
/**
|
|
12926
|
-
*
|
|
12927
|
-
*
|
|
12939
|
+
* Returns a unique integer id.
|
|
12940
|
+
*
|
|
12941
|
+
* @return {number}
|
|
12928
12942
|
*/
|
|
12929
|
-
function
|
|
12930
|
-
|
|
12943
|
+
function generateUniqueId() {
|
|
12944
|
+
// eslint-disable-next-line no-plusplus
|
|
12945
|
+
return uniqueId++;
|
|
12931
12946
|
}
|
|
12932
12947
|
|
|
12933
|
-
|
|
12934
|
-
|
|
12935
|
-
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
const opts = Object.defineProperty({}, 'passive', {
|
|
12939
|
-
// eslint-disable-next-line getter-return
|
|
12940
|
-
get() {
|
|
12941
|
-
supportsPassive = true;
|
|
12942
|
-
},
|
|
12943
|
-
});
|
|
12944
|
-
window.addEventListener('test', null, opts);
|
|
12945
|
-
window.removeEventListener('test', null, opts);
|
|
12946
|
-
} catch (e) {}
|
|
12947
|
-
})();
|
|
12948
|
+
/**
|
|
12949
|
+
* @license
|
|
12950
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
12951
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
12952
|
+
*/
|
|
12948
12953
|
|
|
12949
12954
|
/**
|
|
12950
|
-
*
|
|
12951
|
-
*
|
|
12952
|
-
* @param {string} eventName Event name to determine if `{passive}` option is
|
|
12953
|
-
* needed
|
|
12954
|
-
* @return {{passive: boolean} | undefined} Options to use for addEventListener
|
|
12955
|
-
* and removeEventListener
|
|
12955
|
+
* A controller for providing content to slot element and observing changes.
|
|
12956
12956
|
*/
|
|
12957
|
-
|
|
12958
|
-
|
|
12959
|
-
|
|
12960
|
-
|
|
12961
|
-
|
|
12962
|
-
|
|
12957
|
+
class SlotController extends EventTarget {
|
|
12958
|
+
/**
|
|
12959
|
+
* Ensure that every instance has unique ID.
|
|
12960
|
+
*
|
|
12961
|
+
* @param {string} slotName
|
|
12962
|
+
* @param {HTMLElement} host
|
|
12963
|
+
* @return {string}
|
|
12964
|
+
* @protected
|
|
12965
|
+
*/
|
|
12966
|
+
static generateId(slotName, host) {
|
|
12967
|
+
const prefix = slotName || 'default';
|
|
12968
|
+
return `${prefix}-${host.localName}-${generateUniqueId()}`;
|
|
12963
12969
|
}
|
|
12964
|
-
}
|
|
12965
12970
|
|
|
12966
|
-
|
|
12967
|
-
|
|
12971
|
+
constructor(host, slotName, slotFactory, slotInitializer, useUniqueId) {
|
|
12972
|
+
super();
|
|
12968
12973
|
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
|
|
12972
|
-
|
|
12973
|
-
command: true,
|
|
12974
|
-
fieldset: true,
|
|
12975
|
-
input: true,
|
|
12976
|
-
keygen: true,
|
|
12977
|
-
optgroup: true,
|
|
12978
|
-
option: true,
|
|
12979
|
-
select: true,
|
|
12980
|
-
textarea: true,
|
|
12981
|
-
};
|
|
12974
|
+
this.host = host;
|
|
12975
|
+
this.slotName = slotName;
|
|
12976
|
+
this.slotFactory = slotFactory;
|
|
12977
|
+
this.slotInitializer = slotInitializer;
|
|
12982
12978
|
|
|
12983
|
-
|
|
12984
|
-
|
|
12985
|
-
|
|
12986
|
-
*/
|
|
12987
|
-
function hasLeftMouseButton(ev) {
|
|
12988
|
-
const type = ev.type;
|
|
12989
|
-
// Exit early if the event is not a mouse event
|
|
12990
|
-
if (!isMouseEvent(type)) {
|
|
12991
|
-
return false;
|
|
12992
|
-
}
|
|
12993
|
-
// Ev.button is not reliable for mousemove (0 is overloaded as both left button and no buttons)
|
|
12994
|
-
// instead we use ev.buttons (bitmask of buttons) or fall back to ev.which (deprecated, 0 for no buttons, 1 for left button)
|
|
12995
|
-
if (type === 'mousemove') {
|
|
12996
|
-
// Allow undefined for testing events
|
|
12997
|
-
let buttons = ev.buttons === undefined ? 1 : ev.buttons;
|
|
12998
|
-
if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {
|
|
12999
|
-
buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;
|
|
12979
|
+
// Only generate the default ID if requested by the controller.
|
|
12980
|
+
if (useUniqueId) {
|
|
12981
|
+
this.defaultId = SlotController.generateId(slotName, host);
|
|
13000
12982
|
}
|
|
13001
|
-
// Buttons is a bitmask, check that the left button bit is set (1)
|
|
13002
|
-
return Boolean(buttons & 1);
|
|
13003
12983
|
}
|
|
13004
|
-
// Allow undefined for testing events
|
|
13005
|
-
const button = ev.button === undefined ? 0 : ev.button;
|
|
13006
|
-
// Ev.button is 0 in mousedown/mouseup/click for left button activation
|
|
13007
|
-
return button === 0;
|
|
13008
|
-
}
|
|
13009
12984
|
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
|
|
13013
|
-
if (ev.detail === 0) {
|
|
13014
|
-
return true;
|
|
13015
|
-
}
|
|
13016
|
-
// In the worst case, check that the x/y position of the click is within
|
|
13017
|
-
// the bounding box of the target of the event
|
|
13018
|
-
// Thanks IE 10 >:(
|
|
13019
|
-
const t = _findOriginalTarget(ev);
|
|
13020
|
-
// Make sure the target of the event is an element so we can use getBoundingClientRect,
|
|
13021
|
-
// if not, just assume it is a synthetic click
|
|
13022
|
-
if (!t.nodeType || /** @type {Element} */ (t).nodeType !== Node.ELEMENT_NODE) {
|
|
13023
|
-
return true;
|
|
13024
|
-
}
|
|
13025
|
-
const bcr = /** @type {Element} */ (t).getBoundingClientRect();
|
|
13026
|
-
// Use page x/y to account for scrolling
|
|
13027
|
-
const x = ev.pageX,
|
|
13028
|
-
y = ev.pageY;
|
|
13029
|
-
// Ev is a synthetic click if the position is outside the bounding box of the target
|
|
13030
|
-
return !(x >= bcr.left && x <= bcr.right && y >= bcr.top && y <= bcr.bottom);
|
|
13031
|
-
}
|
|
13032
|
-
return false;
|
|
13033
|
-
}
|
|
12985
|
+
hostConnected() {
|
|
12986
|
+
if (!this.initialized) {
|
|
12987
|
+
let node = this.getSlotChild();
|
|
13034
12988
|
|
|
13035
|
-
|
|
13036
|
-
|
|
13037
|
-
|
|
13038
|
-
|
|
13039
|
-
|
|
13040
|
-
|
|
13041
|
-
x: 0,
|
|
13042
|
-
y: 0,
|
|
13043
|
-
id: -1,
|
|
13044
|
-
scrollDecided: false,
|
|
13045
|
-
},
|
|
13046
|
-
};
|
|
12989
|
+
if (!node) {
|
|
12990
|
+
node = this.attachDefaultNode();
|
|
12991
|
+
} else {
|
|
12992
|
+
this.node = node;
|
|
12993
|
+
this.initCustomNode(node);
|
|
12994
|
+
}
|
|
13047
12995
|
|
|
13048
|
-
|
|
13049
|
-
|
|
13050
|
-
|
|
13051
|
-
|
|
13052
|
-
|
|
13053
|
-
|
|
13054
|
-
|
|
13055
|
-
|
|
12996
|
+
this.initNode(node);
|
|
12997
|
+
|
|
12998
|
+
// TODO: Consider making this behavior opt-in to improve performance.
|
|
12999
|
+
this.observe();
|
|
13000
|
+
|
|
13001
|
+
this.initialized = true;
|
|
13002
|
+
}
|
|
13003
|
+
}
|
|
13004
|
+
|
|
13005
|
+
/**
|
|
13006
|
+
* Create and attach default node using the slot factory.
|
|
13007
|
+
* @return {Node | undefined}
|
|
13008
|
+
* @protected
|
|
13009
|
+
*/
|
|
13010
|
+
attachDefaultNode() {
|
|
13011
|
+
const { host, slotName, slotFactory } = this;
|
|
13012
|
+
|
|
13013
|
+
// Check if the node was created previously and if so, reuse it.
|
|
13014
|
+
let node = this.defaultNode;
|
|
13015
|
+
|
|
13016
|
+
// Slot factory is optional, some slots don't have default content.
|
|
13017
|
+
if (!node && slotFactory) {
|
|
13018
|
+
node = slotFactory(host);
|
|
13019
|
+
if (node instanceof Element) {
|
|
13020
|
+
if (slotName !== '') {
|
|
13021
|
+
node.setAttribute('slot', slotName);
|
|
13022
|
+
}
|
|
13023
|
+
this.node = node;
|
|
13024
|
+
this.defaultNode = node;
|
|
13025
|
+
}
|
|
13026
|
+
}
|
|
13027
|
+
|
|
13028
|
+
if (node) {
|
|
13029
|
+
host.appendChild(node);
|
|
13030
|
+
}
|
|
13031
|
+
|
|
13032
|
+
return node;
|
|
13033
|
+
}
|
|
13034
|
+
|
|
13035
|
+
/**
|
|
13036
|
+
* Return a reference to the node managed by the controller.
|
|
13037
|
+
* @return {Node}
|
|
13038
|
+
*/
|
|
13039
|
+
getSlotChild() {
|
|
13040
|
+
const { slotName } = this;
|
|
13041
|
+
return Array.from(this.host.childNodes).find((node) => {
|
|
13042
|
+
// Either an element (any slot) or a text node (only un-named slot).
|
|
13043
|
+
return (
|
|
13044
|
+
(node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) ||
|
|
13045
|
+
(node.nodeType === Node.TEXT_NODE && node.textContent.trim() && slotName === '')
|
|
13046
|
+
);
|
|
13047
|
+
});
|
|
13048
|
+
}
|
|
13049
|
+
|
|
13050
|
+
/**
|
|
13051
|
+
* @param {Node} node
|
|
13052
|
+
* @protected
|
|
13053
|
+
*/
|
|
13054
|
+
initNode(node) {
|
|
13055
|
+
const { slotInitializer } = this;
|
|
13056
|
+
// Don't try to bind `this` to initializer (normally it's arrow function).
|
|
13057
|
+
// Instead, pass the host as a first argument to access component's state.
|
|
13058
|
+
if (slotInitializer) {
|
|
13059
|
+
slotInitializer(this.host, node);
|
|
13060
|
+
}
|
|
13061
|
+
}
|
|
13062
|
+
|
|
13063
|
+
/**
|
|
13064
|
+
* Override to initialize the newly added custom node.
|
|
13065
|
+
*
|
|
13066
|
+
* @param {Node} _node
|
|
13067
|
+
* @protected
|
|
13068
|
+
*/
|
|
13069
|
+
initCustomNode(_node) {}
|
|
13070
|
+
|
|
13071
|
+
/**
|
|
13072
|
+
* Override to teardown slotted node when it's removed.
|
|
13073
|
+
*
|
|
13074
|
+
* @param {Node} _node
|
|
13075
|
+
* @protected
|
|
13076
|
+
*/
|
|
13077
|
+
teardownNode(_node) {}
|
|
13078
|
+
|
|
13079
|
+
/**
|
|
13080
|
+
* Setup the observer to manage slot content changes.
|
|
13081
|
+
* @protected
|
|
13082
|
+
*/
|
|
13083
|
+
observe() {
|
|
13084
|
+
const { slotName } = this;
|
|
13085
|
+
const selector = slotName === '' ? 'slot:not([name])' : `slot[name=${slotName}]`;
|
|
13086
|
+
const slot = this.host.shadowRoot.querySelector(selector);
|
|
13087
|
+
|
|
13088
|
+
this.__slotObserver = new FlattenedNodesObserver(slot, (info) => {
|
|
13089
|
+
// TODO: support default slot with multiple nodes (e.g. confirm-dialog)
|
|
13090
|
+
const current = this.node;
|
|
13091
|
+
const newNode = info.addedNodes.find((node) => node !== current);
|
|
13092
|
+
|
|
13093
|
+
if (info.removedNodes.length) {
|
|
13094
|
+
info.removedNodes.forEach((node) => {
|
|
13095
|
+
this.teardownNode(node);
|
|
13096
|
+
});
|
|
13097
|
+
}
|
|
13098
|
+
|
|
13099
|
+
if (newNode) {
|
|
13100
|
+
// Custom node is added, remove the current one.
|
|
13101
|
+
if (current && current.isConnected) {
|
|
13102
|
+
this.host.removeChild(current);
|
|
13103
|
+
}
|
|
13104
|
+
|
|
13105
|
+
this.node = newNode;
|
|
13106
|
+
|
|
13107
|
+
if (newNode !== this.defaultNode) {
|
|
13108
|
+
this.initCustomNode(newNode);
|
|
13109
|
+
|
|
13110
|
+
this.initNode(newNode);
|
|
13111
|
+
}
|
|
13112
|
+
}
|
|
13113
|
+
});
|
|
13114
|
+
}
|
|
13115
|
+
}
|
|
13116
|
+
|
|
13117
|
+
/**
|
|
13118
|
+
* @license
|
|
13119
|
+
* Copyright (c) 2022 Vaadin Ltd.
|
|
13120
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
13121
|
+
*/
|
|
13122
|
+
|
|
13123
|
+
/**
|
|
13124
|
+
* A controller that manages the slotted tooltip element.
|
|
13125
|
+
*/
|
|
13126
|
+
class TooltipController extends SlotController {
|
|
13127
|
+
constructor(host) {
|
|
13128
|
+
// Do not provide slot factory to create tooltip lazily.
|
|
13129
|
+
super(host, 'tooltip');
|
|
13130
|
+
|
|
13131
|
+
this.setTarget(host);
|
|
13132
|
+
}
|
|
13133
|
+
|
|
13134
|
+
/**
|
|
13135
|
+
* Override to initialize the newly added custom tooltip.
|
|
13136
|
+
*
|
|
13137
|
+
* @param {Node} tooltipNode
|
|
13138
|
+
* @protected
|
|
13139
|
+
* @override
|
|
13140
|
+
*/
|
|
13141
|
+
initCustomNode(tooltipNode) {
|
|
13142
|
+
tooltipNode.target = this.target;
|
|
13143
|
+
|
|
13144
|
+
if (this.context !== undefined) {
|
|
13145
|
+
tooltipNode.context = this.context;
|
|
13146
|
+
}
|
|
13147
|
+
|
|
13148
|
+
if (this.manual !== undefined) {
|
|
13149
|
+
tooltipNode.manual = this.manual;
|
|
13150
|
+
}
|
|
13151
|
+
|
|
13152
|
+
if (this.opened !== undefined) {
|
|
13153
|
+
tooltipNode.opened = this.opened;
|
|
13154
|
+
}
|
|
13155
|
+
|
|
13156
|
+
if (this.position !== undefined) {
|
|
13157
|
+
tooltipNode._position = this.position;
|
|
13158
|
+
}
|
|
13159
|
+
|
|
13160
|
+
if (this.shouldShow !== undefined) {
|
|
13161
|
+
tooltipNode.shouldShow = this.shouldShow;
|
|
13162
|
+
}
|
|
13163
|
+
}
|
|
13164
|
+
|
|
13165
|
+
/**
|
|
13166
|
+
* Set a context object to be used by generator.
|
|
13167
|
+
* @param {object} context
|
|
13168
|
+
*/
|
|
13169
|
+
setContext(context) {
|
|
13170
|
+
this.context = context;
|
|
13171
|
+
|
|
13172
|
+
const tooltipNode = this.node;
|
|
13173
|
+
if (tooltipNode) {
|
|
13174
|
+
tooltipNode.context = context;
|
|
13175
|
+
}
|
|
13176
|
+
}
|
|
13177
|
+
|
|
13178
|
+
/**
|
|
13179
|
+
* Toggle manual state on the slotted tooltip.
|
|
13180
|
+
* @param {boolean} manual
|
|
13181
|
+
*/
|
|
13182
|
+
setManual(manual) {
|
|
13183
|
+
this.manual = manual;
|
|
13184
|
+
|
|
13185
|
+
const tooltipNode = this.node;
|
|
13186
|
+
if (tooltipNode) {
|
|
13187
|
+
tooltipNode.manual = manual;
|
|
13188
|
+
}
|
|
13189
|
+
}
|
|
13190
|
+
|
|
13191
|
+
/**
|
|
13192
|
+
* Toggle opened state on the slotted tooltip.
|
|
13193
|
+
* @param {boolean} opened
|
|
13194
|
+
*/
|
|
13195
|
+
setOpened(opened) {
|
|
13196
|
+
this.opened = opened;
|
|
13197
|
+
|
|
13198
|
+
const tooltipNode = this.node;
|
|
13199
|
+
if (tooltipNode) {
|
|
13200
|
+
tooltipNode.opened = opened;
|
|
13201
|
+
}
|
|
13202
|
+
}
|
|
13203
|
+
|
|
13204
|
+
/**
|
|
13205
|
+
* Set default position for the slotted tooltip.
|
|
13206
|
+
* This can be overridden by setting the position
|
|
13207
|
+
* using corresponding property or attribute.
|
|
13208
|
+
* @param {string} position
|
|
13209
|
+
*/
|
|
13210
|
+
setPosition(position) {
|
|
13211
|
+
this.position = position;
|
|
13212
|
+
|
|
13213
|
+
const tooltipNode = this.node;
|
|
13214
|
+
if (tooltipNode) {
|
|
13215
|
+
tooltipNode._position = position;
|
|
13216
|
+
}
|
|
13217
|
+
}
|
|
13218
|
+
|
|
13219
|
+
/**
|
|
13220
|
+
* Set function used to detect whether to show
|
|
13221
|
+
* the tooltip based on a condition.
|
|
13222
|
+
* @param {Function} shouldShow
|
|
13223
|
+
*/
|
|
13224
|
+
setShouldShow(shouldShow) {
|
|
13225
|
+
this.shouldShow = shouldShow;
|
|
13226
|
+
|
|
13227
|
+
const tooltipNode = this.node;
|
|
13228
|
+
if (tooltipNode) {
|
|
13229
|
+
tooltipNode.shouldShow = shouldShow;
|
|
13230
|
+
}
|
|
13231
|
+
}
|
|
13232
|
+
|
|
13233
|
+
/**
|
|
13234
|
+
* Set an HTML element to attach the tooltip to.
|
|
13235
|
+
* @param {HTMLElement} target
|
|
13236
|
+
*/
|
|
13237
|
+
setTarget(target) {
|
|
13238
|
+
this.target = target;
|
|
13239
|
+
|
|
13240
|
+
const tooltipNode = this.node;
|
|
13241
|
+
if (tooltipNode) {
|
|
13242
|
+
tooltipNode.target = target;
|
|
13056
13243
|
}
|
|
13057
13244
|
}
|
|
13058
|
-
|
|
13245
|
+
}
|
|
13246
|
+
|
|
13247
|
+
/**
|
|
13248
|
+
* @license
|
|
13249
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
13250
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
13251
|
+
*/
|
|
13252
|
+
|
|
13253
|
+
/**
|
|
13254
|
+
* A mixin to provide disabled property for field components.
|
|
13255
|
+
*
|
|
13256
|
+
* @polymerMixin
|
|
13257
|
+
*/
|
|
13258
|
+
const DisabledMixin = dedupingMixin(
|
|
13259
|
+
(superclass) =>
|
|
13260
|
+
class DisabledMixinClass extends superclass {
|
|
13261
|
+
static get properties() {
|
|
13262
|
+
return {
|
|
13263
|
+
/**
|
|
13264
|
+
* If true, the user cannot interact with this element.
|
|
13265
|
+
*/
|
|
13266
|
+
disabled: {
|
|
13267
|
+
type: Boolean,
|
|
13268
|
+
value: false,
|
|
13269
|
+
observer: '_disabledChanged',
|
|
13270
|
+
reflectToAttribute: true,
|
|
13271
|
+
},
|
|
13272
|
+
};
|
|
13273
|
+
}
|
|
13274
|
+
|
|
13275
|
+
/**
|
|
13276
|
+
* @param {boolean} disabled
|
|
13277
|
+
* @protected
|
|
13278
|
+
*/
|
|
13279
|
+
_disabledChanged(disabled) {
|
|
13280
|
+
this._setAriaDisabled(disabled);
|
|
13281
|
+
}
|
|
13282
|
+
|
|
13283
|
+
/**
|
|
13284
|
+
* @param {boolean} disabled
|
|
13285
|
+
* @protected
|
|
13286
|
+
*/
|
|
13287
|
+
_setAriaDisabled(disabled) {
|
|
13288
|
+
if (disabled) {
|
|
13289
|
+
this.setAttribute('aria-disabled', 'true');
|
|
13290
|
+
} else {
|
|
13291
|
+
this.removeAttribute('aria-disabled');
|
|
13292
|
+
}
|
|
13293
|
+
}
|
|
13294
|
+
|
|
13295
|
+
/**
|
|
13296
|
+
* Overrides the default element `click` method in order to prevent
|
|
13297
|
+
* firing the `click` event when the element is disabled.
|
|
13298
|
+
* @protected
|
|
13299
|
+
* @override
|
|
13300
|
+
*/
|
|
13301
|
+
click() {
|
|
13302
|
+
if (!this.disabled) {
|
|
13303
|
+
super.click();
|
|
13304
|
+
}
|
|
13305
|
+
}
|
|
13306
|
+
},
|
|
13307
|
+
);
|
|
13308
|
+
|
|
13309
|
+
/**
|
|
13310
|
+
@license
|
|
13311
|
+
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
|
13312
|
+
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
|
13313
|
+
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
|
13314
|
+
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
|
13315
|
+
Code distributed by Google as part of the polymer project is also
|
|
13316
|
+
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
|
13317
|
+
*/
|
|
13318
|
+
|
|
13319
|
+
const passiveTouchGestures = false;
|
|
13320
|
+
const wrap = (node) => node;
|
|
13321
|
+
|
|
13322
|
+
// Detect native touch action support
|
|
13323
|
+
const HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
|
|
13324
|
+
const GESTURE_KEY = '__polymerGestures';
|
|
13325
|
+
const HANDLED_OBJ = '__polymerGesturesHandled';
|
|
13326
|
+
const TOUCH_ACTION = '__polymerGesturesTouchAction';
|
|
13327
|
+
// Radius for tap and track
|
|
13328
|
+
const TAP_DISTANCE = 25;
|
|
13329
|
+
const TRACK_DISTANCE = 5;
|
|
13330
|
+
// Number of last N track positions to keep
|
|
13331
|
+
const TRACK_LENGTH = 2;
|
|
13332
|
+
|
|
13333
|
+
const MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'click'];
|
|
13334
|
+
// An array of bitmask values for mapping MouseEvent.which to MouseEvent.buttons
|
|
13335
|
+
const MOUSE_WHICH_TO_BUTTONS = [0, 1, 4, 2];
|
|
13336
|
+
const MOUSE_HAS_BUTTONS = (function () {
|
|
13337
|
+
try {
|
|
13338
|
+
return new MouseEvent('test', { buttons: 1 }).buttons === 1;
|
|
13339
|
+
} catch (e) {
|
|
13340
|
+
return false;
|
|
13341
|
+
}
|
|
13342
|
+
})();
|
|
13343
|
+
|
|
13344
|
+
/**
|
|
13345
|
+
* @param {string} name Possible mouse event name
|
|
13346
|
+
* @return {boolean} true if mouse event, false if not
|
|
13347
|
+
*/
|
|
13348
|
+
function isMouseEvent(name) {
|
|
13349
|
+
return MOUSE_EVENTS.indexOf(name) > -1;
|
|
13350
|
+
}
|
|
13351
|
+
|
|
13352
|
+
/* eslint no-empty: ["error", { "allowEmptyCatch": true }] */
|
|
13353
|
+
// check for passive event listeners
|
|
13354
|
+
let supportsPassive = false;
|
|
13355
|
+
(function () {
|
|
13356
|
+
try {
|
|
13357
|
+
const opts = Object.defineProperty({}, 'passive', {
|
|
13358
|
+
// eslint-disable-next-line getter-return
|
|
13359
|
+
get() {
|
|
13360
|
+
supportsPassive = true;
|
|
13361
|
+
},
|
|
13362
|
+
});
|
|
13363
|
+
window.addEventListener('test', null, opts);
|
|
13364
|
+
window.removeEventListener('test', null, opts);
|
|
13365
|
+
} catch (e) {}
|
|
13366
|
+
})();
|
|
13367
|
+
|
|
13368
|
+
/**
|
|
13369
|
+
* Generate settings for event listeners, dependant on `passiveTouchGestures`
|
|
13370
|
+
*
|
|
13371
|
+
* @param {string} eventName Event name to determine if `{passive}` option is
|
|
13372
|
+
* needed
|
|
13373
|
+
* @return {{passive: boolean} | undefined} Options to use for addEventListener
|
|
13374
|
+
* and removeEventListener
|
|
13375
|
+
*/
|
|
13376
|
+
function PASSIVE_TOUCH(eventName) {
|
|
13377
|
+
if (isMouseEvent(eventName) || eventName === 'touchend') {
|
|
13378
|
+
return;
|
|
13379
|
+
}
|
|
13380
|
+
if (HAS_NATIVE_TA && supportsPassive && passiveTouchGestures) {
|
|
13381
|
+
return { passive: true };
|
|
13382
|
+
}
|
|
13383
|
+
}
|
|
13384
|
+
|
|
13385
|
+
// Check for touch-only devices
|
|
13386
|
+
const IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);
|
|
13387
|
+
|
|
13388
|
+
// Defined at https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute
|
|
13389
|
+
/** @type {!Object<boolean>} */
|
|
13390
|
+
const canBeDisabled = {
|
|
13391
|
+
button: true,
|
|
13392
|
+
command: true,
|
|
13393
|
+
fieldset: true,
|
|
13394
|
+
input: true,
|
|
13395
|
+
keygen: true,
|
|
13396
|
+
optgroup: true,
|
|
13397
|
+
option: true,
|
|
13398
|
+
select: true,
|
|
13399
|
+
textarea: true,
|
|
13400
|
+
};
|
|
13401
|
+
|
|
13402
|
+
/**
|
|
13403
|
+
* @param {MouseEvent} ev event to test for left mouse button down
|
|
13404
|
+
* @return {boolean} has left mouse button down
|
|
13405
|
+
*/
|
|
13406
|
+
function hasLeftMouseButton(ev) {
|
|
13407
|
+
const type = ev.type;
|
|
13408
|
+
// Exit early if the event is not a mouse event
|
|
13409
|
+
if (!isMouseEvent(type)) {
|
|
13410
|
+
return false;
|
|
13411
|
+
}
|
|
13412
|
+
// Ev.button is not reliable for mousemove (0 is overloaded as both left button and no buttons)
|
|
13413
|
+
// instead we use ev.buttons (bitmask of buttons) or fall back to ev.which (deprecated, 0 for no buttons, 1 for left button)
|
|
13414
|
+
if (type === 'mousemove') {
|
|
13415
|
+
// Allow undefined for testing events
|
|
13416
|
+
let buttons = ev.buttons === undefined ? 1 : ev.buttons;
|
|
13417
|
+
if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {
|
|
13418
|
+
buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;
|
|
13419
|
+
}
|
|
13420
|
+
// Buttons is a bitmask, check that the left button bit is set (1)
|
|
13421
|
+
return Boolean(buttons & 1);
|
|
13422
|
+
}
|
|
13423
|
+
// Allow undefined for testing events
|
|
13424
|
+
const button = ev.button === undefined ? 0 : ev.button;
|
|
13425
|
+
// Ev.button is 0 in mousedown/mouseup/click for left button activation
|
|
13426
|
+
return button === 0;
|
|
13427
|
+
}
|
|
13428
|
+
|
|
13429
|
+
function isSyntheticClick(ev) {
|
|
13430
|
+
if (ev.type === 'click') {
|
|
13431
|
+
// Ev.detail is 0 for HTMLElement.click in most browsers
|
|
13432
|
+
if (ev.detail === 0) {
|
|
13433
|
+
return true;
|
|
13434
|
+
}
|
|
13435
|
+
// In the worst case, check that the x/y position of the click is within
|
|
13436
|
+
// the bounding box of the target of the event
|
|
13437
|
+
// Thanks IE 10 >:(
|
|
13438
|
+
const t = _findOriginalTarget(ev);
|
|
13439
|
+
// Make sure the target of the event is an element so we can use getBoundingClientRect,
|
|
13440
|
+
// if not, just assume it is a synthetic click
|
|
13441
|
+
if (!t.nodeType || /** @type {Element} */ (t).nodeType !== Node.ELEMENT_NODE) {
|
|
13442
|
+
return true;
|
|
13443
|
+
}
|
|
13444
|
+
const bcr = /** @type {Element} */ (t).getBoundingClientRect();
|
|
13445
|
+
// Use page x/y to account for scrolling
|
|
13446
|
+
const x = ev.pageX,
|
|
13447
|
+
y = ev.pageY;
|
|
13448
|
+
// Ev is a synthetic click if the position is outside the bounding box of the target
|
|
13449
|
+
return !(x >= bcr.left && x <= bcr.right && y >= bcr.top && y <= bcr.bottom);
|
|
13450
|
+
}
|
|
13451
|
+
return false;
|
|
13452
|
+
}
|
|
13453
|
+
|
|
13454
|
+
const POINTERSTATE = {
|
|
13455
|
+
mouse: {
|
|
13456
|
+
target: null,
|
|
13457
|
+
mouseIgnoreJob: null,
|
|
13458
|
+
},
|
|
13459
|
+
touch: {
|
|
13460
|
+
x: 0,
|
|
13461
|
+
y: 0,
|
|
13462
|
+
id: -1,
|
|
13463
|
+
scrollDecided: false,
|
|
13464
|
+
},
|
|
13465
|
+
};
|
|
13466
|
+
|
|
13467
|
+
function firstTouchAction(ev) {
|
|
13468
|
+
let ta = 'auto';
|
|
13469
|
+
const path = getComposedPath(ev);
|
|
13470
|
+
for (let i = 0, n; i < path.length; i++) {
|
|
13471
|
+
n = path[i];
|
|
13472
|
+
if (n[TOUCH_ACTION]) {
|
|
13473
|
+
ta = n[TOUCH_ACTION];
|
|
13474
|
+
break;
|
|
13475
|
+
}
|
|
13476
|
+
}
|
|
13477
|
+
return ta;
|
|
13059
13478
|
}
|
|
13060
13479
|
|
|
13061
13480
|
function trackDocument(stateObj, movefn, upfn) {
|
|
@@ -13151,7 +13570,7 @@ function _handleNative(ev) {
|
|
|
13151
13570
|
}
|
|
13152
13571
|
if (!ev[HANDLED_OBJ]) {
|
|
13153
13572
|
ev[HANDLED_OBJ] = {};
|
|
13154
|
-
if (type.
|
|
13573
|
+
if (type.startsWith('touch')) {
|
|
13155
13574
|
const t = ev.changedTouches[0];
|
|
13156
13575
|
if (type === 'touchstart') {
|
|
13157
13576
|
// Only handle the first finger
|
|
@@ -13722,100 +14141,38 @@ register({
|
|
|
13722
14141
|
* @param {TouchEvent} e
|
|
13723
14142
|
* @return {void}
|
|
13724
14143
|
*/
|
|
13725
|
-
touchend(e) {
|
|
13726
|
-
trackForward(this.info, e.changedTouches[0], e);
|
|
13727
|
-
},
|
|
13728
|
-
});
|
|
13729
|
-
|
|
13730
|
-
/**
|
|
13731
|
-
* @param {!GestureInfo} info
|
|
13732
|
-
* @param {Event | Touch} e
|
|
13733
|
-
* @param {Event=} preventer
|
|
13734
|
-
* @return {void}
|
|
13735
|
-
*/
|
|
13736
|
-
function trackForward(info, e, preventer) {
|
|
13737
|
-
const dx = Math.abs(e.clientX - info.x);
|
|
13738
|
-
const dy = Math.abs(e.clientY - info.y);
|
|
13739
|
-
// Find original target from `preventer` for TouchEvents, or `e` for MouseEvents
|
|
13740
|
-
const t = _findOriginalTarget(preventer || e);
|
|
13741
|
-
if (!t || (canBeDisabled[/** @type {!HTMLElement} */ (t).localName] && t.hasAttribute('disabled'))) {
|
|
13742
|
-
return;
|
|
13743
|
-
}
|
|
13744
|
-
// Dx,dy can be NaN if `click` has been simulated and there was no `down` for `start`
|
|
13745
|
-
if (isNaN(dx) || isNaN(dy) || (dx <= TAP_DISTANCE && dy <= TAP_DISTANCE) || isSyntheticClick(e)) {
|
|
13746
|
-
// Prevent taps from being generated if an event has canceled them
|
|
13747
|
-
if (!info.prevent) {
|
|
13748
|
-
_fire(t, 'tap', {
|
|
13749
|
-
x: e.clientX,
|
|
13750
|
-
y: e.clientY,
|
|
13751
|
-
sourceEvent: e,
|
|
13752
|
-
preventer,
|
|
13753
|
-
});
|
|
13754
|
-
}
|
|
13755
|
-
}
|
|
13756
|
-
}
|
|
13757
|
-
|
|
13758
|
-
/**
|
|
13759
|
-
* @license
|
|
13760
|
-
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
13761
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
13762
|
-
*/
|
|
13763
|
-
|
|
13764
|
-
/**
|
|
13765
|
-
* A mixin to provide disabled property for field components.
|
|
13766
|
-
*
|
|
13767
|
-
* @polymerMixin
|
|
13768
|
-
*/
|
|
13769
|
-
const DisabledMixin = dedupingMixin(
|
|
13770
|
-
(superclass) =>
|
|
13771
|
-
class DisabledMixinClass extends superclass {
|
|
13772
|
-
static get properties() {
|
|
13773
|
-
return {
|
|
13774
|
-
/**
|
|
13775
|
-
* If true, the user cannot interact with this element.
|
|
13776
|
-
*/
|
|
13777
|
-
disabled: {
|
|
13778
|
-
type: Boolean,
|
|
13779
|
-
value: false,
|
|
13780
|
-
observer: '_disabledChanged',
|
|
13781
|
-
reflectToAttribute: true,
|
|
13782
|
-
},
|
|
13783
|
-
};
|
|
13784
|
-
}
|
|
13785
|
-
|
|
13786
|
-
/**
|
|
13787
|
-
* @param {boolean} disabled
|
|
13788
|
-
* @protected
|
|
13789
|
-
*/
|
|
13790
|
-
_disabledChanged(disabled) {
|
|
13791
|
-
this._setAriaDisabled(disabled);
|
|
13792
|
-
}
|
|
13793
|
-
|
|
13794
|
-
/**
|
|
13795
|
-
* @param {boolean} disabled
|
|
13796
|
-
* @protected
|
|
13797
|
-
*/
|
|
13798
|
-
_setAriaDisabled(disabled) {
|
|
13799
|
-
if (disabled) {
|
|
13800
|
-
this.setAttribute('aria-disabled', 'true');
|
|
13801
|
-
} else {
|
|
13802
|
-
this.removeAttribute('aria-disabled');
|
|
13803
|
-
}
|
|
13804
|
-
}
|
|
14144
|
+
touchend(e) {
|
|
14145
|
+
trackForward(this.info, e.changedTouches[0], e);
|
|
14146
|
+
},
|
|
14147
|
+
});
|
|
13805
14148
|
|
|
13806
|
-
|
|
13807
|
-
|
|
13808
|
-
|
|
13809
|
-
|
|
13810
|
-
|
|
13811
|
-
|
|
13812
|
-
|
|
13813
|
-
|
|
13814
|
-
|
|
13815
|
-
|
|
13816
|
-
|
|
13817
|
-
|
|
13818
|
-
|
|
14149
|
+
/**
|
|
14150
|
+
* @param {!GestureInfo} info
|
|
14151
|
+
* @param {Event | Touch} e
|
|
14152
|
+
* @param {Event=} preventer
|
|
14153
|
+
* @return {void}
|
|
14154
|
+
*/
|
|
14155
|
+
function trackForward(info, e, preventer) {
|
|
14156
|
+
const dx = Math.abs(e.clientX - info.x);
|
|
14157
|
+
const dy = Math.abs(e.clientY - info.y);
|
|
14158
|
+
// Find original target from `preventer` for TouchEvents, or `e` for MouseEvents
|
|
14159
|
+
const t = _findOriginalTarget(preventer || e);
|
|
14160
|
+
if (!t || (canBeDisabled[/** @type {!HTMLElement} */ (t).localName] && t.hasAttribute('disabled'))) {
|
|
14161
|
+
return;
|
|
14162
|
+
}
|
|
14163
|
+
// Dx,dy can be NaN if `click` has been simulated and there was no `down` for `start`
|
|
14164
|
+
if (isNaN(dx) || isNaN(dy) || (dx <= TAP_DISTANCE && dy <= TAP_DISTANCE) || isSyntheticClick(e)) {
|
|
14165
|
+
// Prevent taps from being generated if an event has canceled them
|
|
14166
|
+
if (!info.prevent) {
|
|
14167
|
+
_fire(t, 'tap', {
|
|
14168
|
+
x: e.clientX,
|
|
14169
|
+
y: e.clientY,
|
|
14170
|
+
sourceEvent: e,
|
|
14171
|
+
preventer,
|
|
14172
|
+
});
|
|
14173
|
+
}
|
|
14174
|
+
}
|
|
14175
|
+
}
|
|
13819
14176
|
|
|
13820
14177
|
/**
|
|
13821
14178
|
* @license
|
|
@@ -14010,28 +14367,6 @@ const ActiveMixin = (superclass) =>
|
|
|
14010
14367
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
14011
14368
|
*/
|
|
14012
14369
|
|
|
14013
|
-
// We consider the keyboard to be active if the window has received a keydown
|
|
14014
|
-
// event since the last mousedown event.
|
|
14015
|
-
let keyboardActive = false;
|
|
14016
|
-
|
|
14017
|
-
// Listen for top-level keydown and mousedown events.
|
|
14018
|
-
// Use capture phase so we detect events even if they're handled.
|
|
14019
|
-
window.addEventListener(
|
|
14020
|
-
'keydown',
|
|
14021
|
-
() => {
|
|
14022
|
-
keyboardActive = true;
|
|
14023
|
-
},
|
|
14024
|
-
{ capture: true },
|
|
14025
|
-
);
|
|
14026
|
-
|
|
14027
|
-
window.addEventListener(
|
|
14028
|
-
'mousedown',
|
|
14029
|
-
() => {
|
|
14030
|
-
keyboardActive = false;
|
|
14031
|
-
},
|
|
14032
|
-
{ capture: true },
|
|
14033
|
-
);
|
|
14034
|
-
|
|
14035
14370
|
/**
|
|
14036
14371
|
* A mixin to handle `focused` and `focus-ring` attributes based on focus.
|
|
14037
14372
|
*
|
|
@@ -14045,7 +14380,7 @@ const FocusMixin = dedupingMixin(
|
|
|
14045
14380
|
* @return {boolean}
|
|
14046
14381
|
*/
|
|
14047
14382
|
get _keyboardActive() {
|
|
14048
|
-
return
|
|
14383
|
+
return isKeyboardActive();
|
|
14049
14384
|
}
|
|
14050
14385
|
|
|
14051
14386
|
/** @protected */
|
|
@@ -14309,14 +14644,15 @@ const ButtonMixin = (superClass) =>
|
|
|
14309
14644
|
* `focus-ring` | Set when the button is focused using the keyboard.
|
|
14310
14645
|
* `focused` | Set when the button is focused.
|
|
14311
14646
|
*
|
|
14312
|
-
* See [Styling Components](https://vaadin.com/docs/latest/
|
|
14647
|
+
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
|
|
14313
14648
|
*
|
|
14314
14649
|
* @extends HTMLElement
|
|
14315
14650
|
* @mixes ButtonMixin
|
|
14651
|
+
* @mixes ControllerMixin
|
|
14316
14652
|
* @mixes ElementMixin
|
|
14317
14653
|
* @mixes ThemableMixin
|
|
14318
14654
|
*/
|
|
14319
|
-
class Button extends ButtonMixin(ElementMixin(ThemableMixin(PolymerElement))) {
|
|
14655
|
+
class Button extends ButtonMixin(ElementMixin(ThemableMixin(ControllerMixin(PolymerElement)))) {
|
|
14320
14656
|
static get is() {
|
|
14321
14657
|
return 'vaadin-button';
|
|
14322
14658
|
}
|
|
@@ -14370,18 +14706,27 @@ class Button extends ButtonMixin(ElementMixin(ThemableMixin(PolymerElement))) {
|
|
|
14370
14706
|
}
|
|
14371
14707
|
</style>
|
|
14372
14708
|
<div class="vaadin-button-container">
|
|
14373
|
-
<span part="prefix">
|
|
14709
|
+
<span part="prefix" aria-hidden="true">
|
|
14374
14710
|
<slot name="prefix"></slot>
|
|
14375
14711
|
</span>
|
|
14376
14712
|
<span part="label">
|
|
14377
14713
|
<slot></slot>
|
|
14378
14714
|
</span>
|
|
14379
|
-
<span part="suffix">
|
|
14715
|
+
<span part="suffix" aria-hidden="true">
|
|
14380
14716
|
<slot name="suffix"></slot>
|
|
14381
14717
|
</span>
|
|
14382
14718
|
</div>
|
|
14719
|
+
<slot name="tooltip"></slot>
|
|
14383
14720
|
`;
|
|
14384
14721
|
}
|
|
14722
|
+
|
|
14723
|
+
/** @protected */
|
|
14724
|
+
ready() {
|
|
14725
|
+
super.ready();
|
|
14726
|
+
|
|
14727
|
+
this._tooltipController = new TooltipController(this);
|
|
14728
|
+
this.addController(this._tooltipController);
|
|
14729
|
+
}
|
|
14385
14730
|
}
|
|
14386
14731
|
|
|
14387
14732
|
customElements.define(Button.is, Button);
|
|
@@ -14391,7 +14736,6 @@ registerStyles(
|
|
|
14391
14736
|
i$1`
|
|
14392
14737
|
:host {
|
|
14393
14738
|
position: relative;
|
|
14394
|
-
background-color: transparent;
|
|
14395
14739
|
/* Background for the year scroller, placed here as we are using a mask image on the actual years part */
|
|
14396
14740
|
background-image: linear-gradient(var(--lumo-shade-5pct), var(--lumo-shade-5pct));
|
|
14397
14741
|
background-size: 57px 100%;
|
|
@@ -14417,7 +14761,7 @@ registerStyles(
|
|
|
14417
14761
|
+ var(--lumo-size-m) * 6
|
|
14418
14762
|
+ var(--lumo-space-s)
|
|
14419
14763
|
);
|
|
14420
|
-
--vaadin-infinite-scroller-buffer-offset:
|
|
14764
|
+
--vaadin-infinite-scroller-buffer-offset: 10%;
|
|
14421
14765
|
-webkit-mask-image: linear-gradient(transparent, #000 10%, #000 85%, transparent);
|
|
14422
14766
|
mask-image: linear-gradient(transparent, #000 10%, #000 85%, transparent);
|
|
14423
14767
|
position: relative;
|
|
@@ -14499,17 +14843,10 @@ registerStyles(
|
|
|
14499
14843
|
|
|
14500
14844
|
[part='toolbar'] {
|
|
14501
14845
|
padding: var(--lumo-space-s);
|
|
14502
|
-
box-shadow: 0 -1px 0 0 var(--lumo-contrast-10pct);
|
|
14503
14846
|
border-bottom-left-radius: var(--lumo-border-radius-l);
|
|
14504
14847
|
margin-right: 57px;
|
|
14505
14848
|
}
|
|
14506
14849
|
|
|
14507
|
-
@supports (mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000)) {
|
|
14508
|
-
[part='toolbar'] {
|
|
14509
|
-
box-shadow: none;
|
|
14510
|
-
}
|
|
14511
|
-
}
|
|
14512
|
-
|
|
14513
14850
|
/* Today and Cancel buttons */
|
|
14514
14851
|
|
|
14515
14852
|
[part='toolbar'] [part\$='button'] {
|
|
@@ -14542,8 +14879,6 @@ registerStyles(
|
|
|
14542
14879
|
/* Very narrow screen (year scroller initially hidden) */
|
|
14543
14880
|
|
|
14544
14881
|
[part='years-toggle-button'] {
|
|
14545
|
-
position: relative;
|
|
14546
|
-
right: auto;
|
|
14547
14882
|
display: flex;
|
|
14548
14883
|
align-items: center;
|
|
14549
14884
|
height: var(--lumo-size-s);
|
|
@@ -14561,11 +14896,7 @@ registerStyles(
|
|
|
14561
14896
|
color: var(--lumo-primary-contrast-color);
|
|
14562
14897
|
}
|
|
14563
14898
|
|
|
14564
|
-
|
|
14565
|
-
content: none;
|
|
14566
|
-
}
|
|
14567
|
-
|
|
14568
|
-
/* TODO magic number (same as used for iron-media-query in vaadin-date-picker-overlay-content) */
|
|
14899
|
+
/* TODO magic number (same as used for media-query in vaadin-date-picker-overlay-content) */
|
|
14569
14900
|
@media screen and (max-width: 374px) {
|
|
14570
14901
|
:host {
|
|
14571
14902
|
background-image: none;
|
|
@@ -14740,9 +15071,9 @@ registerStyles(
|
|
|
14740
15071
|
{ moduleId: 'lumo-month-calendar' },
|
|
14741
15072
|
);
|
|
14742
15073
|
|
|
14743
|
-
const $
|
|
15074
|
+
const template$1 = document.createElement('template');
|
|
14744
15075
|
|
|
14745
|
-
$
|
|
15076
|
+
template$1.innerHTML = `
|
|
14746
15077
|
<style>
|
|
14747
15078
|
@keyframes vaadin-date-picker-month-calendar-focus-date {
|
|
14748
15079
|
50% {
|
|
@@ -14752,7 +15083,7 @@ $_documentContainer$1.innerHTML = `
|
|
|
14752
15083
|
</style>
|
|
14753
15084
|
`;
|
|
14754
15085
|
|
|
14755
|
-
document.head.appendChild($
|
|
15086
|
+
document.head.appendChild(template$1.content);
|
|
14756
15087
|
|
|
14757
15088
|
/**
|
|
14758
15089
|
* @license
|
|
@@ -14760,9 +15091,9 @@ document.head.appendChild($_documentContainer$1.content);
|
|
|
14760
15091
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
14761
15092
|
*/
|
|
14762
15093
|
|
|
14763
|
-
const
|
|
15094
|
+
const template = document.createElement('template');
|
|
14764
15095
|
|
|
14765
|
-
|
|
15096
|
+
template.innerHTML = `
|
|
14766
15097
|
<style>
|
|
14767
15098
|
@font-face {
|
|
14768
15099
|
font-family: 'lumo-icons';
|
|
@@ -14818,7 +15149,7 @@ $_documentContainer.innerHTML = `
|
|
|
14818
15149
|
</style>
|
|
14819
15150
|
`;
|
|
14820
15151
|
|
|
14821
|
-
document.head.appendChild(
|
|
15152
|
+
document.head.appendChild(template.content);
|
|
14822
15153
|
|
|
14823
15154
|
/**
|
|
14824
15155
|
* @license
|
|
@@ -14932,6 +15263,10 @@ const requiredField = i$1`
|
|
|
14932
15263
|
line-height: 1;
|
|
14933
15264
|
padding-right: 1em;
|
|
14934
15265
|
padding-bottom: 0.5em;
|
|
15266
|
+
/* As a workaround for diacritics being cut off, add a top padding and a
|
|
15267
|
+
negative margin to compensate */
|
|
15268
|
+
padding-top: 0.25em;
|
|
15269
|
+
margin-top: -0.25em;
|
|
14935
15270
|
overflow: hidden;
|
|
14936
15271
|
white-space: nowrap;
|
|
14937
15272
|
text-overflow: ellipsis;
|
|
@@ -14952,6 +15287,10 @@ const requiredField = i$1`
|
|
|
14952
15287
|
padding-top: var(--lumo-space-m);
|
|
14953
15288
|
}
|
|
14954
15289
|
|
|
15290
|
+
:host([has-label]) ::slotted([slot='tooltip']) {
|
|
15291
|
+
--vaadin-tooltip-offset-bottom: calc((var(--lumo-space-m) - var(--lumo-space-xs)) * -1);
|
|
15292
|
+
}
|
|
15293
|
+
|
|
14955
15294
|
:host([required]) [part='required-indicator']::after {
|
|
14956
15295
|
content: var(--lumo-required-field-indicator, '•');
|
|
14957
15296
|
transition: opacity 0.2s;
|
|
@@ -15385,6 +15724,57 @@ function getAncestorRootNodes(node) {
|
|
|
15385
15724
|
return result;
|
|
15386
15725
|
}
|
|
15387
15726
|
|
|
15727
|
+
/**
|
|
15728
|
+
* @param {string} value
|
|
15729
|
+
* @return {Set<string>}
|
|
15730
|
+
*/
|
|
15731
|
+
function deserializeAttributeValue(value) {
|
|
15732
|
+
if (!value) {
|
|
15733
|
+
return new Set();
|
|
15734
|
+
}
|
|
15735
|
+
|
|
15736
|
+
return new Set(value.split(' '));
|
|
15737
|
+
}
|
|
15738
|
+
|
|
15739
|
+
/**
|
|
15740
|
+
* @param {Set<string>} values
|
|
15741
|
+
* @return {string}
|
|
15742
|
+
*/
|
|
15743
|
+
function serializeAttributeValue(values) {
|
|
15744
|
+
return [...values].join(' ');
|
|
15745
|
+
}
|
|
15746
|
+
|
|
15747
|
+
/**
|
|
15748
|
+
* Adds a value to an attribute containing space-delimited values.
|
|
15749
|
+
*
|
|
15750
|
+
* @param {HTMLElement} element
|
|
15751
|
+
* @param {string} attr
|
|
15752
|
+
* @param {string} value
|
|
15753
|
+
*/
|
|
15754
|
+
function addValueToAttribute(element, attr, value) {
|
|
15755
|
+
const values = deserializeAttributeValue(element.getAttribute(attr));
|
|
15756
|
+
values.add(value);
|
|
15757
|
+
element.setAttribute(attr, serializeAttributeValue(values));
|
|
15758
|
+
}
|
|
15759
|
+
|
|
15760
|
+
/**
|
|
15761
|
+
* Removes a value from an attribute containing space-delimited values.
|
|
15762
|
+
* If the value is the last one, the whole attribute is removed.
|
|
15763
|
+
*
|
|
15764
|
+
* @param {HTMLElement} element
|
|
15765
|
+
* @param {string} attr
|
|
15766
|
+
* @param {string} value
|
|
15767
|
+
*/
|
|
15768
|
+
function removeValueFromAttribute(element, attr, value) {
|
|
15769
|
+
const values = deserializeAttributeValue(element.getAttribute(attr));
|
|
15770
|
+
values.delete(value);
|
|
15771
|
+
if (values.size === 0) {
|
|
15772
|
+
element.removeAttribute(attr);
|
|
15773
|
+
return;
|
|
15774
|
+
}
|
|
15775
|
+
element.setAttribute(attr, serializeAttributeValue(values));
|
|
15776
|
+
}
|
|
15777
|
+
|
|
15388
15778
|
/**
|
|
15389
15779
|
* @license
|
|
15390
15780
|
* Copyright (c) 2017 - 2022 Vaadin Ltd.
|
|
@@ -15401,6 +15791,16 @@ const PROP_NAMES_HORIZONTAL = {
|
|
|
15401
15791
|
end: 'right',
|
|
15402
15792
|
};
|
|
15403
15793
|
|
|
15794
|
+
const targetResizeObserver = new ResizeObserver((entries) => {
|
|
15795
|
+
setTimeout(() => {
|
|
15796
|
+
entries.forEach((entry) => {
|
|
15797
|
+
if (entry.target.__overlay) {
|
|
15798
|
+
entry.target.__overlay._updatePosition();
|
|
15799
|
+
}
|
|
15800
|
+
});
|
|
15801
|
+
});
|
|
15802
|
+
});
|
|
15803
|
+
|
|
15404
15804
|
/**
|
|
15405
15805
|
* @polymerMixin
|
|
15406
15806
|
*/
|
|
@@ -15426,6 +15826,8 @@ const PositionMixin = (superClass) =>
|
|
|
15426
15826
|
* RTL is taken into account when interpreting the value.
|
|
15427
15827
|
* The overlay is automatically flipped to the opposite side when it doesn't fit into
|
|
15428
15828
|
* the default side defined by this property.
|
|
15829
|
+
*
|
|
15830
|
+
* @attr {start|end} horizontal-align
|
|
15429
15831
|
*/
|
|
15430
15832
|
horizontalAlign: {
|
|
15431
15833
|
type: String,
|
|
@@ -15438,6 +15840,8 @@ const PositionMixin = (superClass) =>
|
|
|
15438
15840
|
* Possible values are `top` and `bottom`.
|
|
15439
15841
|
* The overlay is automatically flipped to the opposite side when it doesn't fit into
|
|
15440
15842
|
* the default side defined by this property.
|
|
15843
|
+
*
|
|
15844
|
+
* @attr {top|bottom} vertical-align
|
|
15441
15845
|
*/
|
|
15442
15846
|
verticalAlign: {
|
|
15443
15847
|
type: String,
|
|
@@ -15447,6 +15851,8 @@ const PositionMixin = (superClass) =>
|
|
|
15447
15851
|
/**
|
|
15448
15852
|
* When `positionTarget` is set, this property defines whether the overlay should overlap
|
|
15449
15853
|
* the target element in the x-axis, or be positioned right next to it.
|
|
15854
|
+
*
|
|
15855
|
+
* @attr {boolean} no-horizontal-overlap
|
|
15450
15856
|
*/
|
|
15451
15857
|
noHorizontalOverlap: {
|
|
15452
15858
|
type: Boolean,
|
|
@@ -15456,17 +15862,32 @@ const PositionMixin = (superClass) =>
|
|
|
15456
15862
|
/**
|
|
15457
15863
|
* When `positionTarget` is set, this property defines whether the overlay should overlap
|
|
15458
15864
|
* the target element in the y-axis, or be positioned right above/below it.
|
|
15865
|
+
*
|
|
15866
|
+
* @attr {boolean} no-vertical-overlap
|
|
15459
15867
|
*/
|
|
15460
15868
|
noVerticalOverlap: {
|
|
15461
15869
|
type: Boolean,
|
|
15462
15870
|
value: false,
|
|
15463
15871
|
},
|
|
15872
|
+
|
|
15873
|
+
/**
|
|
15874
|
+
* If the overlay content has no intrinsic height, this property can be used to set
|
|
15875
|
+
* the minimum vertical space (in pixels) required by the overlay. Setting a value to
|
|
15876
|
+
* the property effectively disables the content measurement in favor of using this
|
|
15877
|
+
* fixed value for determining the open direction.
|
|
15878
|
+
*
|
|
15879
|
+
* @attr {number} required-vertical-space
|
|
15880
|
+
*/
|
|
15881
|
+
requiredVerticalSpace: {
|
|
15882
|
+
type: Number,
|
|
15883
|
+
value: 0,
|
|
15884
|
+
},
|
|
15464
15885
|
};
|
|
15465
15886
|
}
|
|
15466
15887
|
|
|
15467
15888
|
static get observers() {
|
|
15468
15889
|
return [
|
|
15469
|
-
'__positionSettingsChanged(horizontalAlign, verticalAlign, noHorizontalOverlap, noVerticalOverlap)',
|
|
15890
|
+
'__positionSettingsChanged(horizontalAlign, verticalAlign, noHorizontalOverlap, noVerticalOverlap, requiredVerticalSpace)',
|
|
15470
15891
|
'__overlayOpenedChanged(opened, positionTarget)',
|
|
15471
15892
|
];
|
|
15472
15893
|
}
|
|
@@ -15474,6 +15895,7 @@ const PositionMixin = (superClass) =>
|
|
|
15474
15895
|
constructor() {
|
|
15475
15896
|
super();
|
|
15476
15897
|
|
|
15898
|
+
this.__onScroll = this.__onScroll.bind(this);
|
|
15477
15899
|
this._updatePosition = this._updatePosition.bind(this);
|
|
15478
15900
|
}
|
|
15479
15901
|
|
|
@@ -15498,7 +15920,7 @@ const PositionMixin = (superClass) =>
|
|
|
15498
15920
|
|
|
15499
15921
|
this.__positionTargetAncestorRootNodes = getAncestorRootNodes(this.positionTarget);
|
|
15500
15922
|
this.__positionTargetAncestorRootNodes.forEach((node) => {
|
|
15501
|
-
node.addEventListener('scroll', this.
|
|
15923
|
+
node.addEventListener('scroll', this.__onScroll, true);
|
|
15502
15924
|
});
|
|
15503
15925
|
}
|
|
15504
15926
|
|
|
@@ -15508,7 +15930,7 @@ const PositionMixin = (superClass) =>
|
|
|
15508
15930
|
|
|
15509
15931
|
if (this.__positionTargetAncestorRootNodes) {
|
|
15510
15932
|
this.__positionTargetAncestorRootNodes.forEach((node) => {
|
|
15511
|
-
node.removeEventListener('scroll', this.
|
|
15933
|
+
node.removeEventListener('scroll', this.__onScroll, true);
|
|
15512
15934
|
});
|
|
15513
15935
|
this.__positionTargetAncestorRootNodes = null;
|
|
15514
15936
|
}
|
|
@@ -15518,8 +15940,15 @@ const PositionMixin = (superClass) =>
|
|
|
15518
15940
|
__overlayOpenedChanged(opened, positionTarget) {
|
|
15519
15941
|
this.__removeUpdatePositionEventListeners();
|
|
15520
15942
|
|
|
15521
|
-
if (
|
|
15522
|
-
|
|
15943
|
+
if (positionTarget) {
|
|
15944
|
+
positionTarget.__overlay = null;
|
|
15945
|
+
targetResizeObserver.unobserve(positionTarget);
|
|
15946
|
+
|
|
15947
|
+
if (opened) {
|
|
15948
|
+
this.__addUpdatePositionEventListeners();
|
|
15949
|
+
positionTarget.__overlay = this;
|
|
15950
|
+
targetResizeObserver.observe(positionTarget);
|
|
15951
|
+
}
|
|
15523
15952
|
}
|
|
15524
15953
|
|
|
15525
15954
|
if (opened) {
|
|
@@ -15546,6 +15975,14 @@ const PositionMixin = (superClass) =>
|
|
|
15546
15975
|
this._updatePosition();
|
|
15547
15976
|
}
|
|
15548
15977
|
|
|
15978
|
+
/** @private */
|
|
15979
|
+
__onScroll(e) {
|
|
15980
|
+
// If the scroll event occurred inside the overlay, ignore it.
|
|
15981
|
+
if (!this.contains(e.target)) {
|
|
15982
|
+
this._updatePosition();
|
|
15983
|
+
}
|
|
15984
|
+
}
|
|
15985
|
+
|
|
15549
15986
|
_updatePosition() {
|
|
15550
15987
|
if (!this.positionTarget || !this.opened) {
|
|
15551
15988
|
return;
|
|
@@ -15618,7 +16055,8 @@ const PositionMixin = (superClass) =>
|
|
|
15618
16055
|
__shouldAlignStartVertically(targetRect) {
|
|
15619
16056
|
// Using previous size to fix a case where window resize may cause the overlay to be squeezed
|
|
15620
16057
|
// smaller than its current space before the fit-calculations.
|
|
15621
|
-
const contentHeight =
|
|
16058
|
+
const contentHeight =
|
|
16059
|
+
this.requiredVerticalSpace || Math.max(this.__oldContentHeight || 0, this.$.overlay.offsetHeight);
|
|
15622
16060
|
this.__oldContentHeight = this.$.overlay.offsetHeight;
|
|
15623
16061
|
|
|
15624
16062
|
const viewportHeight = Math.min(window.innerHeight, document.documentElement.clientHeight);
|
|
@@ -15650,9 +16088,47 @@ const PositionMixin = (superClass) =>
|
|
|
15650
16088
|
return defaultAlignStart === shouldGoToDefaultSide;
|
|
15651
16089
|
}
|
|
15652
16090
|
|
|
16091
|
+
/**
|
|
16092
|
+
* Returns an adjusted value after resizing the browser window,
|
|
16093
|
+
* to avoid wrong calculations when e.g. previously set `bottom`
|
|
16094
|
+
* CSS property value is larger than the updated viewport height.
|
|
16095
|
+
* See https://github.com/vaadin/web-components/issues/4604
|
|
16096
|
+
*/
|
|
16097
|
+
__adjustBottomProperty(cssPropNameToSet, propNames, currentValue) {
|
|
16098
|
+
let adjustedProp;
|
|
16099
|
+
|
|
16100
|
+
if (cssPropNameToSet === propNames.end) {
|
|
16101
|
+
// Adjust horizontally
|
|
16102
|
+
if (propNames.end === PROP_NAMES_VERTICAL.end) {
|
|
16103
|
+
const viewportHeight = Math.min(window.innerHeight, document.documentElement.clientHeight);
|
|
16104
|
+
|
|
16105
|
+
if (currentValue > viewportHeight && this.__oldViewportHeight) {
|
|
16106
|
+
const heightDiff = this.__oldViewportHeight - viewportHeight;
|
|
16107
|
+
adjustedProp = currentValue - heightDiff;
|
|
16108
|
+
}
|
|
16109
|
+
|
|
16110
|
+
this.__oldViewportHeight = viewportHeight;
|
|
16111
|
+
}
|
|
16112
|
+
|
|
16113
|
+
// Adjust vertically
|
|
16114
|
+
if (propNames.end === PROP_NAMES_HORIZONTAL.end) {
|
|
16115
|
+
const viewportWidth = Math.min(window.innerWidth, document.documentElement.clientWidth);
|
|
16116
|
+
|
|
16117
|
+
if (currentValue > viewportWidth && this.__oldViewportWidth) {
|
|
16118
|
+
const widthDiff = this.__oldViewportWidth - viewportWidth;
|
|
16119
|
+
adjustedProp = currentValue - widthDiff;
|
|
16120
|
+
}
|
|
16121
|
+
|
|
16122
|
+
this.__oldViewportWidth = viewportWidth;
|
|
16123
|
+
}
|
|
16124
|
+
}
|
|
16125
|
+
|
|
16126
|
+
return adjustedProp;
|
|
16127
|
+
}
|
|
16128
|
+
|
|
15653
16129
|
/**
|
|
15654
16130
|
* Returns an object with CSS position properties to set,
|
|
15655
|
-
* e.g. { top: "100px"
|
|
16131
|
+
* e.g. { top: "100px" }
|
|
15656
16132
|
*/
|
|
15657
16133
|
// eslint-disable-next-line max-params
|
|
15658
16134
|
__calculatePositionInOneDimension(targetRect, overlayRect, noOverlap, propNames, overlay, shouldAlignStart) {
|
|
@@ -15660,13 +16136,18 @@ const PositionMixin = (superClass) =>
|
|
|
15660
16136
|
const cssPropNameToClear = shouldAlignStart ? propNames.end : propNames.start;
|
|
15661
16137
|
|
|
15662
16138
|
const currentValue = parseFloat(overlay.style[cssPropNameToSet] || getComputedStyle(overlay)[cssPropNameToSet]);
|
|
16139
|
+
const adjustedValue = this.__adjustBottomProperty(cssPropNameToSet, propNames, currentValue);
|
|
15663
16140
|
|
|
15664
16141
|
const diff =
|
|
15665
16142
|
overlayRect[shouldAlignStart ? propNames.start : propNames.end] -
|
|
15666
16143
|
targetRect[noOverlap === shouldAlignStart ? propNames.end : propNames.start];
|
|
15667
16144
|
|
|
16145
|
+
const valueToSet = adjustedValue
|
|
16146
|
+
? `${adjustedValue}px`
|
|
16147
|
+
: `${currentValue + diff * (shouldAlignStart ? -1 : 1)}px`;
|
|
16148
|
+
|
|
15668
16149
|
return {
|
|
15669
|
-
[cssPropNameToSet]:
|
|
16150
|
+
[cssPropNameToSet]: valueToSet,
|
|
15670
16151
|
[cssPropNameToClear]: '',
|
|
15671
16152
|
};
|
|
15672
16153
|
}
|
|
@@ -15683,11 +16164,6 @@ const datePickerStyles = i$1`
|
|
|
15683
16164
|
direction: ltr;
|
|
15684
16165
|
}
|
|
15685
16166
|
|
|
15686
|
-
:host([dir='rtl']) [part='value']::placeholder {
|
|
15687
|
-
direction: rtl;
|
|
15688
|
-
text-align: left;
|
|
15689
|
-
}
|
|
15690
|
-
|
|
15691
16167
|
:host([dir='rtl']) [part='input-field'] ::slotted(input)::placeholder {
|
|
15692
16168
|
direction: rtl;
|
|
15693
16169
|
text-align: left;
|
|
@@ -15720,10 +16196,10 @@ let memoizedTemplate;
|
|
|
15720
16196
|
/**
|
|
15721
16197
|
* An element used internally by `<vaadin-date-picker>`. Not intended to be used separately.
|
|
15722
16198
|
*
|
|
15723
|
-
* @extends
|
|
16199
|
+
* @extends Overlay
|
|
15724
16200
|
* @private
|
|
15725
16201
|
*/
|
|
15726
|
-
class DatePickerOverlay extends DisableUpgradeMixin(PositionMixin(
|
|
16202
|
+
class DatePickerOverlay extends DisableUpgradeMixin(PositionMixin(Overlay)) {
|
|
15727
16203
|
static get is() {
|
|
15728
16204
|
return 'vaadin-date-picker-overlay';
|
|
15729
16205
|
}
|
|
@@ -16863,6 +17339,53 @@ function extractDateParts(date) {
|
|
|
16863
17339
|
};
|
|
16864
17340
|
}
|
|
16865
17341
|
|
|
17342
|
+
/**
|
|
17343
|
+
* Calculate the year of the date based on the provided reference date.
|
|
17344
|
+
* Gets a two-digit year and returns a full year.
|
|
17345
|
+
* @param {!Date} referenceDate The date to act as basis in the calculation
|
|
17346
|
+
* @param {!number} year Should be in the range of [0, 99]
|
|
17347
|
+
* @param {number} month
|
|
17348
|
+
* @param {number} day
|
|
17349
|
+
* @return {!number} Adjusted year value
|
|
17350
|
+
*/
|
|
17351
|
+
function getAdjustedYear(referenceDate, year, month = 0, day = 1) {
|
|
17352
|
+
if (year > 99) {
|
|
17353
|
+
throw new Error('The provided year cannot have more than 2 digits.');
|
|
17354
|
+
}
|
|
17355
|
+
if (year < 0) {
|
|
17356
|
+
throw new Error('The provided year cannot be negative.');
|
|
17357
|
+
}
|
|
17358
|
+
// Year values up to 2 digits are parsed based on the reference date.
|
|
17359
|
+
let adjustedYear = year + Math.floor(referenceDate.getFullYear() / 100) * 100;
|
|
17360
|
+
if (referenceDate < new Date(adjustedYear - 50, month, day)) {
|
|
17361
|
+
adjustedYear -= 100;
|
|
17362
|
+
} else if (referenceDate > new Date(adjustedYear + 50, month, day)) {
|
|
17363
|
+
adjustedYear += 100;
|
|
17364
|
+
}
|
|
17365
|
+
return adjustedYear;
|
|
17366
|
+
}
|
|
17367
|
+
|
|
17368
|
+
/**
|
|
17369
|
+
* Parse date string of one of the following date formats:
|
|
17370
|
+
* - ISO 8601 `"YYYY-MM-DD"`
|
|
17371
|
+
* - 6-digit extended ISO 8601 `"+YYYYYY-MM-DD"`, `"-YYYYYY-MM-DD"`
|
|
17372
|
+
* @param {!string} str Date string to parse
|
|
17373
|
+
* @return {Date} Parsed date
|
|
17374
|
+
*/
|
|
17375
|
+
function parseDate(str) {
|
|
17376
|
+
// Parsing with RegExp to ensure correct format
|
|
17377
|
+
const parts = /^([-+]\d{1}|\d{2,4}|[-+]\d{6})-(\d{1,2})-(\d{1,2})$/.exec(str);
|
|
17378
|
+
if (!parts) {
|
|
17379
|
+
return undefined;
|
|
17380
|
+
}
|
|
17381
|
+
|
|
17382
|
+
const date = new Date(0, 0); // Wrong date (1900-01-01), but with midnight in local time
|
|
17383
|
+
date.setFullYear(parseInt(parts[1], 10));
|
|
17384
|
+
date.setMonth(parseInt(parts[2], 10) - 1);
|
|
17385
|
+
date.setDate(parseInt(parts[3], 10));
|
|
17386
|
+
return date;
|
|
17387
|
+
}
|
|
17388
|
+
|
|
16866
17389
|
/**
|
|
16867
17390
|
* @license
|
|
16868
17391
|
* Copyright (c) 2016 - 2022 Vaadin Ltd.
|
|
@@ -16939,7 +17462,9 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
16939
17462
|
is="dom-repeat"
|
|
16940
17463
|
items="[[_getWeekDayNames(i18n.weekdays, i18n.weekdaysShort, showWeekNumbers, i18n.firstDayOfWeek)]]"
|
|
16941
17464
|
>
|
|
16942
|
-
<th role="columnheader" part="weekday" scope="col" abbr$="[[item.weekDay]]">
|
|
17465
|
+
<th role="columnheader" part="weekday" scope="col" abbr$="[[item.weekDay]]" aria-hidden="true">
|
|
17466
|
+
[[item.weekDayShort]]
|
|
17467
|
+
</th>
|
|
16943
17468
|
</template>
|
|
16944
17469
|
</tr>
|
|
16945
17470
|
</thead>
|
|
@@ -17109,7 +17634,9 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
17109
17634
|
|
|
17110
17635
|
_onMonthGridTouchStart() {
|
|
17111
17636
|
this._notTapping = false;
|
|
17112
|
-
setTimeout(() =>
|
|
17637
|
+
setTimeout(() => {
|
|
17638
|
+
this._notTapping = true;
|
|
17639
|
+
}, 300);
|
|
17113
17640
|
}
|
|
17114
17641
|
|
|
17115
17642
|
_dateAdd(date, delta) {
|
|
@@ -17283,12 +17810,6 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
17283
17810
|
|
|
17284
17811
|
return '-1';
|
|
17285
17812
|
}
|
|
17286
|
-
|
|
17287
|
-
__getWeekNumbers(dates) {
|
|
17288
|
-
return dates
|
|
17289
|
-
.map((date) => this.__getWeekNumber(date, dates))
|
|
17290
|
-
.filter((week, index, arr) => arr.indexOf(week) === index);
|
|
17291
|
-
}
|
|
17292
17813
|
}
|
|
17293
17814
|
|
|
17294
17815
|
customElements.define(MonthCalendar.is, MonthCalendar);
|
|
@@ -17378,6 +17899,7 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17378
17899
|
/**
|
|
17379
17900
|
* The amount of initial scroll top. Needed in order for the
|
|
17380
17901
|
* user to be able to scroll backwards.
|
|
17902
|
+
* @private
|
|
17381
17903
|
*/
|
|
17382
17904
|
_initialScroll: {
|
|
17383
17905
|
value: 500000,
|
|
@@ -17385,17 +17907,22 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17385
17907
|
|
|
17386
17908
|
/**
|
|
17387
17909
|
* The index/position mapped at _initialScroll point.
|
|
17910
|
+
* @private
|
|
17388
17911
|
*/
|
|
17389
17912
|
_initialIndex: {
|
|
17390
17913
|
value: 0,
|
|
17391
17914
|
},
|
|
17392
17915
|
|
|
17916
|
+
/** @private */
|
|
17393
17917
|
_buffers: Array,
|
|
17394
17918
|
|
|
17919
|
+
/** @private */
|
|
17395
17920
|
_preventScrollEvent: Boolean,
|
|
17396
17921
|
|
|
17922
|
+
/** @private */
|
|
17397
17923
|
_mayHaveMomentum: Boolean,
|
|
17398
17924
|
|
|
17925
|
+
/** @private */
|
|
17399
17926
|
_initialized: Boolean,
|
|
17400
17927
|
|
|
17401
17928
|
active: {
|
|
@@ -17405,10 +17932,11 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17405
17932
|
};
|
|
17406
17933
|
}
|
|
17407
17934
|
|
|
17935
|
+
/** @protected */
|
|
17408
17936
|
ready() {
|
|
17409
17937
|
super.ready();
|
|
17410
17938
|
|
|
17411
|
-
this._buffers =
|
|
17939
|
+
this._buffers = [...this.shadowRoot.querySelectorAll('.buffer')];
|
|
17412
17940
|
|
|
17413
17941
|
this.$.fullHeight.style.height = `${this._initialScroll * 2}px`;
|
|
17414
17942
|
|
|
@@ -17417,8 +17945,8 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17417
17945
|
forwardHostProp(prop, value) {
|
|
17418
17946
|
if (prop !== 'index') {
|
|
17419
17947
|
this._buffers.forEach((buffer) => {
|
|
17420
|
-
[].forEach
|
|
17421
|
-
|
|
17948
|
+
[...buffer.children].forEach((slot) => {
|
|
17949
|
+
slot._itemWrapper.instance[prop] = value;
|
|
17422
17950
|
});
|
|
17423
17951
|
});
|
|
17424
17952
|
}
|
|
@@ -17432,6 +17960,19 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17432
17960
|
}
|
|
17433
17961
|
}
|
|
17434
17962
|
|
|
17963
|
+
/**
|
|
17964
|
+
* Force the scroller to update clones after a reset, without
|
|
17965
|
+
* waiting for the debouncer to resolve.
|
|
17966
|
+
*/
|
|
17967
|
+
forceUpdate() {
|
|
17968
|
+
if (this._debouncerUpdateClones) {
|
|
17969
|
+
this._buffers[0].updated = this._buffers[1].updated = false;
|
|
17970
|
+
this._updateClones();
|
|
17971
|
+
this._debouncerUpdateClones.cancel();
|
|
17972
|
+
}
|
|
17973
|
+
}
|
|
17974
|
+
|
|
17975
|
+
/** @private */
|
|
17435
17976
|
_activated(active) {
|
|
17436
17977
|
if (active && !this._initialized) {
|
|
17437
17978
|
this._createPool();
|
|
@@ -17439,12 +17980,15 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17439
17980
|
}
|
|
17440
17981
|
}
|
|
17441
17982
|
|
|
17983
|
+
/** @private */
|
|
17442
17984
|
_finishInit() {
|
|
17443
17985
|
if (!this._initDone) {
|
|
17444
17986
|
// Once the first set of items start fading in, stamp the rest
|
|
17445
17987
|
this._buffers.forEach((buffer) => {
|
|
17446
|
-
[].forEach
|
|
17447
|
-
|
|
17988
|
+
[...buffer.children].forEach((slot) => {
|
|
17989
|
+
this._ensureStampedInstance(slot._itemWrapper);
|
|
17990
|
+
});
|
|
17991
|
+
});
|
|
17448
17992
|
|
|
17449
17993
|
if (!this._buffers[0].translateY) {
|
|
17450
17994
|
this._reset();
|
|
@@ -17454,6 +17998,7 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17454
17998
|
}
|
|
17455
17999
|
}
|
|
17456
18000
|
|
|
18001
|
+
/** @private */
|
|
17457
18002
|
_translateBuffer(up) {
|
|
17458
18003
|
const index = up ? 1 : 0;
|
|
17459
18004
|
this._buffers[index].translateY = this._buffers[index ? 0 : 1].translateY + this._bufferHeight * (index ? -1 : 1);
|
|
@@ -17462,6 +18007,7 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17462
18007
|
this._buffers.reverse();
|
|
17463
18008
|
}
|
|
17464
18009
|
|
|
18010
|
+
/** @private */
|
|
17465
18011
|
_scroll() {
|
|
17466
18012
|
if (this._scrollDisabled) {
|
|
17467
18013
|
return;
|
|
@@ -17558,10 +18104,12 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17558
18104
|
return this._itemHeightVal;
|
|
17559
18105
|
}
|
|
17560
18106
|
|
|
18107
|
+
/** @private */
|
|
17561
18108
|
get _bufferHeight() {
|
|
17562
18109
|
return this.itemHeight * this.bufferSize;
|
|
17563
18110
|
}
|
|
17564
18111
|
|
|
18112
|
+
/** @private */
|
|
17565
18113
|
_reset() {
|
|
17566
18114
|
this._scrollDisabled = true;
|
|
17567
18115
|
this.$.scroller.scrollTop = this._initialScroll;
|
|
@@ -17581,6 +18129,7 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17581
18129
|
this._scrollDisabled = false;
|
|
17582
18130
|
}
|
|
17583
18131
|
|
|
18132
|
+
/** @private */
|
|
17584
18133
|
_createPool() {
|
|
17585
18134
|
const container = this.getBoundingClientRect();
|
|
17586
18135
|
this._buffers.forEach((buffer) => {
|
|
@@ -17592,10 +18141,10 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17592
18141
|
const contentId = (InfiniteScroller._contentIndex = InfiniteScroller._contentIndex + 1 || 0);
|
|
17593
18142
|
const slotName = `vaadin-infinite-scroller-item-content-${contentId}`;
|
|
17594
18143
|
|
|
17595
|
-
const
|
|
17596
|
-
|
|
17597
|
-
|
|
17598
|
-
buffer.appendChild(
|
|
18144
|
+
const slot = document.createElement('slot');
|
|
18145
|
+
slot.setAttribute('name', slotName);
|
|
18146
|
+
slot._itemWrapper = itemWrapper;
|
|
18147
|
+
buffer.appendChild(slot);
|
|
17599
18148
|
|
|
17600
18149
|
itemWrapper.setAttribute('slot', slotName);
|
|
17601
18150
|
this.appendChild(itemWrapper);
|
|
@@ -17607,13 +18156,14 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17607
18156
|
}
|
|
17608
18157
|
}, 1); // Wait for first reset
|
|
17609
18158
|
}
|
|
17610
|
-
}
|
|
18159
|
+
});
|
|
17611
18160
|
|
|
17612
18161
|
setTimeout(() => {
|
|
17613
18162
|
afterNextRender(this, this._finishInit.bind(this));
|
|
17614
18163
|
}, 1);
|
|
17615
18164
|
}
|
|
17616
18165
|
|
|
18166
|
+
/** @private */
|
|
17617
18167
|
_ensureStampedInstance(itemWrapper) {
|
|
17618
18168
|
if (itemWrapper.firstElementChild) {
|
|
17619
18169
|
return;
|
|
@@ -17629,6 +18179,7 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17629
18179
|
});
|
|
17630
18180
|
}
|
|
17631
18181
|
|
|
18182
|
+
/** @private */
|
|
17632
18183
|
_updateClones(viewPortOnly) {
|
|
17633
18184
|
this._firstIndex = ~~((this._buffers[0].translateY - this._initialScroll) / this.itemHeight) + this._initialIndex;
|
|
17634
18185
|
|
|
@@ -17637,17 +18188,18 @@ class InfiniteScroller extends PolymerElement {
|
|
|
17637
18188
|
if (!buffer.updated) {
|
|
17638
18189
|
const firstIndex = this._firstIndex + this.bufferSize * bufferIndex;
|
|
17639
18190
|
|
|
17640
|
-
[].forEach
|
|
17641
|
-
const itemWrapper =
|
|
18191
|
+
[...buffer.children].forEach((slot, index) => {
|
|
18192
|
+
const itemWrapper = slot._itemWrapper;
|
|
17642
18193
|
if (!viewPortOnly || this._isVisible(itemWrapper, scrollerRect)) {
|
|
17643
18194
|
itemWrapper.instance.index = firstIndex + index;
|
|
17644
18195
|
}
|
|
17645
18196
|
});
|
|
17646
18197
|
buffer.updated = true;
|
|
17647
18198
|
}
|
|
17648
|
-
}
|
|
18199
|
+
});
|
|
17649
18200
|
}
|
|
17650
18201
|
|
|
18202
|
+
/** @private */
|
|
17651
18203
|
_isVisible(element, container) {
|
|
17652
18204
|
const rect = element.getBoundingClientRect();
|
|
17653
18205
|
return rect.bottom > container.top && rect.top < container.bottom;
|
|
@@ -17744,7 +18296,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
17744
18296
|
height: 100%;
|
|
17745
18297
|
width: 100%;
|
|
17746
18298
|
outline: none;
|
|
17747
|
-
background: #fff;
|
|
17748
18299
|
}
|
|
17749
18300
|
|
|
17750
18301
|
[part='overlay-header'] {
|
|
@@ -17762,22 +18313,14 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
17762
18313
|
flex-grow: 1;
|
|
17763
18314
|
}
|
|
17764
18315
|
|
|
17765
|
-
[
|
|
17766
|
-
display: none;
|
|
18316
|
+
[hidden] {
|
|
18317
|
+
display: none !important;
|
|
17767
18318
|
}
|
|
17768
18319
|
|
|
17769
18320
|
[part='years-toggle-button'] {
|
|
17770
18321
|
display: flex;
|
|
17771
18322
|
}
|
|
17772
18323
|
|
|
17773
|
-
[part='years-toggle-button'][desktop] {
|
|
17774
|
-
display: none;
|
|
17775
|
-
}
|
|
17776
|
-
|
|
17777
|
-
:host(:not([years-visible])) [part='years-toggle-button']::before {
|
|
17778
|
-
transform: rotate(180deg);
|
|
17779
|
-
}
|
|
17780
|
-
|
|
17781
18324
|
#scrollers {
|
|
17782
18325
|
display: flex;
|
|
17783
18326
|
height: 100%;
|
|
@@ -17851,27 +18394,14 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
17851
18394
|
z-index: 2;
|
|
17852
18395
|
flex-shrink: 0;
|
|
17853
18396
|
}
|
|
17854
|
-
|
|
17855
|
-
[part~='overlay-header']:not([desktop]) {
|
|
17856
|
-
padding-bottom: 40px;
|
|
17857
|
-
}
|
|
17858
|
-
|
|
17859
|
-
[part~='years-toggle-button'] {
|
|
17860
|
-
position: absolute;
|
|
17861
|
-
top: auto;
|
|
17862
|
-
right: 8px;
|
|
17863
|
-
bottom: 0;
|
|
17864
|
-
z-index: 1;
|
|
17865
|
-
padding: 8px;
|
|
17866
|
-
}
|
|
17867
18397
|
</style>
|
|
17868
18398
|
|
|
17869
18399
|
<div part="overlay-header" on-touchend="_preventDefault" desktop$="[[_desktopMode]]" aria-hidden="true">
|
|
17870
18400
|
<div part="label">[[_formatDisplayed(selectedDate, i18n.formatDate, label)]]</div>
|
|
17871
|
-
<div part="clear-button"
|
|
18401
|
+
<div part="clear-button" hidden$="[[!selectedDate]]"></div>
|
|
17872
18402
|
<div part="toggle-button"></div>
|
|
17873
18403
|
|
|
17874
|
-
<div part="years-toggle-button"
|
|
18404
|
+
<div part="years-toggle-button" hidden$="[[_desktopMode]]" aria-hidden="true">
|
|
17875
18405
|
[[_yearAfterXMonths(_visibleMonthIndex)]]
|
|
17876
18406
|
</div>
|
|
17877
18407
|
</div>
|
|
@@ -17957,6 +18487,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
17957
18487
|
*/
|
|
17958
18488
|
selectedDate: {
|
|
17959
18489
|
type: Date,
|
|
18490
|
+
value: null,
|
|
17960
18491
|
},
|
|
17961
18492
|
|
|
17962
18493
|
/**
|
|
@@ -18032,10 +18563,24 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18032
18563
|
return this.getAttribute('dir') === 'rtl';
|
|
18033
18564
|
}
|
|
18034
18565
|
|
|
18566
|
+
/**
|
|
18567
|
+
* Whether to scroll to a sub-month position when scrolling to a date.
|
|
18568
|
+
* This is active if the month scroller is not large enough to fit a
|
|
18569
|
+
* full month. In that case we want to scroll to a position between
|
|
18570
|
+
* two months in order to have the focused date in the visible area.
|
|
18571
|
+
* @returns {boolean} whether to use sub-month scrolling
|
|
18572
|
+
* @private
|
|
18573
|
+
*/
|
|
18574
|
+
get __useSubMonthScrolling() {
|
|
18575
|
+
return this.$.monthScroller.clientHeight < this.$.monthScroller.itemHeight + this.$.monthScroller.bufferOffset;
|
|
18576
|
+
}
|
|
18577
|
+
|
|
18578
|
+
get calendars() {
|
|
18579
|
+
return [...this.shadowRoot.querySelectorAll('vaadin-month-calendar')];
|
|
18580
|
+
}
|
|
18581
|
+
|
|
18035
18582
|
get focusableDateElement() {
|
|
18036
|
-
return
|
|
18037
|
-
.map((calendar) => calendar.focusableDateElement)
|
|
18038
|
-
.find(Boolean);
|
|
18583
|
+
return this.calendars.map((calendar) => calendar.focusableDateElement).find(Boolean);
|
|
18039
18584
|
}
|
|
18040
18585
|
|
|
18041
18586
|
ready() {
|
|
@@ -18043,7 +18588,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18043
18588
|
|
|
18044
18589
|
this.setAttribute('role', 'dialog');
|
|
18045
18590
|
|
|
18046
|
-
addListener(this, 'tap', this._stopPropagation);
|
|
18047
18591
|
addListener(this.$.scrollers, 'track', this._track.bind(this));
|
|
18048
18592
|
addListener(this.shadowRoot.querySelector('[part="clear-button"]'), 'tap', this._clear.bind(this));
|
|
18049
18593
|
addListener(this.shadowRoot.querySelector('[part="today-button"]'), 'tap', this._onTodayTap.bind(this));
|
|
@@ -18088,7 +18632,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18088
18632
|
* Scrolls the list to the given Date.
|
|
18089
18633
|
*/
|
|
18090
18634
|
scrollToDate(date, animate) {
|
|
18091
|
-
this.
|
|
18635
|
+
const offset = this.__useSubMonthScrolling ? this._calculateWeekScrollOffset(date) : 0;
|
|
18636
|
+
this._scrollToPosition(this._differenceInMonths(date, this._originDate) + offset, animate);
|
|
18637
|
+
this.$.monthScroller.forceUpdate();
|
|
18092
18638
|
}
|
|
18093
18639
|
|
|
18094
18640
|
/**
|
|
@@ -18120,23 +18666,63 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18120
18666
|
* Scrolls the month and year scrollers enough to reveal the given date.
|
|
18121
18667
|
*/
|
|
18122
18668
|
revealDate(date, animate = true) {
|
|
18123
|
-
if (date) {
|
|
18124
|
-
|
|
18125
|
-
|
|
18669
|
+
if (!date) {
|
|
18670
|
+
return;
|
|
18671
|
+
}
|
|
18672
|
+
const diff = this._differenceInMonths(date, this._originDate);
|
|
18673
|
+
// If scroll area does not fit the full month, then always scroll with an offset to
|
|
18674
|
+
// approximately display the week of the date
|
|
18675
|
+
if (this.__useSubMonthScrolling) {
|
|
18676
|
+
const offset = this._calculateWeekScrollOffset(date);
|
|
18677
|
+
this._scrollToPosition(diff + offset, animate);
|
|
18678
|
+
return;
|
|
18679
|
+
}
|
|
18126
18680
|
|
|
18127
|
-
|
|
18128
|
-
|
|
18129
|
-
|
|
18130
|
-
|
|
18131
|
-
|
|
18132
|
-
|
|
18681
|
+
// Otherwise determine if we need to scroll to make the month of the date visible
|
|
18682
|
+
const scrolledAboveViewport = this.$.monthScroller.position > diff;
|
|
18683
|
+
|
|
18684
|
+
const visibleArea = Math.max(
|
|
18685
|
+
this.$.monthScroller.itemHeight,
|
|
18686
|
+
this.$.monthScroller.clientHeight - this.$.monthScroller.bufferOffset * 2,
|
|
18687
|
+
);
|
|
18688
|
+
const visibleItems = visibleArea / this.$.monthScroller.itemHeight;
|
|
18689
|
+
const scrolledBelowViewport = this.$.monthScroller.position + visibleItems - 1 < diff;
|
|
18133
18690
|
|
|
18134
|
-
|
|
18135
|
-
|
|
18136
|
-
|
|
18137
|
-
|
|
18691
|
+
if (scrolledAboveViewport) {
|
|
18692
|
+
this._scrollToPosition(diff, animate);
|
|
18693
|
+
} else if (scrolledBelowViewport) {
|
|
18694
|
+
this._scrollToPosition(diff - visibleItems + 1, animate);
|
|
18695
|
+
}
|
|
18696
|
+
}
|
|
18697
|
+
|
|
18698
|
+
/**
|
|
18699
|
+
* Calculates an offset to be added to the month scroll position
|
|
18700
|
+
* when using sub-month scrolling, in order ensure that the week
|
|
18701
|
+
* that the date is in is visible even for small scroll areas.
|
|
18702
|
+
* As the month scroller uses a month as minimal scroll unit
|
|
18703
|
+
* (a value of `1` equals one month), we can not exactly identify
|
|
18704
|
+
* the position of a specific week. This is a best effort
|
|
18705
|
+
* implementation based on manual testing.
|
|
18706
|
+
* @param date the date for which to calculate the offset
|
|
18707
|
+
* @returns {number} the offset
|
|
18708
|
+
* @private
|
|
18709
|
+
*/
|
|
18710
|
+
_calculateWeekScrollOffset(date) {
|
|
18711
|
+
// Get first day of month
|
|
18712
|
+
const temp = new Date(0, 0);
|
|
18713
|
+
temp.setFullYear(date.getFullYear());
|
|
18714
|
+
temp.setMonth(date.getMonth());
|
|
18715
|
+
temp.setDate(1);
|
|
18716
|
+
// Determine week (=row index) of date within the month
|
|
18717
|
+
let week = 0;
|
|
18718
|
+
while (temp.getDate() < date.getDate()) {
|
|
18719
|
+
temp.setDate(temp.getDate() + 1);
|
|
18720
|
+
if (temp.getDay() === this.i18n.firstDayOfWeek) {
|
|
18721
|
+
week += 1;
|
|
18138
18722
|
}
|
|
18139
18723
|
}
|
|
18724
|
+
// Calculate magic number that approximately keeps the week visible
|
|
18725
|
+
return week / 6;
|
|
18140
18726
|
}
|
|
18141
18727
|
|
|
18142
18728
|
_initialPositionChanged(initialPosition) {
|
|
@@ -18165,7 +18751,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18165
18751
|
|
|
18166
18752
|
_onYearScrollTouchStart() {
|
|
18167
18753
|
this._notTapping = false;
|
|
18168
|
-
setTimeout(() =>
|
|
18754
|
+
setTimeout(() => {
|
|
18755
|
+
this._notTapping = true;
|
|
18756
|
+
}, 300);
|
|
18169
18757
|
|
|
18170
18758
|
this._repositionMonthScroller();
|
|
18171
18759
|
}
|
|
@@ -18176,7 +18764,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18176
18764
|
|
|
18177
18765
|
_doIgnoreTaps() {
|
|
18178
18766
|
this._ignoreTaps = true;
|
|
18179
|
-
this._debouncer = Debouncer$1.debounce(this._debouncer, timeOut.after(300), () =>
|
|
18767
|
+
this._debouncer = Debouncer$1.debounce(this._debouncer, timeOut.after(300), () => {
|
|
18768
|
+
this._ignoreTaps = false;
|
|
18769
|
+
});
|
|
18180
18770
|
}
|
|
18181
18771
|
|
|
18182
18772
|
_formatDisplayed(date, formatDate, label) {
|
|
@@ -18207,10 +18797,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18207
18797
|
this.scrollToDate(new Date(), true);
|
|
18208
18798
|
}
|
|
18209
18799
|
|
|
18210
|
-
_showClear(selectedDate) {
|
|
18211
|
-
return !!selectedDate;
|
|
18212
|
-
}
|
|
18213
|
-
|
|
18214
18800
|
_onYearTap(e) {
|
|
18215
18801
|
if (!this._ignoreTaps && !this._notTapping) {
|
|
18216
18802
|
const scrollDelta =
|
|
@@ -18236,6 +18822,11 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18236
18822
|
|
|
18237
18823
|
this._targetPosition = targetPosition;
|
|
18238
18824
|
|
|
18825
|
+
let revealResolve;
|
|
18826
|
+
this._revealPromise = new Promise((resolve) => {
|
|
18827
|
+
revealResolve = resolve;
|
|
18828
|
+
});
|
|
18829
|
+
|
|
18239
18830
|
// http://gizma.com/easing/
|
|
18240
18831
|
const easingFunction = (t, b, c, d) => {
|
|
18241
18832
|
t /= d / 2;
|
|
@@ -18276,7 +18867,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18276
18867
|
|
|
18277
18868
|
this.$.monthScroller.position = this._targetPosition;
|
|
18278
18869
|
this._targetPosition = undefined;
|
|
18279
|
-
|
|
18870
|
+
|
|
18871
|
+
revealResolve();
|
|
18872
|
+
this._revealPromise = undefined;
|
|
18280
18873
|
}
|
|
18281
18874
|
|
|
18282
18875
|
setTimeout(this._repositionYearScroller.bind(this), 1);
|
|
@@ -18392,10 +18985,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18392
18985
|
return months - date2.getMonth() + date1.getMonth();
|
|
18393
18986
|
}
|
|
18394
18987
|
|
|
18395
|
-
_differenceInYears(date1, date2) {
|
|
18396
|
-
return this._differenceInMonths(date1, date2) / 12;
|
|
18397
|
-
}
|
|
18398
|
-
|
|
18399
18988
|
_clear() {
|
|
18400
18989
|
this._selectDate('');
|
|
18401
18990
|
}
|
|
@@ -18486,51 +19075,44 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18486
19075
|
switch (section) {
|
|
18487
19076
|
case 'calendar':
|
|
18488
19077
|
if (event.shiftKey) {
|
|
18489
|
-
// Return focus back to the input field.
|
|
18490
19078
|
event.preventDefault();
|
|
18491
|
-
|
|
19079
|
+
|
|
19080
|
+
if (this.hasAttribute('fullscreen')) {
|
|
19081
|
+
// Trap focus in the overlay
|
|
19082
|
+
this.$.cancelButton.focus();
|
|
19083
|
+
} else {
|
|
19084
|
+
this.__focusInput();
|
|
19085
|
+
}
|
|
18492
19086
|
}
|
|
18493
19087
|
break;
|
|
18494
19088
|
case 'today':
|
|
18495
19089
|
if (event.shiftKey) {
|
|
18496
|
-
|
|
18497
|
-
|
|
18498
|
-
setTimeout(() => this.revealDate(this.focusedDate), 1);
|
|
19090
|
+
event.preventDefault();
|
|
19091
|
+
this.focusDateElement();
|
|
18499
19092
|
}
|
|
18500
19093
|
break;
|
|
18501
19094
|
case 'cancel':
|
|
18502
19095
|
if (!event.shiftKey) {
|
|
18503
|
-
// Return focus back to the input field.
|
|
18504
19096
|
event.preventDefault();
|
|
18505
|
-
|
|
19097
|
+
|
|
19098
|
+
if (this.hasAttribute('fullscreen')) {
|
|
19099
|
+
// Trap focus in the overlay
|
|
19100
|
+
this.focusDateElement();
|
|
19101
|
+
} else {
|
|
19102
|
+
this.__focusInput();
|
|
19103
|
+
}
|
|
18506
19104
|
}
|
|
18507
19105
|
break;
|
|
18508
19106
|
}
|
|
18509
19107
|
}
|
|
18510
19108
|
|
|
18511
19109
|
__onTodayButtonKeyDown(event) {
|
|
18512
|
-
if (this.hasAttribute('fullscreen')) {
|
|
18513
|
-
// Do not prevent closing on Esc
|
|
18514
|
-
if (event.key !== 'Escape') {
|
|
18515
|
-
event.stopPropagation();
|
|
18516
|
-
}
|
|
18517
|
-
return;
|
|
18518
|
-
}
|
|
18519
|
-
|
|
18520
19110
|
if (event.key === 'Tab') {
|
|
18521
19111
|
this._onTabKeyDown(event, 'today');
|
|
18522
19112
|
}
|
|
18523
19113
|
}
|
|
18524
19114
|
|
|
18525
19115
|
__onCancelButtonKeyDown(event) {
|
|
18526
|
-
if (this.hasAttribute('fullscreen')) {
|
|
18527
|
-
// Do not prevent closing on Esc
|
|
18528
|
-
if (event.key !== 'Escape') {
|
|
18529
|
-
event.stopPropagation();
|
|
18530
|
-
}
|
|
18531
|
-
return;
|
|
18532
|
-
}
|
|
18533
|
-
|
|
18534
19116
|
if (event.key === 'Tab') {
|
|
18535
19117
|
this._onTabKeyDown(event, 'cancel');
|
|
18536
19118
|
}
|
|
@@ -18559,15 +19141,29 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18559
19141
|
if (!keepMonth) {
|
|
18560
19142
|
this._focusedMonthDate = dateToFocus.getDate();
|
|
18561
19143
|
}
|
|
18562
|
-
await this.focusDateElement();
|
|
19144
|
+
await this.focusDateElement(false);
|
|
18563
19145
|
}
|
|
18564
19146
|
|
|
18565
|
-
async focusDateElement() {
|
|
19147
|
+
async focusDateElement(reveal = true) {
|
|
18566
19148
|
this.__pendingDateFocus = this.focusedDate;
|
|
18567
19149
|
|
|
18568
|
-
|
|
18569
|
-
|
|
18570
|
-
|
|
19150
|
+
// Wait for `vaadin-month-calendar` elements to be rendered
|
|
19151
|
+
if (!this.calendars.length) {
|
|
19152
|
+
await new Promise((resolve) => {
|
|
19153
|
+
setTimeout(resolve);
|
|
19154
|
+
});
|
|
19155
|
+
}
|
|
19156
|
+
|
|
19157
|
+
// Reveal focused date unless it has been just set,
|
|
19158
|
+
// which triggers `revealDate()` in the observer.
|
|
19159
|
+
if (reveal) {
|
|
19160
|
+
this.revealDate(this.focusedDate);
|
|
19161
|
+
}
|
|
19162
|
+
|
|
19163
|
+
if (this._revealPromise) {
|
|
19164
|
+
// Wait for focused date to be scrolled into view.
|
|
19165
|
+
await this._revealPromise;
|
|
19166
|
+
}
|
|
18571
19167
|
|
|
18572
19168
|
this.__tryFocusDate();
|
|
18573
19169
|
}
|
|
@@ -18665,10 +19261,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
18665
19261
|
todayMidnight.setDate(today.getDate());
|
|
18666
19262
|
return this._dateAllowed(todayMidnight, min, max);
|
|
18667
19263
|
}
|
|
18668
|
-
|
|
18669
|
-
_stopPropagation(e) {
|
|
18670
|
-
e.stopPropagation();
|
|
18671
|
-
}
|
|
18672
19264
|
}
|
|
18673
19265
|
|
|
18674
19266
|
customElements.define(DatePickerOverlayContent.is, DatePickerOverlayContent);
|
|
@@ -18799,277 +19391,105 @@ const DelegateFocusMixin = dedupingMixin(
|
|
|
18799
19391
|
* @param {HTMLElement} element
|
|
18800
19392
|
* @protected
|
|
18801
19393
|
*/
|
|
18802
|
-
_addFocusListeners(element) {
|
|
18803
|
-
element.addEventListener('blur', this._boundOnBlur);
|
|
18804
|
-
element.addEventListener('focus', this._boundOnFocus);
|
|
18805
|
-
}
|
|
18806
|
-
|
|
18807
|
-
/**
|
|
18808
|
-
* @param {HTMLElement} element
|
|
18809
|
-
* @protected
|
|
18810
|
-
*/
|
|
18811
|
-
_removeFocusListeners(element) {
|
|
18812
|
-
element.removeEventListener('blur', this._boundOnBlur);
|
|
18813
|
-
element.removeEventListener('focus', this._boundOnFocus);
|
|
18814
|
-
}
|
|
18815
|
-
|
|
18816
|
-
/**
|
|
18817
|
-
* Focus event does not bubble, so we dispatch it manually
|
|
18818
|
-
* on the host element to support adding focus listeners
|
|
18819
|
-
* when the focusable element is placed in light DOM.
|
|
18820
|
-
* @param {FocusEvent} event
|
|
18821
|
-
* @protected
|
|
18822
|
-
*/
|
|
18823
|
-
_onFocus(event) {
|
|
18824
|
-
event.stopPropagation();
|
|
18825
|
-
this.dispatchEvent(new Event('focus'));
|
|
18826
|
-
}
|
|
18827
|
-
|
|
18828
|
-
/**
|
|
18829
|
-
* Blur event does not bubble, so we dispatch it manually
|
|
18830
|
-
* on the host element to support adding blur listeners
|
|
18831
|
-
* when the focusable element is placed in light DOM.
|
|
18832
|
-
* @param {FocusEvent} event
|
|
18833
|
-
* @protected
|
|
18834
|
-
*/
|
|
18835
|
-
_onBlur(event) {
|
|
18836
|
-
event.stopPropagation();
|
|
18837
|
-
this.dispatchEvent(new Event('blur'));
|
|
18838
|
-
}
|
|
18839
|
-
|
|
18840
|
-
/**
|
|
18841
|
-
* @param {Event} event
|
|
18842
|
-
* @return {boolean}
|
|
18843
|
-
* @protected
|
|
18844
|
-
* @override
|
|
18845
|
-
*/
|
|
18846
|
-
_shouldSetFocus(event) {
|
|
18847
|
-
return event.target === this.focusElement;
|
|
18848
|
-
}
|
|
18849
|
-
|
|
18850
|
-
/**
|
|
18851
|
-
* @param {boolean} disabled
|
|
18852
|
-
* @param {boolean} oldDisabled
|
|
18853
|
-
* @protected
|
|
18854
|
-
* @override
|
|
18855
|
-
*/
|
|
18856
|
-
_disabledChanged(disabled, oldDisabled) {
|
|
18857
|
-
super._disabledChanged(disabled, oldDisabled);
|
|
18858
|
-
|
|
18859
|
-
if (this.focusElement) {
|
|
18860
|
-
this.focusElement.disabled = disabled;
|
|
18861
|
-
}
|
|
18862
|
-
|
|
18863
|
-
if (disabled) {
|
|
18864
|
-
this.blur();
|
|
18865
|
-
}
|
|
18866
|
-
}
|
|
18867
|
-
|
|
18868
|
-
/**
|
|
18869
|
-
* Override an observer from `TabindexMixin`.
|
|
18870
|
-
* Do not call super to remove tabindex attribute
|
|
18871
|
-
* from the host after it has been forwarded.
|
|
18872
|
-
* @param {string} tabindex
|
|
18873
|
-
* @protected
|
|
18874
|
-
* @override
|
|
18875
|
-
*/
|
|
18876
|
-
_tabindexChanged(tabindex) {
|
|
18877
|
-
this.__forwardTabIndex(tabindex);
|
|
18878
|
-
}
|
|
18879
|
-
|
|
18880
|
-
/** @private */
|
|
18881
|
-
__forwardTabIndex(tabindex) {
|
|
18882
|
-
if (tabindex !== undefined && this.focusElement) {
|
|
18883
|
-
this.focusElement.tabIndex = tabindex;
|
|
18884
|
-
|
|
18885
|
-
// Preserve tabindex="-1" on the host element
|
|
18886
|
-
if (tabindex !== -1) {
|
|
18887
|
-
this.tabindex = undefined;
|
|
18888
|
-
}
|
|
18889
|
-
}
|
|
18890
|
-
|
|
18891
|
-
if (this.disabled && tabindex) {
|
|
18892
|
-
// If tabindex attribute was changed while component was disabled
|
|
18893
|
-
if (tabindex !== -1) {
|
|
18894
|
-
this._lastTabIndex = tabindex;
|
|
18895
|
-
}
|
|
18896
|
-
this.tabindex = undefined;
|
|
18897
|
-
}
|
|
18898
|
-
}
|
|
18899
|
-
},
|
|
18900
|
-
);
|
|
18901
|
-
|
|
18902
|
-
/**
|
|
18903
|
-
* @license
|
|
18904
|
-
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
18905
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
18906
|
-
*/
|
|
18907
|
-
|
|
18908
|
-
/**
|
|
18909
|
-
* A controller for providing content to slot element and observing changes.
|
|
18910
|
-
*/
|
|
18911
|
-
class SlotController extends EventTarget {
|
|
18912
|
-
/**
|
|
18913
|
-
* Ensure that every instance has unique ID.
|
|
18914
|
-
*
|
|
18915
|
-
* @param {string} slotName
|
|
18916
|
-
* @param {HTMLElement} host
|
|
18917
|
-
* @return {string}
|
|
18918
|
-
* @protected
|
|
18919
|
-
*/
|
|
18920
|
-
static generateId(slotName, host) {
|
|
18921
|
-
const prefix = slotName || 'default';
|
|
18922
|
-
|
|
18923
|
-
// Support dash-case slot names e.g. "error-message"
|
|
18924
|
-
const field = `${dashToCamelCase(prefix)}Id`;
|
|
18925
|
-
|
|
18926
|
-
// Maintain the unique ID counter for a given prefix.
|
|
18927
|
-
this[field] = 1 + this[field] || 0;
|
|
18928
|
-
|
|
18929
|
-
return `${prefix}-${host.localName}-${this[field]}`;
|
|
18930
|
-
}
|
|
18931
|
-
|
|
18932
|
-
constructor(host, slotName, slotFactory, slotInitializer) {
|
|
18933
|
-
super();
|
|
18934
|
-
|
|
18935
|
-
this.host = host;
|
|
18936
|
-
this.slotName = slotName;
|
|
18937
|
-
this.slotFactory = slotFactory;
|
|
18938
|
-
this.slotInitializer = slotInitializer;
|
|
18939
|
-
this.defaultId = SlotController.generateId(slotName, host);
|
|
18940
|
-
}
|
|
18941
|
-
|
|
18942
|
-
hostConnected() {
|
|
18943
|
-
if (!this.initialized) {
|
|
18944
|
-
let node = this.getSlotChild();
|
|
18945
|
-
|
|
18946
|
-
if (!node) {
|
|
18947
|
-
node = this.attachDefaultNode();
|
|
18948
|
-
} else {
|
|
18949
|
-
this.node = node;
|
|
18950
|
-
this.initCustomNode(node);
|
|
18951
|
-
}
|
|
18952
|
-
|
|
18953
|
-
this.initNode(node);
|
|
18954
|
-
|
|
18955
|
-
// TODO: Consider making this behavior opt-in to improve performance.
|
|
18956
|
-
this.observe();
|
|
18957
|
-
|
|
18958
|
-
this.initialized = true;
|
|
18959
|
-
}
|
|
18960
|
-
}
|
|
18961
|
-
|
|
18962
|
-
/**
|
|
18963
|
-
* Create and attach default node using the slot factory.
|
|
18964
|
-
* @return {Node | undefined}
|
|
18965
|
-
* @protected
|
|
18966
|
-
*/
|
|
18967
|
-
attachDefaultNode() {
|
|
18968
|
-
const { host, slotName, slotFactory } = this;
|
|
18969
|
-
|
|
18970
|
-
// Check if the node was created previously and if so, reuse it.
|
|
18971
|
-
let node = this.defaultNode;
|
|
18972
|
-
|
|
18973
|
-
// Slot factory is optional, some slots don't have default content.
|
|
18974
|
-
if (!node && slotFactory) {
|
|
18975
|
-
node = slotFactory(host);
|
|
18976
|
-
if (node instanceof Element) {
|
|
18977
|
-
if (slotName !== '') {
|
|
18978
|
-
node.setAttribute('slot', slotName);
|
|
18979
|
-
}
|
|
18980
|
-
this.node = node;
|
|
18981
|
-
this.defaultNode = node;
|
|
18982
|
-
}
|
|
18983
|
-
}
|
|
18984
|
-
|
|
18985
|
-
if (node) {
|
|
18986
|
-
host.appendChild(node);
|
|
18987
|
-
}
|
|
18988
|
-
|
|
18989
|
-
return node;
|
|
18990
|
-
}
|
|
18991
|
-
|
|
18992
|
-
/**
|
|
18993
|
-
* Return a reference to the node managed by the controller.
|
|
18994
|
-
* @return {Node}
|
|
18995
|
-
*/
|
|
18996
|
-
getSlotChild() {
|
|
18997
|
-
const { slotName } = this;
|
|
18998
|
-
return Array.from(this.host.childNodes).find((node) => {
|
|
18999
|
-
// Either an element (any slot) or a text node (only un-named slot).
|
|
19000
|
-
return (
|
|
19001
|
-
(node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) ||
|
|
19002
|
-
(node.nodeType === Node.TEXT_NODE && node.textContent.trim() && slotName === '')
|
|
19003
|
-
);
|
|
19004
|
-
});
|
|
19005
|
-
}
|
|
19006
|
-
|
|
19007
|
-
/**
|
|
19008
|
-
* @param {Node} node
|
|
19009
|
-
* @protected
|
|
19010
|
-
*/
|
|
19011
|
-
initNode(node) {
|
|
19012
|
-
const { slotInitializer } = this;
|
|
19013
|
-
// Don't try to bind `this` to initializer (normally it's arrow function).
|
|
19014
|
-
// Instead, pass the host as a first argument to access component's state.
|
|
19015
|
-
if (slotInitializer) {
|
|
19016
|
-
slotInitializer(this.host, node);
|
|
19017
|
-
}
|
|
19018
|
-
}
|
|
19019
|
-
|
|
19020
|
-
/**
|
|
19021
|
-
* Override to initialize the newly added custom node.
|
|
19022
|
-
*
|
|
19023
|
-
* @param {Node} _node
|
|
19024
|
-
* @protected
|
|
19025
|
-
*/
|
|
19026
|
-
initCustomNode(_node) {}
|
|
19394
|
+
_addFocusListeners(element) {
|
|
19395
|
+
element.addEventListener('blur', this._boundOnBlur);
|
|
19396
|
+
element.addEventListener('focus', this._boundOnFocus);
|
|
19397
|
+
}
|
|
19027
19398
|
|
|
19028
|
-
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
19032
|
-
|
|
19033
|
-
|
|
19034
|
-
|
|
19399
|
+
/**
|
|
19400
|
+
* @param {HTMLElement} element
|
|
19401
|
+
* @protected
|
|
19402
|
+
*/
|
|
19403
|
+
_removeFocusListeners(element) {
|
|
19404
|
+
element.removeEventListener('blur', this._boundOnBlur);
|
|
19405
|
+
element.removeEventListener('focus', this._boundOnFocus);
|
|
19406
|
+
}
|
|
19035
19407
|
|
|
19036
|
-
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19042
|
-
|
|
19043
|
-
|
|
19408
|
+
/**
|
|
19409
|
+
* Focus event does not bubble, so we dispatch it manually
|
|
19410
|
+
* on the host element to support adding focus listeners
|
|
19411
|
+
* when the focusable element is placed in light DOM.
|
|
19412
|
+
* @param {FocusEvent} event
|
|
19413
|
+
* @protected
|
|
19414
|
+
*/
|
|
19415
|
+
_onFocus(event) {
|
|
19416
|
+
event.stopPropagation();
|
|
19417
|
+
this.dispatchEvent(new Event('focus'));
|
|
19418
|
+
}
|
|
19044
19419
|
|
|
19045
|
-
|
|
19046
|
-
|
|
19047
|
-
|
|
19048
|
-
|
|
19420
|
+
/**
|
|
19421
|
+
* Blur event does not bubble, so we dispatch it manually
|
|
19422
|
+
* on the host element to support adding blur listeners
|
|
19423
|
+
* when the focusable element is placed in light DOM.
|
|
19424
|
+
* @param {FocusEvent} event
|
|
19425
|
+
* @protected
|
|
19426
|
+
*/
|
|
19427
|
+
_onBlur(event) {
|
|
19428
|
+
event.stopPropagation();
|
|
19429
|
+
this.dispatchEvent(new Event('blur'));
|
|
19430
|
+
}
|
|
19049
19431
|
|
|
19050
|
-
|
|
19051
|
-
|
|
19052
|
-
|
|
19053
|
-
|
|
19432
|
+
/**
|
|
19433
|
+
* @param {Event} event
|
|
19434
|
+
* @return {boolean}
|
|
19435
|
+
* @protected
|
|
19436
|
+
* @override
|
|
19437
|
+
*/
|
|
19438
|
+
_shouldSetFocus(event) {
|
|
19439
|
+
return event.target === this.focusElement;
|
|
19054
19440
|
}
|
|
19055
19441
|
|
|
19056
|
-
|
|
19057
|
-
|
|
19058
|
-
|
|
19059
|
-
|
|
19442
|
+
/**
|
|
19443
|
+
* @param {boolean} disabled
|
|
19444
|
+
* @param {boolean} oldDisabled
|
|
19445
|
+
* @protected
|
|
19446
|
+
* @override
|
|
19447
|
+
*/
|
|
19448
|
+
_disabledChanged(disabled, oldDisabled) {
|
|
19449
|
+
super._disabledChanged(disabled, oldDisabled);
|
|
19450
|
+
|
|
19451
|
+
if (this.focusElement) {
|
|
19452
|
+
this.focusElement.disabled = disabled;
|
|
19060
19453
|
}
|
|
19061
19454
|
|
|
19062
|
-
|
|
19455
|
+
if (disabled) {
|
|
19456
|
+
this.blur();
|
|
19457
|
+
}
|
|
19458
|
+
}
|
|
19063
19459
|
|
|
19064
|
-
|
|
19065
|
-
|
|
19460
|
+
/**
|
|
19461
|
+
* Override an observer from `TabindexMixin`.
|
|
19462
|
+
* Do not call super to remove tabindex attribute
|
|
19463
|
+
* from the host after it has been forwarded.
|
|
19464
|
+
* @param {string} tabindex
|
|
19465
|
+
* @protected
|
|
19466
|
+
* @override
|
|
19467
|
+
*/
|
|
19468
|
+
_tabindexChanged(tabindex) {
|
|
19469
|
+
this.__forwardTabIndex(tabindex);
|
|
19470
|
+
}
|
|
19066
19471
|
|
|
19067
|
-
|
|
19472
|
+
/** @private */
|
|
19473
|
+
__forwardTabIndex(tabindex) {
|
|
19474
|
+
if (tabindex !== undefined && this.focusElement) {
|
|
19475
|
+
this.focusElement.tabIndex = tabindex;
|
|
19476
|
+
|
|
19477
|
+
// Preserve tabindex="-1" on the host element
|
|
19478
|
+
if (tabindex !== -1) {
|
|
19479
|
+
this.tabindex = undefined;
|
|
19480
|
+
}
|
|
19481
|
+
}
|
|
19482
|
+
|
|
19483
|
+
if (this.disabled && tabindex) {
|
|
19484
|
+
// If tabindex attribute was changed while component was disabled
|
|
19485
|
+
if (tabindex !== -1) {
|
|
19486
|
+
this._lastTabIndex = tabindex;
|
|
19487
|
+
}
|
|
19488
|
+
this.tabindex = undefined;
|
|
19068
19489
|
}
|
|
19069
19490
|
}
|
|
19070
|
-
}
|
|
19071
|
-
|
|
19072
|
-
}
|
|
19491
|
+
},
|
|
19492
|
+
);
|
|
19073
19493
|
|
|
19074
19494
|
/**
|
|
19075
19495
|
* @license
|
|
@@ -19091,6 +19511,7 @@ class ErrorController extends SlotController {
|
|
|
19091
19511
|
|
|
19092
19512
|
this.__updateHasError();
|
|
19093
19513
|
},
|
|
19514
|
+
true,
|
|
19094
19515
|
);
|
|
19095
19516
|
}
|
|
19096
19517
|
|
|
@@ -19126,7 +19547,7 @@ class ErrorController extends SlotController {
|
|
|
19126
19547
|
}
|
|
19127
19548
|
|
|
19128
19549
|
/**
|
|
19129
|
-
* Override to initialize the newly added custom
|
|
19550
|
+
* Override to initialize the newly added custom error message.
|
|
19130
19551
|
*
|
|
19131
19552
|
* @param {Node} errorNode
|
|
19132
19553
|
* @protected
|
|
@@ -19144,7 +19565,7 @@ class ErrorController extends SlotController {
|
|
|
19144
19565
|
}
|
|
19145
19566
|
|
|
19146
19567
|
/**
|
|
19147
|
-
* Override to cleanup
|
|
19568
|
+
* Override to cleanup error message node when it's removed.
|
|
19148
19569
|
*
|
|
19149
19570
|
* @param {Node} node
|
|
19150
19571
|
* @protected
|
|
@@ -19157,7 +19578,7 @@ class ErrorController extends SlotController {
|
|
|
19157
19578
|
if (!errorNode && node !== this.defaultNode) {
|
|
19158
19579
|
errorNode = this.attachDefaultNode();
|
|
19159
19580
|
|
|
19160
|
-
// Run initializer to update default
|
|
19581
|
+
// Run initializer to update default error message ID.
|
|
19161
19582
|
this.initNode(errorNode);
|
|
19162
19583
|
}
|
|
19163
19584
|
|
|
@@ -19205,63 +19626,6 @@ class ErrorController extends SlotController {
|
|
|
19205
19626
|
}
|
|
19206
19627
|
}
|
|
19207
19628
|
|
|
19208
|
-
/**
|
|
19209
|
-
* @license
|
|
19210
|
-
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
19211
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
19212
|
-
*/
|
|
19213
|
-
|
|
19214
|
-
/**
|
|
19215
|
-
* @param {string} value
|
|
19216
|
-
* @return {Set<string>}
|
|
19217
|
-
*/
|
|
19218
|
-
function deserializeAttributeValue(value) {
|
|
19219
|
-
if (!value) {
|
|
19220
|
-
return new Set();
|
|
19221
|
-
}
|
|
19222
|
-
|
|
19223
|
-
return new Set(value.split(' '));
|
|
19224
|
-
}
|
|
19225
|
-
|
|
19226
|
-
/**
|
|
19227
|
-
* @param {Set<string>} values
|
|
19228
|
-
* @return {string}
|
|
19229
|
-
*/
|
|
19230
|
-
function serializeAttributeValue(values) {
|
|
19231
|
-
return [...values].join(' ');
|
|
19232
|
-
}
|
|
19233
|
-
|
|
19234
|
-
/**
|
|
19235
|
-
* Adds a value to an attribute containing space-delimited values.
|
|
19236
|
-
*
|
|
19237
|
-
* @param {HTMLElement} element
|
|
19238
|
-
* @param {string} attr
|
|
19239
|
-
* @param {string} value
|
|
19240
|
-
*/
|
|
19241
|
-
function addValueToAttribute(element, attr, value) {
|
|
19242
|
-
const values = deserializeAttributeValue(element.getAttribute(attr));
|
|
19243
|
-
values.add(value);
|
|
19244
|
-
element.setAttribute(attr, serializeAttributeValue(values));
|
|
19245
|
-
}
|
|
19246
|
-
|
|
19247
|
-
/**
|
|
19248
|
-
* Removes a value from an attribute containing space-delimited values.
|
|
19249
|
-
* If the value is the last one, the whole attribute is removed.
|
|
19250
|
-
*
|
|
19251
|
-
* @param {HTMLElement} element
|
|
19252
|
-
* @param {string} attr
|
|
19253
|
-
* @param {string} value
|
|
19254
|
-
*/
|
|
19255
|
-
function removeValueFromAttribute(element, attr, value) {
|
|
19256
|
-
const values = deserializeAttributeValue(element.getAttribute(attr));
|
|
19257
|
-
values.delete(value);
|
|
19258
|
-
if (values.size === 0) {
|
|
19259
|
-
element.removeAttribute(attr);
|
|
19260
|
-
return;
|
|
19261
|
-
}
|
|
19262
|
-
element.setAttribute(attr, serializeAttributeValue(values));
|
|
19263
|
-
}
|
|
19264
|
-
|
|
19265
19629
|
/**
|
|
19266
19630
|
* @license
|
|
19267
19631
|
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
@@ -19436,7 +19800,7 @@ class FieldAriaController {
|
|
|
19436
19800
|
|
|
19437
19801
|
/**
|
|
19438
19802
|
* @license
|
|
19439
|
-
* Copyright (c) 2021 Vaadin Ltd.
|
|
19803
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
19440
19804
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
19441
19805
|
*/
|
|
19442
19806
|
|
|
@@ -19446,7 +19810,7 @@ class FieldAriaController {
|
|
|
19446
19810
|
class HelperController extends SlotController {
|
|
19447
19811
|
constructor(host) {
|
|
19448
19812
|
// Do not provide slot factory, as only create helper lazily.
|
|
19449
|
-
super(host, 'helper');
|
|
19813
|
+
super(host, 'helper', null, null, true);
|
|
19450
19814
|
}
|
|
19451
19815
|
|
|
19452
19816
|
get helperId() {
|
|
@@ -19517,7 +19881,11 @@ class HelperController extends SlotController {
|
|
|
19517
19881
|
return false;
|
|
19518
19882
|
}
|
|
19519
19883
|
|
|
19520
|
-
return
|
|
19884
|
+
return (
|
|
19885
|
+
helperNode.children.length > 0 ||
|
|
19886
|
+
(helperNode.nodeType === Node.ELEMENT_NODE && customElements.get(helperNode.localName)) ||
|
|
19887
|
+
this.__isNotEmpty(helperNode.textContent)
|
|
19888
|
+
);
|
|
19521
19889
|
}
|
|
19522
19890
|
|
|
19523
19891
|
/**
|
|
@@ -19643,6 +20011,7 @@ class LabelController extends SlotController {
|
|
|
19643
20011
|
|
|
19644
20012
|
this.__observeLabel(node);
|
|
19645
20013
|
},
|
|
20014
|
+
true,
|
|
19646
20015
|
);
|
|
19647
20016
|
}
|
|
19648
20017
|
|
|
@@ -19817,7 +20186,7 @@ class LabelController extends SlotController {
|
|
|
19817
20186
|
* A mixin to provide label via corresponding property or named slot.
|
|
19818
20187
|
*
|
|
19819
20188
|
* @polymerMixin
|
|
19820
|
-
* @mixes
|
|
20189
|
+
* @mixes ControllerMixin
|
|
19821
20190
|
*/
|
|
19822
20191
|
const LabelMixin = dedupingMixin(
|
|
19823
20192
|
(superclass) =>
|
|
@@ -19849,6 +20218,12 @@ const LabelMixin = dedupingMixin(
|
|
|
19849
20218
|
super();
|
|
19850
20219
|
|
|
19851
20220
|
this._labelController = new LabelController(this);
|
|
20221
|
+
}
|
|
20222
|
+
|
|
20223
|
+
/** @protected */
|
|
20224
|
+
ready() {
|
|
20225
|
+
super.ready();
|
|
20226
|
+
|
|
19852
20227
|
this.addController(this._labelController);
|
|
19853
20228
|
}
|
|
19854
20229
|
|
|
@@ -19896,12 +20271,17 @@ const ValidateMixin = dedupingMixin(
|
|
|
19896
20271
|
}
|
|
19897
20272
|
|
|
19898
20273
|
/**
|
|
19899
|
-
*
|
|
20274
|
+
* Validates the field and sets the `invalid` property based on the result.
|
|
20275
|
+
*
|
|
20276
|
+
* The method fires a `validated` event with the result of the validation.
|
|
19900
20277
|
*
|
|
19901
20278
|
* @return {boolean} True if the value is valid.
|
|
19902
20279
|
*/
|
|
19903
20280
|
validate() {
|
|
19904
|
-
|
|
20281
|
+
const isValid = this.checkValidity();
|
|
20282
|
+
this._setInvalid(!isValid);
|
|
20283
|
+
this.dispatchEvent(new CustomEvent('validated', { detail: { valid: isValid } }));
|
|
20284
|
+
return isValid;
|
|
19905
20285
|
}
|
|
19906
20286
|
|
|
19907
20287
|
/**
|
|
@@ -19912,6 +20292,35 @@ const ValidateMixin = dedupingMixin(
|
|
|
19912
20292
|
checkValidity() {
|
|
19913
20293
|
return !this.required || !!this.value;
|
|
19914
20294
|
}
|
|
20295
|
+
|
|
20296
|
+
/**
|
|
20297
|
+
* @param {boolean} invalid
|
|
20298
|
+
* @protected
|
|
20299
|
+
*/
|
|
20300
|
+
_setInvalid(invalid) {
|
|
20301
|
+
if (this._shouldSetInvalid(invalid)) {
|
|
20302
|
+
this.invalid = invalid;
|
|
20303
|
+
}
|
|
20304
|
+
}
|
|
20305
|
+
|
|
20306
|
+
/**
|
|
20307
|
+
* Override this method to define whether the given `invalid` state should be set.
|
|
20308
|
+
*
|
|
20309
|
+
* @param {boolean} _invalid
|
|
20310
|
+
* @return {boolean}
|
|
20311
|
+
* @protected
|
|
20312
|
+
*/
|
|
20313
|
+
_shouldSetInvalid(_invalid) {
|
|
20314
|
+
return true;
|
|
20315
|
+
}
|
|
20316
|
+
|
|
20317
|
+
/**
|
|
20318
|
+
* Fired whenever the field is validated.
|
|
20319
|
+
*
|
|
20320
|
+
* @event validated
|
|
20321
|
+
* @param {Object} detail
|
|
20322
|
+
* @param {boolean} detail.valid the result of the validation.
|
|
20323
|
+
*/
|
|
19915
20324
|
},
|
|
19916
20325
|
);
|
|
19917
20326
|
|
|
@@ -20000,10 +20409,6 @@ const FieldMixin = (superclass) =>
|
|
|
20000
20409
|
this._helperController = new HelperController(this);
|
|
20001
20410
|
this._errorController = new ErrorController(this);
|
|
20002
20411
|
|
|
20003
|
-
this.addController(this._fieldAriaController);
|
|
20004
|
-
this.addController(this._helperController);
|
|
20005
|
-
this.addController(this._errorController);
|
|
20006
|
-
|
|
20007
20412
|
this._labelController.addEventListener('label-changed', (event) => {
|
|
20008
20413
|
const { hasLabel, node } = event.detail;
|
|
20009
20414
|
this.__labelChanged(hasLabel, node);
|
|
@@ -20015,6 +20420,15 @@ const FieldMixin = (superclass) =>
|
|
|
20015
20420
|
});
|
|
20016
20421
|
}
|
|
20017
20422
|
|
|
20423
|
+
/** @protected */
|
|
20424
|
+
ready() {
|
|
20425
|
+
super.ready();
|
|
20426
|
+
|
|
20427
|
+
this.addController(this._fieldAriaController);
|
|
20428
|
+
this.addController(this._helperController);
|
|
20429
|
+
this.addController(this._errorController);
|
|
20430
|
+
}
|
|
20431
|
+
|
|
20018
20432
|
/** @private */
|
|
20019
20433
|
__helperChanged(hasHelper, helperNode) {
|
|
20020
20434
|
if (hasHelper) {
|
|
@@ -20070,7 +20484,7 @@ const FieldMixin = (superclass) =>
|
|
|
20070
20484
|
}
|
|
20071
20485
|
|
|
20072
20486
|
/**
|
|
20073
|
-
* @param {boolean}
|
|
20487
|
+
* @param {boolean} invalid
|
|
20074
20488
|
* @protected
|
|
20075
20489
|
*/
|
|
20076
20490
|
_invalidChanged(invalid) {
|
|
@@ -20270,13 +20684,23 @@ const InputMixin = dedupingMixin(
|
|
|
20270
20684
|
observer: '_valueChanged',
|
|
20271
20685
|
notify: true,
|
|
20272
20686
|
},
|
|
20687
|
+
|
|
20688
|
+
/**
|
|
20689
|
+
* When true, the input element has a non-empty value entered by the user.
|
|
20690
|
+
* @protected
|
|
20691
|
+
*/
|
|
20692
|
+
_hasInputValue: {
|
|
20693
|
+
type: Boolean,
|
|
20694
|
+
value: false,
|
|
20695
|
+
observer: '_hasInputValueChanged',
|
|
20696
|
+
},
|
|
20273
20697
|
};
|
|
20274
20698
|
}
|
|
20275
20699
|
|
|
20276
20700
|
constructor() {
|
|
20277
20701
|
super();
|
|
20278
20702
|
|
|
20279
|
-
this._boundOnInput = this.
|
|
20703
|
+
this._boundOnInput = this.__onInput.bind(this);
|
|
20280
20704
|
this._boundOnChange = this._onChange.bind(this);
|
|
20281
20705
|
}
|
|
20282
20706
|
|
|
@@ -20291,6 +20715,7 @@ const InputMixin = dedupingMixin(
|
|
|
20291
20715
|
* Add event listeners to the input element instance.
|
|
20292
20716
|
* Override this method to add custom listeners.
|
|
20293
20717
|
* @param {!HTMLElement} input
|
|
20718
|
+
* @protected
|
|
20294
20719
|
*/
|
|
20295
20720
|
_addInputListeners(input) {
|
|
20296
20721
|
input.addEventListener('input', this._boundOnInput);
|
|
@@ -20300,6 +20725,7 @@ const InputMixin = dedupingMixin(
|
|
|
20300
20725
|
/**
|
|
20301
20726
|
* Remove event listeners from the input element instance.
|
|
20302
20727
|
* @param {!HTMLElement} input
|
|
20728
|
+
* @protected
|
|
20303
20729
|
*/
|
|
20304
20730
|
_removeInputListeners(input) {
|
|
20305
20731
|
input.removeEventListener('input', this._boundOnInput);
|
|
@@ -20313,7 +20739,6 @@ const InputMixin = dedupingMixin(
|
|
|
20313
20739
|
* for example to skip this in certain conditions.
|
|
20314
20740
|
* @param {string} value
|
|
20315
20741
|
* @protected
|
|
20316
|
-
* @override
|
|
20317
20742
|
*/
|
|
20318
20743
|
_forwardInputValue(value) {
|
|
20319
20744
|
// Value might be set before an input element is initialized.
|
|
@@ -20330,7 +20755,11 @@ const InputMixin = dedupingMixin(
|
|
|
20330
20755
|
}
|
|
20331
20756
|
}
|
|
20332
20757
|
|
|
20333
|
-
/**
|
|
20758
|
+
/**
|
|
20759
|
+
* @param {HTMLElement | undefined} input
|
|
20760
|
+
* @param {HTMLElement | undefined} oldInput
|
|
20761
|
+
* @protected
|
|
20762
|
+
*/
|
|
20334
20763
|
_inputElementChanged(input, oldInput) {
|
|
20335
20764
|
if (input) {
|
|
20336
20765
|
this._addInputListeners(input);
|
|
@@ -20339,17 +20768,43 @@ const InputMixin = dedupingMixin(
|
|
|
20339
20768
|
}
|
|
20340
20769
|
}
|
|
20341
20770
|
|
|
20771
|
+
/**
|
|
20772
|
+
* Observer to notify about the change of private property.
|
|
20773
|
+
*
|
|
20774
|
+
* @private
|
|
20775
|
+
*/
|
|
20776
|
+
_hasInputValueChanged(hasValue, oldHasValue) {
|
|
20777
|
+
if (hasValue || oldHasValue) {
|
|
20778
|
+
this.dispatchEvent(new CustomEvent('has-input-value-changed'));
|
|
20779
|
+
}
|
|
20780
|
+
}
|
|
20781
|
+
|
|
20782
|
+
/**
|
|
20783
|
+
* An input event listener used to update `_hasInputValue` property.
|
|
20784
|
+
* Do not override this method.
|
|
20785
|
+
*
|
|
20786
|
+
* @param {Event} event
|
|
20787
|
+
* @private
|
|
20788
|
+
*/
|
|
20789
|
+
__onInput(event) {
|
|
20790
|
+
this._setHasInputValue(event);
|
|
20791
|
+
this._onInput(event);
|
|
20792
|
+
}
|
|
20793
|
+
|
|
20342
20794
|
/**
|
|
20343
20795
|
* An input event listener used to update the field value.
|
|
20344
|
-
*
|
|
20345
|
-
* @param {Event}
|
|
20796
|
+
*
|
|
20797
|
+
* @param {Event} event
|
|
20346
20798
|
* @protected
|
|
20347
|
-
* @override
|
|
20348
20799
|
*/
|
|
20349
20800
|
_onInput(event) {
|
|
20801
|
+
// In the case a custom web component is passed as `inputElement`,
|
|
20802
|
+
// the actual native input element, on which the event occurred,
|
|
20803
|
+
// can be inside shadow trees.
|
|
20804
|
+
const target = event.composedPath()[0];
|
|
20350
20805
|
// Ignore fake input events e.g. used by clear button.
|
|
20351
20806
|
this.__userInput = event.isTrusted;
|
|
20352
|
-
this.value =
|
|
20807
|
+
this.value = target.value;
|
|
20353
20808
|
this.__userInput = false;
|
|
20354
20809
|
}
|
|
20355
20810
|
|
|
@@ -20358,12 +20813,12 @@ const InputMixin = dedupingMixin(
|
|
|
20358
20813
|
* Override this method with an actual implementation.
|
|
20359
20814
|
* @param {Event} _event
|
|
20360
20815
|
* @protected
|
|
20361
|
-
* @override
|
|
20362
20816
|
*/
|
|
20363
20817
|
_onChange(_event) {}
|
|
20364
20818
|
|
|
20365
20819
|
/**
|
|
20366
20820
|
* Toggle the has-value attribute based on the value property.
|
|
20821
|
+
*
|
|
20367
20822
|
* @param {boolean} hasValue
|
|
20368
20823
|
* @protected
|
|
20369
20824
|
*/
|
|
@@ -20376,10 +20831,9 @@ const InputMixin = dedupingMixin(
|
|
|
20376
20831
|
* @param {string | undefined} newVal
|
|
20377
20832
|
* @param {string | undefined} oldVal
|
|
20378
20833
|
* @protected
|
|
20379
|
-
* @override
|
|
20380
20834
|
*/
|
|
20381
20835
|
_valueChanged(newVal, oldVal) {
|
|
20382
|
-
this._toggleHasValue(
|
|
20836
|
+
this._toggleHasValue(this._hasValue);
|
|
20383
20837
|
|
|
20384
20838
|
// Setting initial value to empty string, do nothing.
|
|
20385
20839
|
if (newVal === '' && oldVal === undefined) {
|
|
@@ -20394,6 +20848,30 @@ const InputMixin = dedupingMixin(
|
|
|
20394
20848
|
// Setting a value programmatically, sync it to input element.
|
|
20395
20849
|
this._forwardInputValue(newVal);
|
|
20396
20850
|
}
|
|
20851
|
+
|
|
20852
|
+
/**
|
|
20853
|
+
* Indicates whether the value is different from the default one.
|
|
20854
|
+
* Override if the `value` property has a type other than `string`.
|
|
20855
|
+
*
|
|
20856
|
+
* @protected
|
|
20857
|
+
*/
|
|
20858
|
+
get _hasValue() {
|
|
20859
|
+
return this.value != null && this.value !== '';
|
|
20860
|
+
}
|
|
20861
|
+
|
|
20862
|
+
/**
|
|
20863
|
+
* Sets the `_hasInputValue` property based on the `input` event.
|
|
20864
|
+
*
|
|
20865
|
+
* @param {InputEvent} event
|
|
20866
|
+
* @protected
|
|
20867
|
+
*/
|
|
20868
|
+
_setHasInputValue(event) {
|
|
20869
|
+
// In the case a custom web component is passed as `inputElement`,
|
|
20870
|
+
// the actual native input element, on which the event occurred,
|
|
20871
|
+
// can be inside shadow trees.
|
|
20872
|
+
const target = event.composedPath()[0];
|
|
20873
|
+
this._hasInputValue = target.value.length > 0;
|
|
20874
|
+
}
|
|
20397
20875
|
},
|
|
20398
20876
|
);
|
|
20399
20877
|
|
|
@@ -20465,26 +20943,32 @@ const InputConstraintsMixin = dedupingMixin(
|
|
|
20465
20943
|
_createConstraintsObserver() {
|
|
20466
20944
|
// This complex observer needs to be added dynamically instead of using `static get observers()`
|
|
20467
20945
|
// to make it possible to tweak this behavior in classes that apply this mixin.
|
|
20468
|
-
this._createMethodObserver(`_constraintsChanged(${this.constructor.constraints.join(', ')})`);
|
|
20946
|
+
this._createMethodObserver(`_constraintsChanged(stateTarget, ${this.constructor.constraints.join(', ')})`);
|
|
20469
20947
|
}
|
|
20470
20948
|
|
|
20471
20949
|
/**
|
|
20472
20950
|
* Override this method to implement custom validation constraints.
|
|
20951
|
+
* @param {HTMLElement | undefined} stateTarget
|
|
20473
20952
|
* @param {unknown[]} constraints
|
|
20474
20953
|
* @protected
|
|
20475
20954
|
*/
|
|
20476
|
-
_constraintsChanged(...constraints) {
|
|
20477
|
-
//
|
|
20478
|
-
//
|
|
20479
|
-
if (!
|
|
20955
|
+
_constraintsChanged(stateTarget, ...constraints) {
|
|
20956
|
+
// The input element's validity cannot be determined until
|
|
20957
|
+
// all the necessary constraint attributes aren't set on it.
|
|
20958
|
+
if (!stateTarget) {
|
|
20480
20959
|
return;
|
|
20481
20960
|
}
|
|
20482
20961
|
|
|
20483
|
-
|
|
20962
|
+
const hasConstraints = this._hasValidConstraints(constraints);
|
|
20963
|
+
const isLastConstraintRemoved = this.__previousHasConstraints && !hasConstraints;
|
|
20964
|
+
|
|
20965
|
+
if ((this._hasValue || this.invalid) && hasConstraints) {
|
|
20484
20966
|
this.validate();
|
|
20485
|
-
} else {
|
|
20486
|
-
this.
|
|
20967
|
+
} else if (isLastConstraintRemoved) {
|
|
20968
|
+
this._setInvalid(false);
|
|
20487
20969
|
}
|
|
20970
|
+
|
|
20971
|
+
this.__previousHasConstraints = hasConstraints;
|
|
20488
20972
|
}
|
|
20489
20973
|
|
|
20490
20974
|
/**
|
|
@@ -20519,6 +21003,82 @@ const InputConstraintsMixin = dedupingMixin(
|
|
|
20519
21003
|
},
|
|
20520
21004
|
);
|
|
20521
21005
|
|
|
21006
|
+
/**
|
|
21007
|
+
* @license
|
|
21008
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
21009
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
21010
|
+
*/
|
|
21011
|
+
|
|
21012
|
+
const stylesMap = new WeakMap();
|
|
21013
|
+
|
|
21014
|
+
/**
|
|
21015
|
+
* Get all the styles inserted into root.
|
|
21016
|
+
* @param {DocumentOrShadowRoot} root
|
|
21017
|
+
* @return {Set<string>}
|
|
21018
|
+
*/
|
|
21019
|
+
function getRootStyles(root) {
|
|
21020
|
+
if (!stylesMap.has(root)) {
|
|
21021
|
+
stylesMap.set(root, new Set());
|
|
21022
|
+
}
|
|
21023
|
+
|
|
21024
|
+
return stylesMap.get(root);
|
|
21025
|
+
}
|
|
21026
|
+
|
|
21027
|
+
/**
|
|
21028
|
+
* Insert styles into the root.
|
|
21029
|
+
* @param {string} styles
|
|
21030
|
+
* @param {DocumentOrShadowRoot} root
|
|
21031
|
+
*/
|
|
21032
|
+
function insertStyles(styles, root) {
|
|
21033
|
+
const style = document.createElement('style');
|
|
21034
|
+
style.textContent = styles;
|
|
21035
|
+
|
|
21036
|
+
if (root === document) {
|
|
21037
|
+
document.head.appendChild(style);
|
|
21038
|
+
} else {
|
|
21039
|
+
root.insertBefore(style, root.firstChild);
|
|
21040
|
+
}
|
|
21041
|
+
}
|
|
21042
|
+
|
|
21043
|
+
/**
|
|
21044
|
+
* Mixin to insert styles into the outer scope to handle slotted components.
|
|
21045
|
+
* This is useful e.g. to hide native `<input type="number">` controls.
|
|
21046
|
+
*
|
|
21047
|
+
* @polymerMixin
|
|
21048
|
+
*/
|
|
21049
|
+
const SlotStylesMixin = dedupingMixin(
|
|
21050
|
+
(superclass) =>
|
|
21051
|
+
class SlotStylesMixinClass extends superclass {
|
|
21052
|
+
/**
|
|
21053
|
+
* List of styles to insert into root.
|
|
21054
|
+
* @protected
|
|
21055
|
+
*/
|
|
21056
|
+
get slotStyles() {
|
|
21057
|
+
return {};
|
|
21058
|
+
}
|
|
21059
|
+
|
|
21060
|
+
/** @protected */
|
|
21061
|
+
connectedCallback() {
|
|
21062
|
+
super.connectedCallback();
|
|
21063
|
+
|
|
21064
|
+
this.__applySlotStyles();
|
|
21065
|
+
}
|
|
21066
|
+
|
|
21067
|
+
/** @private */
|
|
21068
|
+
__applySlotStyles() {
|
|
21069
|
+
const root = this.getRootNode();
|
|
21070
|
+
const rootStyles = getRootStyles(root);
|
|
21071
|
+
|
|
21072
|
+
this.slotStyles.forEach((styles) => {
|
|
21073
|
+
if (!rootStyles.has(styles)) {
|
|
21074
|
+
insertStyles(styles, root);
|
|
21075
|
+
rootStyles.add(styles);
|
|
21076
|
+
}
|
|
21077
|
+
});
|
|
21078
|
+
}
|
|
21079
|
+
},
|
|
21080
|
+
);
|
|
21081
|
+
|
|
20522
21082
|
/**
|
|
20523
21083
|
* @license
|
|
20524
21084
|
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
@@ -20533,13 +21093,31 @@ const InputConstraintsMixin = dedupingMixin(
|
|
|
20533
21093
|
* @mixes FieldMixin
|
|
20534
21094
|
* @mixes InputConstraintsMixin
|
|
20535
21095
|
* @mixes KeyboardMixin
|
|
21096
|
+
* @mixes SlotStylesMixin
|
|
20536
21097
|
*/
|
|
20537
21098
|
const InputControlMixin = (superclass) =>
|
|
20538
|
-
class InputControlMixinClass extends
|
|
20539
|
-
InputConstraintsMixin(FieldMixin(KeyboardMixin(superclass))),
|
|
21099
|
+
class InputControlMixinClass extends SlotStylesMixin(
|
|
21100
|
+
DelegateFocusMixin(InputConstraintsMixin(FieldMixin(KeyboardMixin(superclass)))),
|
|
20540
21101
|
) {
|
|
20541
21102
|
static get properties() {
|
|
20542
21103
|
return {
|
|
21104
|
+
/**
|
|
21105
|
+
* A pattern matched against individual characters the user inputs.
|
|
21106
|
+
*
|
|
21107
|
+
* When set, the field will prevent:
|
|
21108
|
+
* - `keydown` events if the entered key doesn't match `/^allowedCharPattern$/`
|
|
21109
|
+
* - `paste` events if the pasted text doesn't match `/^allowedCharPattern*$/`
|
|
21110
|
+
* - `drop` events if the dropped text doesn't match `/^allowedCharPattern*$/`
|
|
21111
|
+
*
|
|
21112
|
+
* For example, to allow entering only numbers and minus signs, use:
|
|
21113
|
+
* `allowedCharPattern = "[\\d-]"`
|
|
21114
|
+
* @attr {string} allowed-char-pattern
|
|
21115
|
+
*/
|
|
21116
|
+
allowedCharPattern: {
|
|
21117
|
+
type: String,
|
|
21118
|
+
observer: '_allowedCharPatternChanged',
|
|
21119
|
+
},
|
|
21120
|
+
|
|
20543
21121
|
/**
|
|
20544
21122
|
* If true, the input text gets fully selected when the field is focused using click or touch / tap.
|
|
20545
21123
|
*/
|
|
@@ -20597,6 +21175,14 @@ const InputControlMixin = (superclass) =>
|
|
|
20597
21175
|
return [...super.delegateAttrs, 'name', 'type', 'placeholder', 'readonly', 'invalid', 'title'];
|
|
20598
21176
|
}
|
|
20599
21177
|
|
|
21178
|
+
constructor() {
|
|
21179
|
+
super();
|
|
21180
|
+
|
|
21181
|
+
this._boundOnPaste = this._onPaste.bind(this);
|
|
21182
|
+
this._boundOnDrop = this._onDrop.bind(this);
|
|
21183
|
+
this._boundOnBeforeInput = this._onBeforeInput.bind(this);
|
|
21184
|
+
}
|
|
21185
|
+
|
|
20600
21186
|
/**
|
|
20601
21187
|
* Any element extending this mixin is required to implement this getter.
|
|
20602
21188
|
* It returns the reference to the clear button element.
|
|
@@ -20608,6 +21194,19 @@ const InputControlMixin = (superclass) =>
|
|
|
20608
21194
|
return null;
|
|
20609
21195
|
}
|
|
20610
21196
|
|
|
21197
|
+
/** @protected */
|
|
21198
|
+
get slotStyles() {
|
|
21199
|
+
// Needed for Safari, where ::slotted(...)::placeholder does not work
|
|
21200
|
+
return [
|
|
21201
|
+
`
|
|
21202
|
+
:is(input[slot='input'], textarea[slot='textarea'])::placeholder {
|
|
21203
|
+
font: inherit;
|
|
21204
|
+
color: inherit;
|
|
21205
|
+
}
|
|
21206
|
+
`,
|
|
21207
|
+
];
|
|
21208
|
+
}
|
|
21209
|
+
|
|
20611
21210
|
/** @protected */
|
|
20612
21211
|
ready() {
|
|
20613
21212
|
super.ready();
|
|
@@ -20689,6 +21288,115 @@ const InputControlMixin = (superclass) =>
|
|
|
20689
21288
|
this.inputElement.dispatchEvent(new Event('change', { bubbles: true }));
|
|
20690
21289
|
}
|
|
20691
21290
|
|
|
21291
|
+
/**
|
|
21292
|
+
* Override a method from `InputMixin`.
|
|
21293
|
+
* @param {!HTMLElement} input
|
|
21294
|
+
* @protected
|
|
21295
|
+
* @override
|
|
21296
|
+
*/
|
|
21297
|
+
_addInputListeners(input) {
|
|
21298
|
+
super._addInputListeners(input);
|
|
21299
|
+
|
|
21300
|
+
input.addEventListener('paste', this._boundOnPaste);
|
|
21301
|
+
input.addEventListener('drop', this._boundOnDrop);
|
|
21302
|
+
input.addEventListener('beforeinput', this._boundOnBeforeInput);
|
|
21303
|
+
}
|
|
21304
|
+
|
|
21305
|
+
/**
|
|
21306
|
+
* Override a method from `InputMixin`.
|
|
21307
|
+
* @param {!HTMLElement} input
|
|
21308
|
+
* @protected
|
|
21309
|
+
* @override
|
|
21310
|
+
*/
|
|
21311
|
+
_removeInputListeners(input) {
|
|
21312
|
+
super._removeInputListeners(input);
|
|
21313
|
+
|
|
21314
|
+
input.removeEventListener('paste', this._boundOnPaste);
|
|
21315
|
+
input.removeEventListener('drop', this._boundOnDrop);
|
|
21316
|
+
input.removeEventListener('beforeinput', this._boundOnBeforeInput);
|
|
21317
|
+
}
|
|
21318
|
+
|
|
21319
|
+
/**
|
|
21320
|
+
* Override an event listener from `KeyboardMixin`.
|
|
21321
|
+
* @param {!KeyboardEvent} event
|
|
21322
|
+
* @protected
|
|
21323
|
+
* @override
|
|
21324
|
+
*/
|
|
21325
|
+
_onKeyDown(event) {
|
|
21326
|
+
super._onKeyDown(event);
|
|
21327
|
+
|
|
21328
|
+
if (this.allowedCharPattern && !this.__shouldAcceptKey(event)) {
|
|
21329
|
+
event.preventDefault();
|
|
21330
|
+
this._markInputPrevented();
|
|
21331
|
+
}
|
|
21332
|
+
}
|
|
21333
|
+
|
|
21334
|
+
/** @protected */
|
|
21335
|
+
_markInputPrevented() {
|
|
21336
|
+
// Add input-prevented attribute for 200ms
|
|
21337
|
+
this.setAttribute('input-prevented', '');
|
|
21338
|
+
this._preventInputDebouncer = Debouncer$1.debounce(this._preventInputDebouncer, timeOut.after(200), () => {
|
|
21339
|
+
this.removeAttribute('input-prevented');
|
|
21340
|
+
});
|
|
21341
|
+
}
|
|
21342
|
+
|
|
21343
|
+
/** @private */
|
|
21344
|
+
__shouldAcceptKey(event) {
|
|
21345
|
+
return (
|
|
21346
|
+
event.metaKey ||
|
|
21347
|
+
event.ctrlKey ||
|
|
21348
|
+
!event.key || // Allow typing anything if event.key is not supported
|
|
21349
|
+
event.key.length !== 1 || // Allow "Backspace", "ArrowLeft" etc.
|
|
21350
|
+
this.__allowedCharRegExp.test(event.key)
|
|
21351
|
+
);
|
|
21352
|
+
}
|
|
21353
|
+
|
|
21354
|
+
/** @private */
|
|
21355
|
+
_onPaste(e) {
|
|
21356
|
+
if (this.allowedCharPattern) {
|
|
21357
|
+
const pastedText = e.clipboardData.getData('text');
|
|
21358
|
+
if (!this.__allowedTextRegExp.test(pastedText)) {
|
|
21359
|
+
e.preventDefault();
|
|
21360
|
+
this._markInputPrevented();
|
|
21361
|
+
}
|
|
21362
|
+
}
|
|
21363
|
+
}
|
|
21364
|
+
|
|
21365
|
+
/** @private */
|
|
21366
|
+
_onDrop(e) {
|
|
21367
|
+
if (this.allowedCharPattern) {
|
|
21368
|
+
const draggedText = e.dataTransfer.getData('text');
|
|
21369
|
+
if (!this.__allowedTextRegExp.test(draggedText)) {
|
|
21370
|
+
e.preventDefault();
|
|
21371
|
+
this._markInputPrevented();
|
|
21372
|
+
}
|
|
21373
|
+
}
|
|
21374
|
+
}
|
|
21375
|
+
|
|
21376
|
+
/** @private */
|
|
21377
|
+
_onBeforeInput(e) {
|
|
21378
|
+
// The `beforeinput` event covers all the cases for `allowedCharPattern`: keyboard, pasting and dropping,
|
|
21379
|
+
// but it is still experimental technology so we can't rely on it. It's used here just as an additional check,
|
|
21380
|
+
// because it seems to be the only way to detect and prevent specific keys on mobile devices.
|
|
21381
|
+
// See https://github.com/vaadin/vaadin-text-field/issues/429
|
|
21382
|
+
if (this.allowedCharPattern && e.data && !this.__allowedTextRegExp.test(e.data)) {
|
|
21383
|
+
e.preventDefault();
|
|
21384
|
+
this._markInputPrevented();
|
|
21385
|
+
}
|
|
21386
|
+
}
|
|
21387
|
+
|
|
21388
|
+
/** @private */
|
|
21389
|
+
_allowedCharPatternChanged(charPattern) {
|
|
21390
|
+
if (charPattern) {
|
|
21391
|
+
try {
|
|
21392
|
+
this.__allowedCharRegExp = new RegExp(`^${charPattern}$`);
|
|
21393
|
+
this.__allowedTextRegExp = new RegExp(`^${charPattern}*$`);
|
|
21394
|
+
} catch (e) {
|
|
21395
|
+
console.error(e);
|
|
21396
|
+
}
|
|
21397
|
+
}
|
|
21398
|
+
}
|
|
21399
|
+
|
|
20692
21400
|
/**
|
|
20693
21401
|
* Fired when the user commits a value change.
|
|
20694
21402
|
*
|
|
@@ -20727,14 +21435,13 @@ class InputController extends SlotController {
|
|
|
20727
21435
|
}
|
|
20728
21436
|
|
|
20729
21437
|
// Ensure every instance has unique ID
|
|
20730
|
-
|
|
20731
|
-
host._inputId = `${host.localName}-${uniqueId}`;
|
|
20732
|
-
node.id = host._inputId;
|
|
21438
|
+
node.id = this.defaultId;
|
|
20733
21439
|
|
|
20734
21440
|
if (typeof callback === 'function') {
|
|
20735
21441
|
callback(node);
|
|
20736
21442
|
}
|
|
20737
21443
|
},
|
|
21444
|
+
true,
|
|
20738
21445
|
);
|
|
20739
21446
|
}
|
|
20740
21447
|
}
|
|
@@ -20916,7 +21623,9 @@ class VirtualKeyboardController {
|
|
|
20916
21623
|
* @param {function(new:HTMLElement)} subclass
|
|
20917
21624
|
*/
|
|
20918
21625
|
const DatePickerMixin = (subclass) =>
|
|
20919
|
-
class VaadinDatePickerMixin extends ControllerMixin(
|
|
21626
|
+
class VaadinDatePickerMixin extends ControllerMixin(
|
|
21627
|
+
DelegateFocusMixin(InputConstraintsMixin(KeyboardMixin(subclass))),
|
|
21628
|
+
) {
|
|
20920
21629
|
static get properties() {
|
|
20921
21630
|
return {
|
|
20922
21631
|
/**
|
|
@@ -20945,7 +21654,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
20945
21654
|
*/
|
|
20946
21655
|
value: {
|
|
20947
21656
|
type: String,
|
|
20948
|
-
observer: '_valueChanged',
|
|
20949
21657
|
notify: true,
|
|
20950
21658
|
value: '',
|
|
20951
21659
|
},
|
|
@@ -21001,13 +21709,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21001
21709
|
value: '(max-width: 420px), (max-height: 420px)',
|
|
21002
21710
|
},
|
|
21003
21711
|
|
|
21004
|
-
/**
|
|
21005
|
-
* An array of ancestor elements whose -webkit-overflow-scrolling is forced from value
|
|
21006
|
-
* 'touch' to value 'auto' in order to prevent them from clipping the dropdown. iOS only.
|
|
21007
|
-
* @private
|
|
21008
|
-
*/
|
|
21009
|
-
_touchPrevented: Array,
|
|
21010
|
-
|
|
21011
21712
|
/**
|
|
21012
21713
|
* The object used to localize this component.
|
|
21013
21714
|
* To change the default localization, replace the entire
|
|
@@ -21063,6 +21764,16 @@ const DatePickerMixin = (subclass) =>
|
|
|
21063
21764
|
* // Translation of the Cancel button text.
|
|
21064
21765
|
* cancel: 'Cancel',
|
|
21065
21766
|
*
|
|
21767
|
+
* // Used for adjusting the year value when parsing dates with short years.
|
|
21768
|
+
* // The year values between 0 and 99 are evaluated and adjusted.
|
|
21769
|
+
* // Example: for a referenceDate of 1970-10-30;
|
|
21770
|
+
* // dateToBeParsed: 40-10-30, result: 1940-10-30
|
|
21771
|
+
* // dateToBeParsed: 80-10-30, result: 1980-10-30
|
|
21772
|
+
* // dateToBeParsed: 10-10-30, result: 2010-10-30
|
|
21773
|
+
* // Supported date format: ISO 8601 `"YYYY-MM-DD"` (default)
|
|
21774
|
+
* // The default value is the current date.
|
|
21775
|
+
* referenceDate: '',
|
|
21776
|
+
*
|
|
21066
21777
|
* // A function to format given `Object` as
|
|
21067
21778
|
* // date string. Object is in the format `{ day: ..., month: ..., year: ... }`
|
|
21068
21779
|
* // Note: The argument month is 0-based. This means that January = 0 and December = 11.
|
|
@@ -21116,11 +21827,12 @@ const DatePickerMixin = (subclass) =>
|
|
|
21116
21827
|
calendar: 'Calendar',
|
|
21117
21828
|
today: 'Today',
|
|
21118
21829
|
cancel: 'Cancel',
|
|
21119
|
-
|
|
21830
|
+
referenceDate: '',
|
|
21831
|
+
formatDate(d) {
|
|
21120
21832
|
const yearStr = String(d.year).replace(/\d+/, (y) => '0000'.substr(y.length) + y);
|
|
21121
21833
|
return [d.month + 1, d.day, yearStr].join('/');
|
|
21122
21834
|
},
|
|
21123
|
-
parseDate
|
|
21835
|
+
parseDate(text) {
|
|
21124
21836
|
const parts = text.split('/');
|
|
21125
21837
|
const today = new Date();
|
|
21126
21838
|
let date,
|
|
@@ -21128,12 +21840,13 @@ const DatePickerMixin = (subclass) =>
|
|
|
21128
21840
|
year = today.getFullYear();
|
|
21129
21841
|
|
|
21130
21842
|
if (parts.length === 3) {
|
|
21843
|
+
month = parseInt(parts[0]) - 1;
|
|
21844
|
+
date = parseInt(parts[1]);
|
|
21131
21845
|
year = parseInt(parts[2]);
|
|
21132
21846
|
if (parts[2].length < 3 && year >= 0) {
|
|
21133
|
-
|
|
21847
|
+
const usedReferenceDate = this.referenceDate ? parseDate(this.referenceDate) : new Date();
|
|
21848
|
+
year = getAdjustedYear(usedReferenceDate, year, month, date);
|
|
21134
21849
|
}
|
|
21135
|
-
month = parseInt(parts[0]) - 1;
|
|
21136
|
-
date = parseInt(parts[1]);
|
|
21137
21850
|
} else if (parts.length === 2) {
|
|
21138
21851
|
month = parseInt(parts[0]) - 1;
|
|
21139
21852
|
date = parseInt(parts[1]);
|
|
@@ -21163,7 +21876,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21163
21876
|
*/
|
|
21164
21877
|
min: {
|
|
21165
21878
|
type: String,
|
|
21166
|
-
observer: '_minChanged',
|
|
21167
21879
|
},
|
|
21168
21880
|
|
|
21169
21881
|
/**
|
|
@@ -21177,28 +21889,26 @@ const DatePickerMixin = (subclass) =>
|
|
|
21177
21889
|
*/
|
|
21178
21890
|
max: {
|
|
21179
21891
|
type: String,
|
|
21180
|
-
observer: '_maxChanged',
|
|
21181
21892
|
},
|
|
21182
21893
|
|
|
21183
21894
|
/**
|
|
21184
21895
|
* The earliest date that can be selected. All earlier dates will be disabled.
|
|
21185
|
-
* @type {Date |
|
|
21896
|
+
* @type {Date | undefined}
|
|
21186
21897
|
* @protected
|
|
21187
21898
|
*/
|
|
21188
21899
|
_minDate: {
|
|
21189
21900
|
type: Date,
|
|
21190
|
-
|
|
21191
|
-
value: '',
|
|
21901
|
+
computed: '__computeMinOrMaxDate(min)',
|
|
21192
21902
|
},
|
|
21193
21903
|
|
|
21194
21904
|
/**
|
|
21195
21905
|
* The latest date that can be selected. All later dates will be disabled.
|
|
21196
|
-
* @type {Date |
|
|
21906
|
+
* @type {Date | undefined}
|
|
21197
21907
|
* @protected
|
|
21198
21908
|
*/
|
|
21199
21909
|
_maxDate: {
|
|
21200
21910
|
type: Date,
|
|
21201
|
-
|
|
21911
|
+
computed: '__computeMinOrMaxDate(max)',
|
|
21202
21912
|
},
|
|
21203
21913
|
|
|
21204
21914
|
/** @private */
|
|
@@ -21213,12 +21923,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21213
21923
|
value: isIOS,
|
|
21214
21924
|
},
|
|
21215
21925
|
|
|
21216
|
-
/** @private */
|
|
21217
|
-
_webkitOverflowScroll: {
|
|
21218
|
-
type: Boolean,
|
|
21219
|
-
value: document.createElement('div').style.webkitOverflowScrolling === '',
|
|
21220
|
-
},
|
|
21221
|
-
|
|
21222
21926
|
/** @private */
|
|
21223
21927
|
_focusOverlayOnOpen: Boolean,
|
|
21224
21928
|
|
|
@@ -21234,6 +21938,10 @@ const DatePickerMixin = (subclass) =>
|
|
|
21234
21938
|
];
|
|
21235
21939
|
}
|
|
21236
21940
|
|
|
21941
|
+
static get constraints() {
|
|
21942
|
+
return [...super.constraints, 'min', 'max'];
|
|
21943
|
+
}
|
|
21944
|
+
|
|
21237
21945
|
/**
|
|
21238
21946
|
* Override a getter from `InputControlMixin` to make it optional
|
|
21239
21947
|
* and to prevent warning when a clear button is missing,
|
|
@@ -21294,18 +22002,13 @@ const DatePickerMixin = (subclass) =>
|
|
|
21294
22002
|
|
|
21295
22003
|
if (!this.opened) {
|
|
21296
22004
|
if (this.autoOpenDisabled) {
|
|
21297
|
-
|
|
21298
|
-
if (this._isValidDate(parsedDate)) {
|
|
21299
|
-
this._selectDate(parsedDate);
|
|
21300
|
-
}
|
|
22005
|
+
this._selectParsedOrFocusedDate();
|
|
21301
22006
|
}
|
|
21302
22007
|
|
|
21303
|
-
|
|
21304
|
-
|
|
22008
|
+
this.validate();
|
|
22009
|
+
|
|
22010
|
+
if (this._inputValue === '' && this.value !== '') {
|
|
21305
22011
|
this.value = '';
|
|
21306
|
-
this.__dispatchChange = false;
|
|
21307
|
-
} else {
|
|
21308
|
-
this.validate();
|
|
21309
22012
|
}
|
|
21310
22013
|
}
|
|
21311
22014
|
}
|
|
@@ -21374,14 +22077,19 @@ const DatePickerMixin = (subclass) =>
|
|
|
21374
22077
|
this.$.overlay.removeAttribute('disable-upgrade');
|
|
21375
22078
|
this._overlayInitialized = true;
|
|
21376
22079
|
|
|
21377
|
-
this.$.overlay.addEventListener('opened-changed', (e) =>
|
|
22080
|
+
this.$.overlay.addEventListener('opened-changed', (e) => {
|
|
22081
|
+
this.opened = e.detail.value;
|
|
22082
|
+
});
|
|
21378
22083
|
|
|
21379
22084
|
this.$.overlay.addEventListener('vaadin-overlay-escape-press', () => {
|
|
21380
22085
|
this._focusedDate = this._selectedDate;
|
|
21381
22086
|
this._close();
|
|
21382
22087
|
});
|
|
21383
22088
|
|
|
21384
|
-
this._overlayContent.addEventListener('close',
|
|
22089
|
+
this._overlayContent.addEventListener('close', () => {
|
|
22090
|
+
this._close();
|
|
22091
|
+
});
|
|
22092
|
+
|
|
21385
22093
|
this._overlayContent.addEventListener('focus-input', this._focusAndSelect.bind(this));
|
|
21386
22094
|
|
|
21387
22095
|
// User confirmed selected date by clicking the calendar.
|
|
@@ -21390,34 +22098,29 @@ const DatePickerMixin = (subclass) =>
|
|
|
21390
22098
|
|
|
21391
22099
|
this._selectDate(e.detail.date);
|
|
21392
22100
|
|
|
21393
|
-
this._close(
|
|
22101
|
+
this._close();
|
|
21394
22102
|
});
|
|
21395
22103
|
|
|
21396
|
-
// User confirmed selected date by pressing Enter or Today.
|
|
22104
|
+
// User confirmed selected date by pressing Enter, Space, or Today.
|
|
21397
22105
|
this._overlayContent.addEventListener('date-selected', (e) => {
|
|
21398
|
-
|
|
22106
|
+
// Reset if a date is deselected.
|
|
22107
|
+
this.__userConfirmedDate = !!e.detail.date;
|
|
21399
22108
|
|
|
21400
22109
|
this._selectDate(e.detail.date);
|
|
21401
22110
|
});
|
|
21402
22111
|
|
|
21403
|
-
//
|
|
22112
|
+
// Set focus-ring attribute when moving focus to the overlay
|
|
22113
|
+
// by pressing Tab or arrow key, after opening it on click.
|
|
21404
22114
|
this._overlayContent.addEventListener('focusin', () => {
|
|
21405
|
-
this.
|
|
22115
|
+
if (this._keyboardActive) {
|
|
22116
|
+
this._setFocused(true);
|
|
22117
|
+
}
|
|
21406
22118
|
});
|
|
21407
22119
|
|
|
21408
22120
|
this.addEventListener('mousedown', () => this.__bringToFront());
|
|
21409
22121
|
this.addEventListener('touchstart', () => this.__bringToFront());
|
|
21410
22122
|
}
|
|
21411
22123
|
|
|
21412
|
-
/**
|
|
21413
|
-
* Returns true if `value` is valid, and sets the `invalid` flag appropriately.
|
|
21414
|
-
*
|
|
21415
|
-
* @return {boolean} True if the value is valid and sets the `invalid` flag appropriately
|
|
21416
|
-
*/
|
|
21417
|
-
validate() {
|
|
21418
|
-
return !(this.invalid = !this.checkValidity());
|
|
21419
|
-
}
|
|
21420
|
-
|
|
21421
22124
|
/**
|
|
21422
22125
|
* Returns true if the current input value satisfies all constraints (if any)
|
|
21423
22126
|
*
|
|
@@ -21428,7 +22131,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21428
22131
|
checkValidity() {
|
|
21429
22132
|
const inputValid =
|
|
21430
22133
|
!this._inputValue ||
|
|
21431
|
-
(this._selectedDate && this._inputValue === this._getFormattedDate(this.i18n.formatDate, this._selectedDate));
|
|
22134
|
+
(!!this._selectedDate && this._inputValue === this._getFormattedDate(this.i18n.formatDate, this._selectedDate));
|
|
21432
22135
|
const minMaxValid = !this._selectedDate || dateAllowed(this._selectedDate, this._minDate, this._maxDate);
|
|
21433
22136
|
|
|
21434
22137
|
let inputValidity = true;
|
|
@@ -21444,6 +22147,51 @@ const DatePickerMixin = (subclass) =>
|
|
|
21444
22147
|
return inputValid && minMaxValid && inputValidity;
|
|
21445
22148
|
}
|
|
21446
22149
|
|
|
22150
|
+
/**
|
|
22151
|
+
* Override method inherited from `FocusMixin`
|
|
22152
|
+
* to not call `_setFocused(true)` when focus
|
|
22153
|
+
* is restored after closing overlay on click,
|
|
22154
|
+
* and to avoid removing `focus-ring` attribute.
|
|
22155
|
+
*
|
|
22156
|
+
* @param {!FocusEvent} _event
|
|
22157
|
+
* @return {boolean}
|
|
22158
|
+
* @protected
|
|
22159
|
+
* @override
|
|
22160
|
+
*/
|
|
22161
|
+
_shouldSetFocus(_event) {
|
|
22162
|
+
return !this._shouldKeepFocusRing;
|
|
22163
|
+
}
|
|
22164
|
+
|
|
22165
|
+
/**
|
|
22166
|
+
* Override method inherited from `FocusMixin`
|
|
22167
|
+
* to prevent removing the `focused` attribute:
|
|
22168
|
+
* - when moving focus to the overlay content,
|
|
22169
|
+
* - when closing on date click / outside click.
|
|
22170
|
+
*
|
|
22171
|
+
* @param {!FocusEvent} _event
|
|
22172
|
+
* @return {boolean}
|
|
22173
|
+
* @protected
|
|
22174
|
+
* @override
|
|
22175
|
+
*/
|
|
22176
|
+
_shouldRemoveFocus(_event) {
|
|
22177
|
+
return !this.opened;
|
|
22178
|
+
}
|
|
22179
|
+
|
|
22180
|
+
/**
|
|
22181
|
+
* Override method inherited from `FocusMixin`
|
|
22182
|
+
* to store the `focus-ring` state to restore
|
|
22183
|
+
* it later when closing on outside click.
|
|
22184
|
+
*
|
|
22185
|
+
* @param {boolean} focused
|
|
22186
|
+
* @protected
|
|
22187
|
+
* @override
|
|
22188
|
+
*/
|
|
22189
|
+
_setFocused(focused) {
|
|
22190
|
+
super._setFocused(focused);
|
|
22191
|
+
|
|
22192
|
+
this._shouldKeepFocusRing = focused && this._keyboardActive;
|
|
22193
|
+
}
|
|
22194
|
+
|
|
21447
22195
|
/**
|
|
21448
22196
|
* Select date on user interaction and set the flag
|
|
21449
22197
|
* to fire change event if necessary.
|
|
@@ -21463,10 +22211,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21463
22211
|
}
|
|
21464
22212
|
|
|
21465
22213
|
/** @private */
|
|
21466
|
-
_close(
|
|
21467
|
-
if (e) {
|
|
21468
|
-
e.stopPropagation();
|
|
21469
|
-
}
|
|
22214
|
+
_close() {
|
|
21470
22215
|
this._focus();
|
|
21471
22216
|
this.close();
|
|
21472
22217
|
}
|
|
@@ -21478,21 +22223,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21478
22223
|
});
|
|
21479
22224
|
}
|
|
21480
22225
|
|
|
21481
|
-
/** @private */
|
|
21482
|
-
_parseDate(str) {
|
|
21483
|
-
// Parsing with RegExp to ensure correct format
|
|
21484
|
-
const parts = /^([-+]\d{1}|\d{2,4}|[-+]\d{6})-(\d{1,2})-(\d{1,2})$/.exec(str);
|
|
21485
|
-
if (!parts) {
|
|
21486
|
-
return;
|
|
21487
|
-
}
|
|
21488
|
-
|
|
21489
|
-
const date = new Date(0, 0); // Wrong date (1900-01-01), but with midnight in local time
|
|
21490
|
-
date.setFullYear(parseInt(parts[1], 10));
|
|
21491
|
-
date.setMonth(parseInt(parts[2], 10) - 1);
|
|
21492
|
-
date.setDate(parseInt(parts[3], 10));
|
|
21493
|
-
return date;
|
|
21494
|
-
}
|
|
21495
|
-
|
|
21496
22226
|
/** @private */
|
|
21497
22227
|
// eslint-disable-next-line max-params
|
|
21498
22228
|
_isNoInput(inputElement, fullscreen, ios, i18n, opened, autoOpenDisabled) {
|
|
@@ -21595,48 +22325,47 @@ const DatePickerMixin = (subclass) =>
|
|
|
21595
22325
|
}
|
|
21596
22326
|
}
|
|
21597
22327
|
|
|
21598
|
-
/**
|
|
21599
|
-
|
|
21600
|
-
|
|
21601
|
-
|
|
21602
|
-
|
|
21603
|
-
|
|
22328
|
+
/**
|
|
22329
|
+
* Override the value observer from `InputMixin` to implement custom
|
|
22330
|
+
* handling of the `value` property. The date-picker doesn't forward
|
|
22331
|
+
* the value directly to the input like the default implementation of `InputMixin`.
|
|
22332
|
+
* Instead, it parses the value into a date, puts it in `_selectedDate` which
|
|
22333
|
+
* is then displayed in the input with respect to the specified date format.
|
|
22334
|
+
*
|
|
22335
|
+
* @param {string | undefined} value
|
|
22336
|
+
* @param {string | undefined} oldValue
|
|
22337
|
+
* @protected
|
|
22338
|
+
* @override
|
|
22339
|
+
*/
|
|
22340
|
+
_valueChanged(value, oldValue) {
|
|
22341
|
+
const newDate = parseDate(value);
|
|
21604
22342
|
|
|
21605
|
-
|
|
21606
|
-
|
|
22343
|
+
if (value && !newDate) {
|
|
22344
|
+
// The new value cannot be parsed, revert the old value.
|
|
21607
22345
|
this.value = oldValue;
|
|
21608
22346
|
return;
|
|
21609
22347
|
}
|
|
21610
|
-
if (!dateEquals(this[property], date)) {
|
|
21611
|
-
this[property] = date;
|
|
21612
|
-
if (this.value) {
|
|
21613
|
-
this.validate();
|
|
21614
|
-
}
|
|
21615
|
-
}
|
|
21616
|
-
}
|
|
21617
|
-
|
|
21618
|
-
/** @private */
|
|
21619
|
-
_valueChanged(value, oldValue) {
|
|
21620
|
-
this._handleDateChange('_selectedDate', value, oldValue);
|
|
21621
22348
|
|
|
21622
|
-
|
|
21623
|
-
|
|
22349
|
+
if (value) {
|
|
22350
|
+
if (!dateEquals(this._selectedDate, newDate)) {
|
|
22351
|
+
// Update the date instance only if the date has actually changed.
|
|
22352
|
+
this._selectedDate = newDate;
|
|
21624
22353
|
|
|
21625
|
-
|
|
21626
|
-
|
|
21627
|
-
|
|
21628
|
-
|
|
22354
|
+
if (oldValue !== undefined) {
|
|
22355
|
+
// Validate only if `value` changes after initialization.
|
|
22356
|
+
this.validate();
|
|
22357
|
+
}
|
|
22358
|
+
}
|
|
22359
|
+
} else {
|
|
22360
|
+
this._selectedDate = null;
|
|
22361
|
+
}
|
|
21629
22362
|
|
|
21630
|
-
|
|
21631
|
-
_maxChanged(value, oldValue) {
|
|
21632
|
-
this._handleDateChange('_maxDate', value, oldValue);
|
|
22363
|
+
this._toggleHasValue(this._hasValue);
|
|
21633
22364
|
}
|
|
21634
22365
|
|
|
21635
22366
|
/** @protected */
|
|
21636
22367
|
_onOverlayOpened() {
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
const parsedInitialPosition = this._parseDate(this.initialPosition);
|
|
22368
|
+
const parsedInitialPosition = parseDate(this.initialPosition);
|
|
21640
22369
|
|
|
21641
22370
|
const initialPosition =
|
|
21642
22371
|
this._selectedDate || this._overlayContent.initialPosition || parsedInitialPosition || new Date();
|
|
@@ -21655,10 +22384,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21655
22384
|
|
|
21656
22385
|
window.addEventListener('scroll', this._boundOnScroll, true);
|
|
21657
22386
|
|
|
21658
|
-
if (this._webkitOverflowScroll) {
|
|
21659
|
-
this._touchPrevented = this._preventWebkitOverflowScrollingTouch(this.parentElement);
|
|
21660
|
-
}
|
|
21661
|
-
|
|
21662
22387
|
if (this._focusOverlayOnOpen) {
|
|
21663
22388
|
this._overlayContent.focusDateElement();
|
|
21664
22389
|
this._focusOverlayOnOpen = false;
|
|
@@ -21672,25 +22397,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21672
22397
|
}
|
|
21673
22398
|
}
|
|
21674
22399
|
|
|
21675
|
-
// A hack needed for iOS to prevent dropdown from being clipped in an
|
|
21676
|
-
// ancestor container with -webkit-overflow-scrolling: touch;
|
|
21677
|
-
/** @private */
|
|
21678
|
-
_preventWebkitOverflowScrollingTouch(element) {
|
|
21679
|
-
const result = [];
|
|
21680
|
-
while (element) {
|
|
21681
|
-
if (window.getComputedStyle(element).webkitOverflowScrolling === 'touch') {
|
|
21682
|
-
const oldInlineValue = element.style.webkitOverflowScrolling;
|
|
21683
|
-
element.style.webkitOverflowScrolling = 'auto';
|
|
21684
|
-
result.push({
|
|
21685
|
-
element,
|
|
21686
|
-
oldInlineValue,
|
|
21687
|
-
});
|
|
21688
|
-
}
|
|
21689
|
-
element = element.parentElement;
|
|
21690
|
-
}
|
|
21691
|
-
return result;
|
|
21692
|
-
}
|
|
21693
|
-
|
|
21694
22400
|
/** @private */
|
|
21695
22401
|
_selectParsedOrFocusedDate() {
|
|
21696
22402
|
// Select the parsed input or focused date
|
|
@@ -21717,13 +22423,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21717
22423
|
_onOverlayClosed() {
|
|
21718
22424
|
window.removeEventListener('scroll', this._boundOnScroll, true);
|
|
21719
22425
|
|
|
21720
|
-
if (this._touchPrevented) {
|
|
21721
|
-
this._touchPrevented.forEach(
|
|
21722
|
-
(prevented) => (prevented.element.style.webkitOverflowScrolling = prevented.oldInlineValue),
|
|
21723
|
-
);
|
|
21724
|
-
this._touchPrevented = [];
|
|
21725
|
-
}
|
|
21726
|
-
|
|
21727
22426
|
// No need to select date on close if it was confirmed by the user.
|
|
21728
22427
|
if (this.__userConfirmedDate) {
|
|
21729
22428
|
this.__userConfirmedDate = false;
|
|
@@ -21739,11 +22438,6 @@ const DatePickerMixin = (subclass) =>
|
|
|
21739
22438
|
if (!this.value) {
|
|
21740
22439
|
this.validate();
|
|
21741
22440
|
}
|
|
21742
|
-
|
|
21743
|
-
// If the input isn't focused when overlay closes (fullscreen mode), clear focused state
|
|
21744
|
-
if (this.getRootNode().activeElement !== this.inputElement) {
|
|
21745
|
-
this._setFocused(false);
|
|
21746
|
-
}
|
|
21747
22441
|
}
|
|
21748
22442
|
|
|
21749
22443
|
/** @private */
|
|
@@ -21796,10 +22490,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21796
22490
|
_onChange(event) {
|
|
21797
22491
|
// For change event on the native <input> blur, after the input is cleared,
|
|
21798
22492
|
// we schedule change event to be dispatched on date-picker blur.
|
|
21799
|
-
if (
|
|
21800
|
-
this.inputElement.value === '' &&
|
|
21801
|
-
!(event.detail && event.detail.sourceEvent && event.detail.sourceEvent.__fromClearButton)
|
|
21802
|
-
) {
|
|
22493
|
+
if (this._inputValue === '') {
|
|
21803
22494
|
this.__dispatchChange = true;
|
|
21804
22495
|
}
|
|
21805
22496
|
|
|
@@ -21886,7 +22577,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21886
22577
|
if (e.shiftKey) {
|
|
21887
22578
|
this._overlayContent.focusCancel();
|
|
21888
22579
|
} else {
|
|
21889
|
-
this._overlayContent.
|
|
22580
|
+
this._overlayContent.focusDateElement();
|
|
21890
22581
|
}
|
|
21891
22582
|
}
|
|
21892
22583
|
break;
|
|
@@ -21901,21 +22592,15 @@ const DatePickerMixin = (subclass) =>
|
|
|
21901
22592
|
* @override
|
|
21902
22593
|
*/
|
|
21903
22594
|
_onEnter(_event) {
|
|
21904
|
-
const
|
|
21905
|
-
const isValidDate = this._isValidDate(parsedDate);
|
|
22595
|
+
const oldValue = this.value;
|
|
21906
22596
|
if (this.opened) {
|
|
21907
|
-
|
|
21908
|
-
this._selectDate(this._overlayContent.focusedDate);
|
|
21909
|
-
}
|
|
22597
|
+
// Closing will implicitly select parsed or focused date
|
|
21910
22598
|
this.close();
|
|
21911
|
-
} else if (!isValidDate && this.inputElement.value !== '') {
|
|
21912
|
-
this.validate();
|
|
21913
22599
|
} else {
|
|
21914
|
-
const oldValue = this.value;
|
|
21915
22600
|
this._selectParsedOrFocusedDate();
|
|
21916
|
-
|
|
21917
|
-
|
|
21918
|
-
|
|
22601
|
+
}
|
|
22602
|
+
if (oldValue === this.value) {
|
|
22603
|
+
this.validate();
|
|
21919
22604
|
}
|
|
21920
22605
|
}
|
|
21921
22606
|
|
|
@@ -21957,7 +22642,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21957
22642
|
/** @private */
|
|
21958
22643
|
_getParsedDate(inputValue = this._inputValue) {
|
|
21959
22644
|
const dateObject = this.i18n.parseDate && this.i18n.parseDate(inputValue);
|
|
21960
|
-
const parsedDate = dateObject &&
|
|
22645
|
+
const parsedDate = dateObject && parseDate(`${dateObject.year}-${dateObject.month + 1}-${dateObject.day}`);
|
|
21961
22646
|
return parsedDate;
|
|
21962
22647
|
}
|
|
21963
22648
|
|
|
@@ -21979,7 +22664,7 @@ const DatePickerMixin = (subclass) =>
|
|
|
21979
22664
|
|
|
21980
22665
|
/** @private */
|
|
21981
22666
|
_userInputValueChanged() {
|
|
21982
|
-
if (this.
|
|
22667
|
+
if (this._inputValue) {
|
|
21983
22668
|
const parsedDate = this._getParsedDate();
|
|
21984
22669
|
|
|
21985
22670
|
if (this._isValidDate(parsedDate)) {
|
|
@@ -21997,6 +22682,11 @@ const DatePickerMixin = (subclass) =>
|
|
|
21997
22682
|
return this.$.overlay.content.querySelector('#overlay-content');
|
|
21998
22683
|
}
|
|
21999
22684
|
|
|
22685
|
+
/** @private */
|
|
22686
|
+
__computeMinOrMaxDate(dateString) {
|
|
22687
|
+
return parseDate(dateString);
|
|
22688
|
+
}
|
|
22689
|
+
|
|
22000
22690
|
/**
|
|
22001
22691
|
* Fired when the user commits a value change.
|
|
22002
22692
|
*
|
|
@@ -22108,12 +22798,13 @@ registerStyles('vaadin-date-picker', [inputFieldShared, datePickerStyles], { mod
|
|
|
22108
22798
|
* Note: the `theme` attribute value set on `<vaadin-date-picker>` is
|
|
22109
22799
|
* propagated to the internal components listed above.
|
|
22110
22800
|
*
|
|
22111
|
-
* See [Styling Components](https://vaadin.com/docs/latest/
|
|
22801
|
+
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
|
|
22112
22802
|
*
|
|
22113
22803
|
* @fires {Event} change - Fired when the user commits a value change.
|
|
22114
22804
|
* @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
|
|
22115
22805
|
* @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
|
|
22116
22806
|
* @fires {CustomEvent} value-changed - Fired when the `value` property changes.
|
|
22807
|
+
* @fires {CustomEvent} validated - Fired whenever the field is validated.
|
|
22117
22808
|
*
|
|
22118
22809
|
* @extends HTMLElement
|
|
22119
22810
|
* @mixes ElementMixin
|
|
@@ -22167,7 +22858,7 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
|
|
|
22167
22858
|
fullscreen$="[[_fullscreen]]"
|
|
22168
22859
|
theme$="[[__getOverlayTheme(_theme, _overlayInitialized)]]"
|
|
22169
22860
|
on-vaadin-overlay-open="_onOverlayOpened"
|
|
22170
|
-
on-vaadin-overlay-
|
|
22861
|
+
on-vaadin-overlay-closing="_onOverlayClosed"
|
|
22171
22862
|
restore-focus-on-close
|
|
22172
22863
|
restore-focus-node="[[inputElement]]"
|
|
22173
22864
|
disable-upgrade
|
|
@@ -22188,6 +22879,8 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
|
|
|
22188
22879
|
></vaadin-date-picker-overlay-content>
|
|
22189
22880
|
</template>
|
|
22190
22881
|
</vaadin-date-picker-overlay>
|
|
22882
|
+
|
|
22883
|
+
<slot name="tooltip"></slot>
|
|
22191
22884
|
`;
|
|
22192
22885
|
}
|
|
22193
22886
|
|
|
@@ -22214,6 +22907,11 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
|
|
|
22214
22907
|
);
|
|
22215
22908
|
this.addController(new LabelledInputController(this.inputElement, this._labelController));
|
|
22216
22909
|
|
|
22910
|
+
this._tooltipController = new TooltipController(this);
|
|
22911
|
+
this.addController(this._tooltipController);
|
|
22912
|
+
this._tooltipController.setPosition('top');
|
|
22913
|
+
this._tooltipController.setShouldShow((target) => !target.opened);
|
|
22914
|
+
|
|
22217
22915
|
const toggleButton = this.shadowRoot.querySelector('[part="toggle-button"]');
|
|
22218
22916
|
toggleButton.addEventListener('mousedown', (e) => e.preventDefault());
|
|
22219
22917
|
}
|
|
@@ -22227,11 +22925,6 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
|
|
|
22227
22925
|
|
|
22228
22926
|
/** @private */
|
|
22229
22927
|
_onVaadinOverlayClose(e) {
|
|
22230
|
-
if (this._openedWithFocusRing && this.hasAttribute('focused')) {
|
|
22231
|
-
this.setAttribute('focus-ring', '');
|
|
22232
|
-
} else if (!this.hasAttribute('focused')) {
|
|
22233
|
-
this.blur();
|
|
22234
|
-
}
|
|
22235
22928
|
if (e.detail.sourceEvent && e.detail.sourceEvent.composedPath().includes(this)) {
|
|
22236
22929
|
e.preventDefault();
|
|
22237
22930
|
}
|
|
@@ -22359,6 +23052,7 @@ const HelperFilters = class {
|
|
|
22359
23052
|
this.modalCloseEvent();
|
|
22360
23053
|
this.showClearButton = true;
|
|
22361
23054
|
this.filterSelectionHandler(this.filterData);
|
|
23055
|
+
console.log(this.showClearButton);
|
|
22362
23056
|
}
|
|
22363
23057
|
resetSearch() {
|
|
22364
23058
|
this.showClearButton = false;
|
|
@@ -22375,7 +23069,7 @@ const HelperFilters = class {
|
|
|
22375
23069
|
this.filterData.filterToCalendar = new Date(event.target.value).toISOString();
|
|
22376
23070
|
}
|
|
22377
23071
|
render() {
|
|
22378
|
-
return (index.h("div", { class: "HelperFilters", ref: el => this.stylingContainer = el }, index.h("div", { class: "FilterButtonsWrapper" }, index.h("button", { class: "FilterOpen", onClick: () => this.toggleFilterModal() }, translate$1('filterOpen', this.language)), (this.showClearButton || this.quickFiltersActive) ?
|
|
23072
|
+
return (index.h("div", { class: "HelperFilters", ref: el => this.stylingContainer = el }, index.h("div", { class: "FilterButtonsWrapper" }, index.h("button", { class: "FilterOpen", onClick: () => this.toggleFilterModal() }, translate$1('filterOpen', this.language)), console.log('in filter Open', this.showClearButton, this.quickFiltersActive), (this.showClearButton || this.quickFiltersActive) ?
|
|
22379
23073
|
index.h("button", { class: "FilterClear", onClick: () => this.resetSearch() }, translate$1('filterClear', this.language))
|
|
22380
23074
|
:
|
|
22381
23075
|
null), index.h("helper-modal", { "title-modal": "Filter Modal", visible: this.showFilterModal, "client-styling": this.clientStyling, "client-styling-url-content": this.clientStylingUrlContent }, index.h("div", { class: "FilterModalHeader" }, index.h("h3", { class: "FilterModalTitle" }, this.activateTicketSearch ? translate$1('filterModalTicketTitle', this.language) : translate$1('filterModalDrawTitle', this.language))), index.h("div", { class: "FilterModalBody" }, index.h("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) }), index.h("p", null, translate$1('filterOrDate', this.language)), index.h("div", { class: "FilterCalendarWrapper" }, index.h("vaadin-date-picker", { value: this.filterData.filterFromCalendar, onChange: (event) => this.handleFilterFrom(event), placeholder: translate$1('filterFromCalendar', this.language), class: "VaadinDatePicker" }), index.h("vaadin-date-picker", { value: this.filterData.filterToCalendar, onChange: (event) => this.handleFilterTo(event), placeholder: translate$1('filterToCalendar', this.language), class: "VaadinDatePicker" }))), index.h("div", { class: "FilterModalFooter" }, index.h("button", { class: "FilterModalButton", onClick: () => this.filterSearch() }, translate$1('filterModalButton', this.language))))));
|