@vaadin/popover 25.3.0-dev.3a3c2d7d2a → 25.3.0-rc1

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.
@@ -62,6 +62,20 @@
62
62
  "description": "A mixin providing common popover overlay functionality.",
63
63
  "name": "PopoverOverlayMixin",
64
64
  "members": [
65
+ {
66
+ "kind": "field",
67
+ "name": "autofocus",
68
+ "privacy": "public",
69
+ "type": {
70
+ "text": "boolean"
71
+ },
72
+ "description": "Set to true to move focus into the overlay automatically on open.\n\nFocus moves to the first tabbable element in the tab order. This\ncan be the overlay itself if it has `tabindex` attribute set to `0`\non the host element or the `overlay` shadow DOM part.",
73
+ "attribute": "autofocus",
74
+ "inheritedFrom": {
75
+ "name": "OverlayFocusMixin",
76
+ "package": "@vaadin/overlay/src/vaadin-overlay-focus-mixin.js"
77
+ }
78
+ },
65
79
  {
66
80
  "kind": "method",
67
81
  "name": "bringToFront",
@@ -94,7 +108,7 @@
94
108
  "type": {
95
109
  "text": "boolean"
96
110
  },
97
- "description": "When true, opening the overlay moves focus to the first focusable child,\nor to the overlay part with tabindex if there are no focusable children.",
111
+ "description": "Set to true to move focus into the overlay automatically on open\nand keep it inside: Tab and Shift+Tab cycle through the overlay's\ncontent until the overlay is closed.\n\nFocus moves to the first tabbable element in the tab order. This\ncan be the overlay itself if it has `tabindex` attribute set to `0`\non the host element or the `overlay` shadow DOM part.",
98
112
  "attribute": "focus-trap",
99
113
  "inheritedFrom": {
100
114
  "name": "OverlayFocusMixin",
@@ -355,12 +369,24 @@
355
369
  }
356
370
  ],
357
371
  "attributes": [
372
+ {
373
+ "name": "autofocus",
374
+ "type": {
375
+ "text": "boolean"
376
+ },
377
+ "description": "Set to true to move focus into the overlay automatically on open.\n\nFocus moves to the first tabbable element in the tab order. This\ncan be the overlay itself if it has `tabindex` attribute set to `0`\non the host element or the `overlay` shadow DOM part.",
378
+ "fieldName": "autofocus",
379
+ "inheritedFrom": {
380
+ "name": "OverlayFocusMixin",
381
+ "package": "@vaadin/overlay/src/vaadin-overlay-focus-mixin.js"
382
+ }
383
+ },
358
384
  {
359
385
  "name": "focus-trap",
360
386
  "type": {
361
387
  "text": "boolean"
362
388
  },
363
- "description": "When true, opening the overlay moves focus to the first focusable child,\nor to the overlay part with tabindex if there are no focusable children.",
389
+ "description": "Set to true to move focus into the overlay automatically on open\nand keep it inside: Tab and Shift+Tab cycle through the overlay's\ncontent until the overlay is closed.\n\nFocus moves to the first tabbable element in the tab order. This\ncan be the overlay itself if it has `tabindex` attribute set to `0`\non the host element or the `overlay` shadow DOM part.",
364
390
  "fieldName": "focusTrap",
365
391
  "inheritedFrom": {
366
392
  "name": "OverlayFocusMixin",
@@ -1127,6 +1153,13 @@
1127
1153
  "description": "The `role` attribute value to be set on the popover.\nWhen not specified, defaults to 'dialog'.",
1128
1154
  "fieldName": "role"
1129
1155
  },
1156
+ {
1157
+ "type": {
1158
+ "text": "string"
1159
+ },
1160
+ "description": "The theme variants to apply to the component.",
1161
+ "name": "theme"
1162
+ },
1130
1163
  {
1131
1164
  "name": "trigger",
1132
1165
  "type": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/popover",
3
- "version": "25.3.0-dev.3a3c2d7d2a",
3
+ "version": "25.3.0-rc1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -37,19 +37,19 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "@open-wc/dedupe-mixin": "^1.3.0",
40
- "@vaadin/a11y-base": "25.3.0-dev.3a3c2d7d2a",
41
- "@vaadin/component-base": "25.3.0-dev.3a3c2d7d2a",
42
- "@vaadin/lit-renderer": "25.3.0-dev.3a3c2d7d2a",
43
- "@vaadin/overlay": "25.3.0-dev.3a3c2d7d2a",
44
- "@vaadin/vaadin-themable-mixin": "25.3.0-dev.3a3c2d7d2a",
40
+ "@vaadin/a11y-base": "25.3.0-rc1",
41
+ "@vaadin/component-base": "25.3.0-rc1",
42
+ "@vaadin/lit-renderer": "25.3.0-rc1",
43
+ "@vaadin/overlay": "25.3.0-rc1",
44
+ "@vaadin/vaadin-themable-mixin": "25.3.0-rc1",
45
45
  "lit": "^3.0.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@vaadin/aura": "25.3.0-dev.3a3c2d7d2a",
49
- "@vaadin/chai-plugins": "25.3.0-dev.3a3c2d7d2a",
50
- "@vaadin/test-runner-commands": "25.3.0-dev.3a3c2d7d2a",
48
+ "@vaadin/aura": "25.3.0-rc1",
49
+ "@vaadin/chai-plugins": "25.3.0-rc1",
50
+ "@vaadin/test-runner-commands": "25.3.0-rc1",
51
51
  "@vaadin/testing-helpers": "^2.0.0",
52
- "@vaadin/vaadin-lumo-styles": "25.3.0-dev.3a3c2d7d2a",
52
+ "@vaadin/vaadin-lumo-styles": "25.3.0-rc1",
53
53
  "sinon": "^22.0.0"
54
54
  },
55
55
  "customElements": "custom-elements.json",
@@ -57,5 +57,5 @@
57
57
  "web-types.json",
58
58
  "web-types.lit.json"
59
59
  ],
60
- "gitHead": "ac506ca7800c23e05da55863c56bcedf12812d37"
60
+ "gitHead": "d4809590b2f61bd607e376ab3dec84f4bfb059a7"
61
61
  }
@@ -4,7 +4,7 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { getActiveTrappingNode } from '@vaadin/a11y-base/src/focus-trap-controller.js';
7
- import { getDeepActiveElement, getFocusableElements, isElementFocused } from '@vaadin/a11y-base/src/focus-utils.js';
7
+ import { getDeepActiveElement, getTabbableElements, isElementFocused } from '@vaadin/a11y-base/src/focus-utils.js';
8
8
 
9
9
  /**
10
10
  * Controller that routes Tab and Shift+Tab when a non-modal popover is opened.
@@ -56,6 +56,18 @@ export class PopoverFocusController {
56
56
  return;
57
57
  }
58
58
 
59
+ // Focus is on the popover itself: move into the content explicitly, so that
60
+ // the tab order does not depend on the browser's sequential focus navigation
61
+ // starting point (Firefox continues from the last clicked node).
62
+ if (!host.noTabFocus && isElementFocused(host)) {
63
+ const firstContent = getTabbableElements(host._overlayElement.$.content)[0];
64
+ if (firstContent) {
65
+ event.preventDefault();
66
+ firstContent.focus();
67
+ return;
68
+ }
69
+ }
70
+
59
71
  // Native Tab would land on the popover when DOM order places it right
60
72
  // after the current element. Skip past it via the logical list.
61
73
  const activeElement = getDeepActiveElement();
@@ -136,6 +148,11 @@ export class PopoverFocusController {
136
148
  if (event.key !== 'Tab') {
137
149
  return;
138
150
  }
151
+ // Another controller (e.g. the one of a parent popover) has already moved
152
+ // focus for this event, so this one must not move it a second time.
153
+ if (event.defaultPrevented) {
154
+ return;
155
+ }
139
156
  if (event.shiftKey) {
140
157
  this.__handleShiftTab(event);
141
158
  } else {
@@ -158,7 +175,7 @@ export class PopoverFocusController {
158
175
  * @private
159
176
  */
160
177
  __getLastPopoverFocusable() {
161
- const lastContent = getFocusableElements(this.host._overlayElement.$.content).pop();
178
+ const lastContent = getTabbableElements(this.host._overlayElement.$.content).pop();
162
179
  return lastContent || this.host;
163
180
  }
164
181
 
@@ -171,7 +188,7 @@ export class PopoverFocusController {
171
188
  __getScopeFocusables() {
172
189
  const host = this.host;
173
190
  const scope = getActiveTrappingNode(host) || document.body;
174
- return getFocusableElements(scope).filter((el) => el === host || !host.contains(el));
191
+ return getTabbableElements(scope).filter((el) => el === host || !host.contains(el));
175
192
  }
176
193
 
177
194
  /**
@@ -16,6 +16,7 @@ import { PopoverOverlayMixin } from './vaadin-popover-overlay-mixin.js';
16
16
  /**
17
17
  * An element used internally by `<vaadin-popover>`. Not intended to be used separately.
18
18
  *
19
+ * @attr {string} theme - The theme variants to apply to the component.
19
20
  * @customElement vaadin-popover-overlay
20
21
  * @extends HTMLElement
21
22
  * @private
@@ -78,11 +79,11 @@ class PopoverOverlay extends PopoverOverlayMixin(
78
79
  }
79
80
 
80
81
  /**
81
- * Override method from OverlayFocusMixin to use owner as focus trap root
82
+ * Override method from OverlayFocusMixin to use owner as focus root
82
83
  * @protected
83
84
  * @override
84
85
  */
85
- get _focusTrapRoot() {
86
+ get _focusRoot() {
86
87
  return this.owner;
87
88
  }
88
89
 
@@ -8,12 +8,14 @@ import { css, html, LitElement } from 'lit';
8
8
  import { ifDefined } from 'lit/directives/if-defined.js';
9
9
  import { isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
10
10
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
11
+ import { setOrRemoveAttribute } from '@vaadin/component-base/src/dom-utils.js';
11
12
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
12
13
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
13
14
  import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
14
15
  import {
15
- hasOnlyNestedOverlays,
16
+ getOverlaysOnTop,
16
17
  isLastOverlay as isLastOverlayBase,
18
+ isNestedOverlay,
17
19
  } from '@vaadin/overlay/src/vaadin-overlay-stack-mixin.js';
18
20
  import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
19
21
  import { PopoverFocusController } from './vaadin-popover-focus-controller.js';
@@ -158,6 +160,14 @@ const isLastOverlay = (overlay) => {
158
160
  return isLastOverlayBase(overlay, filter);
159
161
  };
160
162
 
163
+ /**
164
+ * Returns true if all the overlays shown on top of the given overlay are nested inside it.
165
+ * @param {HTMLElement} overlay
166
+ * @return {boolean}
167
+ * @protected
168
+ */
169
+ const hasOnlyNestedOverlays = (overlay) => getOverlaysOnTop(overlay).every((el) => isNestedOverlay(overlay, el));
170
+
161
171
  /**
162
172
  * `<vaadin-popover>` is a Web Component for creating overlays
163
173
  * that are positioned next to specified DOM element (target).
@@ -207,6 +217,7 @@ const isLastOverlay = (overlay) => {
207
217
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
208
218
  * @fires {CustomEvent} closed - Fired when the popover is closed.
209
219
  *
220
+ * @attr {string} theme - The theme variants to apply to the component.
210
221
  * @customElement vaadin-popover
211
222
  * @extends HTMLElement
212
223
  */
@@ -598,27 +609,15 @@ class Popover extends PopoverPositionMixin(
598
609
  }
599
610
 
600
611
  if (props.has('accessibleName')) {
601
- if (this.accessibleName) {
602
- this.setAttribute('aria-label', this.accessibleName);
603
- } else {
604
- this.removeAttribute('aria-label');
605
- }
612
+ setOrRemoveAttribute(this, 'aria-label', this.accessibleName);
606
613
  }
607
614
 
608
615
  if (props.has('accessibleNameRef')) {
609
- if (this.accessibleNameRef) {
610
- this.setAttribute('aria-labelledby', this.accessibleNameRef);
611
- } else {
612
- this.removeAttribute('aria-labelledby');
613
- }
616
+ setOrRemoveAttribute(this, 'aria-labelledby', this.accessibleNameRef);
614
617
  }
615
618
 
616
619
  if (props.has('modal')) {
617
- if (this.modal) {
618
- this.setAttribute('aria-modal', 'true');
619
- } else {
620
- this.removeAttribute('aria-modal');
621
- }
620
+ setOrRemoveAttribute(this, 'aria-modal', this.modal);
622
621
  }
623
622
  }
624
623
 
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/popover",
4
- "version": "25.3.0-dev.3a3c2d7d2a",
4
+ "version": "25.3.0-rc1",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
@@ -159,9 +159,7 @@
159
159
  "description": "The theme variants to apply to the component.",
160
160
  "value": {
161
161
  "type": [
162
- "string",
163
- "null",
164
- "undefined"
162
+ "string"
165
163
  ]
166
164
  }
167
165
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/popover",
4
- "version": "25.3.0-dev.3a3c2d7d2a",
4
+ "version": "25.3.0-rc1",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {