@vaadin/field-highlighter 23.0.10 → 23.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/field-highlighter",
3
- "version": "23.0.10",
3
+ "version": "23.0.13",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -34,27 +34,27 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@polymer/polymer": "^3.0.0",
37
- "@vaadin/component-base": "^23.0.10",
38
- "@vaadin/vaadin-lumo-styles": "^23.0.10",
39
- "@vaadin/vaadin-material-styles": "^23.0.10",
40
- "@vaadin/vaadin-overlay": "^23.0.10",
41
- "@vaadin/vaadin-themable-mixin": "^23.0.10",
37
+ "@vaadin/component-base": "^23.0.13",
38
+ "@vaadin/vaadin-lumo-styles": "^23.0.13",
39
+ "@vaadin/vaadin-material-styles": "^23.0.13",
40
+ "@vaadin/vaadin-overlay": "^23.0.13",
41
+ "@vaadin/vaadin-themable-mixin": "^23.0.13",
42
42
  "lit": "^2.0.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@esm-bundle/chai": "^4.3.4",
46
- "@vaadin/checkbox": "^23.0.10",
47
- "@vaadin/combo-box": "^23.0.10",
48
- "@vaadin/date-picker": "^23.0.10",
49
- "@vaadin/date-time-picker": "^23.0.10",
50
- "@vaadin/item": "^23.0.10",
51
- "@vaadin/list-box": "^23.0.10",
52
- "@vaadin/radio-group": "^23.0.10",
53
- "@vaadin/select": "^23.0.10",
46
+ "@vaadin/checkbox": "^23.0.13",
47
+ "@vaadin/combo-box": "^23.0.13",
48
+ "@vaadin/date-picker": "^23.0.13",
49
+ "@vaadin/date-time-picker": "^23.0.13",
50
+ "@vaadin/item": "^23.0.13",
51
+ "@vaadin/list-box": "^23.0.13",
52
+ "@vaadin/radio-group": "^23.0.13",
53
+ "@vaadin/select": "^23.0.13",
54
54
  "@vaadin/testing-helpers": "^0.3.2",
55
- "@vaadin/text-field": "^23.0.10",
56
- "@vaadin/time-picker": "^23.0.10",
55
+ "@vaadin/text-field": "^23.0.13",
56
+ "@vaadin/time-picker": "^23.0.13",
57
57
  "sinon": "^9.2.1"
58
58
  },
59
- "gitHead": "e8402a55ce0e823ae6da5c97486998cfd931b1d3"
59
+ "gitHead": "e915550ec6400b5eae6c779fe0afeb1931399312"
60
60
  }
@@ -10,9 +10,6 @@ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
10
10
  import { timeOut } from '@vaadin/component-base/src/async.js';
11
11
  import { Debouncer } from '@vaadin/component-base/src/debounce.js';
12
12
 
13
- const DURATION = 200;
14
- const DELAY = 2000;
15
-
16
13
  const listenOnce = (elem, type) => {
17
14
  return new Promise((resolve) => {
18
15
  const listener = () => {
@@ -96,20 +93,60 @@ export class UserTags extends PolymerElement {
96
93
  value: () => [],
97
94
  },
98
95
 
96
+ duration: {
97
+ type: Number,
98
+ value: 200,
99
+ },
100
+
101
+ delay: {
102
+ type: Number,
103
+ value: 2000,
104
+ },
105
+
99
106
  /** @private */
100
- _flashQueue: {
107
+ __flashQueue: {
101
108
  type: Array,
102
109
  value: () => [],
103
110
  },
111
+
112
+ /** @private */
113
+ __isTargetVisible: {
114
+ type: Boolean,
115
+ value: false,
116
+ },
104
117
  };
105
118
  }
106
119
 
120
+ constructor() {
121
+ super();
122
+
123
+ this.__targetVisibilityObserver = new IntersectionObserver(
124
+ ([entry]) => {
125
+ this.__onTargetVisibilityChange(entry.isIntersecting);
126
+ },
127
+ { threshold: 1 },
128
+ );
129
+ }
130
+
131
+ /** @protected */
132
+ connectedCallback() {
133
+ super.connectedCallback();
134
+
135
+ if (this.target) {
136
+ this.__targetVisibilityObserver.observe(this.target);
137
+ }
138
+ }
139
+
107
140
  /** @protected */
108
141
  disconnectedCallback() {
109
142
  super.disconnectedCallback();
110
143
  this.opened = false;
144
+ if (this.target) {
145
+ this.__targetVisibilityObserver.unobserve(this.target);
146
+ }
111
147
  }
112
148
 
149
+ /** @protected */
113
150
  ready() {
114
151
  super.ready();
115
152
 
@@ -125,8 +162,43 @@ export class UserTags extends PolymerElement {
125
162
  }
126
163
 
127
164
  /** @private */
128
- __targetChanged(target) {
129
- this.$.overlay.positionTarget = target;
165
+ __onTargetVisibilityChange(isVisible) {
166
+ this.__isTargetVisible = isVisible;
167
+
168
+ // Open the overlay and run the flashing animation for the user tags
169
+ // that have been enqueued (if any) during a `.setUsers()` call
170
+ // because the field was not visible at that point.
171
+ if (isVisible && this.__flashQueue.length > 0 && !this.flashing) {
172
+ this.flashTags(this.__flashQueue.shift());
173
+ return;
174
+ }
175
+
176
+ // Open the overlay when the field is visible and focused.
177
+ // - opens the overlay in the case it was not opened during a `.show()` call because the field was not visible at that point.
178
+ // - re-opens the overlay in the case it was closed because the focused field became not visible for a while (see the below check).
179
+ if (isVisible && this.hasFocus) {
180
+ this.opened = true;
181
+ return;
182
+ }
183
+
184
+ // Close the overlay when the field is not visible.
185
+ // The focused field will be re-opened once it becomes visible again (see the above check).
186
+ if (!isVisible && this.opened) {
187
+ this.opened = false;
188
+ }
189
+ }
190
+
191
+ /** @private */
192
+ __targetChanged(newTarget, oldTarget) {
193
+ this.$.overlay.positionTarget = newTarget;
194
+
195
+ if (oldTarget) {
196
+ this.__targetVisibilityObserver.unobserve(oldTarget);
197
+ }
198
+
199
+ if (newTarget) {
200
+ this.__targetVisibilityObserver.observe(newTarget);
201
+ }
130
202
  }
131
203
 
132
204
  /** @private */
@@ -216,13 +288,13 @@ export class UserTags extends PolymerElement {
216
288
 
217
289
  const changedTags = this.getChangedTags(addedUsers, removedUsers);
218
290
 
219
- // check if flash queue contains pending tags for removed users
220
- if (this._flashQueue.length > 0) {
291
+ // Check if flash queue contains pending tags for removed users
292
+ if (this.__flashQueue.length > 0) {
221
293
  for (let i = 0; i < removedUsers.length; i++) {
222
294
  if (changedTags.removed[i] === null) {
223
- for (let j = 0; j < this._flashQueue.length; j++) {
224
- if (this._flashQueue[j].some((tag) => tag.uid === removedUsers[i].id)) {
225
- this.splice('_flashQueue', i, 1);
295
+ for (let j = 0; j < this.__flashQueue.length; j++) {
296
+ if (this.__flashQueue[j].some((tag) => tag.uid === removedUsers[i].id)) {
297
+ this.splice('__flashQueue', i, 1);
226
298
  }
227
299
  }
228
300
  }
@@ -231,16 +303,25 @@ export class UserTags extends PolymerElement {
231
303
 
232
304
  if (this.opened && this.hasFocus) {
233
305
  this.updateTags(users, changedTags);
234
- } else if (addedUsers.length && document.visibilityState !== 'hidden') {
306
+ } else if (addedUsers.length > 0 && document.visibilityState !== 'hidden') {
235
307
  // Avoid adding to queue if window is not visible.
236
- const tags = changedTags.added;
237
- if (this.flashing) {
238
- // schedule next flash later
239
- this.push('_flashQueue', tags);
308
+
309
+ const addedTags = changedTags.added;
310
+ const removedTags = changedTags.removed;
311
+
312
+ // Only sync the removed user tags.
313
+ // The added tags are handled by the `flashTags` method.
314
+ this.updateTagsSync(users, {
315
+ added: [],
316
+ removed: removedTags,
317
+ });
318
+
319
+ if (this.flashing || !this.__isTargetVisible) {
320
+ // Schedule next flash later
321
+ this.push('__flashQueue', addedTags);
240
322
  } else {
241
- this.flashTags(tags);
323
+ this.flashTags(addedTags);
242
324
  }
243
- this.set('users', users);
244
325
  } else {
245
326
  this.updateTagsSync(users, changedTags);
246
327
  }
@@ -271,36 +352,40 @@ export class UserTags extends PolymerElement {
271
352
 
272
353
  this.flashPromise = new Promise((resolve) => {
273
354
  listenOnce(this.$.overlay, 'vaadin-overlay-open').then(() => {
274
- this._debounceFlashStart = Debouncer.debounce(this._debounceFlashStart, timeOut.after(DURATION + DELAY), () => {
275
- // animate disappearing
276
- if (!this.hasFocus) {
277
- added.forEach((tag) => tag.classList.remove('show'));
278
- }
279
- this._debounceFlashEnd = Debouncer.debounce(this._debounceFlashEnd, timeOut.after(DURATION), () => {
280
- // show all tags
281
- const finishFlash = () => {
282
- hidden.forEach((tag) => (tag.style.display = 'block'));
283
- this.flashing = false;
284
- resolve();
285
- };
286
-
287
- if (this.hasFocus) {
288
- finishFlash();
289
- } else {
290
- // wait for overlay closing animation to complete
291
- listenOnce(this.$.overlay, 'animationend').then(() => {
292
- finishFlash();
293
- });
294
-
295
- this.opened = false;
355
+ this._debounceFlashStart = Debouncer.debounce(
356
+ this._debounceFlashStart,
357
+ timeOut.after(this.duration + this.delay),
358
+ () => {
359
+ // Animate disappearing
360
+ if (!this.hasFocus) {
361
+ added.forEach((tag) => tag.classList.remove('show'));
296
362
  }
297
- });
298
- });
363
+ this._debounceFlashEnd = Debouncer.debounce(this._debounceFlashEnd, timeOut.after(this.duration), () => {
364
+ // Show all tags
365
+ const finishFlash = () => {
366
+ hidden.forEach((tag) => (tag.style.display = 'block'));
367
+ this.flashing = false;
368
+ resolve();
369
+ };
370
+
371
+ if (this.hasFocus) {
372
+ finishFlash();
373
+ } else {
374
+ // Wait for overlay closing animation to complete
375
+ listenOnce(this.$.overlay, 'animationend').then(() => {
376
+ finishFlash();
377
+ });
378
+
379
+ this.opened = false;
380
+ }
381
+ });
382
+ },
383
+ );
299
384
  });
300
385
  }).then(() => {
301
- if (this._flashQueue.length > 0) {
302
- const tags = this._flashQueue[0];
303
- this.splice('_flashQueue', 0, 1);
386
+ if (this.__flashQueue.length > 0) {
387
+ const tags = this.__flashQueue[0];
388
+ this.splice('__flashQueue', 0, 1);
304
389
  this.flashTags(tags);
305
390
  }
306
391
  });
@@ -317,7 +402,7 @@ export class UserTags extends PolymerElement {
317
402
  updateTags(users, changed) {
318
403
  this.applyTagsStart(changed);
319
404
 
320
- this._debounceRender = Debouncer.debounce(this._debounceRender, timeOut.after(DURATION), () => {
405
+ this._debounceRender = Debouncer.debounce(this._debounceRender, timeOut.after(this.duration), () => {
321
406
  this.set('users', users);
322
407
 
323
408
  this.applyTagsEnd(changed);
@@ -336,7 +421,9 @@ export class UserTags extends PolymerElement {
336
421
 
337
422
  show() {
338
423
  this.hasFocus = true;
339
- this.opened = true;
424
+ if (this.__isTargetVisible) {
425
+ this.opened = true;
426
+ }
340
427
  }
341
428
 
342
429
  hide() {
@@ -3,5 +3,6 @@
3
3
  * Copyright (c) 2021 - 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 '@vaadin/vaadin-overlay/theme/lumo/vaadin-overlay.js';
6
7
  import './vaadin-user-tags-styles.js';
7
8
  import '../../src/vaadin-user-tags.js';
@@ -3,5 +3,6 @@
3
3
  * Copyright (c) 2021 - 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 '@vaadin/vaadin-overlay/theme/material/vaadin-overlay.js';
6
7
  import './vaadin-user-tags-styles.js';
7
8
  import '../../src/vaadin-user-tags.js';