@vaadin/date-picker 23.3.0-alpha2 → 24.0.0-alpha1

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.
@@ -3,25 +3,36 @@
3
3
  * Copyright (c) 2016 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { DisableUpgradeMixin } from '@polymer/polymer/lib/mixins/disable-upgrade-mixin.js';
7
- import { OverlayElement } from '@vaadin/vaadin-overlay/src/vaadin-overlay.js';
8
- import { PositionMixin } from '@vaadin/vaadin-overlay/src/vaadin-overlay-position-mixin.js';
9
- import { registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
10
- import { datePickerOverlayStyles } from './vaadin-date-picker-styles.js';
6
+ import { Overlay } from '@vaadin/overlay/src/vaadin-overlay.js';
7
+ import { PositionMixin } from '@vaadin/overlay/src/vaadin-overlay-position-mixin.js';
8
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
11
9
 
12
- registerStyles('vaadin-date-picker-overlay', datePickerOverlayStyles, {
13
- moduleId: 'vaadin-date-picker-overlay-styles',
14
- });
10
+ registerStyles(
11
+ 'vaadin-date-picker-overlay',
12
+ css`
13
+ [part='overlay'] {
14
+ display: flex;
15
+ flex: auto;
16
+ }
17
+
18
+ [part~='content'] {
19
+ flex: auto;
20
+ }
21
+ `,
22
+ {
23
+ moduleId: 'vaadin-date-picker-overlay-styles',
24
+ },
25
+ );
15
26
 
16
27
  let memoizedTemplate;
17
28
 
18
29
  /**
19
30
  * An element used internally by `<vaadin-date-picker>`. Not intended to be used separately.
20
31
  *
21
- * @extends OverlayElement
32
+ * @extends Overlay
22
33
  * @private
23
34
  */
24
- class DatePickerOverlay extends DisableUpgradeMixin(PositionMixin(OverlayElement)) {
35
+ class DatePickerOverlay extends PositionMixin(Overlay) {
25
36
  static get is() {
26
37
  return 'vaadin-date-picker-overlay';
27
38
  }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2022 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { html } from '@polymer/polymer/lib/utils/html-tag.js';
7
+ import { InfiniteScroller } from './vaadin-infinite-scroller.js';
8
+
9
+ const stylesTemplate = html`
10
+ <style>
11
+ :host {
12
+ --vaadin-infinite-scroller-item-height: 80px;
13
+ width: 50px;
14
+ display: block;
15
+ height: 100%;
16
+ position: absolute;
17
+ right: 0;
18
+ transform: translateX(100%);
19
+ -webkit-tap-highlight-color: transparent;
20
+ -webkit-user-select: none;
21
+ -moz-user-select: none;
22
+ user-select: none;
23
+ /* Center the year scroller position. */
24
+ --vaadin-infinite-scroller-buffer-offset: 50%;
25
+ }
26
+
27
+ :host::before {
28
+ content: '';
29
+ display: block;
30
+ background: transparent;
31
+ width: 0;
32
+ height: 0;
33
+ position: absolute;
34
+ left: 0;
35
+ top: 50%;
36
+ transform: translateY(-50%);
37
+ border-width: 6px;
38
+ border-style: solid;
39
+ border-color: transparent;
40
+ border-left-color: #000;
41
+ }
42
+ </style>
43
+ `;
44
+
45
+ let memoizedTemplate;
46
+
47
+ /**
48
+ * An element used internally by `<vaadin-date-picker>`. Not intended to be used separately.
49
+ *
50
+ * @extends InfiniteScroller
51
+ * @mixes ThemableMixin
52
+ * @private
53
+ */
54
+ class DatePickerYearScroller extends InfiniteScroller {
55
+ static get is() {
56
+ return 'vaadin-date-picker-year-scroller';
57
+ }
58
+
59
+ static get template() {
60
+ if (!memoizedTemplate) {
61
+ memoizedTemplate = super.template.cloneNode(true);
62
+ memoizedTemplate.content.appendChild(stylesTemplate.content.cloneNode(true));
63
+ }
64
+
65
+ return memoizedTemplate;
66
+ }
67
+
68
+ static get properties() {
69
+ return {
70
+ bufferSize: {
71
+ type: Number,
72
+ value: 12,
73
+ },
74
+ };
75
+ }
76
+
77
+ /**
78
+ * @protected
79
+ * @override
80
+ */
81
+ _createElement() {
82
+ return document.createElement('vaadin-date-picker-year');
83
+ }
84
+
85
+ /**
86
+ * @param {HTMLElement} element
87
+ * @param {number} index
88
+ * @protected
89
+ * @override
90
+ */
91
+ _updateElement(element, index) {
92
+ element.year = this._yearAfterXYears(index);
93
+ }
94
+
95
+ /** @private */
96
+ _yearAfterXYears(index) {
97
+ const today = new Date();
98
+ const result = new Date(today);
99
+ result.setFullYear(parseInt(index) + today.getFullYear());
100
+ return result.getFullYear();
101
+ }
102
+ }
103
+
104
+ customElements.define(DatePickerYearScroller.is, DatePickerYearScroller);
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2022 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
7
+ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
8
+
9
+ /**
10
+ * An element used internally by `<vaadin-date-picker>`. Not intended to be used separately.
11
+ *
12
+ * @extends HTMLElement
13
+ * @mixes ThemableMixin
14
+ * @private
15
+ */
16
+ export class DatePickerYear extends ThemableMixin(PolymerElement) {
17
+ static get is() {
18
+ return 'vaadin-date-picker-year';
19
+ }
20
+
21
+ static get template() {
22
+ return html`
23
+ <style>
24
+ :host {
25
+ display: block;
26
+ height: 100%;
27
+ }
28
+ </style>
29
+ <div part="year-number">[[year]]</div>
30
+ <div part="year-separator" aria-hidden="true"></div>
31
+ `;
32
+ }
33
+
34
+ static get properties() {
35
+ return {
36
+ year: {
37
+ type: String,
38
+ },
39
+
40
+ selectedDate: {
41
+ type: Object,
42
+ },
43
+ };
44
+ }
45
+
46
+ static get observers() {
47
+ return ['__updateSelected(year, selectedDate)'];
48
+ }
49
+
50
+ /** @private */
51
+ __updateSelected(year, selectedDate) {
52
+ this.toggleAttribute('selected', selectedDate && selectedDate.getFullYear() === year);
53
+ this.toggleAttribute('current', year === new Date().getFullYear());
54
+ }
55
+ }
56
+
57
+ customElements.define(DatePickerYear.is, DatePickerYear);
@@ -79,7 +79,6 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
79
79
  * Part name | Description
80
80
  * ----------------------|--------------------
81
81
  * `toggle-button` | Toggle button
82
- * `overlay-content` | The overlay element
83
82
  *
84
83
  * In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
85
84
  *
@@ -99,6 +98,9 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
99
98
  *
100
99
  * - `<vaadin-date-picker-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
101
100
  * - `<vaadin-date-picker-overlay-content>`
101
+ * - `<vaadin-date-picker-month-scroller>`
102
+ * - `<vaadin-date-picker-year-scroller>`
103
+ * - `<vaadin-date-picker-year>`
102
104
  * - `<vaadin-month-calendar>`
103
105
  * - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the input.
104
106
  *
@@ -111,14 +113,15 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
111
113
  * `clear-button` | Fullscreen mode clear button
112
114
  * `toggle-button` | Fullscreen mode toggle button
113
115
  * `years-toggle-button` | Fullscreen mode years scroller toggle
114
- * `months` | Months scroller
115
- * `years` | Years scroller
116
- * `toolbar` | Footer bar with buttons
117
- * `today-button` | Today button
118
- * `cancel-button` | Cancel button
119
- * `month` | Month calendar
120
- * `year-number` | Year number
121
- * `year-separator` | Year separator
116
+ * `toolbar` | Footer bar with slotted buttons
117
+ *
118
+ * The following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:
119
+ *
120
+ * Attribute | Description
121
+ * ----------------|-------------------------------------------------
122
+ * `desktop` | Set when the overlay content is in desktop mode
123
+ * `fullscreen` | Set when the overlay content is in fullscreen mode
124
+ * `years-visible` | Set when the year scroller is visible in fullscreen mode
122
125
  *
123
126
  * In order to style the month calendar, use `<vaadin-month-calendar>` shadow DOM parts:
124
127
  *
@@ -131,6 +134,13 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
131
134
  * `week-number` | Week number element
132
135
  * `date` | Date element
133
136
  *
137
+ * In order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:
138
+ *
139
+ * Part name | Description
140
+ * ----------------------|--------------------
141
+ * `year-number` | Year number
142
+ * `year-separator` | Year separator
143
+ *
134
144
  * Note: the `theme` attribute value set on `<vaadin-date-picker>` is
135
145
  * propagated to the internal components listed above.
136
146
  *
@@ -15,9 +15,8 @@ import { LabelledInputController } from '@vaadin/field-base/src/labelled-input-c
15
15
  import { inputFieldShared } from '@vaadin/field-base/src/styles/input-field-shared-styles.js';
16
16
  import { registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
17
17
  import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
18
- import { datePickerStyles } from './vaadin-date-picker-styles.js';
19
18
 
20
- registerStyles('vaadin-date-picker', [inputFieldShared, datePickerStyles], { moduleId: 'vaadin-date-picker-styles' });
19
+ registerStyles('vaadin-date-picker', inputFieldShared, { moduleId: 'vaadin-date-picker-styles' });
21
20
 
22
21
  /**
23
22
  * `<vaadin-date-picker>` is an input field that allows to enter a date by typing or by selecting from a calendar overlay.
@@ -48,7 +47,6 @@ registerStyles('vaadin-date-picker', [inputFieldShared, datePickerStyles], { mod
48
47
  * Part name | Description
49
48
  * ----------------------|--------------------
50
49
  * `toggle-button` | Toggle button
51
- * `overlay-content` | The overlay element
52
50
  *
53
51
  * In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
54
52
  *
@@ -68,6 +66,9 @@ registerStyles('vaadin-date-picker', [inputFieldShared, datePickerStyles], { mod
68
66
  *
69
67
  * - `<vaadin-date-picker-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
70
68
  * - `<vaadin-date-picker-overlay-content>`
69
+ * - `<vaadin-date-picker-month-scroller>`
70
+ * - `<vaadin-date-picker-year-scroller>`
71
+ * - `<vaadin-date-picker-year>`
71
72
  * - `<vaadin-month-calendar>`
72
73
  * - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the input.
73
74
  *
@@ -80,14 +81,15 @@ registerStyles('vaadin-date-picker', [inputFieldShared, datePickerStyles], { mod
80
81
  * `clear-button` | Fullscreen mode clear button
81
82
  * `toggle-button` | Fullscreen mode toggle button
82
83
  * `years-toggle-button` | Fullscreen mode years scroller toggle
83
- * `months` | Months scroller
84
- * `years` | Years scroller
85
- * `toolbar` | Footer bar with buttons
86
- * `today-button` | Today button
87
- * `cancel-button` | Cancel button
88
- * `month` | Month calendar
89
- * `year-number` | Year number
90
- * `year-separator` | Year separator
84
+ * `toolbar` | Footer bar with slotted buttons
85
+ *
86
+ * The following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:
87
+ *
88
+ * Attribute | Description
89
+ * ----------------|-------------------------------------------------
90
+ * `desktop` | Set when the overlay content is in desktop mode
91
+ * `fullscreen` | Set when the overlay content is in fullscreen mode
92
+ * `years-visible` | Set when the year scroller is visible in fullscreen mode
91
93
  *
92
94
  * In order to style the month calendar, use `<vaadin-month-calendar>` shadow DOM parts:
93
95
  *
@@ -100,6 +102,13 @@ registerStyles('vaadin-date-picker', [inputFieldShared, datePickerStyles], { mod
100
102
  * `week-number` | Week number element
101
103
  * `date` | Date element
102
104
  *
105
+ * In order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:
106
+ *
107
+ * Part name | Description
108
+ * ----------------------|--------------------
109
+ * `year-number` | Year number
110
+ * `year-separator` | Year separator
111
+ *
103
112
  * Note: the `theme` attribute value set on `<vaadin-date-picker>` is
104
113
  * propagated to the internal components listed above.
105
114
  *
@@ -128,6 +137,15 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
128
137
  :host([opened]) {
129
138
  pointer-events: auto;
130
139
  }
140
+
141
+ :host([dir='rtl']) [part='input-field'] {
142
+ direction: ltr;
143
+ }
144
+
145
+ :host([dir='rtl']) [part='input-field'] ::slotted(input)::placeholder {
146
+ direction: rtl;
147
+ text-align: left;
148
+ }
131
149
  </style>
132
150
 
133
151
  <div class="vaadin-date-picker-container">
@@ -161,29 +179,14 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
161
179
  <vaadin-date-picker-overlay
162
180
  id="overlay"
163
181
  fullscreen$="[[_fullscreen]]"
164
- theme$="[[__getOverlayTheme(_theme, _overlayInitialized)]]"
182
+ theme$="[[_theme]]"
183
+ opened="{{opened}}"
184
+ on-vaadin-overlay-escape-press="_onOverlayEscapePress"
165
185
  on-vaadin-overlay-open="_onOverlayOpened"
166
186
  on-vaadin-overlay-closing="_onOverlayClosed"
167
187
  restore-focus-on-close
168
188
  restore-focus-node="[[inputElement]]"
169
- disable-upgrade
170
- >
171
- <template>
172
- <vaadin-date-picker-overlay-content
173
- id="overlay-content"
174
- i18n="[[i18n]]"
175
- fullscreen$="[[_fullscreen]]"
176
- label="[[label]]"
177
- selected-date="[[_selectedDate]]"
178
- focused-date="{{_focusedDate}}"
179
- show-week-numbers="[[showWeekNumbers]]"
180
- min-date="[[_minDate]]"
181
- max-date="[[_maxDate]]"
182
- part="overlay-content"
183
- theme$="[[__getOverlayTheme(_theme, _overlayInitialized)]]"
184
- ></vaadin-date-picker-overlay-content>
185
- </template>
186
- </vaadin-date-picker-overlay>
189
+ ></vaadin-date-picker-overlay>
187
190
 
188
191
  <slot name="tooltip"></slot>
189
192
  `;
@@ -219,11 +222,6 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
219
222
 
220
223
  const toggleButton = this.shadowRoot.querySelector('[part="toggle-button"]');
221
224
  toggleButton.addEventListener('mousedown', (e) => e.preventDefault());
222
- }
223
-
224
- /** @protected */
225
- _initOverlay() {
226
- super._initOverlay();
227
225
 
228
226
  this.$.overlay.addEventListener('vaadin-overlay-close', this._onVaadinOverlayClose.bind(this));
229
227
  }
@@ -238,7 +236,11 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
238
236
  /** @private */
239
237
  _toggle(e) {
240
238
  e.stopPropagation();
241
- this[this._overlayInitialized && this.$.overlay.opened ? 'close' : 'open']();
239
+ if (this.$.overlay.opened) {
240
+ this.close();
241
+ } else {
242
+ this.open();
243
+ }
242
244
  }
243
245
 
244
246
  // Workaround https://github.com/vaadin/web-components/issues/2855
@@ -4,7 +4,6 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { afterNextRender } from '@polymer/polymer/lib/utils/render-status.js';
7
- import { templatize } from '@polymer/polymer/lib/utils/templatize.js';
8
7
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
9
8
  import { timeOut } from '@vaadin/component-base/src/async.js';
10
9
  import { isFirefox } from '@vaadin/component-base/src/browser-utils.js';
@@ -14,7 +13,7 @@ import { Debouncer } from '@vaadin/component-base/src/debounce.js';
14
13
  * @extends HTMLElement
15
14
  * @private
16
15
  */
17
- class InfiniteScroller extends PolymerElement {
16
+ export class InfiniteScroller extends PolymerElement {
18
17
  static get template() {
19
18
  return html`
20
19
  <style>
@@ -69,10 +68,6 @@ class InfiniteScroller extends PolymerElement {
69
68
  `;
70
69
  }
71
70
 
72
- static get is() {
73
- return 'vaadin-infinite-scroller';
74
- }
75
-
76
71
  static get properties() {
77
72
  return {
78
73
  /**
@@ -89,6 +84,7 @@ class InfiniteScroller extends PolymerElement {
89
84
  /**
90
85
  * The amount of initial scroll top. Needed in order for the
91
86
  * user to be able to scroll backwards.
87
+ * @private
92
88
  */
93
89
  _initialScroll: {
94
90
  value: 500000,
@@ -96,17 +92,22 @@ class InfiniteScroller extends PolymerElement {
96
92
 
97
93
  /**
98
94
  * The index/position mapped at _initialScroll point.
95
+ * @private
99
96
  */
100
97
  _initialIndex: {
101
98
  value: 0,
102
99
  },
103
100
 
101
+ /** @private */
104
102
  _buffers: Array,
105
103
 
104
+ /** @private */
106
105
  _preventScrollEvent: Boolean,
107
106
 
107
+ /** @private */
108
108
  _mayHaveMomentum: Boolean,
109
109
 
110
+ /** @private */
110
111
  _initialized: Boolean,
111
112
 
112
113
  active: {
@@ -116,26 +117,14 @@ class InfiniteScroller extends PolymerElement {
116
117
  };
117
118
  }
118
119
 
120
+ /** @protected */
119
121
  ready() {
120
122
  super.ready();
121
123
 
122
- this._buffers = Array.prototype.slice.call(this.root.querySelectorAll('.buffer'));
124
+ this._buffers = [...this.shadowRoot.querySelectorAll('.buffer')];
123
125
 
124
126
  this.$.fullHeight.style.height = `${this._initialScroll * 2}px`;
125
127
 
126
- const tpl = this.querySelector('template');
127
- this._TemplateClass = templatize(tpl, this, {
128
- forwardHostProp(prop, value) {
129
- if (prop !== 'index') {
130
- this._buffers.forEach((buffer) => {
131
- [].forEach.call(buffer.children, (insertionPoint) => {
132
- insertionPoint._itemWrapper.instance[prop] = value;
133
- });
134
- });
135
- }
136
- },
137
- });
138
-
139
128
  // Firefox interprets elements with overflow:auto as focusable
140
129
  // https://bugzilla.mozilla.org/show_bug.cgi?id=1069739
141
130
  if (isFirefox) {
@@ -143,6 +132,37 @@ class InfiniteScroller extends PolymerElement {
143
132
  }
144
133
  }
145
134
 
135
+ /**
136
+ * Force the scroller to update clones after a reset, without
137
+ * waiting for the debouncer to resolve.
138
+ */
139
+ forceUpdate() {
140
+ if (this._debouncerUpdateClones) {
141
+ this._buffers[0].updated = this._buffers[1].updated = false;
142
+ this._updateClones();
143
+ this._debouncerUpdateClones.cancel();
144
+ }
145
+ }
146
+
147
+ /**
148
+ * @protected
149
+ * @override
150
+ */
151
+ _createElement() {
152
+ // To be implemented.
153
+ }
154
+
155
+ /**
156
+ * @param {HTMLElement} _element
157
+ * @param {number} _index
158
+ * @protected
159
+ * @override
160
+ */
161
+ _updateElement(_element, _index) {
162
+ // To be implemented.
163
+ }
164
+
165
+ /** @private */
146
166
  _activated(active) {
147
167
  if (active && !this._initialized) {
148
168
  this._createPool();
@@ -150,11 +170,14 @@ class InfiniteScroller extends PolymerElement {
150
170
  }
151
171
  }
152
172
 
173
+ /** @private */
153
174
  _finishInit() {
154
175
  if (!this._initDone) {
155
176
  // Once the first set of items start fading in, stamp the rest
156
177
  this._buffers.forEach((buffer) => {
157
- [].forEach.call(buffer.children, (insertionPoint) => this._ensureStampedInstance(insertionPoint._itemWrapper));
178
+ [...buffer.children].forEach((slot) => {
179
+ this._ensureStampedInstance(slot._itemWrapper);
180
+ });
158
181
  });
159
182
 
160
183
  if (!this._buffers[0].translateY) {
@@ -162,9 +185,11 @@ class InfiniteScroller extends PolymerElement {
162
185
  }
163
186
 
164
187
  this._initDone = true;
188
+ this.dispatchEvent(new CustomEvent('init-done'));
165
189
  }
166
190
  }
167
191
 
192
+ /** @private */
168
193
  _translateBuffer(up) {
169
194
  const index = up ? 1 : 0;
170
195
  this._buffers[index].translateY = this._buffers[index ? 0 : 1].translateY + this._bufferHeight * (index ? -1 : 1);
@@ -173,6 +198,7 @@ class InfiniteScroller extends PolymerElement {
173
198
  this._buffers.reverse();
174
199
  }
175
200
 
201
+ /** @private */
176
202
  _scroll() {
177
203
  if (this._scrollDisabled) {
178
204
  return;
@@ -269,10 +295,12 @@ class InfiniteScroller extends PolymerElement {
269
295
  return this._itemHeightVal;
270
296
  }
271
297
 
298
+ /** @private */
272
299
  get _bufferHeight() {
273
300
  return this.itemHeight * this.bufferSize;
274
301
  }
275
302
 
303
+ /** @private */
276
304
  _reset() {
277
305
  this._scrollDisabled = true;
278
306
  this.$.scroller.scrollTop = this._initialScroll;
@@ -292,6 +320,7 @@ class InfiniteScroller extends PolymerElement {
292
320
  this._scrollDisabled = false;
293
321
  }
294
322
 
323
+ /** @private */
295
324
  _createPool() {
296
325
  const container = this.getBoundingClientRect();
297
326
  this._buffers.forEach((buffer) => {
@@ -303,28 +332,27 @@ class InfiniteScroller extends PolymerElement {
303
332
  const contentId = (InfiniteScroller._contentIndex = InfiniteScroller._contentIndex + 1 || 0);
304
333
  const slotName = `vaadin-infinite-scroller-item-content-${contentId}`;
305
334
 
306
- const insertionPoint = document.createElement('slot');
307
- insertionPoint.setAttribute('name', slotName);
308
- insertionPoint._itemWrapper = itemWrapper;
309
- buffer.appendChild(insertionPoint);
335
+ const slot = document.createElement('slot');
336
+ slot.setAttribute('name', slotName);
337
+ slot._itemWrapper = itemWrapper;
338
+ buffer.appendChild(slot);
310
339
 
311
340
  itemWrapper.setAttribute('slot', slotName);
312
341
  this.appendChild(itemWrapper);
313
342
 
314
- setTimeout(() => {
315
- // Only stamp the visible instances first
316
- if (this._isVisible(itemWrapper, container)) {
317
- this._ensureStampedInstance(itemWrapper);
318
- }
319
- }, 1); // Wait for first reset
343
+ // Only stamp the visible instances first
344
+ if (this._isVisible(itemWrapper, container)) {
345
+ this._ensureStampedInstance(itemWrapper);
346
+ }
320
347
  }
321
348
  });
322
349
 
323
- setTimeout(() => {
324
- afterNextRender(this, this._finishInit.bind(this));
325
- }, 1);
350
+ afterNextRender(this, () => {
351
+ this._finishInit();
352
+ });
326
353
  }
327
354
 
355
+ /** @private */
328
356
  _ensureStampedInstance(itemWrapper) {
329
357
  if (itemWrapper.firstElementChild) {
330
358
  return;
@@ -332,14 +360,15 @@ class InfiniteScroller extends PolymerElement {
332
360
 
333
361
  const tmpInstance = itemWrapper.instance;
334
362
 
335
- itemWrapper.instance = new this._TemplateClass({});
336
- itemWrapper.appendChild(itemWrapper.instance.root);
363
+ itemWrapper.instance = this._createElement();
364
+ itemWrapper.appendChild(itemWrapper.instance);
337
365
 
338
366
  Object.keys(tmpInstance).forEach((prop) => {
339
367
  itemWrapper.instance.set(prop, tmpInstance[prop]);
340
368
  });
341
369
  }
342
370
 
371
+ /** @private */
343
372
  _updateClones(viewPortOnly) {
344
373
  this._firstIndex = ~~((this._buffers[0].translateY - this._initialScroll) / this.itemHeight) + this._initialIndex;
345
374
 
@@ -348,10 +377,10 @@ class InfiniteScroller extends PolymerElement {
348
377
  if (!buffer.updated) {
349
378
  const firstIndex = this._firstIndex + this.bufferSize * bufferIndex;
350
379
 
351
- [].forEach.call(buffer.children, (insertionPoint, index) => {
352
- const itemWrapper = insertionPoint._itemWrapper;
380
+ [...buffer.children].forEach((slot, index) => {
381
+ const itemWrapper = slot._itemWrapper;
353
382
  if (!viewPortOnly || this._isVisible(itemWrapper, scrollerRect)) {
354
- itemWrapper.instance.index = firstIndex + index;
383
+ this._updateElement(itemWrapper.instance, firstIndex + index);
355
384
  }
356
385
  });
357
386
  buffer.updated = true;
@@ -359,10 +388,9 @@ class InfiniteScroller extends PolymerElement {
359
388
  });
360
389
  }
361
390
 
391
+ /** @private */
362
392
  _isVisible(element, container) {
363
393
  const rect = element.getBoundingClientRect();
364
394
  return rect.bottom > container.top && rect.top < container.bottom;
365
395
  }
366
396
  }
367
-
368
- customElements.define(InfiniteScroller.is, InfiniteScroller);
@@ -80,7 +80,9 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
80
80
  is="dom-repeat"
81
81
  items="[[_getWeekDayNames(i18n.weekdays, i18n.weekdaysShort, showWeekNumbers, i18n.firstDayOfWeek)]]"
82
82
  >
83
- <th role="columnheader" part="weekday" scope="col" abbr$="[[item.weekDay]]">[[item.weekDayShort]]</th>
83
+ <th role="columnheader" part="weekday" scope="col" abbr$="[[item.weekDay]]" aria-hidden="true">
84
+ [[item.weekDayShort]]
85
+ </th>
84
86
  </template>
85
87
  </tr>
86
88
  </thead>
@@ -426,12 +428,6 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
426
428
 
427
429
  return '-1';
428
430
  }
429
-
430
- __getWeekNumbers(dates) {
431
- return dates
432
- .map((date) => this.__getWeekNumber(date, dates))
433
- .filter((week, index, arr) => arr.indexOf(week) === index);
434
- }
435
431
  }
436
432
 
437
433
  customElements.define(MonthCalendar.is, MonthCalendar);