@everymatrix/lottery-game-page 0.1.26 → 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.
Files changed (182) hide show
  1. package/dist/cjs/helper-accordion.cjs.entry.js +10 -2
  2. package/dist/cjs/helper-accordion.cjs.entry.js.map +1 -0
  3. package/dist/cjs/helper-filters_2.cjs.entry.js +1716 -1002
  4. package/dist/cjs/helper-filters_2.cjs.entry.js.map +1 -0
  5. package/dist/cjs/helper-modal.cjs.entry.js +2 -0
  6. package/dist/cjs/helper-modal.cjs.entry.js.map +1 -0
  7. package/dist/cjs/helper-pagination.cjs.entry.js +14 -0
  8. package/dist/cjs/helper-pagination.cjs.entry.js.map +1 -0
  9. package/dist/cjs/helper-tab.cjs.entry.js +2 -0
  10. package/dist/cjs/helper-tab.cjs.entry.js.map +1 -0
  11. package/dist/cjs/helper-tabs.cjs.entry.js +2 -0
  12. package/dist/cjs/helper-tabs.cjs.entry.js.map +1 -0
  13. package/dist/cjs/index-cd44e726.js +2 -0
  14. package/dist/cjs/index-cd44e726.js.map +1 -0
  15. package/dist/cjs/index.cjs.js +2 -0
  16. package/dist/cjs/index.cjs.js.map +1 -0
  17. package/dist/cjs/loader.cjs.js +3 -1
  18. package/dist/cjs/loader.cjs.js.map +1 -0
  19. package/dist/cjs/lottery-bullet_2.cjs.entry.js +13 -2
  20. package/dist/cjs/lottery-bullet_2.cjs.entry.js.map +1 -0
  21. package/dist/cjs/lottery-draw-results-history.cjs.entry.js +45 -16
  22. package/dist/cjs/lottery-draw-results-history.cjs.entry.js.map +1 -0
  23. package/dist/cjs/lottery-game-details.cjs.entry.js +2 -0
  24. package/dist/cjs/lottery-game-details.cjs.entry.js.map +1 -0
  25. package/dist/cjs/lottery-game-page.cjs.entry.js +33 -27
  26. package/dist/cjs/lottery-game-page.cjs.entry.js.map +1 -0
  27. package/dist/cjs/lottery-game-page.cjs.js +3 -1
  28. package/dist/cjs/lottery-game-page.cjs.js.map +1 -0
  29. package/dist/cjs/lottery-ticket-controller.cjs.entry.js +15 -2
  30. package/dist/cjs/lottery-ticket-controller.cjs.entry.js.map +1 -0
  31. package/dist/cjs/lottery-ticket.cjs.entry.js +29 -7
  32. package/dist/cjs/lottery-ticket.cjs.entry.js.map +1 -0
  33. package/dist/collection/components/lottery-game-page/lottery-game-page.css +10 -1
  34. package/dist/collection/components/lottery-game-page/lottery-game-page.js +83 -32
  35. package/dist/collection/components/lottery-game-page/lottery-game-page.js.map +1 -0
  36. package/dist/collection/index.js +1 -0
  37. package/dist/collection/index.js.map +1 -0
  38. package/dist/collection/utils/locale.utils.js +1 -0
  39. package/dist/collection/utils/locale.utils.js.map +1 -0
  40. package/dist/collection/utils/utils.js +1 -0
  41. package/dist/collection/utils/utils.js.map +1 -0
  42. package/dist/components/helper-accordion.js +2 -0
  43. package/dist/components/helper-accordion.js.map +1 -0
  44. package/dist/components/helper-accordion2.js +10 -2
  45. package/dist/components/helper-accordion2.js.map +1 -0
  46. package/dist/components/helper-filters.js +2 -0
  47. package/dist/components/helper-filters.js.map +1 -0
  48. package/dist/components/helper-filters2.js +1696 -974
  49. package/dist/components/helper-filters2.js.map +1 -0
  50. package/dist/components/helper-modal.js +2 -0
  51. package/dist/components/helper-modal.js.map +1 -0
  52. package/dist/components/helper-modal2.js +2 -0
  53. package/dist/components/helper-modal2.js.map +1 -0
  54. package/dist/components/helper-pagination.js +14 -0
  55. package/dist/components/helper-pagination.js.map +1 -0
  56. package/dist/components/helper-tab.js +2 -0
  57. package/dist/components/helper-tab.js.map +1 -0
  58. package/dist/components/helper-tab2.js +2 -0
  59. package/dist/components/helper-tab2.js.map +1 -0
  60. package/dist/components/helper-tabs.js +2 -0
  61. package/dist/components/helper-tabs.js.map +1 -0
  62. package/dist/components/helper-tabs2.js +2 -0
  63. package/dist/components/helper-tabs2.js.map +1 -0
  64. package/dist/components/index.js +2 -0
  65. package/dist/components/index.js.map +1 -0
  66. package/dist/components/lottery-bullet.js +2 -0
  67. package/dist/components/lottery-bullet.js.map +1 -0
  68. package/dist/components/lottery-bullet2.js +2 -0
  69. package/dist/components/lottery-bullet2.js.map +1 -0
  70. package/dist/components/lottery-draw-results-history.js +2 -0
  71. package/dist/components/lottery-draw-results-history.js.map +1 -0
  72. package/dist/components/lottery-draw-results-history2.js +46 -17
  73. package/dist/components/lottery-draw-results-history2.js.map +1 -0
  74. package/dist/components/lottery-draw-results.js +2 -0
  75. package/dist/components/lottery-draw-results.js.map +1 -0
  76. package/dist/components/lottery-draw-results2.js +95 -101
  77. package/dist/components/lottery-draw-results2.js.map +1 -0
  78. package/dist/components/lottery-game-details.js +2 -0
  79. package/dist/components/lottery-game-details.js.map +1 -0
  80. package/dist/components/lottery-game-details2.js +2 -0
  81. package/dist/components/lottery-game-details2.js.map +1 -0
  82. package/dist/components/lottery-game-page.js +35 -28
  83. package/dist/components/lottery-game-page.js.map +1 -0
  84. package/dist/components/lottery-grid.js +2 -0
  85. package/dist/components/lottery-grid.js.map +1 -0
  86. package/dist/components/lottery-grid2.js +13 -2
  87. package/dist/components/lottery-grid2.js.map +1 -0
  88. package/dist/components/lottery-ticket-controller.js +2 -0
  89. package/dist/components/lottery-ticket-controller.js.map +1 -0
  90. package/dist/components/lottery-ticket-controller2.js +30 -16
  91. package/dist/components/lottery-ticket-controller2.js.map +1 -0
  92. package/dist/components/lottery-ticket.js +2 -0
  93. package/dist/components/lottery-ticket.js.map +1 -0
  94. package/dist/components/lottery-ticket2.js +29 -7
  95. package/dist/components/lottery-ticket2.js.map +1 -0
  96. package/dist/esm/helper-accordion.entry.js +10 -2
  97. package/dist/esm/helper-accordion.entry.js.map +1 -0
  98. package/dist/esm/helper-filters_2.entry.js +1716 -1002
  99. package/dist/esm/helper-filters_2.entry.js.map +1 -0
  100. package/dist/esm/helper-modal.entry.js +2 -0
  101. package/dist/esm/helper-modal.entry.js.map +1 -0
  102. package/dist/esm/helper-pagination.entry.js +14 -0
  103. package/dist/esm/helper-pagination.entry.js.map +1 -0
  104. package/dist/esm/helper-tab.entry.js +2 -0
  105. package/dist/esm/helper-tab.entry.js.map +1 -0
  106. package/dist/esm/helper-tabs.entry.js +2 -0
  107. package/dist/esm/helper-tabs.entry.js.map +1 -0
  108. package/dist/esm/index-d1baacd4.js +2 -0
  109. package/dist/esm/index-d1baacd4.js.map +1 -0
  110. package/dist/esm/index.js +2 -0
  111. package/dist/esm/index.js.map +1 -0
  112. package/dist/esm/loader.js +3 -1
  113. package/dist/esm/loader.js.map +1 -0
  114. package/dist/esm/lottery-bullet_2.entry.js +13 -2
  115. package/dist/esm/lottery-bullet_2.entry.js.map +1 -0
  116. package/dist/esm/lottery-draw-results-history.entry.js +45 -16
  117. package/dist/esm/lottery-draw-results-history.entry.js.map +1 -0
  118. package/dist/esm/lottery-game-details.entry.js +2 -0
  119. package/dist/esm/lottery-game-details.entry.js.map +1 -0
  120. package/dist/esm/lottery-game-page.entry.js +34 -28
  121. package/dist/esm/lottery-game-page.entry.js.map +1 -0
  122. package/dist/esm/lottery-game-page.js +3 -1
  123. package/dist/esm/lottery-game-page.js.map +1 -0
  124. package/dist/esm/lottery-ticket-controller.entry.js +15 -2
  125. package/dist/esm/lottery-ticket-controller.entry.js.map +1 -0
  126. package/dist/esm/lottery-ticket.entry.js +29 -7
  127. package/dist/esm/lottery-ticket.entry.js.map +1 -0
  128. package/dist/lottery-game-page/index.esm.js +2 -0
  129. package/dist/lottery-game-page/index.esm.js.map +1 -0
  130. package/dist/lottery-game-page/lottery-game-page.esm.js +2 -1
  131. package/dist/lottery-game-page/lottery-game-page.esm.js.map +1 -0
  132. package/dist/lottery-game-page/p-042065c6.entry.js +2 -0
  133. package/dist/lottery-game-page/p-042065c6.entry.js.map +1 -0
  134. package/dist/lottery-game-page/p-15309f9a.entry.js +2 -0
  135. package/dist/lottery-game-page/p-15309f9a.entry.js.map +1 -0
  136. package/dist/lottery-game-page/p-167c9dbe.entry.js +2 -0
  137. package/dist/lottery-game-page/p-167c9dbe.entry.js.map +1 -0
  138. package/dist/lottery-game-page/p-2e78ed7b.entry.js +2 -0
  139. package/dist/lottery-game-page/p-2e78ed7b.entry.js.map +1 -0
  140. package/dist/lottery-game-page/p-5b49ab69.entry.js +2 -0
  141. package/dist/lottery-game-page/p-5b49ab69.entry.js.map +1 -0
  142. package/dist/lottery-game-page/p-606c0b0f.entry.js +2 -0
  143. package/dist/lottery-game-page/p-606c0b0f.entry.js.map +1 -0
  144. package/dist/lottery-game-page/p-662d9dac.entry.js +2 -0
  145. package/dist/lottery-game-page/p-662d9dac.entry.js.map +1 -0
  146. package/dist/lottery-game-page/p-66729e9c.entry.js +2 -0
  147. package/dist/lottery-game-page/p-66729e9c.entry.js.map +1 -0
  148. package/dist/lottery-game-page/p-76c280ec.entry.js +2 -0
  149. package/dist/lottery-game-page/p-76c280ec.entry.js.map +1 -0
  150. package/dist/lottery-game-page/p-a9ef5b8c.entry.js +2 -0
  151. package/dist/lottery-game-page/p-a9ef5b8c.entry.js.map +1 -0
  152. package/dist/lottery-game-page/p-aa68559a.entry.js +2 -0
  153. package/dist/lottery-game-page/p-aa68559a.entry.js.map +1 -0
  154. package/dist/lottery-game-page/p-d9e7b5da.entry.js +2899 -0
  155. package/dist/lottery-game-page/p-d9e7b5da.entry.js.map +1 -0
  156. package/dist/lottery-game-page/p-e765c7d9.js +2 -1
  157. package/dist/lottery-game-page/p-e765c7d9.js.map +1 -0
  158. package/dist/stencil.config.js +10 -1
  159. package/dist/stencil.config.js.map +1 -0
  160. package/dist/types/Users/adrian.pripon/Documents/Work/stencil/widgets-stencil/packages/lottery-game-page/.stencil/packages/lottery-game-page/stencil.config.d.ts +2 -0
  161. package/dist/types/components/lottery-game-page/lottery-game-page.d.ts +10 -1
  162. package/dist/types/components.d.ts +12 -2
  163. package/package.json +1 -1
  164. package/dist/components/assets/chrono_desktop.png +0 -0
  165. package/dist/components/assets/chrono_lottery_mobile.png +0 -0
  166. package/dist/lottery-game-page/p-023325a2.entry.js +0 -1
  167. package/dist/lottery-game-page/p-04fbc8fd.entry.js +0 -1
  168. package/dist/lottery-game-page/p-256b151c.entry.js +0 -1
  169. package/dist/lottery-game-page/p-381b5507.entry.js +0 -1
  170. package/dist/lottery-game-page/p-3f8b6ad9.entry.js +0 -1
  171. package/dist/lottery-game-page/p-4274053c.entry.js +0 -1
  172. package/dist/lottery-game-page/p-4f81cd37.entry.js +0 -1
  173. package/dist/lottery-game-page/p-5c389034.entry.js +0 -1
  174. package/dist/lottery-game-page/p-7d06371e.entry.js +0 -1
  175. package/dist/lottery-game-page/p-ca8430a0.entry.js +0 -2849
  176. package/dist/lottery-game-page/p-d6f76e8d.entry.js +0 -1
  177. package/dist/lottery-game-page/p-f6fcc22c.entry.js +0 -1
  178. package/dist/lottery-game-page/static/chrono_desktop.png +0 -0
  179. package/dist/lottery-game-page/static/chrono_lottery_mobile.png +0 -0
  180. package/dist/types/Users/user/workspace/everymatrix/widgets-stencil/packages/lottery-game-page/.stencil/packages/lottery-game-page/stencil.config.d.ts +0 -2
  181. /package/dist/{collection/components/lottery-game-page/static → assets}/chrono_desktop.png +0 -0
  182. /package/dist/{collection/components/lottery-game-page/static → assets}/chrono_lottery_mobile.png +0 -0
@@ -28,6 +28,32 @@ const TRANSLATIONS = {
28
28
  filterModalButton: 'Cauta',
29
29
  filterOrDate: 'sau cauta dupa data'
30
30
  },
31
+ fr: {
32
+ filterOpen: 'Filter',
33
+ filterClear: 'Clear',
34
+ filterModalTicketTitle: 'Ticket Results',
35
+ filterModalDrawTitle: 'Draws Results History',
36
+ filterTicketPlaceholder: 'Search for a ticket ID',
37
+ filterDrawPlaceholder: 'Search for a draw ID',
38
+ filterDateRangePlaceholder: 'Date Range',
39
+ filterModalButton: 'Search',
40
+ filterFromCalendar: 'From',
41
+ filterToCalendar: 'To',
42
+ filterOrDate: 'or search by date'
43
+ },
44
+ ar: {
45
+ filterOpen: 'Filter',
46
+ filterClear: 'Clear',
47
+ filterModalTicketTitle: 'Ticket Results',
48
+ filterModalDrawTitle: 'Draws Results History',
49
+ filterTicketPlaceholder: 'Search for a ticket ID',
50
+ filterDrawPlaceholder: 'Search for a draw ID',
51
+ filterDateRangePlaceholder: 'Date Range',
52
+ filterModalButton: 'Search',
53
+ filterFromCalendar: 'From',
54
+ filterToCalendar: 'To',
55
+ filterOrDate: 'or search by date'
56
+ }
31
57
  };
32
58
  const translate$1 = (key, customLang) => {
33
59
  const lang = customLang;
@@ -39,9 +65,16 @@ const translate$1 = (key, customLang) => {
39
65
  * Copyright (c) 2017 - 2022 Vaadin Ltd.
40
66
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
41
67
  */
68
+
69
+ /**
70
+ * Dummy custom element used for collecting
71
+ * development time usage statistics.
72
+ *
73
+ * @private
74
+ */
42
75
  class Lumo extends HTMLElement {
43
76
  static get version() {
44
- return '23.1.5';
77
+ return '23.3.14';
45
78
  }
46
79
  }
47
80
 
@@ -58,20 +91,20 @@ const t$1=window,e$2=t$1.ShadowRoot&&(void 0===t$1.ShadyCSS||t$1.ShadyCSS.native
58
91
  * @license
59
92
  * Copyright 2017 Google LLC
60
93
  * SPDX-License-Identifier: BSD-3-Clause
61
- */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||(this.h=[]),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(),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.4.1");
94
+ */var s$2;const e$1=window,r$1=e$1.trustedTypes,h$1=r$1?r$1.emptyScript:"",o$2=e$1.reactiveElementPolyfillSupport,n$2={toAttribute(t,i){switch(i){case Boolean:t=t?h$1:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t);}return t},fromAttribute(t,i){let s=t;switch(i){case Boolean:s=null!==t;break;case Number:s=null===t?null:Number(t);break;case Object:case Array:try{s=JSON.parse(t);}catch(t){s=null;}}return s}},a$1=(t,i)=>i!==t&&(i==i||t==t),l$2={attribute:!0,type:String,converter:n$2,reflect:!1,hasChanged:a$1};class d$1 extends HTMLElement{constructor(){super(),this._$Ei=new Map,this.isUpdatePending=!1,this.hasUpdated=!1,this._$El=null,this.u();}static addInitializer(t){var i;this.finalize(),(null!==(i=this.h)&&void 0!==i?i:this.h=[]).push(t);}static get observedAttributes(){this.finalize();const t=[];return this.elementProperties.forEach(((i,s)=>{const e=this._$Ep(s,i);void 0!==e&&(this._$Ev.set(e,s),t.push(e));})),t}static createProperty(t,i=l$2){if(i.state&&(i.attribute=!1),this.finalize(),this.elementProperties.set(t,i),!i.noAccessor&&!this.prototype.hasOwnProperty(t)){const s="symbol"==typeof t?Symbol():"__"+t,e=this.getPropertyDescriptor(t,s,i);void 0!==e&&Object.defineProperty(this.prototype,t,e);}}static getPropertyDescriptor(t,i,s){return {get(){return this[i]},set(e){const r=this[t];this[i]=e,this.requestUpdate(t,r,s);},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)||l$2}static finalize(){if(this.hasOwnProperty("finalized"))return !1;this.finalized=!0;const t=Object.getPrototypeOf(this);if(t.finalize(),void 0!==t.h&&(this.h=[...t.h]),this.elementProperties=new Map(t.elementProperties),this._$Ev=new Map,this.hasOwnProperty("properties")){const t=this.properties,i=[...Object.getOwnPropertyNames(t),...Object.getOwnPropertySymbols(t)];for(const s of i)this.createProperty(s,t[s]);}return this.elementStyles=this.finalizeStyles(this.styles),!0}static finalizeStyles(i){const s=[];if(Array.isArray(i)){const e=new Set(i.flat(1/0).reverse());for(const i of e)s.unshift(c$1(i));}else void 0!==i&&s.push(c$1(i));return s}static _$Ep(t,i){const s=i.attribute;return !1===s?void 0:"string"==typeof s?s:"string"==typeof t?t.toLowerCase():void 0}u(){var t;this._$E_=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$Eg(),this.requestUpdate(),null===(t=this.constructor.h)||void 0===t||t.forEach((t=>t(this)));}addController(t){var i,s;(null!==(i=this._$ES)&&void 0!==i?i:this._$ES=[]).push(t),void 0!==this.renderRoot&&this.isConnected&&(null===(s=t.hostConnected)||void 0===s||s.call(t));}removeController(t){var i;null===(i=this._$ES)||void 0===i||i.splice(this._$ES.indexOf(t)>>>0,1);}_$Eg(){this.constructor.elementProperties.forEach(((t,i)=>{this.hasOwnProperty(i)&&(this._$Ei.set(i,this[i]),delete this[i]);}));}createRenderRoot(){var t;const s=null!==(t=this.shadowRoot)&&void 0!==t?t:this.attachShadow(this.constructor.shadowRootOptions);return S$1(s,this.constructor.elementStyles),s}connectedCallback(){var t;void 0===this.renderRoot&&(this.renderRoot=this.createRenderRoot()),this.enableUpdating(!0),null===(t=this._$ES)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostConnected)||void 0===i?void 0:i.call(t)}));}enableUpdating(t){}disconnectedCallback(){var t;null===(t=this._$ES)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostDisconnected)||void 0===i?void 0:i.call(t)}));}attributeChangedCallback(t,i,s){this._$AK(t,s);}_$EO(t,i,s=l$2){var e;const r=this.constructor._$Ep(t,s);if(void 0!==r&&!0===s.reflect){const h=(void 0!==(null===(e=s.converter)||void 0===e?void 0:e.toAttribute)?s.converter:n$2).toAttribute(i,s.type);this._$El=t,null==h?this.removeAttribute(r):this.setAttribute(r,h),this._$El=null;}}_$AK(t,i){var s;const e=this.constructor,r=e._$Ev.get(t);if(void 0!==r&&this._$El!==r){const t=e.getPropertyOptions(r),h="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==(null===(s=t.converter)||void 0===s?void 0:s.fromAttribute)?t.converter:n$2;this._$El=r,this[r]=h.fromAttribute(i,t.type),this._$El=null;}}requestUpdate(t,i,s){let e=!0;void 0!==t&&(((s=s||this.constructor.getPropertyOptions(t)).hasChanged||a$1)(this[t],i)?(this._$AL.has(t)||this._$AL.set(t,i),!0===s.reflect&&this._$El!==t&&(void 0===this._$EC&&(this._$EC=new Map),this._$EC.set(t,s))):e=!1),!this.isUpdatePending&&e&&(this._$E_=this._$Ej());}async _$Ej(){this.isUpdatePending=!0;try{await this._$E_;}catch(t){Promise.reject(t);}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){var t;if(!this.isUpdatePending)return;this._$Ei&&(this._$Ei.forEach(((t,i)=>this[i]=t)),this._$Ei=void 0);let i=!1;const s=this._$AL;try{i=this.shouldUpdate(s),i?(this.willUpdate(s),null===(t=this._$ES)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostUpdate)||void 0===i?void 0:i.call(t)})),this.update(s)):this._$Ek();}catch(t){throw i=!1,this._$Ek(),t}i&&this._$AE(s);}willUpdate(t){}_$AE(t){var i;null===(i=this._$ES)||void 0===i||i.forEach((t=>{var i;return null===(i=t.hostUpdated)||void 0===i?void 0:i.call(t)})),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t);}_$Ek(){this._$AL=new Map,this.isUpdatePending=!1;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$E_}shouldUpdate(t){return !0}update(t){void 0!==this._$EC&&(this._$EC.forEach(((t,i)=>this._$EO(i,this[i],t))),this._$EC=void 0),this._$Ek();}updated(t){}firstUpdated(t){}}d$1.finalized=!0,d$1.elementProperties=new Map,d$1.elementStyles=[],d$1.shadowRootOptions={mode:"open"},null==o$2||o$2({ReactiveElement:d$1}),(null!==(s$2=e$1.reactiveElementVersions)&&void 0!==s$2?s$2:e$1.reactiveElementVersions=[]).push("1.6.1");
62
95
 
63
96
  /**
64
97
  * @license
65
98
  * Copyright 2017 Google LLC
66
99
  * SPDX-License-Identifier: BSD-3-Clause
67
100
  */
68
- 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)}$`,n$1="?"+o$1,l$1=`<${n$1}>`,h=document,r=(t="")=>h.createComment(t),d=t=>null===t||"object"!=typeof t&&"function"!=typeof t,u=Array.isArray,c=t=>u(t)||"function"==typeof(null==t?void 0:t[Symbol.iterator]),v=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,a=/-->/g,f=/>/g,_=RegExp(">|[ \t\n\f\r](?:([^\\s\"'>=/]+)([ \t\n\f\r]*=[ \t\n\f\r]*(?:[^ \t\n\f\r\"'`<>=]|(\"|')|))|$)","g"),m=/'/g,p=/"/g,$=/^(?:script|style|textarea|title)$/i,x=Symbol.for("lit-noChange"),b=Symbol.for("lit-nothing"),T=new WeakMap,A=(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 S(i.insertBefore(r(),t),t,void 0,null!=s?s:{});}return l._$AI(t),l},E=h.createTreeWalker(h,129,null,!1),C=(t,i)=>{const s=t.length-1,n=[];let h,r=2===i?"<svg>":"",d=v;for(let i=0;i<s;i++){const s=t[i];let e,u,c=-1,g=0;for(;g<s.length&&(d.lastIndex=g,u=d.exec(s),null!==u);)g=d.lastIndex,d===v?"!--"===u[1]?d=a:void 0!==u[1]?d=f:void 0!==u[2]?($.test(u[2])&&(h=RegExp("</"+u[2],"g")),d=_):void 0!==u[3]&&(d=_):d===_?">"===u[0]?(d=null!=h?h:v,c=-1):void 0===u[1]?c=-2:(c=d.lastIndex-u[2].length,e=u[1],d=void 0===u[3]?_:'"'===u[3]?p:m):d===p||d===m?d=_:d===a||d===f?d=v:(d=_,h=void 0);const y=d===_&&t[i+1].startsWith("/>")?" ":"";r+=d===v?s+l$1:c>=0?(n.push(e),s.slice(0,c)+"$lit$"+s.slice(c)+o$1+y):s+o$1+(-2===c?(n.push(void 0),i):y);}const u=r+(t[s]||"<?>")+(2===i?"</svg>":"");if(!Array.isArray(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return [void 0!==e?e.createHTML(u):u,n]};class P{constructor({strings:t,_$litType$:i},e){let l;this.parts=[];let h=0,d=0;const u=t.length-1,c=this.parts,[v,a]=C(t,i);if(this.el=P.createElement(v,e),E.currentNode=this.el.content,2===i){const t=this.el.content,i=t.firstChild;i.remove(),t.append(...i.childNodes);}for(;null!==(l=E.nextNode())&&c.length<u;){if(1===l.nodeType){if(l.hasAttributes()){const t=[];for(const i of l.getAttributeNames())if(i.endsWith("$lit$")||i.startsWith(o$1)){const s=a[d++];if(t.push(i),void 0!==s){const t=l.getAttribute(s.toLowerCase()+"$lit$").split(o$1),i=/([.?@])?(.*)/.exec(s);c.push({type:1,index:h,name:i[2],strings:t,ctor:"."===i[1]?R:"?"===i[1]?H:"@"===i[1]?I:M});}else c.push({type:6,index:h});}for(const i of t)l.removeAttribute(i);}if($.test(l.tagName)){const t=l.textContent.split(o$1),i=t.length-1;if(i>0){l.textContent=s$1?s$1.emptyScript:"";for(let s=0;s<i;s++)l.append(t[s],r()),E.nextNode(),c.push({type:2,index:++h});l.append(t[i],r());}}}else if(8===l.nodeType)if(l.data===n$1)c.push({type:2,index:h});else {let t=-1;for(;-1!==(t=l.data.indexOf(o$1,t+1));)c.push({type:7,index:h}),t+=o$1.length-1;}h++;}}static createElement(t,i){const s=h.createElement("template");return s.innerHTML=t,s}}function V(t,i,s=t,e){var o,n,l,h;if(i===x)return i;let r=void 0!==e?null===(o=s._$Cl)||void 0===o?void 0:o[e]:s._$Cu;const u=d(i)?void 0:i._$litDirective$;return (null==r?void 0:r.constructor)!==u&&(null===(n=null==r?void 0:r._$AO)||void 0===n||n.call(r,!1),void 0===u?r=void 0:(r=new u(t),r._$AT(t,s,e)),void 0!==e?(null!==(l=(h=s)._$Cl)&&void 0!==l?l:h._$Cl=[])[e]=r:s._$Cu=r),void 0!==r&&(i=V(t,r._$AS(t,i.values),r,e)),i}class N{constructor(t,i){this.v=[],this._$AN=void 0,this._$AD=t,this._$AM=i;}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}p(t){var i;const{el:{content:s},parts:e}=this._$AD,o=(null!==(i=null==t?void 0:t.creationScope)&&void 0!==i?i:h).importNode(s,!0);E.currentNode=o;let n=E.nextNode(),l=0,r=0,d=e[0];for(;void 0!==d;){if(l===d.index){let i;2===d.type?i=new S(n,n.nextSibling,this,t):1===d.type?i=new d.ctor(n,d.name,d.strings,this,t):6===d.type&&(i=new L(n,this,t)),this.v.push(i),d=e[++r];}l!==(null==d?void 0:d.index)&&(n=E.nextNode(),l++);}return o}m(t){let i=0;for(const s of this.v)void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,i),i+=s.strings.length-2):s._$AI(t[i])),i++;}}class S{constructor(t,i,s,e){var o;this.type=2,this._$AH=b,this._$AN=void 0,this._$AA=t,this._$AB=i,this._$AM=s,this.options=e,this._$C_=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._$C_}get parentNode(){let t=this._$AA.parentNode;const i=this._$AM;return void 0!==i&&11===t.nodeType&&(t=i.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,i=this){t=V(this,t,i),d(t)?t===b||null==t||""===t?(this._$AH!==b&&this._$AR(),this._$AH=b):t!==this._$AH&&t!==x&&this.$(t):void 0!==t._$litType$?this.T(t):void 0!==t.nodeType?this.k(t):c(t)?this.O(t):this.$(t);}S(t,i=this._$AB){return this._$AA.parentNode.insertBefore(t,i)}k(t){this._$AH!==t&&(this._$AR(),this._$AH=this.S(t));}$(t){this._$AH!==b&&d(this._$AH)?this._$AA.nextSibling.data=t:this.k(h.createTextNode(t)),this._$AH=t;}T(t){var i;const{values:s,_$litType$:e}=t,o="number"==typeof e?this._$AC(t):(void 0===e.el&&(e.el=P.createElement(e.h,this.options)),e);if((null===(i=this._$AH)||void 0===i?void 0:i._$AD)===o)this._$AH.m(s);else {const t=new N(o,this),i=t.p(this.options);t.m(s),this.k(i),this._$AH=t;}}_$AC(t){let i=T.get(t.strings);return void 0===i&&T.set(t.strings,i=new P(t)),i}O(t){u(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 S(this.S(r()),this.S(r()),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._$C_=t,null===(i=this._$AP)||void 0===i||i.call(this,t));}}class M{constructor(t,i,s,e,o){this.type=1,this._$AH=b,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=b;}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=V(this,t,i,0),n=!d(t)||t!==this._$AH&&t!==x,n&&(this._$AH=t);else {const e=t;let l,h;for(t=o[0],l=0;l<o.length-1;l++)h=V(this,e[s+l],i,l),h===x&&(h=this._$AH[l]),n||(n=!d(h)||h!==this._$AH[l]),h===b?t=b:t!==b&&(t+=(null!=h?h:"")+o[l+1]),this._$AH[l]=h;}n&&!e&&this.P(t);}P(t){t===b?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,null!=t?t:"");}}class R extends M{constructor(){super(...arguments),this.type=3;}P(t){this.element[this.name]=t===b?void 0:t;}}const k=s$1?s$1.emptyScript:"";class H extends M{constructor(){super(...arguments),this.type=4;}P(t){t&&t!==b?this.element.setAttribute(this.name,k):this.element.removeAttribute(this.name);}}class I extends M{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=V(this,t,i,0))&&void 0!==s?s:b)===x)return;const e=this._$AH,o=t===b&&e!==b||t.capture!==e.capture||t.once!==e.once||t.passive!==e.passive,n=t!==b&&(e===b||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 L{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){V(this,t);}}const Z=i.litHtmlPolyfillSupport;null==Z||Z(P,S),(null!==(t=i.litHtmlVersions)&&void 0!==t?t:i.litHtmlVersions=[]).push("2.3.1");
101
+ var t;const i=window,s$1=i.trustedTypes,e=s$1?s$1.createPolicy("lit-html",{createHTML:t=>t}):void 0,o$1="$lit$",n$1=`lit$${(Math.random()+"").slice(9)}$`,l$1="?"+n$1,h=`<${l$1}>`,r=document,d=()=>r.createComment(""),u=t=>null===t||"object"!=typeof t&&"function"!=typeof t,c=Array.isArray,v=t=>c(t)||"function"==typeof(null==t?void 0:t[Symbol.iterator]),a="[ \t\n\f\r]",f=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,_=/-->/g,m=/>/g,p=RegExp(`>|${a}(?:([^\\s"'>=/]+)(${a}*=${a}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),g=/'/g,$=/"/g,y=/^(?:script|style|textarea|title)$/i,T=Symbol.for("lit-noChange"),A=Symbol.for("lit-nothing"),E=new WeakMap,C=r.createTreeWalker(r,129,null,!1),P=(t,i)=>{const s=t.length-1,l=[];let r,d=2===i?"<svg>":"",u=f;for(let i=0;i<s;i++){const s=t[i];let e,c,v=-1,a=0;for(;a<s.length&&(u.lastIndex=a,c=u.exec(s),null!==c);)a=u.lastIndex,u===f?"!--"===c[1]?u=_:void 0!==c[1]?u=m:void 0!==c[2]?(y.test(c[2])&&(r=RegExp("</"+c[2],"g")),u=p):void 0!==c[3]&&(u=p):u===p?">"===c[0]?(u=null!=r?r:f,v=-1):void 0===c[1]?v=-2:(v=u.lastIndex-c[2].length,e=c[1],u=void 0===c[3]?p:'"'===c[3]?$:g):u===$||u===g?u=p:u===_||u===m?u=f:(u=p,r=void 0);const w=u===p&&t[i+1].startsWith("/>")?" ":"";d+=u===f?s+h:v>=0?(l.push(e),s.slice(0,v)+o$1+s.slice(v)+n$1+w):s+n$1+(-2===v?(l.push(void 0),i):w);}const c=d+(t[s]||"<?>")+(2===i?"</svg>":"");if(!Array.isArray(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return [void 0!==e?e.createHTML(c):c,l]};class V{constructor({strings:t,_$litType$:i},e){let h;this.parts=[];let r=0,u=0;const c=t.length-1,v=this.parts,[a,f]=P(t,i);if(this.el=V.createElement(a,e),C.currentNode=this.el.content,2===i){const t=this.el.content,i=t.firstChild;i.remove(),t.append(...i.childNodes);}for(;null!==(h=C.nextNode())&&v.length<c;){if(1===h.nodeType){if(h.hasAttributes()){const t=[];for(const i of h.getAttributeNames())if(i.endsWith(o$1)||i.startsWith(n$1)){const s=f[u++];if(t.push(i),void 0!==s){const t=h.getAttribute(s.toLowerCase()+o$1).split(n$1),i=/([.?@])?(.*)/.exec(s);v.push({type:1,index:r,name:i[2],strings:t,ctor:"."===i[1]?k:"?"===i[1]?I:"@"===i[1]?L:R});}else v.push({type:6,index:r});}for(const i of t)h.removeAttribute(i);}if(y.test(h.tagName)){const t=h.textContent.split(n$1),i=t.length-1;if(i>0){h.textContent=s$1?s$1.emptyScript:"";for(let s=0;s<i;s++)h.append(t[s],d()),C.nextNode(),v.push({type:2,index:++r});h.append(t[i],d());}}}else if(8===h.nodeType)if(h.data===l$1)v.push({type:2,index:r});else {let t=-1;for(;-1!==(t=h.data.indexOf(n$1,t+1));)v.push({type:7,index:r}),t+=n$1.length-1;}r++;}}static createElement(t,i){const s=r.createElement("template");return s.innerHTML=t,s}}function N(t,i,s=t,e){var o,n,l,h;if(i===T)return i;let r=void 0!==e?null===(o=s._$Co)||void 0===o?void 0:o[e]:s._$Cl;const d=u(i)?void 0:i._$litDirective$;return (null==r?void 0:r.constructor)!==d&&(null===(n=null==r?void 0:r._$AO)||void 0===n||n.call(r,!1),void 0===d?r=void 0:(r=new d(t),r._$AT(t,s,e)),void 0!==e?(null!==(l=(h=s)._$Co)&&void 0!==l?l:h._$Co=[])[e]=r:s._$Cl=r),void 0!==r&&(i=N(t,r._$AS(t,i.values),r,e)),i}class S{constructor(t,i){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=i;}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){var i;const{el:{content:s},parts:e}=this._$AD,o=(null!==(i=null==t?void 0:t.creationScope)&&void 0!==i?i:r).importNode(s,!0);C.currentNode=o;let n=C.nextNode(),l=0,h=0,d=e[0];for(;void 0!==d;){if(l===d.index){let i;2===d.type?i=new M(n,n.nextSibling,this,t):1===d.type?i=new d.ctor(n,d.name,d.strings,this,t):6===d.type&&(i=new z(n,this,t)),this._$AV.push(i),d=e[++h];}l!==(null==d?void 0:d.index)&&(n=C.nextNode(),l++);}return C.currentNode=r,o}v(t){let i=0;for(const s of this._$AV)void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,i),i+=s.strings.length-2):s._$AI(t[i])),i++;}}class M{constructor(t,i,s,e){var o;this.type=2,this._$AH=A,this._$AN=void 0,this._$AA=t,this._$AB=i,this._$AM=s,this.options=e,this._$Cp=null===(o=null==e?void 0:e.isConnected)||void 0===o||o;}get _$AU(){var t,i;return null!==(i=null===(t=this._$AM)||void 0===t?void 0:t._$AU)&&void 0!==i?i:this._$Cp}get parentNode(){let t=this._$AA.parentNode;const i=this._$AM;return void 0!==i&&11===(null==t?void 0:t.nodeType)&&(t=i.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,i=this){t=N(this,t,i),u(t)?t===A||null==t||""===t?(this._$AH!==A&&this._$AR(),this._$AH=A):t!==this._$AH&&t!==T&&this._(t):void 0!==t._$litType$?this.g(t):void 0!==t.nodeType?this.$(t):v(t)?this.T(t):this._(t);}k(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}$(t){this._$AH!==t&&(this._$AR(),this._$AH=this.k(t));}_(t){this._$AH!==A&&u(this._$AH)?this._$AA.nextSibling.data=t:this.$(r.createTextNode(t)),this._$AH=t;}g(t){var i;const{values:s,_$litType$:e}=t,o="number"==typeof e?this._$AC(t):(void 0===e.el&&(e.el=V.createElement(e.h,this.options)),e);if((null===(i=this._$AH)||void 0===i?void 0:i._$AD)===o)this._$AH.v(s);else {const t=new S(o,this),i=t.u(this.options);t.v(s),this.$(i),this._$AH=t;}}_$AC(t){let i=E.get(t.strings);return void 0===i&&E.set(t.strings,i=new V(t)),i}T(t){c(this._$AH)||(this._$AH=[],this._$AR());const i=this._$AH;let s,e=0;for(const o of t)e===i.length?i.push(s=new M(this.k(d()),this.k(d()),this,this.options)):s=i[e],s._$AI(o),e++;e<i.length&&(this._$AR(s&&s._$AB.nextSibling,e),i.length=e);}_$AR(t=this._$AA.nextSibling,i){var s;for(null===(s=this._$AP)||void 0===s||s.call(this,!1,!0,i);t&&t!==this._$AB;){const i=t.nextSibling;t.remove(),t=i;}}setConnected(t){var i;void 0===this._$AM&&(this._$Cp=t,null===(i=this._$AP)||void 0===i||i.call(this,t));}}class R{constructor(t,i,s,e,o){this.type=1,this._$AH=A,this._$AN=void 0,this.element=t,this.name=i,this._$AM=e,this.options=o,s.length>2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=A;}get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}_$AI(t,i=this,s,e){const o=this.strings;let n=!1;if(void 0===o)t=N(this,t,i,0),n=!u(t)||t!==this._$AH&&t!==T,n&&(this._$AH=t);else {const e=t;let l,h;for(t=o[0],l=0;l<o.length-1;l++)h=N(this,e[s+l],i,l),h===T&&(h=this._$AH[l]),n||(n=!u(h)||h!==this._$AH[l]),h===A?t=A:t!==A&&(t+=(null!=h?h:"")+o[l+1]),this._$AH[l]=h;}n&&!e&&this.j(t);}j(t){t===A?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,null!=t?t:"");}}class k extends R{constructor(){super(...arguments),this.type=3;}j(t){this.element[this.name]=t===A?void 0:t;}}const H=s$1?s$1.emptyScript:"";class I extends R{constructor(){super(...arguments),this.type=4;}j(t){t&&t!==A?this.element.setAttribute(this.name,H):this.element.removeAttribute(this.name);}}class L extends R{constructor(t,i,s,e,o){super(t,i,s,e,o),this.type=5;}_$AI(t,i=this){var s;if((t=null!==(s=N(this,t,i,0))&&void 0!==s?s:A)===T)return;const e=this._$AH,o=t===A&&e!==A||t.capture!==e.capture||t.once!==e.once||t.passive!==e.passive,n=t!==A&&(e===A||o);o&&this.element.removeEventListener(this.name,this,e),n&&this.element.addEventListener(this.name,this,t),this._$AH=t;}handleEvent(t){var i,s;"function"==typeof this._$AH?this._$AH.call(null!==(s=null===(i=this.options)||void 0===i?void 0:i.host)&&void 0!==s?s:this.element,t):this._$AH.handleEvent(t);}}class z{constructor(t,i,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=i,this.options=s;}get _$AU(){return this._$AM._$AU}_$AI(t){N(this,t);}}const j=i.litHtmlPolyfillSupport;null==j||j(V,M),(null!==(t=i.litHtmlVersions)&&void 0!==t?t:i.litHtmlVersions=[]).push("2.7.4");const B=(t,i,s)=>{var e,o;const n=null!==(e=null==s?void 0:s.renderBefore)&&void 0!==e?e:i;let l=n._$litPart$;if(void 0===l){const t=null!==(o=null==s?void 0:s.renderBefore)&&void 0!==o?o:null;n._$litPart$=l=new M(i.insertBefore(d(),t),t,void 0,null!=s?s:{});}return l._$AI(t),l};
69
102
 
70
103
  /**
71
104
  * @license
72
105
  * Copyright 2017 Google LLC
73
106
  * SPDX-License-Identifier: BSD-3-Clause
74
- */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=A(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 x}}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.2.2");
107
+ */var l,o;class s extends d$1{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0;}createRenderRoot(){var t,e;const i=super.createRenderRoot();return null!==(t=(e=this.renderOptions).renderBefore)&&void 0!==t||(e.renderBefore=i.firstChild),i}update(t){const i=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=B(i,this.renderRoot,this.renderOptions);}connectedCallback(){var t;super.connectedCallback(),null===(t=this._$Do)||void 0===t||t.setConnected(!0);}disconnectedCallback(){var t;super.disconnectedCallback(),null===(t=this._$Do)||void 0===t||t.setConnected(!1);}render(){return T}}s.finalized=!0,s._$litElement$=!0,null===(l=globalThis.litElementHydrateSupport)||void 0===l||l.call(globalThis,{LitElement:s});const n=globalThis.litElementPolyfillSupport;null==n||n({LitElement:s});(null!==(o=globalThis.litElementVersions)&&void 0!==o?o:globalThis.litElementVersions=[]).push("3.3.2");
75
108
 
76
109
  /**
77
110
  * @license
@@ -97,7 +130,7 @@ const ThemePropertyMixin = (superClass) =>
97
130
  * **NOTE:** Extending the mixin only provides the property for binding,
98
131
  * and does not make the propagation alone.
99
132
  *
100
- * See [Styling Components: Sub-components](https://vaadin.com/docs/latest/ds/customization/styling-components/#sub-components).
133
+ * See [Styling Components: Sub-components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components/#sub-components).
101
134
  * page for more information.
102
135
  *
103
136
  * @deprecated The `theme` property is not supposed for public use and will be dropped in Vaadin 24.
@@ -122,7 +155,7 @@ const ThemePropertyMixin = (superClass) =>
122
155
  * **NOTE:** Extending the mixin only provides the property for binding,
123
156
  * and does not make the propagation alone.
124
157
  *
125
- * See [Styling Components: Sub-components](https://vaadin.com/docs/latest/ds/customization/styling-components/#sub-components).
158
+ * See [Styling Components: Sub-components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components/#sub-components).
126
159
  * page for more information.
127
160
  *
128
161
  * @protected
@@ -227,9 +260,9 @@ function matchesThemeFor(themeFor, tagName) {
227
260
  */
228
261
  function getIncludePriority(moduleName = '') {
229
262
  let includePriority = 0;
230
- if (moduleName.indexOf('lumo-') === 0 || moduleName.indexOf('material-') === 0) {
263
+ if (moduleName.startsWith('lumo-') || moduleName.startsWith('material-')) {
231
264
  includePriority = 1;
232
- } else if (moduleName.indexOf('vaadin-') === 0) {
265
+ } else if (moduleName.startsWith('vaadin-')) {
233
266
  includePriority = 2;
234
267
  }
235
268
  return includePriority;
@@ -463,9 +496,9 @@ const colorBase = i$1`
463
496
  }
464
497
  `;
465
498
 
466
- const $tpl$5 = document.createElement('template');
467
- $tpl$5.innerHTML = `<style>${colorBase.toString().replace(':host', 'html')}</style>`;
468
- document.head.appendChild($tpl$5.content);
499
+ const $tpl$4 = document.createElement('template');
500
+ $tpl$4.innerHTML = `<style>${colorBase.toString().replace(':host', 'html')}</style>`;
501
+ document.head.appendChild($tpl$4.content);
469
502
 
470
503
  const color = i$1`
471
504
  [theme~='dark'] {
@@ -612,9 +645,9 @@ const sizing = i$1`
612
645
  }
613
646
  `;
614
647
 
615
- const $tpl$4 = document.createElement('template');
616
- $tpl$4.innerHTML = `<style>${sizing.toString().replace(':host', 'html')}</style>`;
617
- document.head.appendChild($tpl$4.content);
648
+ const $tpl$3 = document.createElement('template');
649
+ $tpl$3.innerHTML = `<style>${sizing.toString().replace(':host', 'html')}</style>`;
650
+ document.head.appendChild($tpl$3.content);
618
651
 
619
652
  /**
620
653
  * @license
@@ -642,9 +675,19 @@ const style = i$1`
642
675
  }
643
676
  `;
644
677
 
645
- const $tpl$3 = document.createElement('template');
646
- $tpl$3.innerHTML = `<style>${style.toString().replace(':host', 'html')}</style>`;
647
- document.head.appendChild($tpl$3.content);
678
+ /**
679
+ * Default values for component-specific custom properties.
680
+ */
681
+ i$1`
682
+ html {
683
+ --vaadin-checkbox-size: calc(var(--lumo-size-m) / 2);
684
+ --vaadin-radio-button-size: calc(var(--lumo-size-m) / 2);
685
+ }
686
+ `;
687
+
688
+ const $tpl$2 = document.createElement('template');
689
+ $tpl$2.innerHTML = `<style>${style.toString().replace(':host', 'html')}$</style>`;
690
+ document.head.appendChild($tpl$2.content);
648
691
 
649
692
  /**
650
693
  * @license
@@ -781,9 +824,9 @@ const typography = i$1`
781
824
 
782
825
  registerStyles('', typography, { moduleId: 'lumo-typography' });
783
826
 
784
- const $tpl$2 = document.createElement('template');
785
- $tpl$2.innerHTML = `<style>${font.toString().replace(':host', 'html')}</style>`;
786
- document.head.appendChild($tpl$2.content);
827
+ const $tpl$1 = document.createElement('template');
828
+ $tpl$1.innerHTML = `<style>${font.toString().replace(':host', 'html')}</style>`;
829
+ document.head.appendChild($tpl$1.content);
787
830
 
788
831
  registerStyles(
789
832
  'vaadin-input-container',
@@ -8075,6 +8118,7 @@ class DirHelper {
8075
8118
  * Array of Vaadin custom element classes that have been subscribed to the dir changes.
8076
8119
  */
8077
8120
  const directionSubscribers = [];
8121
+
8078
8122
  function directionUpdater() {
8079
8123
  const documentDir = getDocumentDir();
8080
8124
  directionSubscribers.forEach((element) => {
@@ -8140,7 +8184,7 @@ const DirMixin = (superClass) =>
8140
8184
  connectedCallback() {
8141
8185
  super.connectedCallback();
8142
8186
 
8143
- if (!this.hasAttribute('dir')) {
8187
+ if (!this.hasAttribute('dir') || this.__restoreSubscription) {
8144
8188
  this.__subscribe();
8145
8189
  alignDirs(this, getDocumentDir(), null);
8146
8190
  }
@@ -8166,15 +8210,15 @@ const DirMixin = (superClass) =>
8166
8210
  this.__subscribe();
8167
8211
  alignDirs(this, documentDir, newValue);
8168
8212
  } else if (newDiffValue) {
8169
- this.__subscribe(false);
8213
+ this.__unsubscribe();
8170
8214
  }
8171
8215
  }
8172
8216
 
8173
8217
  /** @protected */
8174
8218
  disconnectedCallback() {
8175
8219
  super.disconnectedCallback();
8176
- this.__subscribe(false);
8177
- this.removeAttribute('dir');
8220
+ this.__restoreSubscription = directionSubscribers.includes(this);
8221
+ this.__unsubscribe();
8178
8222
  }
8179
8223
 
8180
8224
  /** @protected */
@@ -8199,12 +8243,15 @@ const DirMixin = (superClass) =>
8199
8243
  }
8200
8244
 
8201
8245
  /** @private */
8202
- __subscribe(push = true) {
8203
- if (push) {
8204
- if (!directionSubscribers.includes(this)) {
8205
- directionSubscribers.push(this);
8206
- }
8207
- } else if (directionSubscribers.includes(this)) {
8246
+ __subscribe() {
8247
+ if (!directionSubscribers.includes(this)) {
8248
+ directionSubscribers.push(this);
8249
+ }
8250
+ }
8251
+
8252
+ /** @private */
8253
+ __unsubscribe() {
8254
+ if (directionSubscribers.includes(this)) {
8208
8255
  directionSubscribers.splice(directionSubscribers.indexOf(this), 1);
8209
8256
  }
8210
8257
  }
@@ -8282,7 +8329,6 @@ class InputContainer extends ThemableMixin(DirMixin(PolymerElement)) {
8282
8329
  ::slotted(:is(input, textarea))::placeholder {
8283
8330
  /* Use ::slotted(input:placeholder-shown) in themes to style the placeholder. */
8284
8331
  /* because ::slotted(...)::placeholder does not work in Safari. */
8285
- /* See the workaround at the end of this file. */
8286
8332
  font: inherit;
8287
8333
  color: inherit;
8288
8334
  /* Override default opacity in Firefox */
@@ -8349,18 +8395,6 @@ class InputContainer extends ThemableMixin(DirMixin(PolymerElement)) {
8349
8395
 
8350
8396
  customElements.define(InputContainer.is, InputContainer);
8351
8397
 
8352
- const placeholderStyleWorkaround = i$1`
8353
- /* Needed for Safari, where ::slotted(...)::placeholder does not work */
8354
- :is(input[slot='input'], textarea[slot='textarea'])::placeholder {
8355
- font: inherit;
8356
- color: inherit;
8357
- }
8358
- `;
8359
-
8360
- const $tpl$1 = document.createElement('template');
8361
- $tpl$1.innerHTML = `<style>${placeholderStyleWorkaround.toString()}</style>`;
8362
- document.head.appendChild($tpl$1.content);
8363
-
8364
8398
  /**
8365
8399
  * @license
8366
8400
  * Copyright (c) 2017 - 2022 Vaadin Ltd.
@@ -10114,6 +10148,38 @@ const ControllerMixin = dedupingMixin(
10114
10148
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
10115
10149
  */
10116
10150
 
10151
+ // We consider the keyboard to be active if the window has received a keydown
10152
+ // event since the last mousedown event.
10153
+ let keyboardActive = false;
10154
+
10155
+ // Listen for top-level keydown and mousedown events.
10156
+ // Use capture phase so we detect events even if they're handled.
10157
+ window.addEventListener(
10158
+ 'keydown',
10159
+ () => {
10160
+ keyboardActive = true;
10161
+ },
10162
+ { capture: true },
10163
+ );
10164
+
10165
+ window.addEventListener(
10166
+ 'mousedown',
10167
+ () => {
10168
+ keyboardActive = false;
10169
+ },
10170
+ { capture: true },
10171
+ );
10172
+
10173
+ /**
10174
+ * Returns true if the window has received a keydown
10175
+ * event since the last mousedown event.
10176
+ *
10177
+ * @return {boolean}
10178
+ */
10179
+ function isKeyboardActive() {
10180
+ return keyboardActive;
10181
+ }
10182
+
10117
10183
  /**
10118
10184
  * Returns true if the element is hidden directly with `display: none` or `visibility: hidden`,
10119
10185
  * false otherwise.
@@ -10554,7 +10620,7 @@ class FocusTrapController {
10554
10620
  * ---|---|---
10555
10621
  * `--vaadin-overlay-viewport-bottom` | Bottom offset of the visible viewport area | `0` or detected offset
10556
10622
  *
10557
- * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
10623
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
10558
10624
  *
10559
10625
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
10560
10626
  * @fires {CustomEvent} vaadin-overlay-open - Fired after the overlay is opened.
@@ -10568,7 +10634,7 @@ class FocusTrapController {
10568
10634
  * @mixes DirMixin
10569
10635
  * @mixes ControllerMixin
10570
10636
  */
10571
- class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerElement))) {
10637
+ class Overlay extends ThemableMixin(DirMixin(ControllerMixin(PolymerElement))) {
10572
10638
  static get template() {
10573
10639
  return html`
10574
10640
  <style>
@@ -10868,7 +10934,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
10868
10934
  * @protected
10869
10935
  */
10870
10936
  _setTemplateFromNodes(nodes) {
10871
- this.template = nodes.filter((node) => node.localName && node.localName === 'template')[0] || this.template;
10937
+ this.template = nodes.find((node) => node.localName && node.localName === 'template') || this.template;
10872
10938
  }
10873
10939
 
10874
10940
  /**
@@ -11195,7 +11261,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
11195
11261
  */
11196
11262
  static get __attachedInstances() {
11197
11263
  return Array.from(document.body.children)
11198
- .filter((el) => el instanceof OverlayElement && !el.hasAttribute('closing'))
11264
+ .filter((el) => el instanceof Overlay && !el.hasAttribute('closing'))
11199
11265
  .sort((a, b) => a.__zIndex - b.__zIndex || 0);
11200
11266
  }
11201
11267
 
@@ -11205,7 +11271,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
11205
11271
  * @protected
11206
11272
  */
11207
11273
  get _last() {
11208
- return this === OverlayElement.__attachedInstances.pop();
11274
+ return this === Overlay.__attachedInstances.pop();
11209
11275
  }
11210
11276
 
11211
11277
  /** @private */
@@ -11240,7 +11306,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
11240
11306
  }
11241
11307
 
11242
11308
  // Disable pointer events in other attached overlays
11243
- OverlayElement.__attachedInstances.forEach((el) => {
11309
+ Overlay.__attachedInstances.forEach((el) => {
11244
11310
  if (el !== this) {
11245
11311
  el.shadowRoot.querySelector('[part="overlay"]').style.pointerEvents = 'none';
11246
11312
  }
@@ -11263,7 +11329,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
11263
11329
  }
11264
11330
 
11265
11331
  // Restore pointer events in the previous overlay(s)
11266
- const instances = OverlayElement.__attachedInstances;
11332
+ const instances = Overlay.__attachedInstances;
11267
11333
  let el;
11268
11334
  // Use instances.pop() to ensure the reverse order
11269
11335
  while ((el = instances.pop())) {
@@ -11442,7 +11508,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
11442
11508
  */
11443
11509
  bringToFront() {
11444
11510
  let zIndex = '';
11445
- const frontmost = OverlayElement.__attachedInstances.filter((o) => o !== this).pop();
11511
+ const frontmost = Overlay.__attachedInstances.filter((o) => o !== this).pop();
11446
11512
  if (frontmost) {
11447
11513
  const frontmostZIndex = frontmost.__zIndex;
11448
11514
  zIndex = frontmostZIndex + 1;
@@ -11452,7 +11518,7 @@ class OverlayElement extends ThemableMixin(DirMixin(ControllerMixin(PolymerEleme
11452
11518
  }
11453
11519
  }
11454
11520
 
11455
- customElements.define(OverlayElement.is, OverlayElement);
11521
+ customElements.define(Overlay.is, Overlay);
11456
11522
 
11457
11523
  /**
11458
11524
  * @license
@@ -11638,7 +11704,7 @@ const button = i$1`
11638
11704
  -moz-osx-font-smoothing: grayscale;
11639
11705
  }
11640
11706
 
11641
- /* Set only for the internal parts so we dont affect the host vertical alignment */
11707
+ /* Set only for the internal parts so we don't affect the host vertical alignment */
11642
11708
  [part='label'],
11643
11709
  [part='prefix'],
11644
11710
  [part='suffix'] {
@@ -11874,7 +11940,7 @@ const button = i$1`
11874
11940
  registerStyles('vaadin-button', button, { moduleId: 'lumo-button' });
11875
11941
 
11876
11942
  const DEV_MODE_CODE_REGEXP =
11877
- /\/\*\*\s+vaadin-dev-mode:start([\s\S]*)vaadin-dev-mode:end\s+\*\*\//i;
11943
+ /\/\*[\*!]\s+vaadin-dev-mode:start([\s\S]*)vaadin-dev-mode:end\s+\*\*\//i;
11878
11944
 
11879
11945
  const FlowClients = window.Vaadin && window.Vaadin.Flow && window.Vaadin.Flow.clients;
11880
11946
 
@@ -12824,7 +12890,7 @@ const registered = new Set();
12824
12890
  const ElementMixin = (superClass) =>
12825
12891
  class VaadinElementMixin extends DirMixin(superClass) {
12826
12892
  static get version() {
12827
- return '23.1.5';
12893
+ return '23.3.14';
12828
12894
  }
12829
12895
 
12830
12896
  /** @protected */
@@ -12859,159 +12925,538 @@ const ElementMixin = (superClass) =>
12859
12925
  };
12860
12926
 
12861
12927
  /**
12862
- @license
12863
- Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
12864
- This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
12865
- The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
12866
- The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
12867
- Code distributed by Google as part of the polymer project is also
12868
- subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
12869
- */
12870
-
12871
- const passiveTouchGestures = false;
12872
- const wrap = (node) => node;
12873
-
12874
- // Detect native touch action support
12875
- const HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
12876
- const GESTURE_KEY = '__polymerGestures';
12877
- const HANDLED_OBJ = '__polymerGesturesHandled';
12878
- const TOUCH_ACTION = '__polymerGesturesTouchAction';
12879
- // Radius for tap and track
12880
- const TAP_DISTANCE = 25;
12881
- const TRACK_DISTANCE = 5;
12882
- // Number of last N track positions to keep
12883
- const TRACK_LENGTH = 2;
12928
+ * @license
12929
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
12930
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
12931
+ */
12884
12932
 
12885
- const MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'click'];
12886
- // An array of bitmask values for mapping MouseEvent.which to MouseEvent.buttons
12887
- const MOUSE_WHICH_TO_BUTTONS = [0, 1, 4, 2];
12888
- const MOUSE_HAS_BUTTONS = (function () {
12889
- try {
12890
- return new MouseEvent('test', { buttons: 1 }).buttons === 1;
12891
- } catch (e) {
12892
- return false;
12893
- }
12894
- })();
12933
+ let uniqueId = 0;
12895
12934
 
12896
12935
  /**
12897
- * @param {string} name Possible mouse event name
12898
- * @return {boolean} true if mouse event, false if not
12936
+ * Returns a unique integer id.
12937
+ *
12938
+ * @return {number}
12899
12939
  */
12900
- function isMouseEvent(name) {
12901
- return MOUSE_EVENTS.indexOf(name) > -1;
12940
+ function generateUniqueId() {
12941
+ // eslint-disable-next-line no-plusplus
12942
+ return uniqueId++;
12902
12943
  }
12903
12944
 
12904
- /* eslint no-empty: ["error", { "allowEmptyCatch": true }] */
12905
- // check for passive event listeners
12906
- let supportsPassive = false;
12907
- (function () {
12908
- try {
12909
- const opts = Object.defineProperty({}, 'passive', {
12910
- // eslint-disable-next-line getter-return
12911
- get() {
12912
- supportsPassive = true;
12913
- },
12914
- });
12915
- window.addEventListener('test', null, opts);
12916
- window.removeEventListener('test', null, opts);
12917
- } catch (e) {}
12918
- })();
12945
+ /**
12946
+ * @license
12947
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
12948
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
12949
+ */
12919
12950
 
12920
12951
  /**
12921
- * Generate settings for event listeners, dependant on `passiveTouchGestures`
12922
- *
12923
- * @param {string} eventName Event name to determine if `{passive}` option is
12924
- * needed
12925
- * @return {{passive: boolean} | undefined} Options to use for addEventListener
12926
- * and removeEventListener
12952
+ * A controller for providing content to slot element and observing changes.
12927
12953
  */
12928
- function PASSIVE_TOUCH(eventName) {
12929
- if (isMouseEvent(eventName) || eventName === 'touchend') {
12930
- return;
12931
- }
12932
- if (HAS_NATIVE_TA && supportsPassive && passiveTouchGestures) {
12933
- return { passive: true };
12954
+ class SlotController extends EventTarget {
12955
+ /**
12956
+ * Ensure that every instance has unique ID.
12957
+ *
12958
+ * @param {string} slotName
12959
+ * @param {HTMLElement} host
12960
+ * @return {string}
12961
+ * @protected
12962
+ */
12963
+ static generateId(slotName, host) {
12964
+ const prefix = slotName || 'default';
12965
+ return `${prefix}-${host.localName}-${generateUniqueId()}`;
12934
12966
  }
12935
- }
12936
12967
 
12937
- // Check for touch-only devices
12938
- const IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);
12968
+ constructor(host, slotName, slotFactory, slotInitializer, useUniqueId) {
12969
+ super();
12939
12970
 
12940
- // Defined at https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute
12941
- /** @type {!Object<boolean>} */
12942
- const canBeDisabled = {
12943
- button: true,
12944
- command: true,
12945
- fieldset: true,
12946
- input: true,
12947
- keygen: true,
12948
- optgroup: true,
12949
- option: true,
12950
- select: true,
12951
- textarea: true,
12952
- };
12971
+ this.host = host;
12972
+ this.slotName = slotName;
12973
+ this.slotFactory = slotFactory;
12974
+ this.slotInitializer = slotInitializer;
12953
12975
 
12954
- /**
12955
- * @param {MouseEvent} ev event to test for left mouse button down
12956
- * @return {boolean} has left mouse button down
12957
- */
12958
- function hasLeftMouseButton(ev) {
12959
- const type = ev.type;
12960
- // Exit early if the event is not a mouse event
12961
- if (!isMouseEvent(type)) {
12962
- return false;
12963
- }
12964
- // Ev.button is not reliable for mousemove (0 is overloaded as both left button and no buttons)
12965
- // instead we use ev.buttons (bitmask of buttons) or fall back to ev.which (deprecated, 0 for no buttons, 1 for left button)
12966
- if (type === 'mousemove') {
12967
- // Allow undefined for testing events
12968
- let buttons = ev.buttons === undefined ? 1 : ev.buttons;
12969
- if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {
12970
- buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;
12976
+ // Only generate the default ID if requested by the controller.
12977
+ if (useUniqueId) {
12978
+ this.defaultId = SlotController.generateId(slotName, host);
12971
12979
  }
12972
- // Buttons is a bitmask, check that the left button bit is set (1)
12973
- return Boolean(buttons & 1);
12974
12980
  }
12975
- // Allow undefined for testing events
12976
- const button = ev.button === undefined ? 0 : ev.button;
12977
- // Ev.button is 0 in mousedown/mouseup/click for left button activation
12978
- return button === 0;
12979
- }
12980
12981
 
12981
- function isSyntheticClick(ev) {
12982
- if (ev.type === 'click') {
12983
- // Ev.detail is 0 for HTMLElement.click in most browsers
12984
- if (ev.detail === 0) {
12985
- return true;
12986
- }
12987
- // In the worst case, check that the x/y position of the click is within
12988
- // the bounding box of the target of the event
12989
- // Thanks IE 10 >:(
12990
- const t = _findOriginalTarget(ev);
12991
- // Make sure the target of the event is an element so we can use getBoundingClientRect,
12992
- // if not, just assume it is a synthetic click
12993
- if (!t.nodeType || /** @type {Element} */ (t).nodeType !== Node.ELEMENT_NODE) {
12994
- return true;
12995
- }
12996
- const bcr = /** @type {Element} */ (t).getBoundingClientRect();
12997
- // Use page x/y to account for scrolling
12998
- const x = ev.pageX,
12999
- y = ev.pageY;
13000
- // Ev is a synthetic click if the position is outside the bounding box of the target
13001
- return !(x >= bcr.left && x <= bcr.right && y >= bcr.top && y <= bcr.bottom);
13002
- }
13003
- return false;
13004
- }
12982
+ hostConnected() {
12983
+ if (!this.initialized) {
12984
+ let node = this.getSlotChild();
13005
12985
 
13006
- const POINTERSTATE = {
13007
- mouse: {
13008
- target: null,
13009
- mouseIgnoreJob: null,
13010
- },
13011
- touch: {
13012
- x: 0,
13013
- y: 0,
13014
- id: -1,
12986
+ if (!node) {
12987
+ node = this.attachDefaultNode();
12988
+ } else {
12989
+ this.node = node;
12990
+ this.initCustomNode(node);
12991
+ }
12992
+
12993
+ this.initNode(node);
12994
+
12995
+ // TODO: Consider making this behavior opt-in to improve performance.
12996
+ this.observe();
12997
+
12998
+ this.initialized = true;
12999
+ }
13000
+ }
13001
+
13002
+ /**
13003
+ * Create and attach default node using the slot factory.
13004
+ * @return {Node | undefined}
13005
+ * @protected
13006
+ */
13007
+ attachDefaultNode() {
13008
+ const { host, slotName, slotFactory } = this;
13009
+
13010
+ // Check if the node was created previously and if so, reuse it.
13011
+ let node = this.defaultNode;
13012
+
13013
+ // Slot factory is optional, some slots don't have default content.
13014
+ if (!node && slotFactory) {
13015
+ node = slotFactory(host);
13016
+ if (node instanceof Element) {
13017
+ if (slotName !== '') {
13018
+ node.setAttribute('slot', slotName);
13019
+ }
13020
+ this.node = node;
13021
+ this.defaultNode = node;
13022
+ }
13023
+ }
13024
+
13025
+ if (node) {
13026
+ host.appendChild(node);
13027
+ }
13028
+
13029
+ return node;
13030
+ }
13031
+
13032
+ /**
13033
+ * Return a reference to the node managed by the controller.
13034
+ * @return {Node}
13035
+ */
13036
+ getSlotChild() {
13037
+ const { slotName } = this;
13038
+ return Array.from(this.host.childNodes).find((node) => {
13039
+ // Either an element (any slot) or a text node (only un-named slot).
13040
+ return (
13041
+ (node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) ||
13042
+ (node.nodeType === Node.TEXT_NODE && node.textContent.trim() && slotName === '')
13043
+ );
13044
+ });
13045
+ }
13046
+
13047
+ /**
13048
+ * @param {Node} node
13049
+ * @protected
13050
+ */
13051
+ initNode(node) {
13052
+ const { slotInitializer } = this;
13053
+ // Don't try to bind `this` to initializer (normally it's arrow function).
13054
+ // Instead, pass the host as a first argument to access component's state.
13055
+ if (slotInitializer) {
13056
+ slotInitializer(this.host, node);
13057
+ }
13058
+ }
13059
+
13060
+ /**
13061
+ * Override to initialize the newly added custom node.
13062
+ *
13063
+ * @param {Node} _node
13064
+ * @protected
13065
+ */
13066
+ initCustomNode(_node) {}
13067
+
13068
+ /**
13069
+ * Override to teardown slotted node when it's removed.
13070
+ *
13071
+ * @param {Node} _node
13072
+ * @protected
13073
+ */
13074
+ teardownNode(_node) {}
13075
+
13076
+ /**
13077
+ * Setup the observer to manage slot content changes.
13078
+ * @protected
13079
+ */
13080
+ observe() {
13081
+ const { slotName } = this;
13082
+ const selector = slotName === '' ? 'slot:not([name])' : `slot[name=${slotName}]`;
13083
+ const slot = this.host.shadowRoot.querySelector(selector);
13084
+
13085
+ this.__slotObserver = new FlattenedNodesObserver(slot, (info) => {
13086
+ // TODO: support default slot with multiple nodes (e.g. confirm-dialog)
13087
+ const current = this.node;
13088
+ const newNode = info.addedNodes.find((node) => node !== current);
13089
+
13090
+ if (info.removedNodes.length) {
13091
+ info.removedNodes.forEach((node) => {
13092
+ this.teardownNode(node);
13093
+ });
13094
+ }
13095
+
13096
+ if (newNode) {
13097
+ // Custom node is added, remove the current one.
13098
+ if (current && current.isConnected) {
13099
+ this.host.removeChild(current);
13100
+ }
13101
+
13102
+ this.node = newNode;
13103
+
13104
+ if (newNode !== this.defaultNode) {
13105
+ this.initCustomNode(newNode);
13106
+
13107
+ this.initNode(newNode);
13108
+ }
13109
+ }
13110
+ });
13111
+ }
13112
+ }
13113
+
13114
+ /**
13115
+ * @license
13116
+ * Copyright (c) 2022 Vaadin Ltd.
13117
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
13118
+ */
13119
+
13120
+ /**
13121
+ * A controller that manages the slotted tooltip element.
13122
+ */
13123
+ class TooltipController extends SlotController {
13124
+ constructor(host) {
13125
+ // Do not provide slot factory to create tooltip lazily.
13126
+ super(host, 'tooltip');
13127
+
13128
+ this.setTarget(host);
13129
+ }
13130
+
13131
+ /**
13132
+ * Override to initialize the newly added custom tooltip.
13133
+ *
13134
+ * @param {Node} tooltipNode
13135
+ * @protected
13136
+ * @override
13137
+ */
13138
+ initCustomNode(tooltipNode) {
13139
+ tooltipNode.target = this.target;
13140
+
13141
+ if (this.context !== undefined) {
13142
+ tooltipNode.context = this.context;
13143
+ }
13144
+
13145
+ if (this.manual !== undefined) {
13146
+ tooltipNode.manual = this.manual;
13147
+ }
13148
+
13149
+ if (this.opened !== undefined) {
13150
+ tooltipNode.opened = this.opened;
13151
+ }
13152
+
13153
+ if (this.position !== undefined) {
13154
+ tooltipNode._position = this.position;
13155
+ }
13156
+
13157
+ if (this.shouldShow !== undefined) {
13158
+ tooltipNode.shouldShow = this.shouldShow;
13159
+ }
13160
+ }
13161
+
13162
+ /**
13163
+ * Set a context object to be used by generator.
13164
+ * @param {object} context
13165
+ */
13166
+ setContext(context) {
13167
+ this.context = context;
13168
+
13169
+ const tooltipNode = this.node;
13170
+ if (tooltipNode) {
13171
+ tooltipNode.context = context;
13172
+ }
13173
+ }
13174
+
13175
+ /**
13176
+ * Toggle manual state on the slotted tooltip.
13177
+ * @param {boolean} manual
13178
+ */
13179
+ setManual(manual) {
13180
+ this.manual = manual;
13181
+
13182
+ const tooltipNode = this.node;
13183
+ if (tooltipNode) {
13184
+ tooltipNode.manual = manual;
13185
+ }
13186
+ }
13187
+
13188
+ /**
13189
+ * Toggle opened state on the slotted tooltip.
13190
+ * @param {boolean} opened
13191
+ */
13192
+ setOpened(opened) {
13193
+ this.opened = opened;
13194
+
13195
+ const tooltipNode = this.node;
13196
+ if (tooltipNode) {
13197
+ tooltipNode.opened = opened;
13198
+ }
13199
+ }
13200
+
13201
+ /**
13202
+ * Set default position for the slotted tooltip.
13203
+ * This can be overridden by setting the position
13204
+ * using corresponding property or attribute.
13205
+ * @param {string} position
13206
+ */
13207
+ setPosition(position) {
13208
+ this.position = position;
13209
+
13210
+ const tooltipNode = this.node;
13211
+ if (tooltipNode) {
13212
+ tooltipNode._position = position;
13213
+ }
13214
+ }
13215
+
13216
+ /**
13217
+ * Set function used to detect whether to show
13218
+ * the tooltip based on a condition.
13219
+ * @param {Function} shouldShow
13220
+ */
13221
+ setShouldShow(shouldShow) {
13222
+ this.shouldShow = shouldShow;
13223
+
13224
+ const tooltipNode = this.node;
13225
+ if (tooltipNode) {
13226
+ tooltipNode.shouldShow = shouldShow;
13227
+ }
13228
+ }
13229
+
13230
+ /**
13231
+ * Set an HTML element to attach the tooltip to.
13232
+ * @param {HTMLElement} target
13233
+ */
13234
+ setTarget(target) {
13235
+ this.target = target;
13236
+
13237
+ const tooltipNode = this.node;
13238
+ if (tooltipNode) {
13239
+ tooltipNode.target = target;
13240
+ }
13241
+ }
13242
+ }
13243
+
13244
+ /**
13245
+ * @license
13246
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
13247
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
13248
+ */
13249
+
13250
+ /**
13251
+ * A mixin to provide disabled property for field components.
13252
+ *
13253
+ * @polymerMixin
13254
+ */
13255
+ const DisabledMixin = dedupingMixin(
13256
+ (superclass) =>
13257
+ class DisabledMixinClass extends superclass {
13258
+ static get properties() {
13259
+ return {
13260
+ /**
13261
+ * If true, the user cannot interact with this element.
13262
+ */
13263
+ disabled: {
13264
+ type: Boolean,
13265
+ value: false,
13266
+ observer: '_disabledChanged',
13267
+ reflectToAttribute: true,
13268
+ },
13269
+ };
13270
+ }
13271
+
13272
+ /**
13273
+ * @param {boolean} disabled
13274
+ * @protected
13275
+ */
13276
+ _disabledChanged(disabled) {
13277
+ this._setAriaDisabled(disabled);
13278
+ }
13279
+
13280
+ /**
13281
+ * @param {boolean} disabled
13282
+ * @protected
13283
+ */
13284
+ _setAriaDisabled(disabled) {
13285
+ if (disabled) {
13286
+ this.setAttribute('aria-disabled', 'true');
13287
+ } else {
13288
+ this.removeAttribute('aria-disabled');
13289
+ }
13290
+ }
13291
+
13292
+ /**
13293
+ * Overrides the default element `click` method in order to prevent
13294
+ * firing the `click` event when the element is disabled.
13295
+ * @protected
13296
+ * @override
13297
+ */
13298
+ click() {
13299
+ if (!this.disabled) {
13300
+ super.click();
13301
+ }
13302
+ }
13303
+ },
13304
+ );
13305
+
13306
+ /**
13307
+ @license
13308
+ Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
13309
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
13310
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
13311
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
13312
+ Code distributed by Google as part of the polymer project is also
13313
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
13314
+ */
13315
+
13316
+ const passiveTouchGestures = false;
13317
+ const wrap = (node) => node;
13318
+
13319
+ // Detect native touch action support
13320
+ const HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
13321
+ const GESTURE_KEY = '__polymerGestures';
13322
+ const HANDLED_OBJ = '__polymerGesturesHandled';
13323
+ const TOUCH_ACTION = '__polymerGesturesTouchAction';
13324
+ // Radius for tap and track
13325
+ const TAP_DISTANCE = 25;
13326
+ const TRACK_DISTANCE = 5;
13327
+ // Number of last N track positions to keep
13328
+ const TRACK_LENGTH = 2;
13329
+
13330
+ const MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'click'];
13331
+ // An array of bitmask values for mapping MouseEvent.which to MouseEvent.buttons
13332
+ const MOUSE_WHICH_TO_BUTTONS = [0, 1, 4, 2];
13333
+ const MOUSE_HAS_BUTTONS = (function () {
13334
+ try {
13335
+ return new MouseEvent('test', { buttons: 1 }).buttons === 1;
13336
+ } catch (e) {
13337
+ return false;
13338
+ }
13339
+ })();
13340
+
13341
+ /**
13342
+ * @param {string} name Possible mouse event name
13343
+ * @return {boolean} true if mouse event, false if not
13344
+ */
13345
+ function isMouseEvent(name) {
13346
+ return MOUSE_EVENTS.indexOf(name) > -1;
13347
+ }
13348
+
13349
+ /* eslint no-empty: ["error", { "allowEmptyCatch": true }] */
13350
+ // check for passive event listeners
13351
+ let supportsPassive = false;
13352
+ (function () {
13353
+ try {
13354
+ const opts = Object.defineProperty({}, 'passive', {
13355
+ // eslint-disable-next-line getter-return
13356
+ get() {
13357
+ supportsPassive = true;
13358
+ },
13359
+ });
13360
+ window.addEventListener('test', null, opts);
13361
+ window.removeEventListener('test', null, opts);
13362
+ } catch (e) {}
13363
+ })();
13364
+
13365
+ /**
13366
+ * Generate settings for event listeners, dependant on `passiveTouchGestures`
13367
+ *
13368
+ * @param {string} eventName Event name to determine if `{passive}` option is
13369
+ * needed
13370
+ * @return {{passive: boolean} | undefined} Options to use for addEventListener
13371
+ * and removeEventListener
13372
+ */
13373
+ function PASSIVE_TOUCH(eventName) {
13374
+ if (isMouseEvent(eventName) || eventName === 'touchend') {
13375
+ return;
13376
+ }
13377
+ if (HAS_NATIVE_TA && supportsPassive && passiveTouchGestures) {
13378
+ return { passive: true };
13379
+ }
13380
+ }
13381
+
13382
+ // Check for touch-only devices
13383
+ const IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);
13384
+
13385
+ // Defined at https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute
13386
+ /** @type {!Object<boolean>} */
13387
+ const canBeDisabled = {
13388
+ button: true,
13389
+ command: true,
13390
+ fieldset: true,
13391
+ input: true,
13392
+ keygen: true,
13393
+ optgroup: true,
13394
+ option: true,
13395
+ select: true,
13396
+ textarea: true,
13397
+ };
13398
+
13399
+ /**
13400
+ * @param {MouseEvent} ev event to test for left mouse button down
13401
+ * @return {boolean} has left mouse button down
13402
+ */
13403
+ function hasLeftMouseButton(ev) {
13404
+ const type = ev.type;
13405
+ // Exit early if the event is not a mouse event
13406
+ if (!isMouseEvent(type)) {
13407
+ return false;
13408
+ }
13409
+ // Ev.button is not reliable for mousemove (0 is overloaded as both left button and no buttons)
13410
+ // instead we use ev.buttons (bitmask of buttons) or fall back to ev.which (deprecated, 0 for no buttons, 1 for left button)
13411
+ if (type === 'mousemove') {
13412
+ // Allow undefined for testing events
13413
+ let buttons = ev.buttons === undefined ? 1 : ev.buttons;
13414
+ if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {
13415
+ buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;
13416
+ }
13417
+ // Buttons is a bitmask, check that the left button bit is set (1)
13418
+ return Boolean(buttons & 1);
13419
+ }
13420
+ // Allow undefined for testing events
13421
+ const button = ev.button === undefined ? 0 : ev.button;
13422
+ // Ev.button is 0 in mousedown/mouseup/click for left button activation
13423
+ return button === 0;
13424
+ }
13425
+
13426
+ function isSyntheticClick(ev) {
13427
+ if (ev.type === 'click') {
13428
+ // Ev.detail is 0 for HTMLElement.click in most browsers
13429
+ if (ev.detail === 0) {
13430
+ return true;
13431
+ }
13432
+ // In the worst case, check that the x/y position of the click is within
13433
+ // the bounding box of the target of the event
13434
+ // Thanks IE 10 >:(
13435
+ const t = _findOriginalTarget(ev);
13436
+ // Make sure the target of the event is an element so we can use getBoundingClientRect,
13437
+ // if not, just assume it is a synthetic click
13438
+ if (!t.nodeType || /** @type {Element} */ (t).nodeType !== Node.ELEMENT_NODE) {
13439
+ return true;
13440
+ }
13441
+ const bcr = /** @type {Element} */ (t).getBoundingClientRect();
13442
+ // Use page x/y to account for scrolling
13443
+ const x = ev.pageX,
13444
+ y = ev.pageY;
13445
+ // Ev is a synthetic click if the position is outside the bounding box of the target
13446
+ return !(x >= bcr.left && x <= bcr.right && y >= bcr.top && y <= bcr.bottom);
13447
+ }
13448
+ return false;
13449
+ }
13450
+
13451
+ const POINTERSTATE = {
13452
+ mouse: {
13453
+ target: null,
13454
+ mouseIgnoreJob: null,
13455
+ },
13456
+ touch: {
13457
+ x: 0,
13458
+ y: 0,
13459
+ id: -1,
13015
13460
  scrollDecided: false,
13016
13461
  },
13017
13462
  };
@@ -13122,7 +13567,7 @@ function _handleNative(ev) {
13122
13567
  }
13123
13568
  if (!ev[HANDLED_OBJ]) {
13124
13569
  ev[HANDLED_OBJ] = {};
13125
- if (type.slice(0, 5) === 'touch') {
13570
+ if (type.startsWith('touch')) {
13126
13571
  const t = ev.changedTouches[0];
13127
13572
  if (type === 'touchstart') {
13128
13573
  // Only handle the first finger
@@ -13692,101 +14137,39 @@ register({
13692
14137
  * @this {GestureRecognizer}
13693
14138
  * @param {TouchEvent} e
13694
14139
  * @return {void}
13695
- */
13696
- touchend(e) {
13697
- trackForward(this.info, e.changedTouches[0], e);
13698
- },
13699
- });
13700
-
13701
- /**
13702
- * @param {!GestureInfo} info
13703
- * @param {Event | Touch} e
13704
- * @param {Event=} preventer
13705
- * @return {void}
13706
- */
13707
- function trackForward(info, e, preventer) {
13708
- const dx = Math.abs(e.clientX - info.x);
13709
- const dy = Math.abs(e.clientY - info.y);
13710
- // Find original target from `preventer` for TouchEvents, or `e` for MouseEvents
13711
- const t = _findOriginalTarget(preventer || e);
13712
- if (!t || (canBeDisabled[/** @type {!HTMLElement} */ (t).localName] && t.hasAttribute('disabled'))) {
13713
- return;
13714
- }
13715
- // Dx,dy can be NaN if `click` has been simulated and there was no `down` for `start`
13716
- if (isNaN(dx) || isNaN(dy) || (dx <= TAP_DISTANCE && dy <= TAP_DISTANCE) || isSyntheticClick(e)) {
13717
- // Prevent taps from being generated if an event has canceled them
13718
- if (!info.prevent) {
13719
- _fire(t, 'tap', {
13720
- x: e.clientX,
13721
- y: e.clientY,
13722
- sourceEvent: e,
13723
- preventer,
13724
- });
13725
- }
13726
- }
13727
- }
13728
-
13729
- /**
13730
- * @license
13731
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
13732
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
13733
- */
13734
-
13735
- /**
13736
- * A mixin to provide disabled property for field components.
13737
- *
13738
- * @polymerMixin
13739
- */
13740
- const DisabledMixin = dedupingMixin(
13741
- (superclass) =>
13742
- class DisabledMixinClass extends superclass {
13743
- static get properties() {
13744
- return {
13745
- /**
13746
- * If true, the user cannot interact with this element.
13747
- */
13748
- disabled: {
13749
- type: Boolean,
13750
- value: false,
13751
- observer: '_disabledChanged',
13752
- reflectToAttribute: true,
13753
- },
13754
- };
13755
- }
13756
-
13757
- /**
13758
- * @param {boolean} disabled
13759
- * @protected
13760
- */
13761
- _disabledChanged(disabled) {
13762
- this._setAriaDisabled(disabled);
13763
- }
13764
-
13765
- /**
13766
- * @param {boolean} disabled
13767
- * @protected
13768
- */
13769
- _setAriaDisabled(disabled) {
13770
- if (disabled) {
13771
- this.setAttribute('aria-disabled', 'true');
13772
- } else {
13773
- this.removeAttribute('aria-disabled');
13774
- }
13775
- }
14140
+ */
14141
+ touchend(e) {
14142
+ trackForward(this.info, e.changedTouches[0], e);
14143
+ },
14144
+ });
13776
14145
 
13777
- /**
13778
- * Overrides the default element `click` method in order to prevent
13779
- * firing the `click` event when the element is disabled.
13780
- * @protected
13781
- * @override
13782
- */
13783
- click() {
13784
- if (!this.disabled) {
13785
- super.click();
13786
- }
13787
- }
13788
- },
13789
- );
14146
+ /**
14147
+ * @param {!GestureInfo} info
14148
+ * @param {Event | Touch} e
14149
+ * @param {Event=} preventer
14150
+ * @return {void}
14151
+ */
14152
+ function trackForward(info, e, preventer) {
14153
+ const dx = Math.abs(e.clientX - info.x);
14154
+ const dy = Math.abs(e.clientY - info.y);
14155
+ // Find original target from `preventer` for TouchEvents, or `e` for MouseEvents
14156
+ const t = _findOriginalTarget(preventer || e);
14157
+ if (!t || (canBeDisabled[/** @type {!HTMLElement} */ (t).localName] && t.hasAttribute('disabled'))) {
14158
+ return;
14159
+ }
14160
+ // Dx,dy can be NaN if `click` has been simulated and there was no `down` for `start`
14161
+ if (isNaN(dx) || isNaN(dy) || (dx <= TAP_DISTANCE && dy <= TAP_DISTANCE) || isSyntheticClick(e)) {
14162
+ // Prevent taps from being generated if an event has canceled them
14163
+ if (!info.prevent) {
14164
+ _fire(t, 'tap', {
14165
+ x: e.clientX,
14166
+ y: e.clientY,
14167
+ sourceEvent: e,
14168
+ preventer,
14169
+ });
14170
+ }
14171
+ }
14172
+ }
13790
14173
 
13791
14174
  /**
13792
14175
  * @license
@@ -13981,28 +14364,6 @@ const ActiveMixin = (superclass) =>
13981
14364
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
13982
14365
  */
13983
14366
 
13984
- // We consider the keyboard to be active if the window has received a keydown
13985
- // event since the last mousedown event.
13986
- let keyboardActive = false;
13987
-
13988
- // Listen for top-level keydown and mousedown events.
13989
- // Use capture phase so we detect events even if they're handled.
13990
- window.addEventListener(
13991
- 'keydown',
13992
- () => {
13993
- keyboardActive = true;
13994
- },
13995
- { capture: true },
13996
- );
13997
-
13998
- window.addEventListener(
13999
- 'mousedown',
14000
- () => {
14001
- keyboardActive = false;
14002
- },
14003
- { capture: true },
14004
- );
14005
-
14006
14367
  /**
14007
14368
  * A mixin to handle `focused` and `focus-ring` attributes based on focus.
14008
14369
  *
@@ -14016,7 +14377,7 @@ const FocusMixin = dedupingMixin(
14016
14377
  * @return {boolean}
14017
14378
  */
14018
14379
  get _keyboardActive() {
14019
- return keyboardActive;
14380
+ return isKeyboardActive();
14020
14381
  }
14021
14382
 
14022
14383
  /** @protected */
@@ -14280,14 +14641,15 @@ const ButtonMixin = (superClass) =>
14280
14641
  * `focus-ring` | Set when the button is focused using the keyboard.
14281
14642
  * `focused` | Set when the button is focused.
14282
14643
  *
14283
- * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
14644
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
14284
14645
  *
14285
14646
  * @extends HTMLElement
14286
14647
  * @mixes ButtonMixin
14648
+ * @mixes ControllerMixin
14287
14649
  * @mixes ElementMixin
14288
14650
  * @mixes ThemableMixin
14289
14651
  */
14290
- class Button extends ButtonMixin(ElementMixin(ThemableMixin(PolymerElement))) {
14652
+ class Button extends ButtonMixin(ElementMixin(ThemableMixin(ControllerMixin(PolymerElement)))) {
14291
14653
  static get is() {
14292
14654
  return 'vaadin-button';
14293
14655
  }
@@ -14341,18 +14703,27 @@ class Button extends ButtonMixin(ElementMixin(ThemableMixin(PolymerElement))) {
14341
14703
  }
14342
14704
  </style>
14343
14705
  <div class="vaadin-button-container">
14344
- <span part="prefix">
14706
+ <span part="prefix" aria-hidden="true">
14345
14707
  <slot name="prefix"></slot>
14346
14708
  </span>
14347
14709
  <span part="label">
14348
14710
  <slot></slot>
14349
14711
  </span>
14350
- <span part="suffix">
14712
+ <span part="suffix" aria-hidden="true">
14351
14713
  <slot name="suffix"></slot>
14352
14714
  </span>
14353
14715
  </div>
14716
+ <slot name="tooltip"></slot>
14354
14717
  `;
14355
14718
  }
14719
+
14720
+ /** @protected */
14721
+ ready() {
14722
+ super.ready();
14723
+
14724
+ this._tooltipController = new TooltipController(this);
14725
+ this.addController(this._tooltipController);
14726
+ }
14356
14727
  }
14357
14728
 
14358
14729
  customElements.define(Button.is, Button);
@@ -14362,7 +14733,6 @@ registerStyles(
14362
14733
  i$1`
14363
14734
  :host {
14364
14735
  position: relative;
14365
- background-color: transparent;
14366
14736
  /* Background for the year scroller, placed here as we are using a mask image on the actual years part */
14367
14737
  background-image: linear-gradient(var(--lumo-shade-5pct), var(--lumo-shade-5pct));
14368
14738
  background-size: 57px 100%;
@@ -14388,7 +14758,7 @@ registerStyles(
14388
14758
  + var(--lumo-size-m) * 6
14389
14759
  + var(--lumo-space-s)
14390
14760
  );
14391
- --vaadin-infinite-scroller-buffer-offset: 20%;
14761
+ --vaadin-infinite-scroller-buffer-offset: 10%;
14392
14762
  -webkit-mask-image: linear-gradient(transparent, #000 10%, #000 85%, transparent);
14393
14763
  mask-image: linear-gradient(transparent, #000 10%, #000 85%, transparent);
14394
14764
  position: relative;
@@ -14470,17 +14840,10 @@ registerStyles(
14470
14840
 
14471
14841
  [part='toolbar'] {
14472
14842
  padding: var(--lumo-space-s);
14473
- box-shadow: 0 -1px 0 0 var(--lumo-contrast-10pct);
14474
14843
  border-bottom-left-radius: var(--lumo-border-radius-l);
14475
14844
  margin-right: 57px;
14476
14845
  }
14477
14846
 
14478
- @supports (mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000)) {
14479
- [part='toolbar'] {
14480
- box-shadow: none;
14481
- }
14482
- }
14483
-
14484
14847
  /* Today and Cancel buttons */
14485
14848
 
14486
14849
  [part='toolbar'] [part\$='button'] {
@@ -14513,8 +14876,6 @@ registerStyles(
14513
14876
  /* Very narrow screen (year scroller initially hidden) */
14514
14877
 
14515
14878
  [part='years-toggle-button'] {
14516
- position: relative;
14517
- right: auto;
14518
14879
  display: flex;
14519
14880
  align-items: center;
14520
14881
  height: var(--lumo-size-s);
@@ -14532,11 +14893,7 @@ registerStyles(
14532
14893
  color: var(--lumo-primary-contrast-color);
14533
14894
  }
14534
14895
 
14535
- [part='years-toggle-button']::before {
14536
- content: none;
14537
- }
14538
-
14539
- /* TODO magic number (same as used for iron-media-query in vaadin-date-picker-overlay-content) */
14896
+ /* TODO magic number (same as used for media-query in vaadin-date-picker-overlay-content) */
14540
14897
  @media screen and (max-width: 374px) {
14541
14898
  :host {
14542
14899
  background-image: none;
@@ -14711,9 +15068,9 @@ registerStyles(
14711
15068
  { moduleId: 'lumo-month-calendar' },
14712
15069
  );
14713
15070
 
14714
- const $_documentContainer$1 = document.createElement('template');
15071
+ const template$1 = document.createElement('template');
14715
15072
 
14716
- $_documentContainer$1.innerHTML = `
15073
+ template$1.innerHTML = `
14717
15074
  <style>
14718
15075
  @keyframes vaadin-date-picker-month-calendar-focus-date {
14719
15076
  50% {
@@ -14723,7 +15080,7 @@ $_documentContainer$1.innerHTML = `
14723
15080
  </style>
14724
15081
  `;
14725
15082
 
14726
- document.head.appendChild($_documentContainer$1.content);
15083
+ document.head.appendChild(template$1.content);
14727
15084
 
14728
15085
  /**
14729
15086
  * @license
@@ -14731,9 +15088,9 @@ document.head.appendChild($_documentContainer$1.content);
14731
15088
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
14732
15089
  */
14733
15090
 
14734
- const $_documentContainer = document.createElement('template');
15091
+ const template = document.createElement('template');
14735
15092
 
14736
- $_documentContainer.innerHTML = `
15093
+ template.innerHTML = `
14737
15094
  <style>
14738
15095
  @font-face {
14739
15096
  font-family: 'lumo-icons';
@@ -14789,7 +15146,7 @@ $_documentContainer.innerHTML = `
14789
15146
  </style>
14790
15147
  `;
14791
15148
 
14792
- document.head.appendChild($_documentContainer.content);
15149
+ document.head.appendChild(template.content);
14793
15150
 
14794
15151
  /**
14795
15152
  * @license
@@ -14903,6 +15260,10 @@ const requiredField = i$1`
14903
15260
  line-height: 1;
14904
15261
  padding-right: 1em;
14905
15262
  padding-bottom: 0.5em;
15263
+ /* As a workaround for diacritics being cut off, add a top padding and a
15264
+ negative margin to compensate */
15265
+ padding-top: 0.25em;
15266
+ margin-top: -0.25em;
14906
15267
  overflow: hidden;
14907
15268
  white-space: nowrap;
14908
15269
  text-overflow: ellipsis;
@@ -14923,6 +15284,10 @@ const requiredField = i$1`
14923
15284
  padding-top: var(--lumo-space-m);
14924
15285
  }
14925
15286
 
15287
+ :host([has-label]) ::slotted([slot='tooltip']) {
15288
+ --vaadin-tooltip-offset-bottom: calc((var(--lumo-space-m) - var(--lumo-space-xs)) * -1);
15289
+ }
15290
+
14926
15291
  :host([required]) [part='required-indicator']::after {
14927
15292
  content: var(--lumo-required-field-indicator, '•');
14928
15293
  transition: opacity 0.2s;
@@ -15356,6 +15721,57 @@ function getAncestorRootNodes(node) {
15356
15721
  return result;
15357
15722
  }
15358
15723
 
15724
+ /**
15725
+ * @param {string} value
15726
+ * @return {Set<string>}
15727
+ */
15728
+ function deserializeAttributeValue(value) {
15729
+ if (!value) {
15730
+ return new Set();
15731
+ }
15732
+
15733
+ return new Set(value.split(' '));
15734
+ }
15735
+
15736
+ /**
15737
+ * @param {Set<string>} values
15738
+ * @return {string}
15739
+ */
15740
+ function serializeAttributeValue(values) {
15741
+ return [...values].join(' ');
15742
+ }
15743
+
15744
+ /**
15745
+ * Adds a value to an attribute containing space-delimited values.
15746
+ *
15747
+ * @param {HTMLElement} element
15748
+ * @param {string} attr
15749
+ * @param {string} value
15750
+ */
15751
+ function addValueToAttribute(element, attr, value) {
15752
+ const values = deserializeAttributeValue(element.getAttribute(attr));
15753
+ values.add(value);
15754
+ element.setAttribute(attr, serializeAttributeValue(values));
15755
+ }
15756
+
15757
+ /**
15758
+ * Removes a value from an attribute containing space-delimited values.
15759
+ * If the value is the last one, the whole attribute is removed.
15760
+ *
15761
+ * @param {HTMLElement} element
15762
+ * @param {string} attr
15763
+ * @param {string} value
15764
+ */
15765
+ function removeValueFromAttribute(element, attr, value) {
15766
+ const values = deserializeAttributeValue(element.getAttribute(attr));
15767
+ values.delete(value);
15768
+ if (values.size === 0) {
15769
+ element.removeAttribute(attr);
15770
+ return;
15771
+ }
15772
+ element.setAttribute(attr, serializeAttributeValue(values));
15773
+ }
15774
+
15359
15775
  /**
15360
15776
  * @license
15361
15777
  * Copyright (c) 2017 - 2022 Vaadin Ltd.
@@ -15372,6 +15788,16 @@ const PROP_NAMES_HORIZONTAL = {
15372
15788
  end: 'right',
15373
15789
  };
15374
15790
 
15791
+ const targetResizeObserver = new ResizeObserver((entries) => {
15792
+ setTimeout(() => {
15793
+ entries.forEach((entry) => {
15794
+ if (entry.target.__overlay) {
15795
+ entry.target.__overlay._updatePosition();
15796
+ }
15797
+ });
15798
+ });
15799
+ });
15800
+
15375
15801
  /**
15376
15802
  * @polymerMixin
15377
15803
  */
@@ -15397,6 +15823,8 @@ const PositionMixin = (superClass) =>
15397
15823
  * RTL is taken into account when interpreting the value.
15398
15824
  * The overlay is automatically flipped to the opposite side when it doesn't fit into
15399
15825
  * the default side defined by this property.
15826
+ *
15827
+ * @attr {start|end} horizontal-align
15400
15828
  */
15401
15829
  horizontalAlign: {
15402
15830
  type: String,
@@ -15409,6 +15837,8 @@ const PositionMixin = (superClass) =>
15409
15837
  * Possible values are `top` and `bottom`.
15410
15838
  * The overlay is automatically flipped to the opposite side when it doesn't fit into
15411
15839
  * the default side defined by this property.
15840
+ *
15841
+ * @attr {top|bottom} vertical-align
15412
15842
  */
15413
15843
  verticalAlign: {
15414
15844
  type: String,
@@ -15418,6 +15848,8 @@ const PositionMixin = (superClass) =>
15418
15848
  /**
15419
15849
  * When `positionTarget` is set, this property defines whether the overlay should overlap
15420
15850
  * the target element in the x-axis, or be positioned right next to it.
15851
+ *
15852
+ * @attr {boolean} no-horizontal-overlap
15421
15853
  */
15422
15854
  noHorizontalOverlap: {
15423
15855
  type: Boolean,
@@ -15427,17 +15859,32 @@ const PositionMixin = (superClass) =>
15427
15859
  /**
15428
15860
  * When `positionTarget` is set, this property defines whether the overlay should overlap
15429
15861
  * the target element in the y-axis, or be positioned right above/below it.
15862
+ *
15863
+ * @attr {boolean} no-vertical-overlap
15430
15864
  */
15431
15865
  noVerticalOverlap: {
15432
15866
  type: Boolean,
15433
15867
  value: false,
15434
15868
  },
15869
+
15870
+ /**
15871
+ * If the overlay content has no intrinsic height, this property can be used to set
15872
+ * the minimum vertical space (in pixels) required by the overlay. Setting a value to
15873
+ * the property effectively disables the content measurement in favor of using this
15874
+ * fixed value for determining the open direction.
15875
+ *
15876
+ * @attr {number} required-vertical-space
15877
+ */
15878
+ requiredVerticalSpace: {
15879
+ type: Number,
15880
+ value: 0,
15881
+ },
15435
15882
  };
15436
15883
  }
15437
15884
 
15438
15885
  static get observers() {
15439
15886
  return [
15440
- '__positionSettingsChanged(horizontalAlign, verticalAlign, noHorizontalOverlap, noVerticalOverlap)',
15887
+ '__positionSettingsChanged(horizontalAlign, verticalAlign, noHorizontalOverlap, noVerticalOverlap, requiredVerticalSpace)',
15441
15888
  '__overlayOpenedChanged(opened, positionTarget)',
15442
15889
  ];
15443
15890
  }
@@ -15445,6 +15892,7 @@ const PositionMixin = (superClass) =>
15445
15892
  constructor() {
15446
15893
  super();
15447
15894
 
15895
+ this.__onScroll = this.__onScroll.bind(this);
15448
15896
  this._updatePosition = this._updatePosition.bind(this);
15449
15897
  }
15450
15898
 
@@ -15469,7 +15917,7 @@ const PositionMixin = (superClass) =>
15469
15917
 
15470
15918
  this.__positionTargetAncestorRootNodes = getAncestorRootNodes(this.positionTarget);
15471
15919
  this.__positionTargetAncestorRootNodes.forEach((node) => {
15472
- node.addEventListener('scroll', this._updatePosition, true);
15920
+ node.addEventListener('scroll', this.__onScroll, true);
15473
15921
  });
15474
15922
  }
15475
15923
 
@@ -15479,7 +15927,7 @@ const PositionMixin = (superClass) =>
15479
15927
 
15480
15928
  if (this.__positionTargetAncestorRootNodes) {
15481
15929
  this.__positionTargetAncestorRootNodes.forEach((node) => {
15482
- node.removeEventListener('scroll', this._updatePosition, true);
15930
+ node.removeEventListener('scroll', this.__onScroll, true);
15483
15931
  });
15484
15932
  this.__positionTargetAncestorRootNodes = null;
15485
15933
  }
@@ -15489,8 +15937,15 @@ const PositionMixin = (superClass) =>
15489
15937
  __overlayOpenedChanged(opened, positionTarget) {
15490
15938
  this.__removeUpdatePositionEventListeners();
15491
15939
 
15492
- if (opened && positionTarget) {
15493
- this.__addUpdatePositionEventListeners();
15940
+ if (positionTarget) {
15941
+ positionTarget.__overlay = null;
15942
+ targetResizeObserver.unobserve(positionTarget);
15943
+
15944
+ if (opened) {
15945
+ this.__addUpdatePositionEventListeners();
15946
+ positionTarget.__overlay = this;
15947
+ targetResizeObserver.observe(positionTarget);
15948
+ }
15494
15949
  }
15495
15950
 
15496
15951
  if (opened) {
@@ -15517,6 +15972,14 @@ const PositionMixin = (superClass) =>
15517
15972
  this._updatePosition();
15518
15973
  }
15519
15974
 
15975
+ /** @private */
15976
+ __onScroll(e) {
15977
+ // If the scroll event occurred inside the overlay, ignore it.
15978
+ if (!this.contains(e.target)) {
15979
+ this._updatePosition();
15980
+ }
15981
+ }
15982
+
15520
15983
  _updatePosition() {
15521
15984
  if (!this.positionTarget || !this.opened) {
15522
15985
  return;
@@ -15589,7 +16052,8 @@ const PositionMixin = (superClass) =>
15589
16052
  __shouldAlignStartVertically(targetRect) {
15590
16053
  // Using previous size to fix a case where window resize may cause the overlay to be squeezed
15591
16054
  // smaller than its current space before the fit-calculations.
15592
- const contentHeight = Math.max(this.__oldContentHeight || 0, this.$.overlay.offsetHeight);
16055
+ const contentHeight =
16056
+ this.requiredVerticalSpace || Math.max(this.__oldContentHeight || 0, this.$.overlay.offsetHeight);
15593
16057
  this.__oldContentHeight = this.$.overlay.offsetHeight;
15594
16058
 
15595
16059
  const viewportHeight = Math.min(window.innerHeight, document.documentElement.clientHeight);
@@ -15621,9 +16085,47 @@ const PositionMixin = (superClass) =>
15621
16085
  return defaultAlignStart === shouldGoToDefaultSide;
15622
16086
  }
15623
16087
 
16088
+ /**
16089
+ * Returns an adjusted value after resizing the browser window,
16090
+ * to avoid wrong calculations when e.g. previously set `bottom`
16091
+ * CSS property value is larger than the updated viewport height.
16092
+ * See https://github.com/vaadin/web-components/issues/4604
16093
+ */
16094
+ __adjustBottomProperty(cssPropNameToSet, propNames, currentValue) {
16095
+ let adjustedProp;
16096
+
16097
+ if (cssPropNameToSet === propNames.end) {
16098
+ // Adjust horizontally
16099
+ if (propNames.end === PROP_NAMES_VERTICAL.end) {
16100
+ const viewportHeight = Math.min(window.innerHeight, document.documentElement.clientHeight);
16101
+
16102
+ if (currentValue > viewportHeight && this.__oldViewportHeight) {
16103
+ const heightDiff = this.__oldViewportHeight - viewportHeight;
16104
+ adjustedProp = currentValue - heightDiff;
16105
+ }
16106
+
16107
+ this.__oldViewportHeight = viewportHeight;
16108
+ }
16109
+
16110
+ // Adjust vertically
16111
+ if (propNames.end === PROP_NAMES_HORIZONTAL.end) {
16112
+ const viewportWidth = Math.min(window.innerWidth, document.documentElement.clientWidth);
16113
+
16114
+ if (currentValue > viewportWidth && this.__oldViewportWidth) {
16115
+ const widthDiff = this.__oldViewportWidth - viewportWidth;
16116
+ adjustedProp = currentValue - widthDiff;
16117
+ }
16118
+
16119
+ this.__oldViewportWidth = viewportWidth;
16120
+ }
16121
+ }
16122
+
16123
+ return adjustedProp;
16124
+ }
16125
+
15624
16126
  /**
15625
16127
  * Returns an object with CSS position properties to set,
15626
- * e.g. { top: "100px", bottom: "" }
16128
+ * e.g. { top: "100px" }
15627
16129
  */
15628
16130
  // eslint-disable-next-line max-params
15629
16131
  __calculatePositionInOneDimension(targetRect, overlayRect, noOverlap, propNames, overlay, shouldAlignStart) {
@@ -15631,13 +16133,18 @@ const PositionMixin = (superClass) =>
15631
16133
  const cssPropNameToClear = shouldAlignStart ? propNames.end : propNames.start;
15632
16134
 
15633
16135
  const currentValue = parseFloat(overlay.style[cssPropNameToSet] || getComputedStyle(overlay)[cssPropNameToSet]);
16136
+ const adjustedValue = this.__adjustBottomProperty(cssPropNameToSet, propNames, currentValue);
15634
16137
 
15635
16138
  const diff =
15636
16139
  overlayRect[shouldAlignStart ? propNames.start : propNames.end] -
15637
16140
  targetRect[noOverlap === shouldAlignStart ? propNames.end : propNames.start];
15638
16141
 
16142
+ const valueToSet = adjustedValue
16143
+ ? `${adjustedValue}px`
16144
+ : `${currentValue + diff * (shouldAlignStart ? -1 : 1)}px`;
16145
+
15639
16146
  return {
15640
- [cssPropNameToSet]: `${currentValue + diff * (shouldAlignStart ? -1 : 1)}px`,
16147
+ [cssPropNameToSet]: valueToSet,
15641
16148
  [cssPropNameToClear]: '',
15642
16149
  };
15643
16150
  }
@@ -15654,11 +16161,6 @@ const datePickerStyles = i$1`
15654
16161
  direction: ltr;
15655
16162
  }
15656
16163
 
15657
- :host([dir='rtl']) [part='value']::placeholder {
15658
- direction: rtl;
15659
- text-align: left;
15660
- }
15661
-
15662
16164
  :host([dir='rtl']) [part='input-field'] ::slotted(input)::placeholder {
15663
16165
  direction: rtl;
15664
16166
  text-align: left;
@@ -15691,10 +16193,10 @@ let memoizedTemplate;
15691
16193
  /**
15692
16194
  * An element used internally by `<vaadin-date-picker>`. Not intended to be used separately.
15693
16195
  *
15694
- * @extends OverlayElement
16196
+ * @extends Overlay
15695
16197
  * @private
15696
16198
  */
15697
- class DatePickerOverlay extends DisableUpgradeMixin(PositionMixin(OverlayElement)) {
16199
+ class DatePickerOverlay extends DisableUpgradeMixin(PositionMixin(Overlay)) {
15698
16200
  static get is() {
15699
16201
  return 'vaadin-date-picker-overlay';
15700
16202
  }
@@ -16834,6 +17336,53 @@ function extractDateParts(date) {
16834
17336
  };
16835
17337
  }
16836
17338
 
17339
+ /**
17340
+ * Calculate the year of the date based on the provided reference date.
17341
+ * Gets a two-digit year and returns a full year.
17342
+ * @param {!Date} referenceDate The date to act as basis in the calculation
17343
+ * @param {!number} year Should be in the range of [0, 99]
17344
+ * @param {number} month
17345
+ * @param {number} day
17346
+ * @return {!number} Adjusted year value
17347
+ */
17348
+ function getAdjustedYear(referenceDate, year, month = 0, day = 1) {
17349
+ if (year > 99) {
17350
+ throw new Error('The provided year cannot have more than 2 digits.');
17351
+ }
17352
+ if (year < 0) {
17353
+ throw new Error('The provided year cannot be negative.');
17354
+ }
17355
+ // Year values up to 2 digits are parsed based on the reference date.
17356
+ let adjustedYear = year + Math.floor(referenceDate.getFullYear() / 100) * 100;
17357
+ if (referenceDate < new Date(adjustedYear - 50, month, day)) {
17358
+ adjustedYear -= 100;
17359
+ } else if (referenceDate > new Date(adjustedYear + 50, month, day)) {
17360
+ adjustedYear += 100;
17361
+ }
17362
+ return adjustedYear;
17363
+ }
17364
+
17365
+ /**
17366
+ * Parse date string of one of the following date formats:
17367
+ * - ISO 8601 `"YYYY-MM-DD"`
17368
+ * - 6-digit extended ISO 8601 `"+YYYYYY-MM-DD"`, `"-YYYYYY-MM-DD"`
17369
+ * @param {!string} str Date string to parse
17370
+ * @return {Date} Parsed date
17371
+ */
17372
+ function parseDate(str) {
17373
+ // Parsing with RegExp to ensure correct format
17374
+ const parts = /^([-+]\d{1}|\d{2,4}|[-+]\d{6})-(\d{1,2})-(\d{1,2})$/.exec(str);
17375
+ if (!parts) {
17376
+ return undefined;
17377
+ }
17378
+
17379
+ const date = new Date(0, 0); // Wrong date (1900-01-01), but with midnight in local time
17380
+ date.setFullYear(parseInt(parts[1], 10));
17381
+ date.setMonth(parseInt(parts[2], 10) - 1);
17382
+ date.setDate(parseInt(parts[3], 10));
17383
+ return date;
17384
+ }
17385
+
16837
17386
  /**
16838
17387
  * @license
16839
17388
  * Copyright (c) 2016 - 2022 Vaadin Ltd.
@@ -16910,7 +17459,9 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
16910
17459
  is="dom-repeat"
16911
17460
  items="[[_getWeekDayNames(i18n.weekdays, i18n.weekdaysShort, showWeekNumbers, i18n.firstDayOfWeek)]]"
16912
17461
  >
16913
- <th role="columnheader" part="weekday" scope="col" abbr$="[[item.weekDay]]">[[item.weekDayShort]]</th>
17462
+ <th role="columnheader" part="weekday" scope="col" abbr$="[[item.weekDay]]" aria-hidden="true">
17463
+ [[item.weekDayShort]]
17464
+ </th>
16914
17465
  </template>
16915
17466
  </tr>
16916
17467
  </thead>
@@ -17080,7 +17631,9 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
17080
17631
 
17081
17632
  _onMonthGridTouchStart() {
17082
17633
  this._notTapping = false;
17083
- setTimeout(() => (this._notTapping = true), 300);
17634
+ setTimeout(() => {
17635
+ this._notTapping = true;
17636
+ }, 300);
17084
17637
  }
17085
17638
 
17086
17639
  _dateAdd(date, delta) {
@@ -17254,12 +17807,6 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
17254
17807
 
17255
17808
  return '-1';
17256
17809
  }
17257
-
17258
- __getWeekNumbers(dates) {
17259
- return dates
17260
- .map((date) => this.__getWeekNumber(date, dates))
17261
- .filter((week, index, arr) => arr.indexOf(week) === index);
17262
- }
17263
17810
  }
17264
17811
 
17265
17812
  customElements.define(MonthCalendar.is, MonthCalendar);
@@ -17349,6 +17896,7 @@ class InfiniteScroller extends PolymerElement {
17349
17896
  /**
17350
17897
  * The amount of initial scroll top. Needed in order for the
17351
17898
  * user to be able to scroll backwards.
17899
+ * @private
17352
17900
  */
17353
17901
  _initialScroll: {
17354
17902
  value: 500000,
@@ -17356,17 +17904,22 @@ class InfiniteScroller extends PolymerElement {
17356
17904
 
17357
17905
  /**
17358
17906
  * The index/position mapped at _initialScroll point.
17907
+ * @private
17359
17908
  */
17360
17909
  _initialIndex: {
17361
17910
  value: 0,
17362
17911
  },
17363
17912
 
17913
+ /** @private */
17364
17914
  _buffers: Array,
17365
17915
 
17916
+ /** @private */
17366
17917
  _preventScrollEvent: Boolean,
17367
17918
 
17919
+ /** @private */
17368
17920
  _mayHaveMomentum: Boolean,
17369
17921
 
17922
+ /** @private */
17370
17923
  _initialized: Boolean,
17371
17924
 
17372
17925
  active: {
@@ -17376,10 +17929,11 @@ class InfiniteScroller extends PolymerElement {
17376
17929
  };
17377
17930
  }
17378
17931
 
17932
+ /** @protected */
17379
17933
  ready() {
17380
17934
  super.ready();
17381
17935
 
17382
- this._buffers = Array.prototype.slice.call(this.root.querySelectorAll('.buffer'));
17936
+ this._buffers = [...this.shadowRoot.querySelectorAll('.buffer')];
17383
17937
 
17384
17938
  this.$.fullHeight.style.height = `${this._initialScroll * 2}px`;
17385
17939
 
@@ -17388,8 +17942,8 @@ class InfiniteScroller extends PolymerElement {
17388
17942
  forwardHostProp(prop, value) {
17389
17943
  if (prop !== 'index') {
17390
17944
  this._buffers.forEach((buffer) => {
17391
- [].forEach.call(buffer.children, (insertionPoint) => {
17392
- insertionPoint._itemWrapper.instance[prop] = value;
17945
+ [...buffer.children].forEach((slot) => {
17946
+ slot._itemWrapper.instance[prop] = value;
17393
17947
  });
17394
17948
  });
17395
17949
  }
@@ -17403,6 +17957,19 @@ class InfiniteScroller extends PolymerElement {
17403
17957
  }
17404
17958
  }
17405
17959
 
17960
+ /**
17961
+ * Force the scroller to update clones after a reset, without
17962
+ * waiting for the debouncer to resolve.
17963
+ */
17964
+ forceUpdate() {
17965
+ if (this._debouncerUpdateClones) {
17966
+ this._buffers[0].updated = this._buffers[1].updated = false;
17967
+ this._updateClones();
17968
+ this._debouncerUpdateClones.cancel();
17969
+ }
17970
+ }
17971
+
17972
+ /** @private */
17406
17973
  _activated(active) {
17407
17974
  if (active && !this._initialized) {
17408
17975
  this._createPool();
@@ -17410,12 +17977,15 @@ class InfiniteScroller extends PolymerElement {
17410
17977
  }
17411
17978
  }
17412
17979
 
17980
+ /** @private */
17413
17981
  _finishInit() {
17414
17982
  if (!this._initDone) {
17415
17983
  // Once the first set of items start fading in, stamp the rest
17416
17984
  this._buffers.forEach((buffer) => {
17417
- [].forEach.call(buffer.children, (insertionPoint) => this._ensureStampedInstance(insertionPoint._itemWrapper));
17418
- }, this);
17985
+ [...buffer.children].forEach((slot) => {
17986
+ this._ensureStampedInstance(slot._itemWrapper);
17987
+ });
17988
+ });
17419
17989
 
17420
17990
  if (!this._buffers[0].translateY) {
17421
17991
  this._reset();
@@ -17425,6 +17995,7 @@ class InfiniteScroller extends PolymerElement {
17425
17995
  }
17426
17996
  }
17427
17997
 
17998
+ /** @private */
17428
17999
  _translateBuffer(up) {
17429
18000
  const index = up ? 1 : 0;
17430
18001
  this._buffers[index].translateY = this._buffers[index ? 0 : 1].translateY + this._bufferHeight * (index ? -1 : 1);
@@ -17433,6 +18004,7 @@ class InfiniteScroller extends PolymerElement {
17433
18004
  this._buffers.reverse();
17434
18005
  }
17435
18006
 
18007
+ /** @private */
17436
18008
  _scroll() {
17437
18009
  if (this._scrollDisabled) {
17438
18010
  return;
@@ -17529,10 +18101,12 @@ class InfiniteScroller extends PolymerElement {
17529
18101
  return this._itemHeightVal;
17530
18102
  }
17531
18103
 
18104
+ /** @private */
17532
18105
  get _bufferHeight() {
17533
18106
  return this.itemHeight * this.bufferSize;
17534
18107
  }
17535
18108
 
18109
+ /** @private */
17536
18110
  _reset() {
17537
18111
  this._scrollDisabled = true;
17538
18112
  this.$.scroller.scrollTop = this._initialScroll;
@@ -17552,6 +18126,7 @@ class InfiniteScroller extends PolymerElement {
17552
18126
  this._scrollDisabled = false;
17553
18127
  }
17554
18128
 
18129
+ /** @private */
17555
18130
  _createPool() {
17556
18131
  const container = this.getBoundingClientRect();
17557
18132
  this._buffers.forEach((buffer) => {
@@ -17563,10 +18138,10 @@ class InfiniteScroller extends PolymerElement {
17563
18138
  const contentId = (InfiniteScroller._contentIndex = InfiniteScroller._contentIndex + 1 || 0);
17564
18139
  const slotName = `vaadin-infinite-scroller-item-content-${contentId}`;
17565
18140
 
17566
- const insertionPoint = document.createElement('slot');
17567
- insertionPoint.setAttribute('name', slotName);
17568
- insertionPoint._itemWrapper = itemWrapper;
17569
- buffer.appendChild(insertionPoint);
18141
+ const slot = document.createElement('slot');
18142
+ slot.setAttribute('name', slotName);
18143
+ slot._itemWrapper = itemWrapper;
18144
+ buffer.appendChild(slot);
17570
18145
 
17571
18146
  itemWrapper.setAttribute('slot', slotName);
17572
18147
  this.appendChild(itemWrapper);
@@ -17578,13 +18153,14 @@ class InfiniteScroller extends PolymerElement {
17578
18153
  }
17579
18154
  }, 1); // Wait for first reset
17580
18155
  }
17581
- }, this);
18156
+ });
17582
18157
 
17583
18158
  setTimeout(() => {
17584
18159
  afterNextRender(this, this._finishInit.bind(this));
17585
18160
  }, 1);
17586
18161
  }
17587
18162
 
18163
+ /** @private */
17588
18164
  _ensureStampedInstance(itemWrapper) {
17589
18165
  if (itemWrapper.firstElementChild) {
17590
18166
  return;
@@ -17600,6 +18176,7 @@ class InfiniteScroller extends PolymerElement {
17600
18176
  });
17601
18177
  }
17602
18178
 
18179
+ /** @private */
17603
18180
  _updateClones(viewPortOnly) {
17604
18181
  this._firstIndex = ~~((this._buffers[0].translateY - this._initialScroll) / this.itemHeight) + this._initialIndex;
17605
18182
 
@@ -17608,17 +18185,18 @@ class InfiniteScroller extends PolymerElement {
17608
18185
  if (!buffer.updated) {
17609
18186
  const firstIndex = this._firstIndex + this.bufferSize * bufferIndex;
17610
18187
 
17611
- [].forEach.call(buffer.children, (insertionPoint, index) => {
17612
- const itemWrapper = insertionPoint._itemWrapper;
18188
+ [...buffer.children].forEach((slot, index) => {
18189
+ const itemWrapper = slot._itemWrapper;
17613
18190
  if (!viewPortOnly || this._isVisible(itemWrapper, scrollerRect)) {
17614
18191
  itemWrapper.instance.index = firstIndex + index;
17615
18192
  }
17616
18193
  });
17617
18194
  buffer.updated = true;
17618
18195
  }
17619
- }, this);
18196
+ });
17620
18197
  }
17621
18198
 
18199
+ /** @private */
17622
18200
  _isVisible(element, container) {
17623
18201
  const rect = element.getBoundingClientRect();
17624
18202
  return rect.bottom > container.top && rect.top < container.bottom;
@@ -17715,7 +18293,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
17715
18293
  height: 100%;
17716
18294
  width: 100%;
17717
18295
  outline: none;
17718
- background: #fff;
17719
18296
  }
17720
18297
 
17721
18298
  [part='overlay-header'] {
@@ -17733,22 +18310,14 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
17733
18310
  flex-grow: 1;
17734
18311
  }
17735
18312
 
17736
- [part='clear-button']:not([showclear]) {
17737
- display: none;
18313
+ [hidden] {
18314
+ display: none !important;
17738
18315
  }
17739
18316
 
17740
18317
  [part='years-toggle-button'] {
17741
18318
  display: flex;
17742
18319
  }
17743
18320
 
17744
- [part='years-toggle-button'][desktop] {
17745
- display: none;
17746
- }
17747
-
17748
- :host(:not([years-visible])) [part='years-toggle-button']::before {
17749
- transform: rotate(180deg);
17750
- }
17751
-
17752
18321
  #scrollers {
17753
18322
  display: flex;
17754
18323
  height: 100%;
@@ -17822,27 +18391,14 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
17822
18391
  z-index: 2;
17823
18392
  flex-shrink: 0;
17824
18393
  }
17825
-
17826
- [part~='overlay-header']:not([desktop]) {
17827
- padding-bottom: 40px;
17828
- }
17829
-
17830
- [part~='years-toggle-button'] {
17831
- position: absolute;
17832
- top: auto;
17833
- right: 8px;
17834
- bottom: 0;
17835
- z-index: 1;
17836
- padding: 8px;
17837
- }
17838
18394
  </style>
17839
18395
 
17840
18396
  <div part="overlay-header" on-touchend="_preventDefault" desktop$="[[_desktopMode]]" aria-hidden="true">
17841
18397
  <div part="label">[[_formatDisplayed(selectedDate, i18n.formatDate, label)]]</div>
17842
- <div part="clear-button" showclear$="[[_showClear(selectedDate)]]"></div>
18398
+ <div part="clear-button" hidden$="[[!selectedDate]]"></div>
17843
18399
  <div part="toggle-button"></div>
17844
18400
 
17845
- <div part="years-toggle-button" desktop$="[[_desktopMode]]" aria-hidden="true">
18401
+ <div part="years-toggle-button" hidden$="[[_desktopMode]]" aria-hidden="true">
17846
18402
  [[_yearAfterXMonths(_visibleMonthIndex)]]
17847
18403
  </div>
17848
18404
  </div>
@@ -17928,6 +18484,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
17928
18484
  */
17929
18485
  selectedDate: {
17930
18486
  type: Date,
18487
+ value: null,
17931
18488
  },
17932
18489
 
17933
18490
  /**
@@ -18003,10 +18560,24 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18003
18560
  return this.getAttribute('dir') === 'rtl';
18004
18561
  }
18005
18562
 
18563
+ /**
18564
+ * Whether to scroll to a sub-month position when scrolling to a date.
18565
+ * This is active if the month scroller is not large enough to fit a
18566
+ * full month. In that case we want to scroll to a position between
18567
+ * two months in order to have the focused date in the visible area.
18568
+ * @returns {boolean} whether to use sub-month scrolling
18569
+ * @private
18570
+ */
18571
+ get __useSubMonthScrolling() {
18572
+ return this.$.monthScroller.clientHeight < this.$.monthScroller.itemHeight + this.$.monthScroller.bufferOffset;
18573
+ }
18574
+
18575
+ get calendars() {
18576
+ return [...this.shadowRoot.querySelectorAll('vaadin-month-calendar')];
18577
+ }
18578
+
18006
18579
  get focusableDateElement() {
18007
- return [...this.shadowRoot.querySelectorAll('vaadin-month-calendar')]
18008
- .map((calendar) => calendar.focusableDateElement)
18009
- .find(Boolean);
18580
+ return this.calendars.map((calendar) => calendar.focusableDateElement).find(Boolean);
18010
18581
  }
18011
18582
 
18012
18583
  ready() {
@@ -18014,7 +18585,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18014
18585
 
18015
18586
  this.setAttribute('role', 'dialog');
18016
18587
 
18017
- addListener(this, 'tap', this._stopPropagation);
18018
18588
  addListener(this.$.scrollers, 'track', this._track.bind(this));
18019
18589
  addListener(this.shadowRoot.querySelector('[part="clear-button"]'), 'tap', this._clear.bind(this));
18020
18590
  addListener(this.shadowRoot.querySelector('[part="today-button"]'), 'tap', this._onTodayTap.bind(this));
@@ -18059,7 +18629,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18059
18629
  * Scrolls the list to the given Date.
18060
18630
  */
18061
18631
  scrollToDate(date, animate) {
18062
- this._scrollToPosition(this._differenceInMonths(date, this._originDate), animate);
18632
+ const offset = this.__useSubMonthScrolling ? this._calculateWeekScrollOffset(date) : 0;
18633
+ this._scrollToPosition(this._differenceInMonths(date, this._originDate) + offset, animate);
18634
+ this.$.monthScroller.forceUpdate();
18063
18635
  }
18064
18636
 
18065
18637
  /**
@@ -18091,23 +18663,63 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18091
18663
  * Scrolls the month and year scrollers enough to reveal the given date.
18092
18664
  */
18093
18665
  revealDate(date, animate = true) {
18094
- if (date) {
18095
- const diff = this._differenceInMonths(date, this._originDate);
18096
- const scrolledAboveViewport = this.$.monthScroller.position > diff;
18666
+ if (!date) {
18667
+ return;
18668
+ }
18669
+ const diff = this._differenceInMonths(date, this._originDate);
18670
+ // If scroll area does not fit the full month, then always scroll with an offset to
18671
+ // approximately display the week of the date
18672
+ if (this.__useSubMonthScrolling) {
18673
+ const offset = this._calculateWeekScrollOffset(date);
18674
+ this._scrollToPosition(diff + offset, animate);
18675
+ return;
18676
+ }
18097
18677
 
18098
- const visibleArea = Math.max(
18099
- this.$.monthScroller.itemHeight,
18100
- this.$.monthScroller.clientHeight - this.$.monthScroller.bufferOffset * 2,
18101
- );
18102
- const visibleItems = visibleArea / this.$.monthScroller.itemHeight;
18103
- const scrolledBelowViewport = this.$.monthScroller.position + visibleItems - 1 < diff;
18678
+ // Otherwise determine if we need to scroll to make the month of the date visible
18679
+ const scrolledAboveViewport = this.$.monthScroller.position > diff;
18680
+
18681
+ const visibleArea = Math.max(
18682
+ this.$.monthScroller.itemHeight,
18683
+ this.$.monthScroller.clientHeight - this.$.monthScroller.bufferOffset * 2,
18684
+ );
18685
+ const visibleItems = visibleArea / this.$.monthScroller.itemHeight;
18686
+ const scrolledBelowViewport = this.$.monthScroller.position + visibleItems - 1 < diff;
18687
+
18688
+ if (scrolledAboveViewport) {
18689
+ this._scrollToPosition(diff, animate);
18690
+ } else if (scrolledBelowViewport) {
18691
+ this._scrollToPosition(diff - visibleItems + 1, animate);
18692
+ }
18693
+ }
18104
18694
 
18105
- if (scrolledAboveViewport) {
18106
- this._scrollToPosition(diff, animate);
18107
- } else if (scrolledBelowViewport) {
18108
- this._scrollToPosition(diff - visibleItems + 1, animate);
18695
+ /**
18696
+ * Calculates an offset to be added to the month scroll position
18697
+ * when using sub-month scrolling, in order ensure that the week
18698
+ * that the date is in is visible even for small scroll areas.
18699
+ * As the month scroller uses a month as minimal scroll unit
18700
+ * (a value of `1` equals one month), we can not exactly identify
18701
+ * the position of a specific week. This is a best effort
18702
+ * implementation based on manual testing.
18703
+ * @param date the date for which to calculate the offset
18704
+ * @returns {number} the offset
18705
+ * @private
18706
+ */
18707
+ _calculateWeekScrollOffset(date) {
18708
+ // Get first day of month
18709
+ const temp = new Date(0, 0);
18710
+ temp.setFullYear(date.getFullYear());
18711
+ temp.setMonth(date.getMonth());
18712
+ temp.setDate(1);
18713
+ // Determine week (=row index) of date within the month
18714
+ let week = 0;
18715
+ while (temp.getDate() < date.getDate()) {
18716
+ temp.setDate(temp.getDate() + 1);
18717
+ if (temp.getDay() === this.i18n.firstDayOfWeek) {
18718
+ week += 1;
18109
18719
  }
18110
18720
  }
18721
+ // Calculate magic number that approximately keeps the week visible
18722
+ return week / 6;
18111
18723
  }
18112
18724
 
18113
18725
  _initialPositionChanged(initialPosition) {
@@ -18136,7 +18748,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18136
18748
 
18137
18749
  _onYearScrollTouchStart() {
18138
18750
  this._notTapping = false;
18139
- setTimeout(() => (this._notTapping = true), 300);
18751
+ setTimeout(() => {
18752
+ this._notTapping = true;
18753
+ }, 300);
18140
18754
 
18141
18755
  this._repositionMonthScroller();
18142
18756
  }
@@ -18147,7 +18761,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18147
18761
 
18148
18762
  _doIgnoreTaps() {
18149
18763
  this._ignoreTaps = true;
18150
- this._debouncer = Debouncer$1.debounce(this._debouncer, timeOut.after(300), () => (this._ignoreTaps = false));
18764
+ this._debouncer = Debouncer$1.debounce(this._debouncer, timeOut.after(300), () => {
18765
+ this._ignoreTaps = false;
18766
+ });
18151
18767
  }
18152
18768
 
18153
18769
  _formatDisplayed(date, formatDate, label) {
@@ -18178,10 +18794,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18178
18794
  this.scrollToDate(new Date(), true);
18179
18795
  }
18180
18796
 
18181
- _showClear(selectedDate) {
18182
- return !!selectedDate;
18183
- }
18184
-
18185
18797
  _onYearTap(e) {
18186
18798
  if (!this._ignoreTaps && !this._notTapping) {
18187
18799
  const scrollDelta =
@@ -18207,6 +18819,11 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18207
18819
 
18208
18820
  this._targetPosition = targetPosition;
18209
18821
 
18822
+ let revealResolve;
18823
+ this._revealPromise = new Promise((resolve) => {
18824
+ revealResolve = resolve;
18825
+ });
18826
+
18210
18827
  // http://gizma.com/easing/
18211
18828
  const easingFunction = (t, b, c, d) => {
18212
18829
  t /= d / 2;
@@ -18247,7 +18864,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18247
18864
 
18248
18865
  this.$.monthScroller.position = this._targetPosition;
18249
18866
  this._targetPosition = undefined;
18250
- this.__tryFocusDate();
18867
+
18868
+ revealResolve();
18869
+ this._revealPromise = undefined;
18251
18870
  }
18252
18871
 
18253
18872
  setTimeout(this._repositionYearScroller.bind(this), 1);
@@ -18363,10 +18982,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18363
18982
  return months - date2.getMonth() + date1.getMonth();
18364
18983
  }
18365
18984
 
18366
- _differenceInYears(date1, date2) {
18367
- return this._differenceInMonths(date1, date2) / 12;
18368
- }
18369
-
18370
18985
  _clear() {
18371
18986
  this._selectDate('');
18372
18987
  }
@@ -18457,51 +19072,44 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18457
19072
  switch (section) {
18458
19073
  case 'calendar':
18459
19074
  if (event.shiftKey) {
18460
- // Return focus back to the input field.
18461
19075
  event.preventDefault();
18462
- this.__focusInput();
19076
+
19077
+ if (this.hasAttribute('fullscreen')) {
19078
+ // Trap focus in the overlay
19079
+ this.$.cancelButton.focus();
19080
+ } else {
19081
+ this.__focusInput();
19082
+ }
18463
19083
  }
18464
19084
  break;
18465
19085
  case 'today':
18466
19086
  if (event.shiftKey) {
18467
- // Browser returns focus back to the calendar.
18468
- // We need to move the scroll to focused date.
18469
- setTimeout(() => this.revealDate(this.focusedDate), 1);
19087
+ event.preventDefault();
19088
+ this.focusDateElement();
18470
19089
  }
18471
19090
  break;
18472
19091
  case 'cancel':
18473
19092
  if (!event.shiftKey) {
18474
- // Return focus back to the input field.
18475
19093
  event.preventDefault();
18476
- this.__focusInput();
19094
+
19095
+ if (this.hasAttribute('fullscreen')) {
19096
+ // Trap focus in the overlay
19097
+ this.focusDateElement();
19098
+ } else {
19099
+ this.__focusInput();
19100
+ }
18477
19101
  }
18478
19102
  break;
18479
19103
  }
18480
19104
  }
18481
19105
 
18482
19106
  __onTodayButtonKeyDown(event) {
18483
- if (this.hasAttribute('fullscreen')) {
18484
- // Do not prevent closing on Esc
18485
- if (event.key !== 'Escape') {
18486
- event.stopPropagation();
18487
- }
18488
- return;
18489
- }
18490
-
18491
19107
  if (event.key === 'Tab') {
18492
19108
  this._onTabKeyDown(event, 'today');
18493
19109
  }
18494
19110
  }
18495
19111
 
18496
19112
  __onCancelButtonKeyDown(event) {
18497
- if (this.hasAttribute('fullscreen')) {
18498
- // Do not prevent closing on Esc
18499
- if (event.key !== 'Escape') {
18500
- event.stopPropagation();
18501
- }
18502
- return;
18503
- }
18504
-
18505
19113
  if (event.key === 'Tab') {
18506
19114
  this._onTabKeyDown(event, 'cancel');
18507
19115
  }
@@ -18530,15 +19138,29 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18530
19138
  if (!keepMonth) {
18531
19139
  this._focusedMonthDate = dateToFocus.getDate();
18532
19140
  }
18533
- await this.focusDateElement();
19141
+ await this.focusDateElement(false);
18534
19142
  }
18535
19143
 
18536
- async focusDateElement() {
19144
+ async focusDateElement(reveal = true) {
18537
19145
  this.__pendingDateFocus = this.focusedDate;
18538
19146
 
18539
- await new Promise((resolve) => {
18540
- requestAnimationFrame(resolve);
18541
- });
19147
+ // Wait for `vaadin-month-calendar` elements to be rendered
19148
+ if (!this.calendars.length) {
19149
+ await new Promise((resolve) => {
19150
+ setTimeout(resolve);
19151
+ });
19152
+ }
19153
+
19154
+ // Reveal focused date unless it has been just set,
19155
+ // which triggers `revealDate()` in the observer.
19156
+ if (reveal) {
19157
+ this.revealDate(this.focusedDate);
19158
+ }
19159
+
19160
+ if (this._revealPromise) {
19161
+ // Wait for focused date to be scrolled into view.
19162
+ await this._revealPromise;
19163
+ }
18542
19164
 
18543
19165
  this.__tryFocusDate();
18544
19166
  }
@@ -18636,10 +19258,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
18636
19258
  todayMidnight.setDate(today.getDate());
18637
19259
  return this._dateAllowed(todayMidnight, min, max);
18638
19260
  }
18639
-
18640
- _stopPropagation(e) {
18641
- e.stopPropagation();
18642
- }
18643
19261
  }
18644
19262
 
18645
19263
  customElements.define(DatePickerOverlayContent.is, DatePickerOverlayContent);
@@ -18771,276 +19389,104 @@ const DelegateFocusMixin = dedupingMixin(
18771
19389
  * @protected
18772
19390
  */
18773
19391
  _addFocusListeners(element) {
18774
- element.addEventListener('blur', this._boundOnBlur);
18775
- element.addEventListener('focus', this._boundOnFocus);
18776
- }
18777
-
18778
- /**
18779
- * @param {HTMLElement} element
18780
- * @protected
18781
- */
18782
- _removeFocusListeners(element) {
18783
- element.removeEventListener('blur', this._boundOnBlur);
18784
- element.removeEventListener('focus', this._boundOnFocus);
18785
- }
18786
-
18787
- /**
18788
- * Focus event does not bubble, so we dispatch it manually
18789
- * on the host element to support adding focus listeners
18790
- * when the focusable element is placed in light DOM.
18791
- * @param {FocusEvent} event
18792
- * @protected
18793
- */
18794
- _onFocus(event) {
18795
- event.stopPropagation();
18796
- this.dispatchEvent(new Event('focus'));
18797
- }
18798
-
18799
- /**
18800
- * Blur event does not bubble, so we dispatch it manually
18801
- * on the host element to support adding blur listeners
18802
- * when the focusable element is placed in light DOM.
18803
- * @param {FocusEvent} event
18804
- * @protected
18805
- */
18806
- _onBlur(event) {
18807
- event.stopPropagation();
18808
- this.dispatchEvent(new Event('blur'));
18809
- }
18810
-
18811
- /**
18812
- * @param {Event} event
18813
- * @return {boolean}
18814
- * @protected
18815
- * @override
18816
- */
18817
- _shouldSetFocus(event) {
18818
- return event.target === this.focusElement;
18819
- }
18820
-
18821
- /**
18822
- * @param {boolean} disabled
18823
- * @param {boolean} oldDisabled
18824
- * @protected
18825
- * @override
18826
- */
18827
- _disabledChanged(disabled, oldDisabled) {
18828
- super._disabledChanged(disabled, oldDisabled);
18829
-
18830
- if (this.focusElement) {
18831
- this.focusElement.disabled = disabled;
18832
- }
18833
-
18834
- if (disabled) {
18835
- this.blur();
18836
- }
18837
- }
18838
-
18839
- /**
18840
- * Override an observer from `TabindexMixin`.
18841
- * Do not call super to remove tabindex attribute
18842
- * from the host after it has been forwarded.
18843
- * @param {string} tabindex
18844
- * @protected
18845
- * @override
18846
- */
18847
- _tabindexChanged(tabindex) {
18848
- this.__forwardTabIndex(tabindex);
18849
- }
18850
-
18851
- /** @private */
18852
- __forwardTabIndex(tabindex) {
18853
- if (tabindex !== undefined && this.focusElement) {
18854
- this.focusElement.tabIndex = tabindex;
18855
-
18856
- // Preserve tabindex="-1" on the host element
18857
- if (tabindex !== -1) {
18858
- this.tabindex = undefined;
18859
- }
18860
- }
18861
-
18862
- if (this.disabled && tabindex) {
18863
- // If tabindex attribute was changed while component was disabled
18864
- if (tabindex !== -1) {
18865
- this._lastTabIndex = tabindex;
18866
- }
18867
- this.tabindex = undefined;
18868
- }
18869
- }
18870
- },
18871
- );
18872
-
18873
- /**
18874
- * @license
18875
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
18876
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
18877
- */
18878
-
18879
- /**
18880
- * A controller for providing content to slot element and observing changes.
18881
- */
18882
- class SlotController extends EventTarget {
18883
- /**
18884
- * Ensure that every instance has unique ID.
18885
- *
18886
- * @param {string} slotName
18887
- * @param {HTMLElement} host
18888
- * @return {string}
18889
- * @protected
18890
- */
18891
- static generateId(slotName, host) {
18892
- const prefix = slotName || 'default';
18893
-
18894
- // Support dash-case slot names e.g. "error-message"
18895
- const field = `${dashToCamelCase(prefix)}Id`;
18896
-
18897
- // Maintain the unique ID counter for a given prefix.
18898
- this[field] = 1 + this[field] || 0;
18899
-
18900
- return `${prefix}-${host.localName}-${this[field]}`;
18901
- }
18902
-
18903
- constructor(host, slotName, slotFactory, slotInitializer) {
18904
- super();
18905
-
18906
- this.host = host;
18907
- this.slotName = slotName;
18908
- this.slotFactory = slotFactory;
18909
- this.slotInitializer = slotInitializer;
18910
- this.defaultId = SlotController.generateId(slotName, host);
18911
- }
18912
-
18913
- hostConnected() {
18914
- if (!this.initialized) {
18915
- let node = this.getSlotChild();
18916
-
18917
- if (!node) {
18918
- node = this.attachDefaultNode();
18919
- } else {
18920
- this.node = node;
18921
- this.initCustomNode(node);
18922
- }
18923
-
18924
- this.initNode(node);
18925
-
18926
- // TODO: Consider making this behavior opt-in to improve performance.
18927
- this.observe();
18928
-
18929
- this.initialized = true;
18930
- }
18931
- }
18932
-
18933
- /**
18934
- * Create and attach default node using the slot factory.
18935
- * @return {Node | undefined}
18936
- * @protected
18937
- */
18938
- attachDefaultNode() {
18939
- const { host, slotName, slotFactory } = this;
18940
-
18941
- // Check if the node was created previously and if so, reuse it.
18942
- let node = this.defaultNode;
18943
-
18944
- // Slot factory is optional, some slots don't have default content.
18945
- if (!node && slotFactory) {
18946
- node = slotFactory(host);
18947
- if (node instanceof Element) {
18948
- if (slotName !== '') {
18949
- node.setAttribute('slot', slotName);
18950
- }
18951
- this.node = node;
18952
- this.defaultNode = node;
18953
- }
18954
- }
18955
-
18956
- if (node) {
18957
- host.appendChild(node);
18958
- }
18959
-
18960
- return node;
18961
- }
18962
-
18963
- /**
18964
- * Return a reference to the node managed by the controller.
18965
- * @return {Node}
18966
- */
18967
- getSlotChild() {
18968
- const { slotName } = this;
18969
- return Array.from(this.host.childNodes).find((node) => {
18970
- // Either an element (any slot) or a text node (only un-named slot).
18971
- return (
18972
- (node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) ||
18973
- (node.nodeType === Node.TEXT_NODE && node.textContent.trim() && slotName === '')
18974
- );
18975
- });
18976
- }
18977
-
18978
- /**
18979
- * @param {Node} node
18980
- * @protected
18981
- */
18982
- initNode(node) {
18983
- const { slotInitializer } = this;
18984
- // Don't try to bind `this` to initializer (normally it's arrow function).
18985
- // Instead, pass the host as a first argument to access component's state.
18986
- if (slotInitializer) {
18987
- slotInitializer(this.host, node);
18988
- }
18989
- }
18990
-
18991
- /**
18992
- * Override to initialize the newly added custom node.
18993
- *
18994
- * @param {Node} _node
18995
- * @protected
18996
- */
18997
- initCustomNode(_node) {}
19392
+ element.addEventListener('blur', this._boundOnBlur);
19393
+ element.addEventListener('focus', this._boundOnFocus);
19394
+ }
18998
19395
 
18999
- /**
19000
- * Override to teardown slotted node when it's removed.
19001
- *
19002
- * @param {Node} _node
19003
- * @protected
19004
- */
19005
- teardownNode(_node) {}
19396
+ /**
19397
+ * @param {HTMLElement} element
19398
+ * @protected
19399
+ */
19400
+ _removeFocusListeners(element) {
19401
+ element.removeEventListener('blur', this._boundOnBlur);
19402
+ element.removeEventListener('focus', this._boundOnFocus);
19403
+ }
19006
19404
 
19007
- /**
19008
- * Setup the observer to manage slot content changes.
19009
- * @protected
19010
- */
19011
- observe() {
19012
- const { slotName } = this;
19013
- const selector = slotName === '' ? 'slot:not([name])' : `slot[name=${slotName}]`;
19014
- const slot = this.host.shadowRoot.querySelector(selector);
19405
+ /**
19406
+ * Focus event does not bubble, so we dispatch it manually
19407
+ * on the host element to support adding focus listeners
19408
+ * when the focusable element is placed in light DOM.
19409
+ * @param {FocusEvent} event
19410
+ * @protected
19411
+ */
19412
+ _onFocus(event) {
19413
+ event.stopPropagation();
19414
+ this.dispatchEvent(new Event('focus'));
19415
+ }
19015
19416
 
19016
- this.__slotObserver = new FlattenedNodesObserver(slot, (info) => {
19017
- // TODO: support default slot with multiple nodes (e.g. confirm-dialog)
19018
- const current = this.node;
19019
- const newNode = info.addedNodes.find((node) => node !== current);
19417
+ /**
19418
+ * Blur event does not bubble, so we dispatch it manually
19419
+ * on the host element to support adding blur listeners
19420
+ * when the focusable element is placed in light DOM.
19421
+ * @param {FocusEvent} event
19422
+ * @protected
19423
+ */
19424
+ _onBlur(event) {
19425
+ event.stopPropagation();
19426
+ this.dispatchEvent(new Event('blur'));
19427
+ }
19020
19428
 
19021
- if (info.removedNodes.length) {
19022
- info.removedNodes.forEach((node) => {
19023
- this.teardownNode(node);
19024
- });
19429
+ /**
19430
+ * @param {Event} event
19431
+ * @return {boolean}
19432
+ * @protected
19433
+ * @override
19434
+ */
19435
+ _shouldSetFocus(event) {
19436
+ return event.target === this.focusElement;
19025
19437
  }
19026
19438
 
19027
- if (newNode) {
19028
- // Custom node is added, remove the current one.
19029
- if (current && current.isConnected) {
19030
- this.host.removeChild(current);
19439
+ /**
19440
+ * @param {boolean} disabled
19441
+ * @param {boolean} oldDisabled
19442
+ * @protected
19443
+ * @override
19444
+ */
19445
+ _disabledChanged(disabled, oldDisabled) {
19446
+ super._disabledChanged(disabled, oldDisabled);
19447
+
19448
+ if (this.focusElement) {
19449
+ this.focusElement.disabled = disabled;
19031
19450
  }
19032
19451
 
19033
- this.node = newNode;
19452
+ if (disabled) {
19453
+ this.blur();
19454
+ }
19455
+ }
19034
19456
 
19035
- if (newNode !== this.defaultNode) {
19036
- this.initCustomNode(newNode);
19457
+ /**
19458
+ * Override an observer from `TabindexMixin`.
19459
+ * Do not call super to remove tabindex attribute
19460
+ * from the host after it has been forwarded.
19461
+ * @param {string} tabindex
19462
+ * @protected
19463
+ * @override
19464
+ */
19465
+ _tabindexChanged(tabindex) {
19466
+ this.__forwardTabIndex(tabindex);
19467
+ }
19037
19468
 
19038
- this.initNode(newNode);
19469
+ /** @private */
19470
+ __forwardTabIndex(tabindex) {
19471
+ if (tabindex !== undefined && this.focusElement) {
19472
+ this.focusElement.tabIndex = tabindex;
19473
+
19474
+ // Preserve tabindex="-1" on the host element
19475
+ if (tabindex !== -1) {
19476
+ this.tabindex = undefined;
19477
+ }
19478
+ }
19479
+
19480
+ if (this.disabled && tabindex) {
19481
+ // If tabindex attribute was changed while component was disabled
19482
+ if (tabindex !== -1) {
19483
+ this._lastTabIndex = tabindex;
19484
+ }
19485
+ this.tabindex = undefined;
19039
19486
  }
19040
19487
  }
19041
- });
19042
- }
19043
- }
19488
+ },
19489
+ );
19044
19490
 
19045
19491
  /**
19046
19492
  * @license
@@ -19062,6 +19508,7 @@ class ErrorController extends SlotController {
19062
19508
 
19063
19509
  this.__updateHasError();
19064
19510
  },
19511
+ true,
19065
19512
  );
19066
19513
  }
19067
19514
 
@@ -19097,7 +19544,7 @@ class ErrorController extends SlotController {
19097
19544
  }
19098
19545
 
19099
19546
  /**
19100
- * Override to initialize the newly added custom label.
19547
+ * Override to initialize the newly added custom error message.
19101
19548
  *
19102
19549
  * @param {Node} errorNode
19103
19550
  * @protected
@@ -19115,7 +19562,7 @@ class ErrorController extends SlotController {
19115
19562
  }
19116
19563
 
19117
19564
  /**
19118
- * Override to cleanup label node when it's removed.
19565
+ * Override to cleanup error message node when it's removed.
19119
19566
  *
19120
19567
  * @param {Node} node
19121
19568
  * @protected
@@ -19128,7 +19575,7 @@ class ErrorController extends SlotController {
19128
19575
  if (!errorNode && node !== this.defaultNode) {
19129
19576
  errorNode = this.attachDefaultNode();
19130
19577
 
19131
- // Run initializer to update default label and ID.
19578
+ // Run initializer to update default error message ID.
19132
19579
  this.initNode(errorNode);
19133
19580
  }
19134
19581
 
@@ -19176,63 +19623,6 @@ class ErrorController extends SlotController {
19176
19623
  }
19177
19624
  }
19178
19625
 
19179
- /**
19180
- * @license
19181
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
19182
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
19183
- */
19184
-
19185
- /**
19186
- * @param {string} value
19187
- * @return {Set<string>}
19188
- */
19189
- function deserializeAttributeValue(value) {
19190
- if (!value) {
19191
- return new Set();
19192
- }
19193
-
19194
- return new Set(value.split(' '));
19195
- }
19196
-
19197
- /**
19198
- * @param {Set<string>} values
19199
- * @return {string}
19200
- */
19201
- function serializeAttributeValue(values) {
19202
- return [...values].join(' ');
19203
- }
19204
-
19205
- /**
19206
- * Adds a value to an attribute containing space-delimited values.
19207
- *
19208
- * @param {HTMLElement} element
19209
- * @param {string} attr
19210
- * @param {string} value
19211
- */
19212
- function addValueToAttribute(element, attr, value) {
19213
- const values = deserializeAttributeValue(element.getAttribute(attr));
19214
- values.add(value);
19215
- element.setAttribute(attr, serializeAttributeValue(values));
19216
- }
19217
-
19218
- /**
19219
- * Removes a value from an attribute containing space-delimited values.
19220
- * If the value is the last one, the whole attribute is removed.
19221
- *
19222
- * @param {HTMLElement} element
19223
- * @param {string} attr
19224
- * @param {string} value
19225
- */
19226
- function removeValueFromAttribute(element, attr, value) {
19227
- const values = deserializeAttributeValue(element.getAttribute(attr));
19228
- values.delete(value);
19229
- if (values.size === 0) {
19230
- element.removeAttribute(attr);
19231
- return;
19232
- }
19233
- element.setAttribute(attr, serializeAttributeValue(values));
19234
- }
19235
-
19236
19626
  /**
19237
19627
  * @license
19238
19628
  * Copyright (c) 2021 - 2022 Vaadin Ltd.
@@ -19407,7 +19797,7 @@ class FieldAriaController {
19407
19797
 
19408
19798
  /**
19409
19799
  * @license
19410
- * Copyright (c) 2021 Vaadin Ltd.
19800
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
19411
19801
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
19412
19802
  */
19413
19803
 
@@ -19417,7 +19807,7 @@ class FieldAriaController {
19417
19807
  class HelperController extends SlotController {
19418
19808
  constructor(host) {
19419
19809
  // Do not provide slot factory, as only create helper lazily.
19420
- super(host, 'helper');
19810
+ super(host, 'helper', null, null, true);
19421
19811
  }
19422
19812
 
19423
19813
  get helperId() {
@@ -19488,7 +19878,11 @@ class HelperController extends SlotController {
19488
19878
  return false;
19489
19879
  }
19490
19880
 
19491
- return helperNode.children.length > 0 || this.__isNotEmpty(helperNode.textContent);
19881
+ return (
19882
+ helperNode.children.length > 0 ||
19883
+ (helperNode.nodeType === Node.ELEMENT_NODE && customElements.get(helperNode.localName)) ||
19884
+ this.__isNotEmpty(helperNode.textContent)
19885
+ );
19492
19886
  }
19493
19887
 
19494
19888
  /**
@@ -19614,6 +20008,7 @@ class LabelController extends SlotController {
19614
20008
 
19615
20009
  this.__observeLabel(node);
19616
20010
  },
20011
+ true,
19617
20012
  );
19618
20013
  }
19619
20014
 
@@ -19788,7 +20183,7 @@ class LabelController extends SlotController {
19788
20183
  * A mixin to provide label via corresponding property or named slot.
19789
20184
  *
19790
20185
  * @polymerMixin
19791
- * @mixes SlotMixin
20186
+ * @mixes ControllerMixin
19792
20187
  */
19793
20188
  const LabelMixin = dedupingMixin(
19794
20189
  (superclass) =>
@@ -19820,6 +20215,12 @@ const LabelMixin = dedupingMixin(
19820
20215
  super();
19821
20216
 
19822
20217
  this._labelController = new LabelController(this);
20218
+ }
20219
+
20220
+ /** @protected */
20221
+ ready() {
20222
+ super.ready();
20223
+
19823
20224
  this.addController(this._labelController);
19824
20225
  }
19825
20226
 
@@ -19867,12 +20268,17 @@ const ValidateMixin = dedupingMixin(
19867
20268
  }
19868
20269
 
19869
20270
  /**
19870
- * Returns true if field is valid, and sets `invalid` based on the field validity.
20271
+ * Validates the field and sets the `invalid` property based on the result.
20272
+ *
20273
+ * The method fires a `validated` event with the result of the validation.
19871
20274
  *
19872
20275
  * @return {boolean} True if the value is valid.
19873
20276
  */
19874
20277
  validate() {
19875
- return !(this.invalid = !this.checkValidity());
20278
+ const isValid = this.checkValidity();
20279
+ this._setInvalid(!isValid);
20280
+ this.dispatchEvent(new CustomEvent('validated', { detail: { valid: isValid } }));
20281
+ return isValid;
19876
20282
  }
19877
20283
 
19878
20284
  /**
@@ -19883,6 +20289,35 @@ const ValidateMixin = dedupingMixin(
19883
20289
  checkValidity() {
19884
20290
  return !this.required || !!this.value;
19885
20291
  }
20292
+
20293
+ /**
20294
+ * @param {boolean} invalid
20295
+ * @protected
20296
+ */
20297
+ _setInvalid(invalid) {
20298
+ if (this._shouldSetInvalid(invalid)) {
20299
+ this.invalid = invalid;
20300
+ }
20301
+ }
20302
+
20303
+ /**
20304
+ * Override this method to define whether the given `invalid` state should be set.
20305
+ *
20306
+ * @param {boolean} _invalid
20307
+ * @return {boolean}
20308
+ * @protected
20309
+ */
20310
+ _shouldSetInvalid(_invalid) {
20311
+ return true;
20312
+ }
20313
+
20314
+ /**
20315
+ * Fired whenever the field is validated.
20316
+ *
20317
+ * @event validated
20318
+ * @param {Object} detail
20319
+ * @param {boolean} detail.valid the result of the validation.
20320
+ */
19886
20321
  },
19887
20322
  );
19888
20323
 
@@ -19971,10 +20406,6 @@ const FieldMixin = (superclass) =>
19971
20406
  this._helperController = new HelperController(this);
19972
20407
  this._errorController = new ErrorController(this);
19973
20408
 
19974
- this.addController(this._fieldAriaController);
19975
- this.addController(this._helperController);
19976
- this.addController(this._errorController);
19977
-
19978
20409
  this._labelController.addEventListener('label-changed', (event) => {
19979
20410
  const { hasLabel, node } = event.detail;
19980
20411
  this.__labelChanged(hasLabel, node);
@@ -19986,6 +20417,15 @@ const FieldMixin = (superclass) =>
19986
20417
  });
19987
20418
  }
19988
20419
 
20420
+ /** @protected */
20421
+ ready() {
20422
+ super.ready();
20423
+
20424
+ this.addController(this._fieldAriaController);
20425
+ this.addController(this._helperController);
20426
+ this.addController(this._errorController);
20427
+ }
20428
+
19989
20429
  /** @private */
19990
20430
  __helperChanged(hasHelper, helperNode) {
19991
20431
  if (hasHelper) {
@@ -20041,7 +20481,7 @@ const FieldMixin = (superclass) =>
20041
20481
  }
20042
20482
 
20043
20483
  /**
20044
- * @param {boolean} required
20484
+ * @param {boolean} invalid
20045
20485
  * @protected
20046
20486
  */
20047
20487
  _invalidChanged(invalid) {
@@ -20241,13 +20681,23 @@ const InputMixin = dedupingMixin(
20241
20681
  observer: '_valueChanged',
20242
20682
  notify: true,
20243
20683
  },
20684
+
20685
+ /**
20686
+ * When true, the input element has a non-empty value entered by the user.
20687
+ * @protected
20688
+ */
20689
+ _hasInputValue: {
20690
+ type: Boolean,
20691
+ value: false,
20692
+ observer: '_hasInputValueChanged',
20693
+ },
20244
20694
  };
20245
20695
  }
20246
20696
 
20247
20697
  constructor() {
20248
20698
  super();
20249
20699
 
20250
- this._boundOnInput = this._onInput.bind(this);
20700
+ this._boundOnInput = this.__onInput.bind(this);
20251
20701
  this._boundOnChange = this._onChange.bind(this);
20252
20702
  }
20253
20703
 
@@ -20262,6 +20712,7 @@ const InputMixin = dedupingMixin(
20262
20712
  * Add event listeners to the input element instance.
20263
20713
  * Override this method to add custom listeners.
20264
20714
  * @param {!HTMLElement} input
20715
+ * @protected
20265
20716
  */
20266
20717
  _addInputListeners(input) {
20267
20718
  input.addEventListener('input', this._boundOnInput);
@@ -20271,6 +20722,7 @@ const InputMixin = dedupingMixin(
20271
20722
  /**
20272
20723
  * Remove event listeners from the input element instance.
20273
20724
  * @param {!HTMLElement} input
20725
+ * @protected
20274
20726
  */
20275
20727
  _removeInputListeners(input) {
20276
20728
  input.removeEventListener('input', this._boundOnInput);
@@ -20284,7 +20736,6 @@ const InputMixin = dedupingMixin(
20284
20736
  * for example to skip this in certain conditions.
20285
20737
  * @param {string} value
20286
20738
  * @protected
20287
- * @override
20288
20739
  */
20289
20740
  _forwardInputValue(value) {
20290
20741
  // Value might be set before an input element is initialized.
@@ -20301,7 +20752,11 @@ const InputMixin = dedupingMixin(
20301
20752
  }
20302
20753
  }
20303
20754
 
20304
- /** @protected */
20755
+ /**
20756
+ * @param {HTMLElement | undefined} input
20757
+ * @param {HTMLElement | undefined} oldInput
20758
+ * @protected
20759
+ */
20305
20760
  _inputElementChanged(input, oldInput) {
20306
20761
  if (input) {
20307
20762
  this._addInputListeners(input);
@@ -20310,17 +20765,43 @@ const InputMixin = dedupingMixin(
20310
20765
  }
20311
20766
  }
20312
20767
 
20768
+ /**
20769
+ * Observer to notify about the change of private property.
20770
+ *
20771
+ * @private
20772
+ */
20773
+ _hasInputValueChanged(hasValue, oldHasValue) {
20774
+ if (hasValue || oldHasValue) {
20775
+ this.dispatchEvent(new CustomEvent('has-input-value-changed'));
20776
+ }
20777
+ }
20778
+
20779
+ /**
20780
+ * An input event listener used to update `_hasInputValue` property.
20781
+ * Do not override this method.
20782
+ *
20783
+ * @param {Event} event
20784
+ * @private
20785
+ */
20786
+ __onInput(event) {
20787
+ this._setHasInputValue(event);
20788
+ this._onInput(event);
20789
+ }
20790
+
20313
20791
  /**
20314
20792
  * An input event listener used to update the field value.
20315
- * Override this method with an actual implementation.
20316
- * @param {Event} _event
20793
+ *
20794
+ * @param {Event} event
20317
20795
  * @protected
20318
- * @override
20319
20796
  */
20320
20797
  _onInput(event) {
20798
+ // In the case a custom web component is passed as `inputElement`,
20799
+ // the actual native input element, on which the event occurred,
20800
+ // can be inside shadow trees.
20801
+ const target = event.composedPath()[0];
20321
20802
  // Ignore fake input events e.g. used by clear button.
20322
20803
  this.__userInput = event.isTrusted;
20323
- this.value = event.target.value;
20804
+ this.value = target.value;
20324
20805
  this.__userInput = false;
20325
20806
  }
20326
20807
 
@@ -20329,12 +20810,12 @@ const InputMixin = dedupingMixin(
20329
20810
  * Override this method with an actual implementation.
20330
20811
  * @param {Event} _event
20331
20812
  * @protected
20332
- * @override
20333
20813
  */
20334
20814
  _onChange(_event) {}
20335
20815
 
20336
20816
  /**
20337
20817
  * Toggle the has-value attribute based on the value property.
20818
+ *
20338
20819
  * @param {boolean} hasValue
20339
20820
  * @protected
20340
20821
  */
@@ -20347,10 +20828,9 @@ const InputMixin = dedupingMixin(
20347
20828
  * @param {string | undefined} newVal
20348
20829
  * @param {string | undefined} oldVal
20349
20830
  * @protected
20350
- * @override
20351
20831
  */
20352
20832
  _valueChanged(newVal, oldVal) {
20353
- this._toggleHasValue(newVal !== '' && newVal != null);
20833
+ this._toggleHasValue(this._hasValue);
20354
20834
 
20355
20835
  // Setting initial value to empty string, do nothing.
20356
20836
  if (newVal === '' && oldVal === undefined) {
@@ -20365,6 +20845,30 @@ const InputMixin = dedupingMixin(
20365
20845
  // Setting a value programmatically, sync it to input element.
20366
20846
  this._forwardInputValue(newVal);
20367
20847
  }
20848
+
20849
+ /**
20850
+ * Indicates whether the value is different from the default one.
20851
+ * Override if the `value` property has a type other than `string`.
20852
+ *
20853
+ * @protected
20854
+ */
20855
+ get _hasValue() {
20856
+ return this.value != null && this.value !== '';
20857
+ }
20858
+
20859
+ /**
20860
+ * Sets the `_hasInputValue` property based on the `input` event.
20861
+ *
20862
+ * @param {InputEvent} event
20863
+ * @protected
20864
+ */
20865
+ _setHasInputValue(event) {
20866
+ // In the case a custom web component is passed as `inputElement`,
20867
+ // the actual native input element, on which the event occurred,
20868
+ // can be inside shadow trees.
20869
+ const target = event.composedPath()[0];
20870
+ this._hasInputValue = target.value.length > 0;
20871
+ }
20368
20872
  },
20369
20873
  );
20370
20874
 
@@ -20436,26 +20940,32 @@ const InputConstraintsMixin = dedupingMixin(
20436
20940
  _createConstraintsObserver() {
20437
20941
  // This complex observer needs to be added dynamically instead of using `static get observers()`
20438
20942
  // to make it possible to tweak this behavior in classes that apply this mixin.
20439
- this._createMethodObserver(`_constraintsChanged(${this.constructor.constraints.join(', ')})`);
20943
+ this._createMethodObserver(`_constraintsChanged(stateTarget, ${this.constructor.constraints.join(', ')})`);
20440
20944
  }
20441
20945
 
20442
20946
  /**
20443
20947
  * Override this method to implement custom validation constraints.
20948
+ * @param {HTMLElement | undefined} stateTarget
20444
20949
  * @param {unknown[]} constraints
20445
20950
  * @protected
20446
20951
  */
20447
- _constraintsChanged(...constraints) {
20448
- // Prevent marking field as invalid when setting required state
20449
- // or any other constraint before a user has entered the value.
20450
- if (!this.invalid) {
20952
+ _constraintsChanged(stateTarget, ...constraints) {
20953
+ // The input element's validity cannot be determined until
20954
+ // all the necessary constraint attributes aren't set on it.
20955
+ if (!stateTarget) {
20451
20956
  return;
20452
20957
  }
20453
20958
 
20454
- if (this._hasValidConstraints(constraints)) {
20959
+ const hasConstraints = this._hasValidConstraints(constraints);
20960
+ const isLastConstraintRemoved = this.__previousHasConstraints && !hasConstraints;
20961
+
20962
+ if ((this._hasValue || this.invalid) && hasConstraints) {
20455
20963
  this.validate();
20456
- } else {
20457
- this.invalid = false;
20964
+ } else if (isLastConstraintRemoved) {
20965
+ this._setInvalid(false);
20458
20966
  }
20967
+
20968
+ this.__previousHasConstraints = hasConstraints;
20459
20969
  }
20460
20970
 
20461
20971
  /**
@@ -20490,6 +21000,82 @@ const InputConstraintsMixin = dedupingMixin(
20490
21000
  },
20491
21001
  );
20492
21002
 
21003
+ /**
21004
+ * @license
21005
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
21006
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
21007
+ */
21008
+
21009
+ const stylesMap = new WeakMap();
21010
+
21011
+ /**
21012
+ * Get all the styles inserted into root.
21013
+ * @param {DocumentOrShadowRoot} root
21014
+ * @return {Set<string>}
21015
+ */
21016
+ function getRootStyles(root) {
21017
+ if (!stylesMap.has(root)) {
21018
+ stylesMap.set(root, new Set());
21019
+ }
21020
+
21021
+ return stylesMap.get(root);
21022
+ }
21023
+
21024
+ /**
21025
+ * Insert styles into the root.
21026
+ * @param {string} styles
21027
+ * @param {DocumentOrShadowRoot} root
21028
+ */
21029
+ function insertStyles(styles, root) {
21030
+ const style = document.createElement('style');
21031
+ style.textContent = styles;
21032
+
21033
+ if (root === document) {
21034
+ document.head.appendChild(style);
21035
+ } else {
21036
+ root.insertBefore(style, root.firstChild);
21037
+ }
21038
+ }
21039
+
21040
+ /**
21041
+ * Mixin to insert styles into the outer scope to handle slotted components.
21042
+ * This is useful e.g. to hide native `<input type="number">` controls.
21043
+ *
21044
+ * @polymerMixin
21045
+ */
21046
+ const SlotStylesMixin = dedupingMixin(
21047
+ (superclass) =>
21048
+ class SlotStylesMixinClass extends superclass {
21049
+ /**
21050
+ * List of styles to insert into root.
21051
+ * @protected
21052
+ */
21053
+ get slotStyles() {
21054
+ return {};
21055
+ }
21056
+
21057
+ /** @protected */
21058
+ connectedCallback() {
21059
+ super.connectedCallback();
21060
+
21061
+ this.__applySlotStyles();
21062
+ }
21063
+
21064
+ /** @private */
21065
+ __applySlotStyles() {
21066
+ const root = this.getRootNode();
21067
+ const rootStyles = getRootStyles(root);
21068
+
21069
+ this.slotStyles.forEach((styles) => {
21070
+ if (!rootStyles.has(styles)) {
21071
+ insertStyles(styles, root);
21072
+ rootStyles.add(styles);
21073
+ }
21074
+ });
21075
+ }
21076
+ },
21077
+ );
21078
+
20493
21079
  /**
20494
21080
  * @license
20495
21081
  * Copyright (c) 2021 - 2022 Vaadin Ltd.
@@ -20504,13 +21090,31 @@ const InputConstraintsMixin = dedupingMixin(
20504
21090
  * @mixes FieldMixin
20505
21091
  * @mixes InputConstraintsMixin
20506
21092
  * @mixes KeyboardMixin
21093
+ * @mixes SlotStylesMixin
20507
21094
  */
20508
21095
  const InputControlMixin = (superclass) =>
20509
- class InputControlMixinClass extends DelegateFocusMixin(
20510
- InputConstraintsMixin(FieldMixin(KeyboardMixin(superclass))),
21096
+ class InputControlMixinClass extends SlotStylesMixin(
21097
+ DelegateFocusMixin(InputConstraintsMixin(FieldMixin(KeyboardMixin(superclass)))),
20511
21098
  ) {
20512
21099
  static get properties() {
20513
21100
  return {
21101
+ /**
21102
+ * A pattern matched against individual characters the user inputs.
21103
+ *
21104
+ * When set, the field will prevent:
21105
+ * - `keydown` events if the entered key doesn't match `/^allowedCharPattern$/`
21106
+ * - `paste` events if the pasted text doesn't match `/^allowedCharPattern*$/`
21107
+ * - `drop` events if the dropped text doesn't match `/^allowedCharPattern*$/`
21108
+ *
21109
+ * For example, to allow entering only numbers and minus signs, use:
21110
+ * `allowedCharPattern = "[\\d-]"`
21111
+ * @attr {string} allowed-char-pattern
21112
+ */
21113
+ allowedCharPattern: {
21114
+ type: String,
21115
+ observer: '_allowedCharPatternChanged',
21116
+ },
21117
+
20514
21118
  /**
20515
21119
  * If true, the input text gets fully selected when the field is focused using click or touch / tap.
20516
21120
  */
@@ -20568,6 +21172,14 @@ const InputControlMixin = (superclass) =>
20568
21172
  return [...super.delegateAttrs, 'name', 'type', 'placeholder', 'readonly', 'invalid', 'title'];
20569
21173
  }
20570
21174
 
21175
+ constructor() {
21176
+ super();
21177
+
21178
+ this._boundOnPaste = this._onPaste.bind(this);
21179
+ this._boundOnDrop = this._onDrop.bind(this);
21180
+ this._boundOnBeforeInput = this._onBeforeInput.bind(this);
21181
+ }
21182
+
20571
21183
  /**
20572
21184
  * Any element extending this mixin is required to implement this getter.
20573
21185
  * It returns the reference to the clear button element.
@@ -20579,6 +21191,19 @@ const InputControlMixin = (superclass) =>
20579
21191
  return null;
20580
21192
  }
20581
21193
 
21194
+ /** @protected */
21195
+ get slotStyles() {
21196
+ // Needed for Safari, where ::slotted(...)::placeholder does not work
21197
+ return [
21198
+ `
21199
+ :is(input[slot='input'], textarea[slot='textarea'])::placeholder {
21200
+ font: inherit;
21201
+ color: inherit;
21202
+ }
21203
+ `,
21204
+ ];
21205
+ }
21206
+
20582
21207
  /** @protected */
20583
21208
  ready() {
20584
21209
  super.ready();
@@ -20660,6 +21285,115 @@ const InputControlMixin = (superclass) =>
20660
21285
  this.inputElement.dispatchEvent(new Event('change', { bubbles: true }));
20661
21286
  }
20662
21287
 
21288
+ /**
21289
+ * Override a method from `InputMixin`.
21290
+ * @param {!HTMLElement} input
21291
+ * @protected
21292
+ * @override
21293
+ */
21294
+ _addInputListeners(input) {
21295
+ super._addInputListeners(input);
21296
+
21297
+ input.addEventListener('paste', this._boundOnPaste);
21298
+ input.addEventListener('drop', this._boundOnDrop);
21299
+ input.addEventListener('beforeinput', this._boundOnBeforeInput);
21300
+ }
21301
+
21302
+ /**
21303
+ * Override a method from `InputMixin`.
21304
+ * @param {!HTMLElement} input
21305
+ * @protected
21306
+ * @override
21307
+ */
21308
+ _removeInputListeners(input) {
21309
+ super._removeInputListeners(input);
21310
+
21311
+ input.removeEventListener('paste', this._boundOnPaste);
21312
+ input.removeEventListener('drop', this._boundOnDrop);
21313
+ input.removeEventListener('beforeinput', this._boundOnBeforeInput);
21314
+ }
21315
+
21316
+ /**
21317
+ * Override an event listener from `KeyboardMixin`.
21318
+ * @param {!KeyboardEvent} event
21319
+ * @protected
21320
+ * @override
21321
+ */
21322
+ _onKeyDown(event) {
21323
+ super._onKeyDown(event);
21324
+
21325
+ if (this.allowedCharPattern && !this.__shouldAcceptKey(event)) {
21326
+ event.preventDefault();
21327
+ this._markInputPrevented();
21328
+ }
21329
+ }
21330
+
21331
+ /** @protected */
21332
+ _markInputPrevented() {
21333
+ // Add input-prevented attribute for 200ms
21334
+ this.setAttribute('input-prevented', '');
21335
+ this._preventInputDebouncer = Debouncer$1.debounce(this._preventInputDebouncer, timeOut.after(200), () => {
21336
+ this.removeAttribute('input-prevented');
21337
+ });
21338
+ }
21339
+
21340
+ /** @private */
21341
+ __shouldAcceptKey(event) {
21342
+ return (
21343
+ event.metaKey ||
21344
+ event.ctrlKey ||
21345
+ !event.key || // Allow typing anything if event.key is not supported
21346
+ event.key.length !== 1 || // Allow "Backspace", "ArrowLeft" etc.
21347
+ this.__allowedCharRegExp.test(event.key)
21348
+ );
21349
+ }
21350
+
21351
+ /** @private */
21352
+ _onPaste(e) {
21353
+ if (this.allowedCharPattern) {
21354
+ const pastedText = e.clipboardData.getData('text');
21355
+ if (!this.__allowedTextRegExp.test(pastedText)) {
21356
+ e.preventDefault();
21357
+ this._markInputPrevented();
21358
+ }
21359
+ }
21360
+ }
21361
+
21362
+ /** @private */
21363
+ _onDrop(e) {
21364
+ if (this.allowedCharPattern) {
21365
+ const draggedText = e.dataTransfer.getData('text');
21366
+ if (!this.__allowedTextRegExp.test(draggedText)) {
21367
+ e.preventDefault();
21368
+ this._markInputPrevented();
21369
+ }
21370
+ }
21371
+ }
21372
+
21373
+ /** @private */
21374
+ _onBeforeInput(e) {
21375
+ // The `beforeinput` event covers all the cases for `allowedCharPattern`: keyboard, pasting and dropping,
21376
+ // but it is still experimental technology so we can't rely on it. It's used here just as an additional check,
21377
+ // because it seems to be the only way to detect and prevent specific keys on mobile devices.
21378
+ // See https://github.com/vaadin/vaadin-text-field/issues/429
21379
+ if (this.allowedCharPattern && e.data && !this.__allowedTextRegExp.test(e.data)) {
21380
+ e.preventDefault();
21381
+ this._markInputPrevented();
21382
+ }
21383
+ }
21384
+
21385
+ /** @private */
21386
+ _allowedCharPatternChanged(charPattern) {
21387
+ if (charPattern) {
21388
+ try {
21389
+ this.__allowedCharRegExp = new RegExp(`^${charPattern}$`);
21390
+ this.__allowedTextRegExp = new RegExp(`^${charPattern}*$`);
21391
+ } catch (e) {
21392
+ console.error(e);
21393
+ }
21394
+ }
21395
+ }
21396
+
20663
21397
  /**
20664
21398
  * Fired when the user commits a value change.
20665
21399
  *
@@ -20698,14 +21432,13 @@ class InputController extends SlotController {
20698
21432
  }
20699
21433
 
20700
21434
  // Ensure every instance has unique ID
20701
- const uniqueId = (InputController._uniqueInputId = 1 + InputController._uniqueInputId || 0);
20702
- host._inputId = `${host.localName}-${uniqueId}`;
20703
- node.id = host._inputId;
21435
+ node.id = this.defaultId;
20704
21436
 
20705
21437
  if (typeof callback === 'function') {
20706
21438
  callback(node);
20707
21439
  }
20708
21440
  },
21441
+ true,
20709
21442
  );
20710
21443
  }
20711
21444
  }
@@ -20887,7 +21620,9 @@ class VirtualKeyboardController {
20887
21620
  * @param {function(new:HTMLElement)} subclass
20888
21621
  */
20889
21622
  const DatePickerMixin = (subclass) =>
20890
- class VaadinDatePickerMixin extends ControllerMixin(DelegateFocusMixin(InputMixin(KeyboardMixin(subclass)))) {
21623
+ class VaadinDatePickerMixin extends ControllerMixin(
21624
+ DelegateFocusMixin(InputConstraintsMixin(KeyboardMixin(subclass))),
21625
+ ) {
20891
21626
  static get properties() {
20892
21627
  return {
20893
21628
  /**
@@ -20916,7 +21651,6 @@ const DatePickerMixin = (subclass) =>
20916
21651
  */
20917
21652
  value: {
20918
21653
  type: String,
20919
- observer: '_valueChanged',
20920
21654
  notify: true,
20921
21655
  value: '',
20922
21656
  },
@@ -20972,13 +21706,6 @@ const DatePickerMixin = (subclass) =>
20972
21706
  value: '(max-width: 420px), (max-height: 420px)',
20973
21707
  },
20974
21708
 
20975
- /**
20976
- * An array of ancestor elements whose -webkit-overflow-scrolling is forced from value
20977
- * 'touch' to value 'auto' in order to prevent them from clipping the dropdown. iOS only.
20978
- * @private
20979
- */
20980
- _touchPrevented: Array,
20981
-
20982
21709
  /**
20983
21710
  * The object used to localize this component.
20984
21711
  * To change the default localization, replace the entire
@@ -21034,6 +21761,16 @@ const DatePickerMixin = (subclass) =>
21034
21761
  * // Translation of the Cancel button text.
21035
21762
  * cancel: 'Cancel',
21036
21763
  *
21764
+ * // Used for adjusting the year value when parsing dates with short years.
21765
+ * // The year values between 0 and 99 are evaluated and adjusted.
21766
+ * // Example: for a referenceDate of 1970-10-30;
21767
+ * // dateToBeParsed: 40-10-30, result: 1940-10-30
21768
+ * // dateToBeParsed: 80-10-30, result: 1980-10-30
21769
+ * // dateToBeParsed: 10-10-30, result: 2010-10-30
21770
+ * // Supported date format: ISO 8601 `"YYYY-MM-DD"` (default)
21771
+ * // The default value is the current date.
21772
+ * referenceDate: '',
21773
+ *
21037
21774
  * // A function to format given `Object` as
21038
21775
  * // date string. Object is in the format `{ day: ..., month: ..., year: ... }`
21039
21776
  * // Note: The argument month is 0-based. This means that January = 0 and December = 11.
@@ -21087,11 +21824,12 @@ const DatePickerMixin = (subclass) =>
21087
21824
  calendar: 'Calendar',
21088
21825
  today: 'Today',
21089
21826
  cancel: 'Cancel',
21090
- formatDate: (d) => {
21827
+ referenceDate: '',
21828
+ formatDate(d) {
21091
21829
  const yearStr = String(d.year).replace(/\d+/, (y) => '0000'.substr(y.length) + y);
21092
21830
  return [d.month + 1, d.day, yearStr].join('/');
21093
21831
  },
21094
- parseDate: (text) => {
21832
+ parseDate(text) {
21095
21833
  const parts = text.split('/');
21096
21834
  const today = new Date();
21097
21835
  let date,
@@ -21099,12 +21837,13 @@ const DatePickerMixin = (subclass) =>
21099
21837
  year = today.getFullYear();
21100
21838
 
21101
21839
  if (parts.length === 3) {
21840
+ month = parseInt(parts[0]) - 1;
21841
+ date = parseInt(parts[1]);
21102
21842
  year = parseInt(parts[2]);
21103
21843
  if (parts[2].length < 3 && year >= 0) {
21104
- year += year < 50 ? 2000 : 1900;
21844
+ const usedReferenceDate = this.referenceDate ? parseDate(this.referenceDate) : new Date();
21845
+ year = getAdjustedYear(usedReferenceDate, year, month, date);
21105
21846
  }
21106
- month = parseInt(parts[0]) - 1;
21107
- date = parseInt(parts[1]);
21108
21847
  } else if (parts.length === 2) {
21109
21848
  month = parseInt(parts[0]) - 1;
21110
21849
  date = parseInt(parts[1]);
@@ -21134,7 +21873,6 @@ const DatePickerMixin = (subclass) =>
21134
21873
  */
21135
21874
  min: {
21136
21875
  type: String,
21137
- observer: '_minChanged',
21138
21876
  },
21139
21877
 
21140
21878
  /**
@@ -21148,28 +21886,26 @@ const DatePickerMixin = (subclass) =>
21148
21886
  */
21149
21887
  max: {
21150
21888
  type: String,
21151
- observer: '_maxChanged',
21152
21889
  },
21153
21890
 
21154
21891
  /**
21155
21892
  * The earliest date that can be selected. All earlier dates will be disabled.
21156
- * @type {Date | string}
21893
+ * @type {Date | undefined}
21157
21894
  * @protected
21158
21895
  */
21159
21896
  _minDate: {
21160
21897
  type: Date,
21161
- // Null does not work here because minimizer passes undefined to overlay (#351)
21162
- value: '',
21898
+ computed: '__computeMinOrMaxDate(min)',
21163
21899
  },
21164
21900
 
21165
21901
  /**
21166
21902
  * The latest date that can be selected. All later dates will be disabled.
21167
- * @type {Date | string}
21903
+ * @type {Date | undefined}
21168
21904
  * @protected
21169
21905
  */
21170
21906
  _maxDate: {
21171
21907
  type: Date,
21172
- value: '',
21908
+ computed: '__computeMinOrMaxDate(max)',
21173
21909
  },
21174
21910
 
21175
21911
  /** @private */
@@ -21184,12 +21920,6 @@ const DatePickerMixin = (subclass) =>
21184
21920
  value: isIOS,
21185
21921
  },
21186
21922
 
21187
- /** @private */
21188
- _webkitOverflowScroll: {
21189
- type: Boolean,
21190
- value: document.createElement('div').style.webkitOverflowScrolling === '',
21191
- },
21192
-
21193
21923
  /** @private */
21194
21924
  _focusOverlayOnOpen: Boolean,
21195
21925
 
@@ -21205,6 +21935,10 @@ const DatePickerMixin = (subclass) =>
21205
21935
  ];
21206
21936
  }
21207
21937
 
21938
+ static get constraints() {
21939
+ return [...super.constraints, 'min', 'max'];
21940
+ }
21941
+
21208
21942
  /**
21209
21943
  * Override a getter from `InputControlMixin` to make it optional
21210
21944
  * and to prevent warning when a clear button is missing,
@@ -21265,18 +21999,13 @@ const DatePickerMixin = (subclass) =>
21265
21999
 
21266
22000
  if (!this.opened) {
21267
22001
  if (this.autoOpenDisabled) {
21268
- const parsedDate = this._getParsedDate();
21269
- if (this._isValidDate(parsedDate)) {
21270
- this._selectDate(parsedDate);
21271
- }
22002
+ this._selectParsedOrFocusedDate();
21272
22003
  }
21273
22004
 
21274
- if (this.inputElement.value === '' && this.__dispatchChange) {
21275
- this.validate();
22005
+ this.validate();
22006
+
22007
+ if (this._inputValue === '' && this.value !== '') {
21276
22008
  this.value = '';
21277
- this.__dispatchChange = false;
21278
- } else {
21279
- this.validate();
21280
22009
  }
21281
22010
  }
21282
22011
  }
@@ -21345,14 +22074,19 @@ const DatePickerMixin = (subclass) =>
21345
22074
  this.$.overlay.removeAttribute('disable-upgrade');
21346
22075
  this._overlayInitialized = true;
21347
22076
 
21348
- this.$.overlay.addEventListener('opened-changed', (e) => (this.opened = e.detail.value));
22077
+ this.$.overlay.addEventListener('opened-changed', (e) => {
22078
+ this.opened = e.detail.value;
22079
+ });
21349
22080
 
21350
22081
  this.$.overlay.addEventListener('vaadin-overlay-escape-press', () => {
21351
22082
  this._focusedDate = this._selectedDate;
21352
22083
  this._close();
21353
22084
  });
21354
22085
 
21355
- this._overlayContent.addEventListener('close', this._close.bind(this));
22086
+ this._overlayContent.addEventListener('close', () => {
22087
+ this._close();
22088
+ });
22089
+
21356
22090
  this._overlayContent.addEventListener('focus-input', this._focusAndSelect.bind(this));
21357
22091
 
21358
22092
  // User confirmed selected date by clicking the calendar.
@@ -21361,34 +22095,29 @@ const DatePickerMixin = (subclass) =>
21361
22095
 
21362
22096
  this._selectDate(e.detail.date);
21363
22097
 
21364
- this._close(e);
22098
+ this._close();
21365
22099
  });
21366
22100
 
21367
- // User confirmed selected date by pressing Enter or Today.
22101
+ // User confirmed selected date by pressing Enter, Space, or Today.
21368
22102
  this._overlayContent.addEventListener('date-selected', (e) => {
21369
- this.__userConfirmedDate = true;
22103
+ // Reset if a date is deselected.
22104
+ this.__userConfirmedDate = !!e.detail.date;
21370
22105
 
21371
22106
  this._selectDate(e.detail.date);
21372
22107
  });
21373
22108
 
21374
- // Keep focus attribute in focusElement for styling
22109
+ // Set focus-ring attribute when moving focus to the overlay
22110
+ // by pressing Tab or arrow key, after opening it on click.
21375
22111
  this._overlayContent.addEventListener('focusin', () => {
21376
- this._setFocused(true);
22112
+ if (this._keyboardActive) {
22113
+ this._setFocused(true);
22114
+ }
21377
22115
  });
21378
22116
 
21379
22117
  this.addEventListener('mousedown', () => this.__bringToFront());
21380
22118
  this.addEventListener('touchstart', () => this.__bringToFront());
21381
22119
  }
21382
22120
 
21383
- /**
21384
- * Returns true if `value` is valid, and sets the `invalid` flag appropriately.
21385
- *
21386
- * @return {boolean} True if the value is valid and sets the `invalid` flag appropriately
21387
- */
21388
- validate() {
21389
- return !(this.invalid = !this.checkValidity());
21390
- }
21391
-
21392
22121
  /**
21393
22122
  * Returns true if the current input value satisfies all constraints (if any)
21394
22123
  *
@@ -21399,7 +22128,7 @@ const DatePickerMixin = (subclass) =>
21399
22128
  checkValidity() {
21400
22129
  const inputValid =
21401
22130
  !this._inputValue ||
21402
- (this._selectedDate && this._inputValue === this._getFormattedDate(this.i18n.formatDate, this._selectedDate));
22131
+ (!!this._selectedDate && this._inputValue === this._getFormattedDate(this.i18n.formatDate, this._selectedDate));
21403
22132
  const minMaxValid = !this._selectedDate || dateAllowed(this._selectedDate, this._minDate, this._maxDate);
21404
22133
 
21405
22134
  let inputValidity = true;
@@ -21415,6 +22144,51 @@ const DatePickerMixin = (subclass) =>
21415
22144
  return inputValid && minMaxValid && inputValidity;
21416
22145
  }
21417
22146
 
22147
+ /**
22148
+ * Override method inherited from `FocusMixin`
22149
+ * to not call `_setFocused(true)` when focus
22150
+ * is restored after closing overlay on click,
22151
+ * and to avoid removing `focus-ring` attribute.
22152
+ *
22153
+ * @param {!FocusEvent} _event
22154
+ * @return {boolean}
22155
+ * @protected
22156
+ * @override
22157
+ */
22158
+ _shouldSetFocus(_event) {
22159
+ return !this._shouldKeepFocusRing;
22160
+ }
22161
+
22162
+ /**
22163
+ * Override method inherited from `FocusMixin`
22164
+ * to prevent removing the `focused` attribute:
22165
+ * - when moving focus to the overlay content,
22166
+ * - when closing on date click / outside click.
22167
+ *
22168
+ * @param {!FocusEvent} _event
22169
+ * @return {boolean}
22170
+ * @protected
22171
+ * @override
22172
+ */
22173
+ _shouldRemoveFocus(_event) {
22174
+ return !this.opened;
22175
+ }
22176
+
22177
+ /**
22178
+ * Override method inherited from `FocusMixin`
22179
+ * to store the `focus-ring` state to restore
22180
+ * it later when closing on outside click.
22181
+ *
22182
+ * @param {boolean} focused
22183
+ * @protected
22184
+ * @override
22185
+ */
22186
+ _setFocused(focused) {
22187
+ super._setFocused(focused);
22188
+
22189
+ this._shouldKeepFocusRing = focused && this._keyboardActive;
22190
+ }
22191
+
21418
22192
  /**
21419
22193
  * Select date on user interaction and set the flag
21420
22194
  * to fire change event if necessary.
@@ -21434,10 +22208,7 @@ const DatePickerMixin = (subclass) =>
21434
22208
  }
21435
22209
 
21436
22210
  /** @private */
21437
- _close(e) {
21438
- if (e) {
21439
- e.stopPropagation();
21440
- }
22211
+ _close() {
21441
22212
  this._focus();
21442
22213
  this.close();
21443
22214
  }
@@ -21449,21 +22220,6 @@ const DatePickerMixin = (subclass) =>
21449
22220
  });
21450
22221
  }
21451
22222
 
21452
- /** @private */
21453
- _parseDate(str) {
21454
- // Parsing with RegExp to ensure correct format
21455
- const parts = /^([-+]\d{1}|\d{2,4}|[-+]\d{6})-(\d{1,2})-(\d{1,2})$/.exec(str);
21456
- if (!parts) {
21457
- return;
21458
- }
21459
-
21460
- const date = new Date(0, 0); // Wrong date (1900-01-01), but with midnight in local time
21461
- date.setFullYear(parseInt(parts[1], 10));
21462
- date.setMonth(parseInt(parts[2], 10) - 1);
21463
- date.setDate(parseInt(parts[3], 10));
21464
- return date;
21465
- }
21466
-
21467
22223
  /** @private */
21468
22224
  // eslint-disable-next-line max-params
21469
22225
  _isNoInput(inputElement, fullscreen, ios, i18n, opened, autoOpenDisabled) {
@@ -21566,48 +22322,47 @@ const DatePickerMixin = (subclass) =>
21566
22322
  }
21567
22323
  }
21568
22324
 
21569
- /** @private */
21570
- _handleDateChange(property, value, oldValue) {
21571
- if (!value) {
21572
- this[property] = '';
21573
- return;
21574
- }
22325
+ /**
22326
+ * Override the value observer from `InputMixin` to implement custom
22327
+ * handling of the `value` property. The date-picker doesn't forward
22328
+ * the value directly to the input like the default implementation of `InputMixin`.
22329
+ * Instead, it parses the value into a date, puts it in `_selectedDate` which
22330
+ * is then displayed in the input with respect to the specified date format.
22331
+ *
22332
+ * @param {string | undefined} value
22333
+ * @param {string | undefined} oldValue
22334
+ * @protected
22335
+ * @override
22336
+ */
22337
+ _valueChanged(value, oldValue) {
22338
+ const newDate = parseDate(value);
21575
22339
 
21576
- const date = this._parseDate(value);
21577
- if (!date) {
22340
+ if (value && !newDate) {
22341
+ // The new value cannot be parsed, revert the old value.
21578
22342
  this.value = oldValue;
21579
22343
  return;
21580
22344
  }
21581
- if (!dateEquals(this[property], date)) {
21582
- this[property] = date;
21583
- if (this.value) {
21584
- this.validate();
21585
- }
21586
- }
21587
- }
21588
-
21589
- /** @private */
21590
- _valueChanged(value, oldValue) {
21591
- this._handleDateChange('_selectedDate', value, oldValue);
21592
22345
 
21593
- this._toggleHasValue(!!value);
21594
- }
22346
+ if (value) {
22347
+ if (!dateEquals(this._selectedDate, newDate)) {
22348
+ // Update the date instance only if the date has actually changed.
22349
+ this._selectedDate = newDate;
21595
22350
 
21596
- /** @private */
21597
- _minChanged(value, oldValue) {
21598
- this._handleDateChange('_minDate', value, oldValue);
21599
- }
22351
+ if (oldValue !== undefined) {
22352
+ // Validate only if `value` changes after initialization.
22353
+ this.validate();
22354
+ }
22355
+ }
22356
+ } else {
22357
+ this._selectedDate = null;
22358
+ }
21600
22359
 
21601
- /** @private */
21602
- _maxChanged(value, oldValue) {
21603
- this._handleDateChange('_maxDate', value, oldValue);
22360
+ this._toggleHasValue(this._hasValue);
21604
22361
  }
21605
22362
 
21606
22363
  /** @protected */
21607
22364
  _onOverlayOpened() {
21608
- this._openedWithFocusRing = this.hasAttribute('focus-ring');
21609
-
21610
- const parsedInitialPosition = this._parseDate(this.initialPosition);
22365
+ const parsedInitialPosition = parseDate(this.initialPosition);
21611
22366
 
21612
22367
  const initialPosition =
21613
22368
  this._selectedDate || this._overlayContent.initialPosition || parsedInitialPosition || new Date();
@@ -21626,10 +22381,6 @@ const DatePickerMixin = (subclass) =>
21626
22381
 
21627
22382
  window.addEventListener('scroll', this._boundOnScroll, true);
21628
22383
 
21629
- if (this._webkitOverflowScroll) {
21630
- this._touchPrevented = this._preventWebkitOverflowScrollingTouch(this.parentElement);
21631
- }
21632
-
21633
22384
  if (this._focusOverlayOnOpen) {
21634
22385
  this._overlayContent.focusDateElement();
21635
22386
  this._focusOverlayOnOpen = false;
@@ -21643,25 +22394,6 @@ const DatePickerMixin = (subclass) =>
21643
22394
  }
21644
22395
  }
21645
22396
 
21646
- // A hack needed for iOS to prevent dropdown from being clipped in an
21647
- // ancestor container with -webkit-overflow-scrolling: touch;
21648
- /** @private */
21649
- _preventWebkitOverflowScrollingTouch(element) {
21650
- const result = [];
21651
- while (element) {
21652
- if (window.getComputedStyle(element).webkitOverflowScrolling === 'touch') {
21653
- const oldInlineValue = element.style.webkitOverflowScrolling;
21654
- element.style.webkitOverflowScrolling = 'auto';
21655
- result.push({
21656
- element,
21657
- oldInlineValue,
21658
- });
21659
- }
21660
- element = element.parentElement;
21661
- }
21662
- return result;
21663
- }
21664
-
21665
22397
  /** @private */
21666
22398
  _selectParsedOrFocusedDate() {
21667
22399
  // Select the parsed input or focused date
@@ -21688,13 +22420,6 @@ const DatePickerMixin = (subclass) =>
21688
22420
  _onOverlayClosed() {
21689
22421
  window.removeEventListener('scroll', this._boundOnScroll, true);
21690
22422
 
21691
- if (this._touchPrevented) {
21692
- this._touchPrevented.forEach(
21693
- (prevented) => (prevented.element.style.webkitOverflowScrolling = prevented.oldInlineValue),
21694
- );
21695
- this._touchPrevented = [];
21696
- }
21697
-
21698
22423
  // No need to select date on close if it was confirmed by the user.
21699
22424
  if (this.__userConfirmedDate) {
21700
22425
  this.__userConfirmedDate = false;
@@ -21710,11 +22435,6 @@ const DatePickerMixin = (subclass) =>
21710
22435
  if (!this.value) {
21711
22436
  this.validate();
21712
22437
  }
21713
-
21714
- // If the input isn't focused when overlay closes (fullscreen mode), clear focused state
21715
- if (this.getRootNode().activeElement !== this.inputElement) {
21716
- this._setFocused(false);
21717
- }
21718
22438
  }
21719
22439
 
21720
22440
  /** @private */
@@ -21767,10 +22487,7 @@ const DatePickerMixin = (subclass) =>
21767
22487
  _onChange(event) {
21768
22488
  // For change event on the native <input> blur, after the input is cleared,
21769
22489
  // we schedule change event to be dispatched on date-picker blur.
21770
- if (
21771
- this.inputElement.value === '' &&
21772
- !(event.detail && event.detail.sourceEvent && event.detail.sourceEvent.__fromClearButton)
21773
- ) {
22490
+ if (this._inputValue === '') {
21774
22491
  this.__dispatchChange = true;
21775
22492
  }
21776
22493
 
@@ -21857,7 +22574,7 @@ const DatePickerMixin = (subclass) =>
21857
22574
  if (e.shiftKey) {
21858
22575
  this._overlayContent.focusCancel();
21859
22576
  } else {
21860
- this._overlayContent.focusDate(this._focusedDate);
22577
+ this._overlayContent.focusDateElement();
21861
22578
  }
21862
22579
  }
21863
22580
  break;
@@ -21872,21 +22589,15 @@ const DatePickerMixin = (subclass) =>
21872
22589
  * @override
21873
22590
  */
21874
22591
  _onEnter(_event) {
21875
- const parsedDate = this._getParsedDate();
21876
- const isValidDate = this._isValidDate(parsedDate);
22592
+ const oldValue = this.value;
21877
22593
  if (this.opened) {
21878
- if (this._overlayInitialized && this._overlayContent.focusedDate && isValidDate) {
21879
- this._selectDate(this._overlayContent.focusedDate);
21880
- }
22594
+ // Closing will implicitly select parsed or focused date
21881
22595
  this.close();
21882
- } else if (!isValidDate && this.inputElement.value !== '') {
21883
- this.validate();
21884
22596
  } else {
21885
- const oldValue = this.value;
21886
22597
  this._selectParsedOrFocusedDate();
21887
- if (oldValue === this.value) {
21888
- this.validate();
21889
- }
22598
+ }
22599
+ if (oldValue === this.value) {
22600
+ this.validate();
21890
22601
  }
21891
22602
  }
21892
22603
 
@@ -21928,7 +22639,7 @@ const DatePickerMixin = (subclass) =>
21928
22639
  /** @private */
21929
22640
  _getParsedDate(inputValue = this._inputValue) {
21930
22641
  const dateObject = this.i18n.parseDate && this.i18n.parseDate(inputValue);
21931
- const parsedDate = dateObject && this._parseDate(`${dateObject.year}-${dateObject.month + 1}-${dateObject.day}`);
22642
+ const parsedDate = dateObject && parseDate(`${dateObject.year}-${dateObject.month + 1}-${dateObject.day}`);
21932
22643
  return parsedDate;
21933
22644
  }
21934
22645
 
@@ -21950,7 +22661,7 @@ const DatePickerMixin = (subclass) =>
21950
22661
 
21951
22662
  /** @private */
21952
22663
  _userInputValueChanged() {
21953
- if (this.opened && this._inputValue) {
22664
+ if (this._inputValue) {
21954
22665
  const parsedDate = this._getParsedDate();
21955
22666
 
21956
22667
  if (this._isValidDate(parsedDate)) {
@@ -21968,6 +22679,11 @@ const DatePickerMixin = (subclass) =>
21968
22679
  return this.$.overlay.content.querySelector('#overlay-content');
21969
22680
  }
21970
22681
 
22682
+ /** @private */
22683
+ __computeMinOrMaxDate(dateString) {
22684
+ return parseDate(dateString);
22685
+ }
22686
+
21971
22687
  /**
21972
22688
  * Fired when the user commits a value change.
21973
22689
  *
@@ -22079,12 +22795,13 @@ registerStyles('vaadin-date-picker', [inputFieldShared, datePickerStyles], { mod
22079
22795
  * Note: the `theme` attribute value set on `<vaadin-date-picker>` is
22080
22796
  * propagated to the internal components listed above.
22081
22797
  *
22082
- * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
22798
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
22083
22799
  *
22084
22800
  * @fires {Event} change - Fired when the user commits a value change.
22085
22801
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
22086
22802
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
22087
22803
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
22804
+ * @fires {CustomEvent} validated - Fired whenever the field is validated.
22088
22805
  *
22089
22806
  * @extends HTMLElement
22090
22807
  * @mixes ElementMixin
@@ -22138,7 +22855,7 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
22138
22855
  fullscreen$="[[_fullscreen]]"
22139
22856
  theme$="[[__getOverlayTheme(_theme, _overlayInitialized)]]"
22140
22857
  on-vaadin-overlay-open="_onOverlayOpened"
22141
- on-vaadin-overlay-close="_onOverlayClosed"
22858
+ on-vaadin-overlay-closing="_onOverlayClosed"
22142
22859
  restore-focus-on-close
22143
22860
  restore-focus-node="[[inputElement]]"
22144
22861
  disable-upgrade
@@ -22159,6 +22876,8 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
22159
22876
  ></vaadin-date-picker-overlay-content>
22160
22877
  </template>
22161
22878
  </vaadin-date-picker-overlay>
22879
+
22880
+ <slot name="tooltip"></slot>
22162
22881
  `;
22163
22882
  }
22164
22883
 
@@ -22185,6 +22904,11 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
22185
22904
  );
22186
22905
  this.addController(new LabelledInputController(this.inputElement, this._labelController));
22187
22906
 
22907
+ this._tooltipController = new TooltipController(this);
22908
+ this.addController(this._tooltipController);
22909
+ this._tooltipController.setPosition('top');
22910
+ this._tooltipController.setShouldShow((target) => !target.opened);
22911
+
22188
22912
  const toggleButton = this.shadowRoot.querySelector('[part="toggle-button"]');
22189
22913
  toggleButton.addEventListener('mousedown', (e) => e.preventDefault());
22190
22914
  }
@@ -22198,11 +22922,6 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
22198
22922
 
22199
22923
  /** @private */
22200
22924
  _onVaadinOverlayClose(e) {
22201
- if (this._openedWithFocusRing && this.hasAttribute('focused')) {
22202
- this.setAttribute('focus-ring', '');
22203
- } else if (!this.hasAttribute('focused')) {
22204
- this.blur();
22205
- }
22206
22925
  if (e.detail.sourceEvent && e.detail.sourceEvent.composedPath().includes(this)) {
22207
22926
  e.preventDefault();
22208
22927
  }
@@ -22332,6 +23051,7 @@ const HelperFilters = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
22332
23051
  this.modalCloseEvent();
22333
23052
  this.showClearButton = true;
22334
23053
  this.filterSelectionHandler(this.filterData);
23054
+ console.log(this.showClearButton);
22335
23055
  }
22336
23056
  resetSearch() {
22337
23057
  this.showClearButton = false;
@@ -22348,7 +23068,7 @@ const HelperFilters = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
22348
23068
  this.filterData.filterToCalendar = new Date(event.target.value).toISOString();
22349
23069
  }
22350
23070
  render() {
22351
- return (h$2("div", { class: "HelperFilters", ref: el => this.stylingContainer = el }, h$2("div", { class: "FilterButtonsWrapper" }, h$2("button", { class: "FilterOpen", onClick: () => this.toggleFilterModal() }, translate$1('filterOpen', this.language)), (this.showClearButton || this.quickFiltersActive) ?
23071
+ return (h$2("div", { class: "HelperFilters", ref: el => this.stylingContainer = el }, h$2("div", { class: "FilterButtonsWrapper" }, h$2("button", { class: "FilterOpen", onClick: () => this.toggleFilterModal() }, translate$1('filterOpen', this.language)), console.log('in filter Open', this.showClearButton, this.quickFiltersActive), (this.showClearButton || this.quickFiltersActive) ?
22352
23072
  h$2("button", { class: "FilterClear", onClick: () => this.resetSearch() }, translate$1('filterClear', this.language))
22353
23073
  :
22354
23074
  null), h$2("helper-modal", { "title-modal": "Filter Modal", visible: this.showFilterModal, "client-styling": this.clientStyling, "client-styling-url-content": this.clientStylingUrlContent }, h$2("div", { class: "FilterModalHeader" }, h$2("h3", { class: "FilterModalTitle" }, this.activateTicketSearch ? translate$1('filterModalTicketTitle', this.language) : translate$1('filterModalDrawTitle', this.language))), h$2("div", { class: "FilterModalBody" }, h$2("input", { id: "FilterById", type: "text", value: this.filterData.ticketDrawId, onInput: (event) => this.handleTicketDrawId(event), class: "FilterModalSearch", placeholder: this.activateTicketSearch ? translate$1('filterTicketPlaceholder', this.language) : translate$1('filterDrawPlaceholder', this.language) }), h$2("p", null, translate$1('filterOrDate', this.language)), h$2("div", { class: "FilterCalendarWrapper" }, h$2("vaadin-date-picker", { value: this.filterData.filterFromCalendar, onChange: (event) => this.handleFilterFrom(event), placeholder: translate$1('filterFromCalendar', this.language), class: "VaadinDatePicker" }), h$2("vaadin-date-picker", { value: this.filterData.filterToCalendar, onChange: (event) => this.handleFilterTo(event), placeholder: translate$1('filterToCalendar', this.language), class: "VaadinDatePicker" }))), h$2("div", { class: "FilterModalFooter" }, h$2("button", { class: "FilterModalButton", onClick: () => this.filterSearch() }, translate$1('filterModalButton', this.language))))));
@@ -22392,3 +23112,5 @@ function defineCustomElement() {
22392
23112
  defineCustomElement();
22393
23113
 
22394
23114
  export { HelperFilters as H, defineCustomElement as d };
23115
+
23116
+ //# sourceMappingURL=helper-filters2.js.map