@spectrum-web-components/overlay 1.4.0-beta.0 → 1.4.0
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/README.md +9 -13
- package/custom-elements.json +0 -28
- package/package.json +6 -6
- package/src/AbstractOverlay.d.ts +0 -3
- package/src/AbstractOverlay.dev.js +0 -25
- package/src/AbstractOverlay.dev.js.map +2 -2
- package/src/AbstractOverlay.js +1 -1
- package/src/AbstractOverlay.js.map +2 -2
- package/src/Overlay.dev.js +3 -1
- package/src/Overlay.dev.js.map +2 -2
- package/src/Overlay.js +7 -7
- package/src/Overlay.js.map +3 -3
- package/src/OverlayDialog.dev.js +0 -2
- package/src/OverlayDialog.dev.js.map +2 -2
- package/src/OverlayDialog.js +1 -1
- package/src/OverlayDialog.js.map +2 -2
- package/src/overlay-trigger.css.dev.js +1 -1
- package/src/overlay-trigger.css.dev.js.map +1 -1
- package/src/overlay-trigger.css.js +3 -3
- package/src/overlay-trigger.css.js.map +1 -1
package/README.md
CHANGED
|
@@ -250,21 +250,17 @@ This overlay type does not accept focus and does not interfere with the user's i
|
|
|
250
250
|
|
|
251
251
|
### Auto
|
|
252
252
|
|
|
253
|
-
`'auto'` Overlays provide a place for content that is ephemeral _and_ interactive. These Overlays can accept focus
|
|
253
|
+
`'auto'` Overlays provide a place for content that is ephemeral _and_ interactive. These Overlays can accept focus and remain open while interacting with their content. They will close when focus moves outside the overlay or when clicking elsewhere on the page.
|
|
254
254
|
|
|
255
255
|
```html
|
|
256
|
-
<
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
</
|
|
263
|
-
|
|
264
|
-
<sp-overlay trigger="trigger@click" type="auto">
|
|
265
|
-
<sp-toast variant="info">
|
|
266
|
-
This is information that you should read.
|
|
267
|
-
</sp-toast>
|
|
256
|
+
<sp-button id="trigger">Open Overlay</sp-button>
|
|
257
|
+
<sp-overlay trigger="trigger@click" type="auto" placement="bottom">
|
|
258
|
+
<sp-popover dialog>
|
|
259
|
+
<p>
|
|
260
|
+
My slider in overlay element:
|
|
261
|
+
<sp-slider label="Slider Label - Editable" editable></sp-slider>
|
|
262
|
+
</p>
|
|
263
|
+
</sp-popover>
|
|
268
264
|
</sp-overlay>
|
|
269
265
|
```
|
|
270
266
|
|
package/custom-elements.json
CHANGED
|
@@ -524,34 +524,6 @@
|
|
|
524
524
|
}
|
|
525
525
|
}
|
|
526
526
|
]
|
|
527
|
-
},
|
|
528
|
-
{
|
|
529
|
-
"kind": "field",
|
|
530
|
-
"name": "iosEventPropagationController",
|
|
531
|
-
"type": {
|
|
532
|
-
"text": "AbortController | undefined"
|
|
533
|
-
},
|
|
534
|
-
"privacy": "private"
|
|
535
|
-
},
|
|
536
|
-
{
|
|
537
|
-
"kind": "method",
|
|
538
|
-
"name": "setupIOSEventManagement",
|
|
539
|
-
"privacy": "protected",
|
|
540
|
-
"return": {
|
|
541
|
-
"type": {
|
|
542
|
-
"text": "void"
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
},
|
|
546
|
-
{
|
|
547
|
-
"kind": "method",
|
|
548
|
-
"name": "cleanupIOSEventManagement",
|
|
549
|
-
"privacy": "protected",
|
|
550
|
-
"return": {
|
|
551
|
-
"type": {
|
|
552
|
-
"text": "void"
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
527
|
}
|
|
556
528
|
],
|
|
557
529
|
"superclass": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spectrum-web-components/overlay",
|
|
3
|
-
"version": "1.4.0
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -160,11 +160,11 @@
|
|
|
160
160
|
"dependencies": {
|
|
161
161
|
"@floating-ui/dom": "^1.6.1",
|
|
162
162
|
"@floating-ui/utils": "^0.2.1",
|
|
163
|
-
"@spectrum-web-components/action-button": "1.4.0
|
|
164
|
-
"@spectrum-web-components/base": "1.4.0
|
|
165
|
-
"@spectrum-web-components/reactive-controllers": "1.4.0
|
|
166
|
-
"@spectrum-web-components/shared": "1.4.0
|
|
167
|
-
"@spectrum-web-components/theme": "1.4.0
|
|
163
|
+
"@spectrum-web-components/action-button": "1.4.0",
|
|
164
|
+
"@spectrum-web-components/base": "1.4.0",
|
|
165
|
+
"@spectrum-web-components/reactive-controllers": "1.4.0",
|
|
166
|
+
"@spectrum-web-components/shared": "1.4.0",
|
|
167
|
+
"@spectrum-web-components/theme": "1.4.0"
|
|
168
168
|
},
|
|
169
169
|
"types": "./src/index.d.ts",
|
|
170
170
|
"customElements": "custom-elements.json",
|
package/src/AbstractOverlay.d.ts
CHANGED
|
@@ -69,8 +69,5 @@ export declare class AbstractOverlay extends SpectrumElement {
|
|
|
69
69
|
static open(trigger: HTMLElement, interaction: TriggerInteractionsV1, content: HTMLElement, optionsV1: OverlayOptionsV1): Promise<() => void>;
|
|
70
70
|
static open(content: HTMLElement, options?: OverlayOptions): Promise<Overlay>;
|
|
71
71
|
static applyOptions(overlay: AbstractOverlay, options: OverlayOptions): void;
|
|
72
|
-
private iosEventPropagationController?;
|
|
73
|
-
protected setupIOSEventManagement(): void;
|
|
74
|
-
protected cleanupIOSEventManagement(): void;
|
|
75
72
|
disconnectedCallback(): void;
|
|
76
73
|
}
|
|
@@ -230,32 +230,7 @@ export class AbstractOverlay extends SpectrumElement {
|
|
|
230
230
|
overlay.placement = options.placement;
|
|
231
231
|
overlay.willPreventClose = !!options.notImmediatelyClosable;
|
|
232
232
|
}
|
|
233
|
-
setupIOSEventManagement() {
|
|
234
|
-
this.iosEventPropagationController = new AbortController();
|
|
235
|
-
this.dialogEl.addEventListener(
|
|
236
|
-
"pointerup",
|
|
237
|
-
(event) => event.stopPropagation(),
|
|
238
|
-
{
|
|
239
|
-
capture: true,
|
|
240
|
-
signal: this.iosEventPropagationController.signal
|
|
241
|
-
}
|
|
242
|
-
);
|
|
243
|
-
this.dialogEl.addEventListener(
|
|
244
|
-
"touchend",
|
|
245
|
-
(event) => event.stopPropagation(),
|
|
246
|
-
{
|
|
247
|
-
capture: true,
|
|
248
|
-
signal: this.iosEventPropagationController.signal
|
|
249
|
-
}
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
cleanupIOSEventManagement() {
|
|
253
|
-
var _a;
|
|
254
|
-
(_a = this.iosEventPropagationController) == null ? void 0 : _a.abort();
|
|
255
|
-
this.iosEventPropagationController = void 0;
|
|
256
|
-
}
|
|
257
233
|
disconnectedCallback() {
|
|
258
|
-
this.cleanupIOSEventManagement();
|
|
259
234
|
super.disconnectedCallback();
|
|
260
235
|
}
|
|
261
236
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["AbstractOverlay.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport { SpectrumElement } from '@spectrum-web-components/base';\nimport { reparentChildren } from '@spectrum-web-components/shared/src/reparent-children.js';\n\nimport type {\n OpenableElement,\n OverlayOptions,\n OverlayOptionsV1,\n OverlayState,\n OverlayTypes,\n Placement,\n TriggerInteractionsV1,\n} from './overlay-types.dev.js'\nimport type { Overlay } from './Overlay.dev.js'\nimport type { VirtualTrigger } from './VirtualTrigger.dev.js'\nimport { OverlayTimer } from './overlay-timer.dev.js'\nimport type { PlacementController } from './PlacementController.dev.js'\nimport type { ElementResolutionController } from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';\n\nexport const overlayTimer = new OverlayTimer();\n\nexport const noop = (): void => {\n return;\n};\n\n/**\n * Apply a \"transitionend\" listener to an element that may not transition but\n * guarantee the callback will be fired either way.\n *\n * @param el {HTMLElement} - Target of the \"transition\" listeners.\n * @param action {Function} - Method to trigger the \"transition\".\n * @param cb {Function} - Callback to trigger when the \"transition\" has ended.\n */\nexport const guaranteedAllTransitionend = (\n el: HTMLElement,\n action: () => void,\n cb: () => void\n): void => {\n const abortController = new AbortController();\n const runningTransitions = new Map<string, number>();\n const cleanup = (): void => {\n abortController.abort();\n cb();\n };\n let guarantee2: number;\n let guarantee3: number;\n // WebKit fires `transitionrun` a little earlier, the multiple guarantees here\n // allow WebKit to be caught, but doesn't remove the animation listener until\n // after it would have fired in Chromium.\n const guarantee1 = requestAnimationFrame(() => {\n guarantee2 = requestAnimationFrame(() => {\n guarantee3 = requestAnimationFrame(() => {\n cleanup();\n });\n });\n });\n const handleTransitionend = (event: TransitionEvent): void => {\n if (event.target !== el) {\n return;\n }\n runningTransitions.set(\n event.propertyName,\n (runningTransitions.get(event.propertyName) as number) - 1\n );\n if (!runningTransitions.get(event.propertyName)) {\n runningTransitions.delete(event.propertyName);\n }\n if (runningTransitions.size === 0) {\n cleanup();\n }\n };\n const handleTransitionrun = (event: TransitionEvent): void => {\n if (event.target !== el) {\n return;\n }\n if (!runningTransitions.has(event.propertyName)) {\n runningTransitions.set(event.propertyName, 0);\n }\n runningTransitions.set(\n event.propertyName,\n (runningTransitions.get(event.propertyName) as number) + 1\n );\n cancelAnimationFrame(guarantee1);\n cancelAnimationFrame(guarantee2);\n cancelAnimationFrame(guarantee3);\n };\n el.addEventListener('transitionrun', handleTransitionrun, {\n signal: abortController.signal,\n });\n el.addEventListener('transitionend', handleTransitionend, {\n signal: abortController.signal,\n });\n el.addEventListener('transitioncancel', handleTransitionend, {\n signal: abortController.signal,\n });\n action();\n};\n\nexport function nextFrame(): Promise<void> {\n return new Promise((res) => requestAnimationFrame(() => res()));\n}\n\n/**\n * Abstract Overlay base class so that property tyings and imperative API\n * interfaces can be held separate from the actual class definition.\n */\nexport class AbstractOverlay extends SpectrumElement {\n protected async applyFocus(\n _targetOpenState: boolean,\n _focusEl: HTMLElement | null\n ): Promise<void> {\n return;\n }\n /* c8 ignore next 6 */\n get delayed(): boolean {\n return false;\n }\n set delayed(_delayed: boolean) {\n return;\n }\n dialogEl!: HTMLDialogElement & {\n showPopover(): void;\n hidePopover(): void;\n };\n /* c8 ignore next 6 */\n get disabled(): boolean {\n return false;\n }\n set disabled(_disabled: boolean) {\n return;\n }\n dispose = noop;\n protected get elementResolver(): ElementResolutionController {\n return this._elementResolver;\n }\n protected set elementResolver(controller) {\n this._elementResolver = controller;\n }\n protected _elementResolver!: ElementResolutionController;\n /* c8 ignore next 3 */\n protected async ensureOnDOM(_targetOpenState: boolean): Promise<void> {\n return;\n }\n elements!: OpenableElement[];\n /* c8 ignore next 5 */\n protected async makeTransition(\n _targetOpenState: boolean\n ): Promise<HTMLElement | null> {\n return null;\n }\n protected async manageDelay(_targetOpenState: boolean): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected async manageDialogOpen(): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected async managePopoverOpen(): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected managePosition(): void {\n return;\n }\n protected offset: number | [number, number] = 0;\n /* c8 ignore next 6 */\n get open(): boolean {\n return false;\n }\n set open(_open: boolean) {\n return;\n }\n placement?: Placement;\n protected get placementController(): PlacementController {\n return this._placementController;\n }\n protected set placementController(controller) {\n this._placementController = controller;\n }\n protected _placementController!: PlacementController;\n receivesFocus!: 'true' | 'false' | 'auto';\n protected requestSlottable(): void {}\n protected returnFocus(): void {\n return;\n }\n /* c8 ignore next 6 */\n get state(): OverlayState {\n return 'closed';\n }\n set state(_state: OverlayState) {\n return;\n }\n protected _state!: OverlayState;\n triggerElement!: HTMLElement | VirtualTrigger | null;\n type!: OverlayTypes;\n willPreventClose = false;\n /* c8 ignore next 3 */\n public manuallyKeepOpen(): void {\n return;\n }\n\n public static update(): void {\n const overlayUpdateEvent = new CustomEvent('sp-update-overlays', {\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n document.dispatchEvent(overlayUpdateEvent);\n }\n\n /**\n * Overloaded imperative API entry point that allows for both the pre-0.37.0\n * argument signature as well as the post-0.37.0 signature. This allows for\n * consumers to continue to leverage it as they had been in previous releases\n * while also surfacing the more feature-rich API that has been made available.\n */\n public static async open(\n trigger: HTMLElement,\n interaction: TriggerInteractionsV1,\n content: HTMLElement,\n optionsV1: OverlayOptionsV1\n ): Promise<() => void>;\n public static async open(\n content: HTMLElement,\n options?: OverlayOptions\n ): Promise<Overlay>;\n public static async open(\n triggerOrContent: HTMLElement,\n interactionOrOptions:\n | TriggerInteractionsV1\n | OverlayOptions\n | undefined,\n content?: HTMLElement,\n optionsV1?: OverlayOptionsV1\n ): Promise<Overlay | (() => void)> {\n await import('@spectrum-web-components/overlay/sp-overlay.js');\n const v2 = arguments.length === 2;\n const overlayContent = content || triggerOrContent;\n // Use the `this` from the `static` method context rather than a\n // specific imported constructor to prevent opening a circular dependency.\n const overlay = new this() as Overlay;\n let restored = false;\n overlay.dispose = () => {\n overlay.addEventListener('sp-closed', () => {\n if (!restored) {\n restoreContent();\n restored = true;\n }\n requestAnimationFrame(() => {\n overlay.remove();\n });\n });\n overlay.open = false;\n overlay.dispose = noop;\n };\n /**\n * Since content must exist in an <sp-overlay>, we need a way to get it there.\n * The best & most-direct way is to declaratively use an <sp-overlay> element,\n * but for imperative users, we'll reparent content into an overlay that we've created for them.\n **/\n const restoreContent = reparentChildren([overlayContent], overlay, {\n position: 'beforeend',\n prepareCallback: (el) => {\n // Ensure that content to be overlaid is no longer targetted to a specific `slot`.\n // This allow for it to be visible in the overlaid context.\n const slot = el.slot;\n el.removeAttribute('slot');\n return () => {\n el.slot = slot;\n };\n },\n });\n\n const v1 = !v2 && overlayContent && optionsV1;\n if (v1) {\n if (window.__swc.DEBUG) {\n window.__swc.warn(\n overlay,\n `You are interacting with an ${overlay.localName} element via a deprecated imperative API. This API will be removed in a future version of the SWC library. Consider leveraging an ${overlay.localName} directly.`,\n 'https://opensource.adobe.com/spectrum-web-components/components/overlay/',\n { level: 'deprecation' }\n );\n }\n const trigger = triggerOrContent;\n const interaction = interactionOrOptions;\n const options = optionsV1;\n AbstractOverlay.applyOptions(overlay, {\n ...options,\n delayed:\n options.delayed || overlayContent.hasAttribute('delayed'),\n trigger: options.virtualTrigger || trigger,\n type:\n interaction === 'modal'\n ? 'modal'\n : interaction === 'hover'\n ? 'hint'\n : 'auto',\n });\n trigger.insertAdjacentElement('afterend', overlay);\n await overlay.updateComplete;\n overlay.open = true;\n return overlay.dispose;\n }\n\n const options = interactionOrOptions as OverlayOptions;\n overlay.append(overlayContent);\n AbstractOverlay.applyOptions(overlay, {\n ...options,\n delayed: options.delayed || overlayContent.hasAttribute('delayed'),\n });\n overlay.updateComplete.then(() => {\n // Do we want to \"open\" this path, or leave that to the consumer?\n overlay.open = true;\n });\n return overlay;\n }\n\n static applyOptions(\n overlay: AbstractOverlay,\n options: OverlayOptions\n ): void {\n overlay.delayed = !!options.delayed;\n overlay.receivesFocus = options.receivesFocus ?? 'auto';\n overlay.triggerElement = options.trigger || null;\n overlay.type = options.type || 'modal';\n overlay.offset = options.offset ?? 0;\n overlay.placement = options.placement;\n overlay.willPreventClose = !!options.notImmediatelyClosable;\n }\n\n private iosEventPropagationController?: AbortController;\n\n protected setupIOSEventManagement(): void {\n // This is a workaround for a bug in iOS <17 where the event leaks out of the dialog to the element below it.\n // Issue - https://github.com/adobe/spectrum-web-components/issues/5042\n this.iosEventPropagationController = new AbortController();\n this.dialogEl.addEventListener(\n 'pointerup',\n (event) => event.stopPropagation(),\n {\n capture: true,\n signal: this.iosEventPropagationController.signal,\n }\n );\n this.dialogEl.addEventListener(\n 'touchend',\n (event) => event.stopPropagation(),\n {\n capture: true,\n signal: this.iosEventPropagationController.signal,\n }\n );\n }\n\n protected cleanupIOSEventManagement(): void {\n this.iosEventPropagationController?.abort();\n this.iosEventPropagationController = undefined;\n }\n\n override disconnectedCallback(): void {\n this.cleanupIOSEventManagement();\n super.disconnectedCallback();\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport { SpectrumElement } from '@spectrum-web-components/base';\nimport { reparentChildren } from '@spectrum-web-components/shared/src/reparent-children.js';\n\nimport type {\n OpenableElement,\n OverlayOptions,\n OverlayOptionsV1,\n OverlayState,\n OverlayTypes,\n Placement,\n TriggerInteractionsV1,\n} from './overlay-types.dev.js'\nimport type { Overlay } from './Overlay.dev.js'\nimport type { VirtualTrigger } from './VirtualTrigger.dev.js'\nimport { OverlayTimer } from './overlay-timer.dev.js'\nimport type { PlacementController } from './PlacementController.dev.js'\nimport type { ElementResolutionController } from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';\n\nexport const overlayTimer = new OverlayTimer();\n\nexport const noop = (): void => {\n return;\n};\n\n/**\n * Apply a \"transitionend\" listener to an element that may not transition but\n * guarantee the callback will be fired either way.\n *\n * @param el {HTMLElement} - Target of the \"transition\" listeners.\n * @param action {Function} - Method to trigger the \"transition\".\n * @param cb {Function} - Callback to trigger when the \"transition\" has ended.\n */\nexport const guaranteedAllTransitionend = (\n el: HTMLElement,\n action: () => void,\n cb: () => void\n): void => {\n const abortController = new AbortController();\n const runningTransitions = new Map<string, number>();\n const cleanup = (): void => {\n abortController.abort();\n cb();\n };\n let guarantee2: number;\n let guarantee3: number;\n // WebKit fires `transitionrun` a little earlier, the multiple guarantees here\n // allow WebKit to be caught, but doesn't remove the animation listener until\n // after it would have fired in Chromium.\n const guarantee1 = requestAnimationFrame(() => {\n guarantee2 = requestAnimationFrame(() => {\n guarantee3 = requestAnimationFrame(() => {\n cleanup();\n });\n });\n });\n const handleTransitionend = (event: TransitionEvent): void => {\n if (event.target !== el) {\n return;\n }\n runningTransitions.set(\n event.propertyName,\n (runningTransitions.get(event.propertyName) as number) - 1\n );\n if (!runningTransitions.get(event.propertyName)) {\n runningTransitions.delete(event.propertyName);\n }\n if (runningTransitions.size === 0) {\n cleanup();\n }\n };\n const handleTransitionrun = (event: TransitionEvent): void => {\n if (event.target !== el) {\n return;\n }\n if (!runningTransitions.has(event.propertyName)) {\n runningTransitions.set(event.propertyName, 0);\n }\n runningTransitions.set(\n event.propertyName,\n (runningTransitions.get(event.propertyName) as number) + 1\n );\n cancelAnimationFrame(guarantee1);\n cancelAnimationFrame(guarantee2);\n cancelAnimationFrame(guarantee3);\n };\n el.addEventListener('transitionrun', handleTransitionrun, {\n signal: abortController.signal,\n });\n el.addEventListener('transitionend', handleTransitionend, {\n signal: abortController.signal,\n });\n el.addEventListener('transitioncancel', handleTransitionend, {\n signal: abortController.signal,\n });\n action();\n};\n\nexport function nextFrame(): Promise<void> {\n return new Promise((res) => requestAnimationFrame(() => res()));\n}\n\n/**\n * Abstract Overlay base class so that property tyings and imperative API\n * interfaces can be held separate from the actual class definition.\n */\nexport class AbstractOverlay extends SpectrumElement {\n protected async applyFocus(\n _targetOpenState: boolean,\n _focusEl: HTMLElement | null\n ): Promise<void> {\n return;\n }\n /* c8 ignore next 6 */\n get delayed(): boolean {\n return false;\n }\n set delayed(_delayed: boolean) {\n return;\n }\n dialogEl!: HTMLDialogElement & {\n showPopover(): void;\n hidePopover(): void;\n };\n /* c8 ignore next 6 */\n get disabled(): boolean {\n return false;\n }\n set disabled(_disabled: boolean) {\n return;\n }\n dispose = noop;\n protected get elementResolver(): ElementResolutionController {\n return this._elementResolver;\n }\n protected set elementResolver(controller) {\n this._elementResolver = controller;\n }\n protected _elementResolver!: ElementResolutionController;\n /* c8 ignore next 3 */\n protected async ensureOnDOM(_targetOpenState: boolean): Promise<void> {\n return;\n }\n elements!: OpenableElement[];\n /* c8 ignore next 5 */\n protected async makeTransition(\n _targetOpenState: boolean\n ): Promise<HTMLElement | null> {\n return null;\n }\n protected async manageDelay(_targetOpenState: boolean): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected async manageDialogOpen(): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected async managePopoverOpen(): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected managePosition(): void {\n return;\n }\n protected offset: number | [number, number] = 0;\n /* c8 ignore next 6 */\n get open(): boolean {\n return false;\n }\n set open(_open: boolean) {\n return;\n }\n placement?: Placement;\n protected get placementController(): PlacementController {\n return this._placementController;\n }\n protected set placementController(controller) {\n this._placementController = controller;\n }\n protected _placementController!: PlacementController;\n receivesFocus!: 'true' | 'false' | 'auto';\n protected requestSlottable(): void {}\n protected returnFocus(): void {\n return;\n }\n /* c8 ignore next 6 */\n get state(): OverlayState {\n return 'closed';\n }\n set state(_state: OverlayState) {\n return;\n }\n protected _state!: OverlayState;\n triggerElement!: HTMLElement | VirtualTrigger | null;\n type!: OverlayTypes;\n willPreventClose = false;\n /* c8 ignore next 3 */\n public manuallyKeepOpen(): void {\n return;\n }\n\n public static update(): void {\n const overlayUpdateEvent = new CustomEvent('sp-update-overlays', {\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n document.dispatchEvent(overlayUpdateEvent);\n }\n\n /**\n * Overloaded imperative API entry point that allows for both the pre-0.37.0\n * argument signature as well as the post-0.37.0 signature. This allows for\n * consumers to continue to leverage it as they had been in previous releases\n * while also surfacing the more feature-rich API that has been made available.\n */\n public static async open(\n trigger: HTMLElement,\n interaction: TriggerInteractionsV1,\n content: HTMLElement,\n optionsV1: OverlayOptionsV1\n ): Promise<() => void>;\n public static async open(\n content: HTMLElement,\n options?: OverlayOptions\n ): Promise<Overlay>;\n public static async open(\n triggerOrContent: HTMLElement,\n interactionOrOptions:\n | TriggerInteractionsV1\n | OverlayOptions\n | undefined,\n content?: HTMLElement,\n optionsV1?: OverlayOptionsV1\n ): Promise<Overlay | (() => void)> {\n await import('@spectrum-web-components/overlay/sp-overlay.js');\n const v2 = arguments.length === 2;\n const overlayContent = content || triggerOrContent;\n // Use the `this` from the `static` method context rather than a\n // specific imported constructor to prevent opening a circular dependency.\n const overlay = new this() as Overlay;\n let restored = false;\n overlay.dispose = () => {\n overlay.addEventListener('sp-closed', () => {\n if (!restored) {\n restoreContent();\n restored = true;\n }\n requestAnimationFrame(() => {\n overlay.remove();\n });\n });\n overlay.open = false;\n overlay.dispose = noop;\n };\n /**\n * Since content must exist in an <sp-overlay>, we need a way to get it there.\n * The best & most-direct way is to declaratively use an <sp-overlay> element,\n * but for imperative users, we'll reparent content into an overlay that we've created for them.\n **/\n const restoreContent = reparentChildren([overlayContent], overlay, {\n position: 'beforeend',\n prepareCallback: (el) => {\n // Ensure that content to be overlaid is no longer targetted to a specific `slot`.\n // This allow for it to be visible in the overlaid context.\n const slot = el.slot;\n el.removeAttribute('slot');\n return () => {\n el.slot = slot;\n };\n },\n });\n\n const v1 = !v2 && overlayContent && optionsV1;\n if (v1) {\n if (window.__swc.DEBUG) {\n window.__swc.warn(\n overlay,\n `You are interacting with an ${overlay.localName} element via a deprecated imperative API. This API will be removed in a future version of the SWC library. Consider leveraging an ${overlay.localName} directly.`,\n 'https://opensource.adobe.com/spectrum-web-components/components/overlay/',\n { level: 'deprecation' }\n );\n }\n const trigger = triggerOrContent;\n const interaction = interactionOrOptions;\n const options = optionsV1;\n AbstractOverlay.applyOptions(overlay, {\n ...options,\n delayed:\n options.delayed || overlayContent.hasAttribute('delayed'),\n trigger: options.virtualTrigger || trigger,\n type:\n interaction === 'modal'\n ? 'modal'\n : interaction === 'hover'\n ? 'hint'\n : 'auto',\n });\n trigger.insertAdjacentElement('afterend', overlay);\n await overlay.updateComplete;\n overlay.open = true;\n return overlay.dispose;\n }\n\n const options = interactionOrOptions as OverlayOptions;\n overlay.append(overlayContent);\n AbstractOverlay.applyOptions(overlay, {\n ...options,\n delayed: options.delayed || overlayContent.hasAttribute('delayed'),\n });\n overlay.updateComplete.then(() => {\n // Do we want to \"open\" this path, or leave that to the consumer?\n overlay.open = true;\n });\n return overlay;\n }\n\n static applyOptions(\n overlay: AbstractOverlay,\n options: OverlayOptions\n ): void {\n overlay.delayed = !!options.delayed;\n overlay.receivesFocus = options.receivesFocus ?? 'auto';\n overlay.triggerElement = options.trigger || null;\n overlay.type = options.type || 'modal';\n overlay.offset = options.offset ?? 0;\n overlay.placement = options.placement;\n overlay.willPreventClose = !!options.notImmediatelyClosable;\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["options"]
|
|
7
7
|
}
|
package/src/AbstractOverlay.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";import{SpectrumElement as
|
|
1
|
+
"use strict";import{SpectrumElement as g}from"@spectrum-web-components/base";import{reparentChildren as b}from"@spectrum-web-components/shared/src/reparent-children.js";import{OverlayTimer as O}from"./overlay-timer.js";export const overlayTimer=new O,noop=()=>{},guaranteedAllTransitionend=(i,v,e)=>{const r=new AbortController,n=new Map,a=()=>{r.abort(),e()};let m,l;const t=requestAnimationFrame(()=>{m=requestAnimationFrame(()=>{l=requestAnimationFrame(()=>{a()})})}),p=o=>{o.target===i&&(n.set(o.propertyName,n.get(o.propertyName)-1),n.get(o.propertyName)||n.delete(o.propertyName),n.size===0&&a())},d=o=>{o.target===i&&(n.has(o.propertyName)||n.set(o.propertyName,0),n.set(o.propertyName,n.get(o.propertyName)+1),cancelAnimationFrame(t),cancelAnimationFrame(m),cancelAnimationFrame(l))};i.addEventListener("transitionrun",d,{signal:r.signal}),i.addEventListener("transitionend",p,{signal:r.signal}),i.addEventListener("transitioncancel",p,{signal:r.signal}),v()};export function nextFrame(){return new Promise(i=>requestAnimationFrame(()=>i()))}export class AbstractOverlay extends g{constructor(){super(...arguments);this.dispose=noop;this.offset=0;this.willPreventClose=!1}async applyFocus(e,r){}get delayed(){return!1}set delayed(e){}get disabled(){return!1}set disabled(e){}get elementResolver(){return this._elementResolver}set elementResolver(e){this._elementResolver=e}async ensureOnDOM(e){}async makeTransition(e){return null}async manageDelay(e){}async manageDialogOpen(){}async managePopoverOpen(){}managePosition(){}get open(){return!1}set open(e){}get placementController(){return this._placementController}set placementController(e){this._placementController=e}requestSlottable(){}returnFocus(){}get state(){return"closed"}set state(e){}manuallyKeepOpen(){}static update(){const e=new CustomEvent("sp-update-overlays",{bubbles:!0,composed:!0,cancelable:!0});document.dispatchEvent(e)}static async open(e,r,n,a){await import("@spectrum-web-components/overlay/sp-overlay.js");const m=arguments.length===2,l=n||e,t=new this;let p=!1;t.dispose=()=>{t.addEventListener("sp-closed",()=>{p||(d(),p=!0),requestAnimationFrame(()=>{t.remove()})}),t.open=!1,t.dispose=noop};const d=b([l],t,{position:"beforeend",prepareCallback:s=>{const c=s.slot;return s.removeAttribute("slot"),()=>{s.slot=c}}});if(!m&&l&&a){const s=e,c=r,u=a;return AbstractOverlay.applyOptions(t,{...u,delayed:u.delayed||l.hasAttribute("delayed"),trigger:u.virtualTrigger||s,type:c==="modal"?"modal":c==="hover"?"hint":"auto"}),s.insertAdjacentElement("afterend",t),await t.updateComplete,t.open=!0,t.dispose}const y=r;return t.append(l),AbstractOverlay.applyOptions(t,{...y,delayed:y.delayed||l.hasAttribute("delayed")}),t.updateComplete.then(()=>{t.open=!0}),t}static applyOptions(e,r){var n,a;e.delayed=!!r.delayed,e.receivesFocus=(n=r.receivesFocus)!=null?n:"auto",e.triggerElement=r.trigger||null,e.type=r.type||"modal",e.offset=(a=r.offset)!=null?a:0,e.placement=r.placement,e.willPreventClose=!!r.notImmediatelyClosable}disconnectedCallback(){super.disconnectedCallback()}}
|
|
2
2
|
//# sourceMappingURL=AbstractOverlay.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["AbstractOverlay.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport { SpectrumElement } from '@spectrum-web-components/base';\nimport { reparentChildren } from '@spectrum-web-components/shared/src/reparent-children.js';\n\nimport type {\n OpenableElement,\n OverlayOptions,\n OverlayOptionsV1,\n OverlayState,\n OverlayTypes,\n Placement,\n TriggerInteractionsV1,\n} from './overlay-types.js';\nimport type { Overlay } from './Overlay.js';\nimport type { VirtualTrigger } from './VirtualTrigger.js';\nimport { OverlayTimer } from './overlay-timer.js';\nimport type { PlacementController } from './PlacementController.js';\nimport type { ElementResolutionController } from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';\n\nexport const overlayTimer = new OverlayTimer();\n\nexport const noop = (): void => {\n return;\n};\n\n/**\n * Apply a \"transitionend\" listener to an element that may not transition but\n * guarantee the callback will be fired either way.\n *\n * @param el {HTMLElement} - Target of the \"transition\" listeners.\n * @param action {Function} - Method to trigger the \"transition\".\n * @param cb {Function} - Callback to trigger when the \"transition\" has ended.\n */\nexport const guaranteedAllTransitionend = (\n el: HTMLElement,\n action: () => void,\n cb: () => void\n): void => {\n const abortController = new AbortController();\n const runningTransitions = new Map<string, number>();\n const cleanup = (): void => {\n abortController.abort();\n cb();\n };\n let guarantee2: number;\n let guarantee3: number;\n // WebKit fires `transitionrun` a little earlier, the multiple guarantees here\n // allow WebKit to be caught, but doesn't remove the animation listener until\n // after it would have fired in Chromium.\n const guarantee1 = requestAnimationFrame(() => {\n guarantee2 = requestAnimationFrame(() => {\n guarantee3 = requestAnimationFrame(() => {\n cleanup();\n });\n });\n });\n const handleTransitionend = (event: TransitionEvent): void => {\n if (event.target !== el) {\n return;\n }\n runningTransitions.set(\n event.propertyName,\n (runningTransitions.get(event.propertyName) as number) - 1\n );\n if (!runningTransitions.get(event.propertyName)) {\n runningTransitions.delete(event.propertyName);\n }\n if (runningTransitions.size === 0) {\n cleanup();\n }\n };\n const handleTransitionrun = (event: TransitionEvent): void => {\n if (event.target !== el) {\n return;\n }\n if (!runningTransitions.has(event.propertyName)) {\n runningTransitions.set(event.propertyName, 0);\n }\n runningTransitions.set(\n event.propertyName,\n (runningTransitions.get(event.propertyName) as number) + 1\n );\n cancelAnimationFrame(guarantee1);\n cancelAnimationFrame(guarantee2);\n cancelAnimationFrame(guarantee3);\n };\n el.addEventListener('transitionrun', handleTransitionrun, {\n signal: abortController.signal,\n });\n el.addEventListener('transitionend', handleTransitionend, {\n signal: abortController.signal,\n });\n el.addEventListener('transitioncancel', handleTransitionend, {\n signal: abortController.signal,\n });\n action();\n};\n\nexport function nextFrame(): Promise<void> {\n return new Promise((res) => requestAnimationFrame(() => res()));\n}\n\n/**\n * Abstract Overlay base class so that property tyings and imperative API\n * interfaces can be held separate from the actual class definition.\n */\nexport class AbstractOverlay extends SpectrumElement {\n protected async applyFocus(\n _targetOpenState: boolean,\n _focusEl: HTMLElement | null\n ): Promise<void> {\n return;\n }\n /* c8 ignore next 6 */\n get delayed(): boolean {\n return false;\n }\n set delayed(_delayed: boolean) {\n return;\n }\n dialogEl!: HTMLDialogElement & {\n showPopover(): void;\n hidePopover(): void;\n };\n /* c8 ignore next 6 */\n get disabled(): boolean {\n return false;\n }\n set disabled(_disabled: boolean) {\n return;\n }\n dispose = noop;\n protected get elementResolver(): ElementResolutionController {\n return this._elementResolver;\n }\n protected set elementResolver(controller) {\n this._elementResolver = controller;\n }\n protected _elementResolver!: ElementResolutionController;\n /* c8 ignore next 3 */\n protected async ensureOnDOM(_targetOpenState: boolean): Promise<void> {\n return;\n }\n elements!: OpenableElement[];\n /* c8 ignore next 5 */\n protected async makeTransition(\n _targetOpenState: boolean\n ): Promise<HTMLElement | null> {\n return null;\n }\n protected async manageDelay(_targetOpenState: boolean): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected async manageDialogOpen(): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected async managePopoverOpen(): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected managePosition(): void {\n return;\n }\n protected offset: number | [number, number] = 0;\n /* c8 ignore next 6 */\n get open(): boolean {\n return false;\n }\n set open(_open: boolean) {\n return;\n }\n placement?: Placement;\n protected get placementController(): PlacementController {\n return this._placementController;\n }\n protected set placementController(controller) {\n this._placementController = controller;\n }\n protected _placementController!: PlacementController;\n receivesFocus!: 'true' | 'false' | 'auto';\n protected requestSlottable(): void {}\n protected returnFocus(): void {\n return;\n }\n /* c8 ignore next 6 */\n get state(): OverlayState {\n return 'closed';\n }\n set state(_state: OverlayState) {\n return;\n }\n protected _state!: OverlayState;\n triggerElement!: HTMLElement | VirtualTrigger | null;\n type!: OverlayTypes;\n willPreventClose = false;\n /* c8 ignore next 3 */\n public manuallyKeepOpen(): void {\n return;\n }\n\n public static update(): void {\n const overlayUpdateEvent = new CustomEvent('sp-update-overlays', {\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n document.dispatchEvent(overlayUpdateEvent);\n }\n\n /**\n * Overloaded imperative API entry point that allows for both the pre-0.37.0\n * argument signature as well as the post-0.37.0 signature. This allows for\n * consumers to continue to leverage it as they had been in previous releases\n * while also surfacing the more feature-rich API that has been made available.\n */\n public static async open(\n trigger: HTMLElement,\n interaction: TriggerInteractionsV1,\n content: HTMLElement,\n optionsV1: OverlayOptionsV1\n ): Promise<() => void>;\n public static async open(\n content: HTMLElement,\n options?: OverlayOptions\n ): Promise<Overlay>;\n public static async open(\n triggerOrContent: HTMLElement,\n interactionOrOptions:\n | TriggerInteractionsV1\n | OverlayOptions\n | undefined,\n content?: HTMLElement,\n optionsV1?: OverlayOptionsV1\n ): Promise<Overlay | (() => void)> {\n await import('@spectrum-web-components/overlay/sp-overlay.js');\n const v2 = arguments.length === 2;\n const overlayContent = content || triggerOrContent;\n // Use the `this` from the `static` method context rather than a\n // specific imported constructor to prevent opening a circular dependency.\n const overlay = new this() as Overlay;\n let restored = false;\n overlay.dispose = () => {\n overlay.addEventListener('sp-closed', () => {\n if (!restored) {\n restoreContent();\n restored = true;\n }\n requestAnimationFrame(() => {\n overlay.remove();\n });\n });\n overlay.open = false;\n overlay.dispose = noop;\n };\n /**\n * Since content must exist in an <sp-overlay>, we need a way to get it there.\n * The best & most-direct way is to declaratively use an <sp-overlay> element,\n * but for imperative users, we'll reparent content into an overlay that we've created for them.\n **/\n const restoreContent = reparentChildren([overlayContent], overlay, {\n position: 'beforeend',\n prepareCallback: (el) => {\n // Ensure that content to be overlaid is no longer targetted to a specific `slot`.\n // This allow for it to be visible in the overlaid context.\n const slot = el.slot;\n el.removeAttribute('slot');\n return () => {\n el.slot = slot;\n };\n },\n });\n\n const v1 = !v2 && overlayContent && optionsV1;\n if (v1) {\n if (window.__swc.DEBUG) {\n window.__swc.warn(\n overlay,\n `You are interacting with an ${overlay.localName} element via a deprecated imperative API. This API will be removed in a future version of the SWC library. Consider leveraging an ${overlay.localName} directly.`,\n 'https://opensource.adobe.com/spectrum-web-components/components/overlay/',\n { level: 'deprecation' }\n );\n }\n const trigger = triggerOrContent;\n const interaction = interactionOrOptions;\n const options = optionsV1;\n AbstractOverlay.applyOptions(overlay, {\n ...options,\n delayed:\n options.delayed || overlayContent.hasAttribute('delayed'),\n trigger: options.virtualTrigger || trigger,\n type:\n interaction === 'modal'\n ? 'modal'\n : interaction === 'hover'\n ? 'hint'\n : 'auto',\n });\n trigger.insertAdjacentElement('afterend', overlay);\n await overlay.updateComplete;\n overlay.open = true;\n return overlay.dispose;\n }\n\n const options = interactionOrOptions as OverlayOptions;\n overlay.append(overlayContent);\n AbstractOverlay.applyOptions(overlay, {\n ...options,\n delayed: options.delayed || overlayContent.hasAttribute('delayed'),\n });\n overlay.updateComplete.then(() => {\n // Do we want to \"open\" this path, or leave that to the consumer?\n overlay.open = true;\n });\n return overlay;\n }\n\n static applyOptions(\n overlay: AbstractOverlay,\n options: OverlayOptions\n ): void {\n overlay.delayed = !!options.delayed;\n overlay.receivesFocus = options.receivesFocus ?? 'auto';\n overlay.triggerElement = options.trigger || null;\n overlay.type = options.type || 'modal';\n overlay.offset = options.offset ?? 0;\n overlay.placement = options.placement;\n overlay.willPreventClose = !!options.notImmediatelyClosable;\n }\n\n private iosEventPropagationController?: AbortController;\n\n protected setupIOSEventManagement(): void {\n // This is a workaround for a bug in iOS <17 where the event leaks out of the dialog to the element below it.\n // Issue - https://github.com/adobe/spectrum-web-components/issues/5042\n this.iosEventPropagationController = new AbortController();\n this.dialogEl.addEventListener(\n 'pointerup',\n (event) => event.stopPropagation(),\n {\n capture: true,\n signal: this.iosEventPropagationController.signal,\n }\n );\n this.dialogEl.addEventListener(\n 'touchend',\n (event) => event.stopPropagation(),\n {\n capture: true,\n signal: this.iosEventPropagationController.signal,\n }\n );\n }\n\n protected cleanupIOSEventManagement(): void {\n this.iosEventPropagationController?.abort();\n this.iosEventPropagationController = undefined;\n }\n\n override disconnectedCallback(): void {\n this.cleanupIOSEventManagement();\n super.disconnectedCallback();\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport { SpectrumElement } from '@spectrum-web-components/base';\nimport { reparentChildren } from '@spectrum-web-components/shared/src/reparent-children.js';\n\nimport type {\n OpenableElement,\n OverlayOptions,\n OverlayOptionsV1,\n OverlayState,\n OverlayTypes,\n Placement,\n TriggerInteractionsV1,\n} from './overlay-types.js';\nimport type { Overlay } from './Overlay.js';\nimport type { VirtualTrigger } from './VirtualTrigger.js';\nimport { OverlayTimer } from './overlay-timer.js';\nimport type { PlacementController } from './PlacementController.js';\nimport type { ElementResolutionController } from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';\n\nexport const overlayTimer = new OverlayTimer();\n\nexport const noop = (): void => {\n return;\n};\n\n/**\n * Apply a \"transitionend\" listener to an element that may not transition but\n * guarantee the callback will be fired either way.\n *\n * @param el {HTMLElement} - Target of the \"transition\" listeners.\n * @param action {Function} - Method to trigger the \"transition\".\n * @param cb {Function} - Callback to trigger when the \"transition\" has ended.\n */\nexport const guaranteedAllTransitionend = (\n el: HTMLElement,\n action: () => void,\n cb: () => void\n): void => {\n const abortController = new AbortController();\n const runningTransitions = new Map<string, number>();\n const cleanup = (): void => {\n abortController.abort();\n cb();\n };\n let guarantee2: number;\n let guarantee3: number;\n // WebKit fires `transitionrun` a little earlier, the multiple guarantees here\n // allow WebKit to be caught, but doesn't remove the animation listener until\n // after it would have fired in Chromium.\n const guarantee1 = requestAnimationFrame(() => {\n guarantee2 = requestAnimationFrame(() => {\n guarantee3 = requestAnimationFrame(() => {\n cleanup();\n });\n });\n });\n const handleTransitionend = (event: TransitionEvent): void => {\n if (event.target !== el) {\n return;\n }\n runningTransitions.set(\n event.propertyName,\n (runningTransitions.get(event.propertyName) as number) - 1\n );\n if (!runningTransitions.get(event.propertyName)) {\n runningTransitions.delete(event.propertyName);\n }\n if (runningTransitions.size === 0) {\n cleanup();\n }\n };\n const handleTransitionrun = (event: TransitionEvent): void => {\n if (event.target !== el) {\n return;\n }\n if (!runningTransitions.has(event.propertyName)) {\n runningTransitions.set(event.propertyName, 0);\n }\n runningTransitions.set(\n event.propertyName,\n (runningTransitions.get(event.propertyName) as number) + 1\n );\n cancelAnimationFrame(guarantee1);\n cancelAnimationFrame(guarantee2);\n cancelAnimationFrame(guarantee3);\n };\n el.addEventListener('transitionrun', handleTransitionrun, {\n signal: abortController.signal,\n });\n el.addEventListener('transitionend', handleTransitionend, {\n signal: abortController.signal,\n });\n el.addEventListener('transitioncancel', handleTransitionend, {\n signal: abortController.signal,\n });\n action();\n};\n\nexport function nextFrame(): Promise<void> {\n return new Promise((res) => requestAnimationFrame(() => res()));\n}\n\n/**\n * Abstract Overlay base class so that property tyings and imperative API\n * interfaces can be held separate from the actual class definition.\n */\nexport class AbstractOverlay extends SpectrumElement {\n protected async applyFocus(\n _targetOpenState: boolean,\n _focusEl: HTMLElement | null\n ): Promise<void> {\n return;\n }\n /* c8 ignore next 6 */\n get delayed(): boolean {\n return false;\n }\n set delayed(_delayed: boolean) {\n return;\n }\n dialogEl!: HTMLDialogElement & {\n showPopover(): void;\n hidePopover(): void;\n };\n /* c8 ignore next 6 */\n get disabled(): boolean {\n return false;\n }\n set disabled(_disabled: boolean) {\n return;\n }\n dispose = noop;\n protected get elementResolver(): ElementResolutionController {\n return this._elementResolver;\n }\n protected set elementResolver(controller) {\n this._elementResolver = controller;\n }\n protected _elementResolver!: ElementResolutionController;\n /* c8 ignore next 3 */\n protected async ensureOnDOM(_targetOpenState: boolean): Promise<void> {\n return;\n }\n elements!: OpenableElement[];\n /* c8 ignore next 5 */\n protected async makeTransition(\n _targetOpenState: boolean\n ): Promise<HTMLElement | null> {\n return null;\n }\n protected async manageDelay(_targetOpenState: boolean): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected async manageDialogOpen(): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected async managePopoverOpen(): Promise<void> {\n return;\n }\n /* c8 ignore next 3 */\n protected managePosition(): void {\n return;\n }\n protected offset: number | [number, number] = 0;\n /* c8 ignore next 6 */\n get open(): boolean {\n return false;\n }\n set open(_open: boolean) {\n return;\n }\n placement?: Placement;\n protected get placementController(): PlacementController {\n return this._placementController;\n }\n protected set placementController(controller) {\n this._placementController = controller;\n }\n protected _placementController!: PlacementController;\n receivesFocus!: 'true' | 'false' | 'auto';\n protected requestSlottable(): void {}\n protected returnFocus(): void {\n return;\n }\n /* c8 ignore next 6 */\n get state(): OverlayState {\n return 'closed';\n }\n set state(_state: OverlayState) {\n return;\n }\n protected _state!: OverlayState;\n triggerElement!: HTMLElement | VirtualTrigger | null;\n type!: OverlayTypes;\n willPreventClose = false;\n /* c8 ignore next 3 */\n public manuallyKeepOpen(): void {\n return;\n }\n\n public static update(): void {\n const overlayUpdateEvent = new CustomEvent('sp-update-overlays', {\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n document.dispatchEvent(overlayUpdateEvent);\n }\n\n /**\n * Overloaded imperative API entry point that allows for both the pre-0.37.0\n * argument signature as well as the post-0.37.0 signature. This allows for\n * consumers to continue to leverage it as they had been in previous releases\n * while also surfacing the more feature-rich API that has been made available.\n */\n public static async open(\n trigger: HTMLElement,\n interaction: TriggerInteractionsV1,\n content: HTMLElement,\n optionsV1: OverlayOptionsV1\n ): Promise<() => void>;\n public static async open(\n content: HTMLElement,\n options?: OverlayOptions\n ): Promise<Overlay>;\n public static async open(\n triggerOrContent: HTMLElement,\n interactionOrOptions:\n | TriggerInteractionsV1\n | OverlayOptions\n | undefined,\n content?: HTMLElement,\n optionsV1?: OverlayOptionsV1\n ): Promise<Overlay | (() => void)> {\n await import('@spectrum-web-components/overlay/sp-overlay.js');\n const v2 = arguments.length === 2;\n const overlayContent = content || triggerOrContent;\n // Use the `this` from the `static` method context rather than a\n // specific imported constructor to prevent opening a circular dependency.\n const overlay = new this() as Overlay;\n let restored = false;\n overlay.dispose = () => {\n overlay.addEventListener('sp-closed', () => {\n if (!restored) {\n restoreContent();\n restored = true;\n }\n requestAnimationFrame(() => {\n overlay.remove();\n });\n });\n overlay.open = false;\n overlay.dispose = noop;\n };\n /**\n * Since content must exist in an <sp-overlay>, we need a way to get it there.\n * The best & most-direct way is to declaratively use an <sp-overlay> element,\n * but for imperative users, we'll reparent content into an overlay that we've created for them.\n **/\n const restoreContent = reparentChildren([overlayContent], overlay, {\n position: 'beforeend',\n prepareCallback: (el) => {\n // Ensure that content to be overlaid is no longer targetted to a specific `slot`.\n // This allow for it to be visible in the overlaid context.\n const slot = el.slot;\n el.removeAttribute('slot');\n return () => {\n el.slot = slot;\n };\n },\n });\n\n const v1 = !v2 && overlayContent && optionsV1;\n if (v1) {\n if (window.__swc.DEBUG) {\n window.__swc.warn(\n overlay,\n `You are interacting with an ${overlay.localName} element via a deprecated imperative API. This API will be removed in a future version of the SWC library. Consider leveraging an ${overlay.localName} directly.`,\n 'https://opensource.adobe.com/spectrum-web-components/components/overlay/',\n { level: 'deprecation' }\n );\n }\n const trigger = triggerOrContent;\n const interaction = interactionOrOptions;\n const options = optionsV1;\n AbstractOverlay.applyOptions(overlay, {\n ...options,\n delayed:\n options.delayed || overlayContent.hasAttribute('delayed'),\n trigger: options.virtualTrigger || trigger,\n type:\n interaction === 'modal'\n ? 'modal'\n : interaction === 'hover'\n ? 'hint'\n : 'auto',\n });\n trigger.insertAdjacentElement('afterend', overlay);\n await overlay.updateComplete;\n overlay.open = true;\n return overlay.dispose;\n }\n\n const options = interactionOrOptions as OverlayOptions;\n overlay.append(overlayContent);\n AbstractOverlay.applyOptions(overlay, {\n ...options,\n delayed: options.delayed || overlayContent.hasAttribute('delayed'),\n });\n overlay.updateComplete.then(() => {\n // Do we want to \"open\" this path, or leave that to the consumer?\n overlay.open = true;\n });\n return overlay;\n }\n\n static applyOptions(\n overlay: AbstractOverlay,\n options: OverlayOptions\n ): void {\n overlay.delayed = !!options.delayed;\n overlay.receivesFocus = options.receivesFocus ?? 'auto';\n overlay.triggerElement = options.trigger || null;\n overlay.type = options.type || 'modal';\n overlay.offset = options.offset ?? 0;\n overlay.placement = options.placement;\n overlay.willPreventClose = !!options.notImmediatelyClosable;\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["SpectrumElement", "reparentChildren", "OverlayTimer", "el", "action", "cb", "abortController", "runningTransitions", "cleanup", "guarantee2", "guarantee3", "guarantee1", "handleTransitionend", "event", "handleTransitionrun", "res", "_targetOpenState", "_focusEl", "_delayed", "_disabled", "controller", "_open", "_state", "overlayUpdateEvent", "triggerOrContent", "interactionOrOptions", "content", "optionsV1", "v2", "overlayContent", "overlay", "restored", "restoreContent", "slot", "trigger", "interaction", "options", "_a", "_b"]
|
|
7
7
|
}
|
package/src/Overlay.dev.js
CHANGED
|
@@ -96,7 +96,9 @@ const _Overlay = class _Overlay extends ComputedOverlayBase {
|
|
|
96
96
|
event.relatedTarget.addEventListener(
|
|
97
97
|
relationEvent.type,
|
|
98
98
|
(event2) => {
|
|
99
|
-
|
|
99
|
+
const path = event2.composedPath();
|
|
100
|
+
const isWithinOverlay = path.some((el) => el === this);
|
|
101
|
+
if (!isWithinOverlay) {
|
|
100
102
|
this.open = false;
|
|
101
103
|
}
|
|
102
104
|
}
|
package/src/Overlay.dev.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["Overlay.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2023 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport {\n html,\n PropertyValues,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport {\n property,\n query,\n queryAssignedElements,\n state,\n} from '@spectrum-web-components/base/src/decorators.js';\nimport {\n ElementResolutionController,\n elementResolverUpdatedSymbol,\n} from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';\nimport {\n ifDefined,\n StyleInfo,\n styleMap,\n} from '@spectrum-web-components/base/src/directives.js';\nimport { randomID } from '@spectrum-web-components/shared/src/random-id.js';\nimport type {\n OpenableElement,\n OverlayState,\n OverlayTypes,\n Placement,\n TriggerInteraction,\n} from './overlay-types.dev.js'\nimport { AbstractOverlay, nextFrame } from './AbstractOverlay.dev.js'\nimport { OverlayDialog } from './OverlayDialog.dev.js'\nimport { OverlayPopover } from './OverlayPopover.dev.js'\nimport { OverlayNoPopover } from './OverlayNoPopover.dev.js'\nimport { overlayStack } from './OverlayStack.dev.js'\nimport { VirtualTrigger } from './VirtualTrigger.dev.js'\nimport { PlacementController } from './PlacementController.dev.js'\nimport type { ClickController } from './ClickController.dev.js'\nimport type { HoverController } from './HoverController.dev.js'\nimport type { LongpressController } from './LongpressController.dev.js'\nexport { LONGPRESS_INSTRUCTIONS } from './LongpressController.dev.js'\nimport { strategies } from './strategies.dev.js'\nimport {\n removeSlottableRequest,\n SlottableRequestEvent,\n} from './slottable-request-event.dev.js'\n\nimport styles from './overlay.css.js';\n\nconst browserSupportsPopover = 'showPopover' in document.createElement('div');\n\n// Start the base class and add the popover or no-popover functionality\nlet ComputedOverlayBase = OverlayDialog(AbstractOverlay);\n\nif (browserSupportsPopover) {\n ComputedOverlayBase = OverlayPopover(ComputedOverlayBase);\n} else {\n ComputedOverlayBase = OverlayNoPopover(ComputedOverlayBase);\n}\n\n/**\n * @element sp-overlay\n *\n * @fires sp-opened - announces that an overlay has completed any entry animations\n * @fires sp-closed - announce that an overlay has compelted any exit animations\n * @fires slottable-request - requests to add or remove slottable content\n */\nexport class Overlay extends ComputedOverlayBase {\n static override styles = [styles];\n\n /**\n * An Overlay that is `delayed` will wait until a warm-up period of 1000ms\n * has completed before opening. Once the warm-up period has completed, all\n * subsequent Overlays will open immediately. When no Overlays are opened,\n * a cool-down period of 1000ms will begin. Once the cool-down has completed,\n * the next Overlay to be opened will be subject to the warm-up period if\n * provided that option.\n *\n * This behavior helps to manage the performance and user experience by\n * preventing multiple overlays from opening simultaneously and ensuring\n * a smooth transition between opening and closing overlays.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean })\n override get delayed(): boolean {\n return this.elements.at(-1)?.hasAttribute('delayed') || this._delayed;\n }\n\n override set delayed(delayed: boolean) {\n this._delayed = delayed;\n }\n\n private _delayed = false;\n\n /**\n * A reference to the dialog element within the overlay.\n * This element is expected to have `showPopover` and `hidePopover` methods.\n */\n @query('.dialog')\n override dialogEl!: HTMLDialogElement & {\n showPopover(): void;\n hidePopover(): void;\n };\n\n /**\n * Indicates whether the overlay is currently functional or not.\n *\n * When set to `true`, the overlay is disabled, and any active strategy is aborted.\n * The overlay will also close if it is currently open. When set to `false`, the\n * overlay will re-bind events and re-open if it was previously open.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean })\n override get disabled(): boolean {\n return this._disabled;\n }\n\n override set disabled(disabled: boolean) {\n this._disabled = disabled;\n if (disabled) {\n // Abort any active strategy and close the overlay if it is currently open\n this.strategy?.abort();\n this.wasOpen = this.open;\n this.open = false;\n } else {\n // Re-bind events and re-open the overlay if it was previously open\n this.bindEvents();\n this.open = this.open || this.wasOpen;\n this.wasOpen = false;\n }\n }\n\n private _disabled = false;\n\n /**\n * A query to gather all elements slotted into the default slot, excluding elements\n * with the slot name \"longpress-describedby-descriptor\".\n */\n @queryAssignedElements({\n flatten: true,\n selector: ':not([slot=\"longpress-describedby-descriptor\"], slot)',\n })\n override elements!: OpenableElement[];\n\n /**\n * A reference to the parent overlay that should be force-closed, if any.\n */\n public parentOverlayToForceClose?: Overlay;\n\n /**\n * Determines if the overlay has a non-virtual trigger element.\n *\n * @returns {boolean} `true` if the trigger element is not a virtual trigger, otherwise `false`.\n */\n private get hasNonVirtualTrigger(): boolean {\n return (\n !!this.triggerElement &&\n !(this.triggerElement instanceof VirtualTrigger)\n );\n }\n\n /**\n * The `offset` property accepts either a single number to define the offset of the\n * Overlay along the main axis from the trigger, or a 2-tuple to define the offset\n * along both the main axis and the cross axis. This option has no effect when there\n * is no trigger element.\n *\n * @type {number | [number, number]}\n * @default 0\n */\n @property({ type: Number })\n override offset: number | [number, number] = 0;\n\n /**\n * Provides an instance of the `PlacementController` for managing the positioning\n * of the overlay relative to its trigger element.\n *\n * If the `PlacementController` instance does not already exist, it is created and\n * assigned to the `_placementController` property.\n *\n * @protected\n * @returns {PlacementController} The `PlacementController` instance.\n */\n protected override get placementController(): PlacementController {\n if (!this._placementController) {\n this._placementController = new PlacementController(this);\n }\n return this._placementController;\n }\n\n /**\n * Indicates whether the Overlay is projected onto the \"top layer\" or not.\n *\n * When set to `true`, the overlay is open and visible. When set to `false`, the overlay is closed and hidden.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean, reflect: true })\n override get open(): boolean {\n return this._open;\n }\n\n override set open(open: boolean) {\n // Don't respond if the overlay is disabled.\n if (open && this.disabled) return;\n\n // Don't respond if the state is not changing.\n if (open === this.open) return;\n\n // Don't respond if the overlay is in the shadow state during a longpress.\n // The shadow state occurs when the first \"click\" would normally close the popover.\n if (this.strategy?.activelyOpening && !open) return;\n\n // Update the internal _open property.\n this._open = open;\n\n // Increment the open count if the overlay is opening.\n if (this.open) {\n Overlay.openCount += 1;\n }\n\n // Request an update to re-render the component if necessary.\n this.requestUpdate('open', !this.open);\n\n // Request slottable content if the overlay is opening.\n if (this.open) {\n this.requestSlottable();\n }\n }\n\n private _open = false;\n\n /**\n * Tracks the number of overlays that have been opened.\n *\n * This static property is used to manage the stacking context of multiple overlays.\n *\n * @type {number}\n * @default 1\n */\n static openCount = 1;\n\n /**\n * Instruct the Overlay where to place itself in relationship to the trigger element.\n *\n * @type {\"top\" | \"top-start\" | \"top-end\" | \"right\" | \"right-start\" | \"right-end\" | \"bottom\" | \"bottom-start\" | \"bottom-end\" | \"left\" | \"left-start\" | \"left-end\"}\n */\n @property()\n override placement?: Placement;\n\n /**\n * The state in which the last `request-slottable` event was dispatched.\n *\n * This property ensures that overlays do not dispatch the same state twice in a row.\n *\n * @type {boolean}\n * @default false\n */\n private lastRequestSlottableState = false;\n\n /**\n * Whether to pass focus to the overlay once opened, or\n * to the appropriate value based on the \"type\" of the overlay\n * when set to `\"auto\"`.\n *\n * @type {'true' | 'false' | 'auto'}\n * @default 'auto'\n */\n @property({ attribute: 'receives-focus' })\n override receivesFocus: 'true' | 'false' | 'auto' = 'auto';\n\n /**\n * A reference to the slot element within the overlay.\n *\n * This element is used to manage the content slotted into the overlay.\n *\n * @type {HTMLSlotElement}\n */\n @query('slot')\n slotEl!: HTMLSlotElement;\n\n /**\n * The current state of the overlay.\n *\n * This property reflects the current state of the overlay, such as 'opened' or 'closed'.\n * When the state changes, it triggers the appropriate actions and updates the component.\n *\n * @type {OverlayState}\n * @default 'closed'\n */\n @state()\n override get state(): OverlayState {\n return this._state;\n }\n\n override set state(state) {\n // Do not respond if the state is not changing.\n if (state === this.state) return;\n\n const oldState = this.state;\n\n this._state = state;\n\n // Complete the opening strategy if the state is 'opened' or 'closed'.\n if (this.state === 'opened' || this.state === 'closed') {\n this.strategy?.shouldCompleteOpen();\n }\n\n // Request an update to re-render the component if necessary.\n this.requestUpdate('state', oldState);\n }\n\n override _state: OverlayState = 'closed';\n\n /**\n * The interaction strategy for opening the overlay.\n * This can be a ClickController, HoverController, or LongpressController.\n */\n public strategy?: ClickController | HoverController | LongpressController;\n\n /**\n * The padding around the tip of the overlay.\n * This property defines the padding around the tip of the overlay, which can be used to adjust its positioning.\n *\n * @type {number}\n */\n @property({ type: Number, attribute: 'tip-padding' })\n tipPadding?: number;\n\n /**\n * An optional ID reference for the trigger element combined with the optional\n * interaction (click | hover | longpress) by which the overlay should open.\n * The format is `trigger@interaction`, e.g., `trigger@click` opens the overlay\n * when an element with the ID \"trigger\" is clicked.\n *\n * @type {string}\n */\n @property()\n trigger?: string;\n\n /**\n * An element reference for the trigger element that the overlay should relate to.\n * This property is not reflected as an attribute.\n *\n * @type {HTMLElement | VirtualTrigger | null}\n */\n @property({ attribute: false })\n override triggerElement: HTMLElement | VirtualTrigger | null = null;\n\n /**\n * The specific interaction to listen for on the `triggerElement` to open the overlay.\n * This property is not reflected as an attribute.\n *\n * @type {TriggerInteraction}\n */\n @property({ attribute: false })\n triggerInteraction?: TriggerInteraction;\n\n /**\n * Configures the open/close heuristics of the Overlay.\n *\n * @type {\"auto\" | \"hint\" | \"manual\" | \"modal\" | \"page\"}\n * @default \"auto\"\n */\n @property()\n override type: OverlayTypes = 'auto';\n\n /**\n * Tracks whether the overlay was previously open.\n * This is used to restore the open state when re-enabling the overlay.\n *\n * @type {boolean}\n * @default false\n */\n protected wasOpen = false;\n\n /**\n * Provides an instance of the `ElementResolutionController` for managing the element\n * that the overlay should be associated with. If the instance does not already exist,\n * it is created and assigned to the `_elementResolver` property.\n *\n * @protected\n * @returns {ElementResolutionController} The `ElementResolutionController` instance.\n */\n protected override get elementResolver(): ElementResolutionController {\n if (!this._elementResolver) {\n this._elementResolver = new ElementResolutionController(this);\n }\n\n return this._elementResolver;\n }\n\n /**\n * Determines if the overlay uses a dialog.\n * Returns `true` if the overlay type is \"modal\" or \"page\".\n *\n * @private\n * @returns {boolean} `true` if the overlay uses a dialog, otherwise `false`.\n */\n private get usesDialog(): boolean {\n return this.type === 'modal' || this.type === 'page';\n }\n\n /**\n * Determines the value for the popover attribute based on the overlay type.\n *\n * @private\n * @returns {'auto' | 'manual' | undefined} The popover value or undefined if not applicable.\n */\n private get popoverValue(): 'auto' | 'manual' | undefined {\n const hasPopoverAttribute = 'popover' in this;\n\n if (!hasPopoverAttribute) {\n return undefined;\n }\n\n switch (this.type) {\n case 'modal':\n case 'page':\n return undefined;\n case 'hint':\n return 'manual';\n default:\n return this.type;\n }\n }\n\n /**\n * Determines if the overlay requires positioning based on its type and state.\n *\n * @protected\n * @returns {boolean} True if the overlay requires positioning, otherwise false.\n */\n protected get requiresPositioning(): boolean {\n // Do not position \"page\" overlays as they should block the entire UI.\n if (this.type === 'page' || !this.open) return false;\n\n // Do not position content without a trigger element, as there is nothing to position it relative to.\n // Do not automatically position content unless it is a \"hint\".\n if (!this.triggerElement || (!this.placement && this.type !== 'hint'))\n return false;\n\n return true;\n }\n\n /**\n * Manages the positioning of the overlay relative to its trigger element.\n *\n * This method calculates the necessary parameters for positioning the overlay,\n * such as offset, placement, and tip padding, and then delegates the actual\n * positioning to the `PlacementController`.\n *\n * @protected\n * @override\n */\n protected override managePosition(): void {\n // Do not proceed if positioning is not required or the overlay is not open.\n if (!this.requiresPositioning || !this.open) return;\n\n const offset = this.offset || 0;\n\n const trigger = this.triggerElement as HTMLElement;\n\n const placement = (this.placement as Placement) || 'right';\n\n const tipPadding = this.tipPadding;\n\n this.placementController.placeOverlay(this.dialogEl, {\n offset,\n placement,\n tipPadding,\n trigger,\n type: this.type,\n });\n }\n\n /**\n * Manages the process of opening the popover.\n *\n * This method handles the necessary steps to open the popover, including managing delays,\n * ensuring the popover is in the DOM, making transitions, and applying focus.\n *\n * @protected\n * @override\n * @returns {Promise<void>} A promise that resolves when the popover has been fully opened.\n */\n protected override async managePopoverOpen(): Promise<void> {\n // Call the base class method to handle any initial setup.\n super.managePopoverOpen();\n\n const targetOpenState = this.open;\n\n // Ensure the open state has not changed before proceeding.\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Manage any delays before opening the popover.\n await this.manageDelay(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Ensure the popover is in the DOM before proceeding.\n await this.ensureOnDOM(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Make any necessary transitions for opening the popover.\n const focusEl = await this.makeTransition(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Apply focus to the appropriate element after opening the popover.\n await this.applyFocus(targetOpenState, focusEl);\n }\n\n /**\n * Applies focus to the appropriate element after the popover has been opened.\n *\n * This method handles the focus management for the overlay, ensuring that the correct\n * element receives focus based on the overlay's type and state.\n *\n * @protected\n * @override\n * @param {boolean} targetOpenState - The target open state of the overlay.\n * @param {HTMLElement | null} focusEl - The element to focus after opening the popover.\n * @returns {Promise<void>} A promise that resolves when the focus has been applied.\n */\n protected override async applyFocus(\n targetOpenState: boolean,\n focusEl: HTMLElement | null\n ): Promise<void> {\n // Do not move focus when explicitly told not to or when the overlay is a \"hint\".\n if (this.receivesFocus === 'false' || this.type === 'hint') {\n return;\n }\n\n // Wait for the next two animation frames to ensure the DOM is updated.\n await nextFrame();\n await nextFrame();\n\n // If the open state has changed during the delay, do not proceed.\n if (targetOpenState === this.open && !this.open) {\n // If the overlay is closing and the trigger element is still focused, return focus to the trigger element.\n if (\n this.hasNonVirtualTrigger &&\n this.contains((this.getRootNode() as Document).activeElement)\n ) {\n (this.triggerElement as HTMLElement).focus();\n }\n return;\n }\n\n // Apply focus to the specified focus element.\n focusEl?.focus();\n }\n\n /**\n * Returns focus to the trigger element if the overlay is closed.\n *\n * This method ensures that focus is returned to the trigger element when the overlay is closed,\n * unless the overlay is of type \"hint\" or the focus is already outside the overlay.\n *\n * @protected\n * @override\n */\n protected override returnFocus(): void {\n // Do not proceed if the overlay is open or if the overlay type is \"hint\".\n if (this.open || this.type === 'hint') return;\n\n /**\n * Retrieves the ancestors of the currently focused element.\n *\n * @returns {HTMLElement[]} An array of ancestor elements.\n */\n const getAncestors = (): HTMLElement[] => {\n const ancestors: HTMLElement[] = [];\n\n // eslint-disable-next-line @spectrum-web-components/document-active-element\n let currentNode = document.activeElement;\n\n // Traverse the shadow DOM to find the active element.\n while (currentNode?.shadowRoot?.activeElement) {\n currentNode = currentNode.shadowRoot.activeElement;\n }\n\n // Traverse the DOM tree to collect ancestor elements.\n while (currentNode) {\n const ancestor =\n currentNode.assignedSlot ||\n currentNode.parentElement ||\n (currentNode.getRootNode() as ShadowRoot)?.host;\n if (ancestor) {\n ancestors.push(ancestor as HTMLElement);\n }\n currentNode = ancestor;\n }\n return ancestors;\n };\n\n // Check if focus should be returned to the trigger element.\n if (\n this.receivesFocus !== 'false' &&\n !!(this.triggerElement as HTMLElement)?.focus &&\n (this.contains((this.getRootNode() as Document).activeElement) ||\n getAncestors().includes(this) ||\n // eslint-disable-next-line @spectrum-web-components/document-active-element\n document.activeElement === document.body)\n ) {\n // Return focus to the trigger element.\n (this.triggerElement as HTMLElement).focus();\n }\n }\n\n /**\n * Handles the focus out event to close the overlay if the focus moves outside of it.\n *\n * This method ensures that the overlay is closed when the focus moves to an element\n * outside of the overlay, unless the focus is moved to a related element.\n *\n * @private\n * @param {FocusEvent} event - The focus out event.\n */\n private closeOnFocusOut = (event: FocusEvent): void => {\n // If the related target (newly focused element) is not known, do nothing.\n if (!event.relatedTarget) {\n return;\n }\n\n // Create a custom event to query the relationship of the newly focused element.\n const relationEvent = new Event('overlay-relation-query', {\n bubbles: true,\n composed: true,\n });\n\n // Add an event listener to the related target to handle the custom event.\n event.relatedTarget.addEventListener(\n relationEvent.type,\n (event: Event) => {\n // If the newly focused element is not within the overlay, close the overlay.\n if (!event.composedPath().includes(this)) {\n this.open = false;\n }\n }\n );\n\n // Dispatch the custom event to the related target.\n event.relatedTarget.dispatchEvent(relationEvent);\n };\n\n /**\n * Manages the process of opening or closing the overlay.\n *\n * This method handles the necessary steps to open or close the overlay, including updating the state,\n * managing the overlay stack, and handling focus events.\n *\n * @protected\n * @param {boolean} oldOpen - The previous open state of the overlay.\n * @returns {Promise<void>} A promise that resolves when the overlay has been fully managed.\n */\n protected async manageOpen(oldOpen: boolean): Promise<void> {\n // Prevent entering the manage workflow if the overlay is not connected to the DOM.\n // The `.showPopover()` and `.showModal()` events will error on content that is not connected to the DOM.\n if (!this.isConnected && this.open) return;\n\n // Wait for the component to finish updating if it has not already done so.\n if (!this.hasUpdated) {\n await this.updateComplete;\n }\n\n if (this.open) {\n // Add the overlay to the overlay stack.\n overlayStack.add(this);\n\n if (this.willPreventClose) {\n // Add an event listener to handle the pointerup event and toggle the 'not-immediately-closable' class.\n document.addEventListener(\n 'pointerup',\n () => {\n this.dialogEl.classList.toggle(\n 'not-immediately-closable',\n false\n );\n this.willPreventClose = false;\n },\n { once: true }\n );\n this.dialogEl.classList.toggle(\n 'not-immediately-closable',\n true\n );\n }\n } else {\n if (oldOpen) {\n // Dispose of the overlay if it was previously open.\n this.dispose();\n }\n\n // Remove the overlay from the overlay stack.\n overlayStack.remove(this);\n }\n\n // Update the state of the overlay based on the open property.\n if (this.open && this.state !== 'opened') {\n this.state = 'opening';\n } else if (!this.open && this.state !== 'closed') {\n this.state = 'closing';\n }\n\n // Manage the dialog or popover based on the overlay type.\n if (this.usesDialog) {\n this.manageDialogOpen();\n } else {\n this.managePopoverOpen();\n }\n\n // Handle focus events for auto type overlays.\n if (this.type === 'auto') {\n const listenerRoot = this.getRootNode() as Document;\n if (this.open) {\n listenerRoot.addEventListener(\n 'focusout',\n this.closeOnFocusOut,\n { capture: true }\n );\n } else {\n listenerRoot.removeEventListener(\n 'focusout',\n this.closeOnFocusOut,\n { capture: true }\n );\n }\n }\n }\n\n /**\n * Binds event handling strategies to the overlay based on the specified trigger interaction.\n *\n * This method sets up the appropriate event handling strategy for the overlay, ensuring that\n * it responds correctly to user interactions such as clicks, hovers, or long presses.\n *\n * @protected\n */\n protected bindEvents(): void {\n // Abort any existing strategy to ensure a clean setup.\n this.strategy?.abort();\n this.strategy = undefined;\n\n // Return early if there is no non-virtual trigger element.\n if (!this.hasNonVirtualTrigger) return;\n\n // Return early if no trigger interaction is specified.\n if (!this.triggerInteraction) return;\n\n // Set up a new event handling strategy based on the specified trigger interaction.\n this.strategy = new strategies[this.triggerInteraction](\n this.triggerElement as HTMLElement,\n {\n overlay: this,\n }\n );\n }\n\n /**\n * Handles the `beforetoggle` event to manage the overlay's state.\n *\n * This method checks the new state of the event and calls `handleBrowserClose`\n * if the new state is not 'open'.\n *\n * @protected\n * @param {Event & { newState: string }} event - The `beforetoggle` event with the new state.\n */\n protected handleBeforetoggle(event: Event & { newState: string }): void {\n if (event.newState !== 'open') {\n this.handleBrowserClose(event);\n }\n }\n\n /**\n * Handles the browser's close event to manage the overlay's state.\n *\n * This method stops the propagation of the event and closes the overlay if it is not\n * actively opening. If the overlay is actively opening, it calls `manuallyKeepOpen`.\n *\n * @protected\n * @param {Event} event - The browser's close event.\n */\n protected handleBrowserClose(event: Event): void {\n event.stopPropagation();\n if (!this.strategy?.activelyOpening) {\n this.open = false;\n return;\n }\n this.manuallyKeepOpen();\n }\n\n /**\n * Manually keeps the overlay open.\n *\n * This method sets the overlay to open, allows placement updates, and manages the open state.\n *\n * @public\n * @override\n */\n public override manuallyKeepOpen(): void {\n this.open = true;\n this.placementController.allowPlacementUpdate = true;\n this.manageOpen(false);\n }\n\n /**\n * Handles the `slotchange` event to manage the overlay's state.\n *\n * This method checks if there are any elements in the slot. If there are no elements,\n * it releases the description from the strategy. If there are elements and the trigger\n * is non-virtual, it prepares the description for the trigger element.\n *\n * @protected\n */\n protected handleSlotchange(): void {\n if (!this.elements.length) {\n // Release the description if there are no elements in the slot.\n this.strategy?.releaseDescription();\n } else if (this.hasNonVirtualTrigger) {\n // Prepare the description for the trigger element if it is non-virtual.\n this.strategy?.prepareDescription(\n this.triggerElement as HTMLElement\n );\n }\n }\n\n /**\n * Determines whether the overlay should prevent closing.\n *\n * This method checks the `willPreventClose` flag and resets it to `false`.\n * It returns the value of the `willPreventClose` flag.\n *\n * @public\n * @returns {boolean} `true` if the overlay should prevent closing, otherwise `false`.\n */\n public shouldPreventClose(): boolean {\n const shouldPreventClose = this.willPreventClose;\n this.willPreventClose = false;\n return shouldPreventClose;\n }\n\n /**\n * Requests slottable content for the overlay.\n *\n * This method dispatches a `SlottableRequestEvent` to request or remove slottable content\n * based on the current open state of the overlay. It ensures that the same state is not\n * dispatched twice in a row.\n *\n * @protected\n * @override\n */\n protected override requestSlottable(): void {\n // Do not dispatch the same state twice in a row.\n if (this.lastRequestSlottableState === this.open) {\n return;\n }\n\n // Force a reflow if the overlay is closing.\n if (!this.open) {\n document.body.offsetHeight;\n }\n\n /**\n * @ignore\n */\n // Dispatch a custom event to request or remove slottable content based on the open state.\n this.dispatchEvent(\n new SlottableRequestEvent(\n 'overlay-content',\n this.open ? {} : removeSlottableRequest\n )\n );\n\n // Update the last request slottable state.\n this.lastRequestSlottableState = this.open;\n }\n\n /**\n * Lifecycle method called before the component updates.\n *\n * This method handles various tasks before the component updates, such as setting an ID,\n * managing the open state, resolving the trigger element, and binding events.\n *\n * @override\n * @param {PropertyValues} changes - The properties that have changed.\n */\n override willUpdate(changes: PropertyValues): void {\n // Ensure the component has an ID attribute.\n if (!this.hasAttribute('id')) {\n this.setAttribute(\n 'id',\n `${this.tagName.toLowerCase()}-${randomID()}`\n );\n }\n\n // Manage the open state if the 'open' property has changed.\n if (changes.has('open') && (this.hasUpdated || this.open)) {\n this.manageOpen(changes.get('open'));\n }\n\n // Resolve the trigger element if the 'trigger' property has changed.\n if (changes.has('trigger')) {\n const [id, interaction] = this.trigger?.split('@') || [];\n this.elementResolver.selector = id ? `#${id}` : '';\n this.triggerInteraction = interaction as\n | 'click'\n | 'longpress'\n | 'hover'\n | undefined;\n }\n\n // Initialize oldTrigger to track the previous trigger element.\n let oldTrigger: HTMLElement | false | undefined = false;\n\n // Check if the element resolver has been updated.\n if (changes.has(elementResolverUpdatedSymbol)) {\n // Store the current trigger element.\n oldTrigger = this.triggerElement as HTMLElement;\n // Update the trigger element from the element resolver.\n this.triggerElement = this.elementResolver.element;\n }\n\n // Check if the 'triggerElement' property has changed.\n if (changes.has('triggerElement')) {\n // Store the old trigger element.\n oldTrigger = changes.get('triggerElement');\n }\n\n // If the trigger element has changed, bind the new events.\n if (oldTrigger !== false) {\n this.bindEvents();\n }\n }\n\n /**\n * Lifecycle method called after the component updates.\n *\n * This method handles various tasks after the component updates, such as updating the placement\n * attribute, resetting the overlay position, and clearing the overlay position based on the state.\n *\n * @override\n * @param {PropertyValues} changes - The properties that have changed.\n */\n protected override updated(changes: PropertyValues): void {\n // Call the base class method to handle any initial setup.\n super.updated(changes);\n\n // Check if the 'placement' property has changed.\n if (changes.has('placement')) {\n if (this.placement) {\n // Set the 'actual-placement' attribute on the dialog element.\n this.dialogEl.setAttribute('actual-placement', this.placement);\n } else {\n // Remove the 'actual-placement' attribute from the dialog element.\n this.dialogEl.removeAttribute('actual-placement');\n }\n\n // If the overlay is open and the 'placement' property has changed, reset the overlay position.\n if (this.open && typeof changes.get('placement') !== 'undefined') {\n this.placementController.resetOverlayPosition();\n }\n }\n\n // Check if the 'state' property has changed and the overlay is closed.\n if (\n changes.has('state') &&\n this.state === 'closed' &&\n typeof changes.get('state') !== 'undefined'\n ) {\n // Clear the overlay position.\n this.placementController.clearOverlayPosition();\n }\n }\n\n /**\n * Renders the content of the overlay.\n *\n * This method returns a template result containing a slot element. The slot element\n * listens for the `slotchange` event to manage the overlay's state.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the slot element.\n */\n protected renderContent(): TemplateResult {\n return html`\n <slot @slotchange=${this.handleSlotchange}></slot>\n `;\n }\n\n /**\n * Generates a style map for the dialog element.\n *\n * This method returns an object containing CSS custom properties for the dialog element.\n * The `--swc-overlay-open-count` custom property is set to the current open count of overlays.\n *\n * @private\n * @returns {StyleInfo} The style map for the dialog element.\n */\n private get dialogStyleMap(): StyleInfo {\n return {\n '--swc-overlay-open-count': Overlay.openCount.toString(),\n };\n }\n\n /**\n * Renders the dialog element for the overlay.\n *\n * This method returns a template result containing a dialog element. The dialog element\n * includes various attributes and event listeners to manage the overlay's state and behavior.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the dialog element.\n */\n protected renderDialog(): TemplateResult {\n /**\n * The `--swc-overlay-open-count` custom property is applied to mimic the single stack\n * nature of the top layer in browsers that do not yet support it.\n *\n * The value should always represent the total number of overlays that have ever been opened.\n * This value will be added to the `--swc-overlay-z-index-base` custom property, which can be\n * provided by a consuming developer. By default, `--swc-overlay-z-index-base` is set to 1000\n * to ensure that the overlay stacks above most other elements during fallback delivery.\n */\n return html`\n <dialog\n class=\"dialog\"\n part=\"dialog\"\n placement=${ifDefined(\n this.requiresPositioning\n ? this.placement || 'right'\n : undefined\n )}\n style=${styleMap(this.dialogStyleMap)}\n @close=${this.handleBrowserClose}\n @cancel=${this.handleBrowserClose}\n @beforetoggle=${this.handleBeforetoggle}\n ?is-visible=${this.state !== 'closed'}\n >\n ${this.renderContent()}\n </dialog>\n `;\n }\n\n /**\n * Renders the popover element for the overlay.\n *\n * This method returns a template result containing a div element styled as a popover.\n * The popover element includes various attributes and event listeners to manage the overlay's state and behavior.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the popover element.\n */\n protected renderPopover(): TemplateResult {\n /**\n * The `--swc-overlay-open-count` custom property is applied to mimic the single stack\n * nature of the top layer in browsers that do not yet support it.\n *\n * The value should always represent the total number of overlays that have ever been opened.\n * This value will be added to the `--swc-overlay-z-index-base` custom property, which can be\n * provided by a consuming developer. By default, `--swc-overlay-z-index-base` is set to 1000\n * to ensure that the overlay stacks above most other elements during fallback delivery.\n */\n return html`\n <div\n class=\"dialog\"\n part=\"dialog\"\n placement=${ifDefined(\n this.requiresPositioning\n ? this.placement || 'right'\n : undefined\n )}\n popover=${ifDefined(this.popoverValue)}\n style=${styleMap(this.dialogStyleMap)}\n @beforetoggle=${this.handleBeforetoggle}\n @close=${this.handleBrowserClose}\n ?is-visible=${this.state !== 'closed'}\n >\n ${this.renderContent()}\n </div>\n `;\n }\n\n /**\n * Renders the overlay component.\n *\n * This method returns a template result containing either a dialog or popover element\n * based on the overlay type. It also includes a slot for longpress descriptors.\n *\n * @override\n * @returns {TemplateResult} The template result containing the overlay content.\n */\n public override render(): TemplateResult {\n const isDialog = this.type === 'modal' || this.type === 'page';\n return html`\n ${isDialog ? this.renderDialog() : this.renderPopover()}\n <slot name=\"longpress-describedby-descriptor\"></slot>\n `;\n }\n\n /**\n * Lifecycle method called when the component is added to the DOM.\n *\n * This method sets up event listeners and binds events if the component has already updated.\n *\n * @override\n */\n override connectedCallback(): void {\n super.connectedCallback();\n\n // Add an event listener to handle the 'close' event and update the 'open' property.\n this.addEventListener('close', () => {\n this.open = false;\n });\n\n // Bind events if the component has already updated.\n if (this.hasUpdated) {\n this.bindEvents();\n }\n }\n\n /**\n * Lifecycle method called when the component is removed from the DOM.\n *\n * This method releases the description from the strategy and updates the 'open' property.\n *\n * @override\n */\n override disconnectedCallback(): void {\n // Release the description from the strategy.\n this.strategy?.releaseDescription();\n // Update the 'open' property to false.\n this.open = false;\n super.disconnectedCallback();\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2023 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport {\n html,\n PropertyValues,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport {\n property,\n query,\n queryAssignedElements,\n state,\n} from '@spectrum-web-components/base/src/decorators.js';\nimport {\n ElementResolutionController,\n elementResolverUpdatedSymbol,\n} from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';\nimport {\n ifDefined,\n StyleInfo,\n styleMap,\n} from '@spectrum-web-components/base/src/directives.js';\nimport { randomID } from '@spectrum-web-components/shared/src/random-id.js';\nimport type {\n OpenableElement,\n OverlayState,\n OverlayTypes,\n Placement,\n TriggerInteraction,\n} from './overlay-types.dev.js'\nimport { AbstractOverlay, nextFrame } from './AbstractOverlay.dev.js'\nimport { OverlayDialog } from './OverlayDialog.dev.js'\nimport { OverlayPopover } from './OverlayPopover.dev.js'\nimport { OverlayNoPopover } from './OverlayNoPopover.dev.js'\nimport { overlayStack } from './OverlayStack.dev.js'\nimport { VirtualTrigger } from './VirtualTrigger.dev.js'\nimport { PlacementController } from './PlacementController.dev.js'\nimport type { ClickController } from './ClickController.dev.js'\nimport type { HoverController } from './HoverController.dev.js'\nimport type { LongpressController } from './LongpressController.dev.js'\nexport { LONGPRESS_INSTRUCTIONS } from './LongpressController.dev.js'\nimport { strategies } from './strategies.dev.js'\nimport {\n removeSlottableRequest,\n SlottableRequestEvent,\n} from './slottable-request-event.dev.js'\n\nimport styles from './overlay.css.js';\n\nconst browserSupportsPopover = 'showPopover' in document.createElement('div');\n\n// Start the base class and add the popover or no-popover functionality\nlet ComputedOverlayBase = OverlayDialog(AbstractOverlay);\n\nif (browserSupportsPopover) {\n ComputedOverlayBase = OverlayPopover(ComputedOverlayBase);\n} else {\n ComputedOverlayBase = OverlayNoPopover(ComputedOverlayBase);\n}\n\n/**\n * @element sp-overlay\n *\n * @fires sp-opened - announces that an overlay has completed any entry animations\n * @fires sp-closed - announce that an overlay has compelted any exit animations\n * @fires slottable-request - requests to add or remove slottable content\n */\nexport class Overlay extends ComputedOverlayBase {\n static override styles = [styles];\n\n /**\n * An Overlay that is `delayed` will wait until a warm-up period of 1000ms\n * has completed before opening. Once the warm-up period has completed, all\n * subsequent Overlays will open immediately. When no Overlays are opened,\n * a cool-down period of 1000ms will begin. Once the cool-down has completed,\n * the next Overlay to be opened will be subject to the warm-up period if\n * provided that option.\n *\n * This behavior helps to manage the performance and user experience by\n * preventing multiple overlays from opening simultaneously and ensuring\n * a smooth transition between opening and closing overlays.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean })\n override get delayed(): boolean {\n return this.elements.at(-1)?.hasAttribute('delayed') || this._delayed;\n }\n\n override set delayed(delayed: boolean) {\n this._delayed = delayed;\n }\n\n private _delayed = false;\n\n /**\n * A reference to the dialog element within the overlay.\n * This element is expected to have `showPopover` and `hidePopover` methods.\n */\n @query('.dialog')\n override dialogEl!: HTMLDialogElement & {\n showPopover(): void;\n hidePopover(): void;\n };\n\n /**\n * Indicates whether the overlay is currently functional or not.\n *\n * When set to `true`, the overlay is disabled, and any active strategy is aborted.\n * The overlay will also close if it is currently open. When set to `false`, the\n * overlay will re-bind events and re-open if it was previously open.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean })\n override get disabled(): boolean {\n return this._disabled;\n }\n\n override set disabled(disabled: boolean) {\n this._disabled = disabled;\n if (disabled) {\n // Abort any active strategy and close the overlay if it is currently open\n this.strategy?.abort();\n this.wasOpen = this.open;\n this.open = false;\n } else {\n // Re-bind events and re-open the overlay if it was previously open\n this.bindEvents();\n this.open = this.open || this.wasOpen;\n this.wasOpen = false;\n }\n }\n\n private _disabled = false;\n\n /**\n * A query to gather all elements slotted into the default slot, excluding elements\n * with the slot name \"longpress-describedby-descriptor\".\n */\n @queryAssignedElements({\n flatten: true,\n selector: ':not([slot=\"longpress-describedby-descriptor\"], slot)',\n })\n override elements!: OpenableElement[];\n\n /**\n * A reference to the parent overlay that should be force-closed, if any.\n */\n public parentOverlayToForceClose?: Overlay;\n\n /**\n * Determines if the overlay has a non-virtual trigger element.\n *\n * @returns {boolean} `true` if the trigger element is not a virtual trigger, otherwise `false`.\n */\n private get hasNonVirtualTrigger(): boolean {\n return (\n !!this.triggerElement &&\n !(this.triggerElement instanceof VirtualTrigger)\n );\n }\n\n /**\n * The `offset` property accepts either a single number to define the offset of the\n * Overlay along the main axis from the trigger, or a 2-tuple to define the offset\n * along both the main axis and the cross axis. This option has no effect when there\n * is no trigger element.\n *\n * @type {number | [number, number]}\n * @default 0\n */\n @property({ type: Number })\n override offset: number | [number, number] = 0;\n\n /**\n * Provides an instance of the `PlacementController` for managing the positioning\n * of the overlay relative to its trigger element.\n *\n * If the `PlacementController` instance does not already exist, it is created and\n * assigned to the `_placementController` property.\n *\n * @protected\n * @returns {PlacementController} The `PlacementController` instance.\n */\n protected override get placementController(): PlacementController {\n if (!this._placementController) {\n this._placementController = new PlacementController(this);\n }\n return this._placementController;\n }\n\n /**\n * Indicates whether the Overlay is projected onto the \"top layer\" or not.\n *\n * When set to `true`, the overlay is open and visible. When set to `false`, the overlay is closed and hidden.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean, reflect: true })\n override get open(): boolean {\n return this._open;\n }\n\n override set open(open: boolean) {\n // Don't respond if the overlay is disabled.\n if (open && this.disabled) return;\n\n // Don't respond if the state is not changing.\n if (open === this.open) return;\n\n // Don't respond if the overlay is in the shadow state during a longpress.\n // The shadow state occurs when the first \"click\" would normally close the popover.\n if (this.strategy?.activelyOpening && !open) return;\n\n // Update the internal _open property.\n this._open = open;\n\n // Increment the open count if the overlay is opening.\n if (this.open) {\n Overlay.openCount += 1;\n }\n\n // Request an update to re-render the component if necessary.\n this.requestUpdate('open', !this.open);\n\n // Request slottable content if the overlay is opening.\n if (this.open) {\n this.requestSlottable();\n }\n }\n\n private _open = false;\n\n /**\n * Tracks the number of overlays that have been opened.\n *\n * This static property is used to manage the stacking context of multiple overlays.\n *\n * @type {number}\n * @default 1\n */\n static openCount = 1;\n\n /**\n * Instruct the Overlay where to place itself in relationship to the trigger element.\n *\n * @type {\"top\" | \"top-start\" | \"top-end\" | \"right\" | \"right-start\" | \"right-end\" | \"bottom\" | \"bottom-start\" | \"bottom-end\" | \"left\" | \"left-start\" | \"left-end\"}\n */\n @property()\n override placement?: Placement;\n\n /**\n * The state in which the last `request-slottable` event was dispatched.\n *\n * This property ensures that overlays do not dispatch the same state twice in a row.\n *\n * @type {boolean}\n * @default false\n */\n private lastRequestSlottableState = false;\n\n /**\n * Whether to pass focus to the overlay once opened, or\n * to the appropriate value based on the \"type\" of the overlay\n * when set to `\"auto\"`.\n *\n * @type {'true' | 'false' | 'auto'}\n * @default 'auto'\n */\n @property({ attribute: 'receives-focus' })\n override receivesFocus: 'true' | 'false' | 'auto' = 'auto';\n\n /**\n * A reference to the slot element within the overlay.\n *\n * This element is used to manage the content slotted into the overlay.\n *\n * @type {HTMLSlotElement}\n */\n @query('slot')\n slotEl!: HTMLSlotElement;\n\n /**\n * The current state of the overlay.\n *\n * This property reflects the current state of the overlay, such as 'opened' or 'closed'.\n * When the state changes, it triggers the appropriate actions and updates the component.\n *\n * @type {OverlayState}\n * @default 'closed'\n */\n @state()\n override get state(): OverlayState {\n return this._state;\n }\n\n override set state(state) {\n // Do not respond if the state is not changing.\n if (state === this.state) return;\n\n const oldState = this.state;\n\n this._state = state;\n\n // Complete the opening strategy if the state is 'opened' or 'closed'.\n if (this.state === 'opened' || this.state === 'closed') {\n this.strategy?.shouldCompleteOpen();\n }\n\n // Request an update to re-render the component if necessary.\n this.requestUpdate('state', oldState);\n }\n\n override _state: OverlayState = 'closed';\n\n /**\n * The interaction strategy for opening the overlay.\n * This can be a ClickController, HoverController, or LongpressController.\n */\n public strategy?: ClickController | HoverController | LongpressController;\n\n /**\n * The padding around the tip of the overlay.\n * This property defines the padding around the tip of the overlay, which can be used to adjust its positioning.\n *\n * @type {number}\n */\n @property({ type: Number, attribute: 'tip-padding' })\n tipPadding?: number;\n\n /**\n * An optional ID reference for the trigger element combined with the optional\n * interaction (click | hover | longpress) by which the overlay should open.\n * The format is `trigger@interaction`, e.g., `trigger@click` opens the overlay\n * when an element with the ID \"trigger\" is clicked.\n *\n * @type {string}\n */\n @property()\n trigger?: string;\n\n /**\n * An element reference for the trigger element that the overlay should relate to.\n * This property is not reflected as an attribute.\n *\n * @type {HTMLElement | VirtualTrigger | null}\n */\n @property({ attribute: false })\n override triggerElement: HTMLElement | VirtualTrigger | null = null;\n\n /**\n * The specific interaction to listen for on the `triggerElement` to open the overlay.\n * This property is not reflected as an attribute.\n *\n * @type {TriggerInteraction}\n */\n @property({ attribute: false })\n triggerInteraction?: TriggerInteraction;\n\n /**\n * Configures the open/close heuristics of the Overlay.\n *\n * @type {\"auto\" | \"hint\" | \"manual\" | \"modal\" | \"page\"}\n * @default \"auto\"\n */\n @property()\n override type: OverlayTypes = 'auto';\n\n /**\n * Tracks whether the overlay was previously open.\n * This is used to restore the open state when re-enabling the overlay.\n *\n * @type {boolean}\n * @default false\n */\n protected wasOpen = false;\n\n /**\n * Provides an instance of the `ElementResolutionController` for managing the element\n * that the overlay should be associated with. If the instance does not already exist,\n * it is created and assigned to the `_elementResolver` property.\n *\n * @protected\n * @returns {ElementResolutionController} The `ElementResolutionController` instance.\n */\n protected override get elementResolver(): ElementResolutionController {\n if (!this._elementResolver) {\n this._elementResolver = new ElementResolutionController(this);\n }\n\n return this._elementResolver;\n }\n\n /**\n * Determines if the overlay uses a dialog.\n * Returns `true` if the overlay type is \"modal\" or \"page\".\n *\n * @private\n * @returns {boolean} `true` if the overlay uses a dialog, otherwise `false`.\n */\n private get usesDialog(): boolean {\n return this.type === 'modal' || this.type === 'page';\n }\n\n /**\n * Determines the value for the popover attribute based on the overlay type.\n *\n * @private\n * @returns {'auto' | 'manual' | undefined} The popover value or undefined if not applicable.\n */\n private get popoverValue(): 'auto' | 'manual' | undefined {\n const hasPopoverAttribute = 'popover' in this;\n\n if (!hasPopoverAttribute) {\n return undefined;\n }\n\n switch (this.type) {\n case 'modal':\n case 'page':\n return undefined;\n case 'hint':\n return 'manual';\n default:\n return this.type;\n }\n }\n\n /**\n * Determines if the overlay requires positioning based on its type and state.\n *\n * @protected\n * @returns {boolean} True if the overlay requires positioning, otherwise false.\n */\n protected get requiresPositioning(): boolean {\n // Do not position \"page\" overlays as they should block the entire UI.\n if (this.type === 'page' || !this.open) return false;\n\n // Do not position content without a trigger element, as there is nothing to position it relative to.\n // Do not automatically position content unless it is a \"hint\".\n if (!this.triggerElement || (!this.placement && this.type !== 'hint'))\n return false;\n\n return true;\n }\n\n /**\n * Manages the positioning of the overlay relative to its trigger element.\n *\n * This method calculates the necessary parameters for positioning the overlay,\n * such as offset, placement, and tip padding, and then delegates the actual\n * positioning to the `PlacementController`.\n *\n * @protected\n * @override\n */\n protected override managePosition(): void {\n // Do not proceed if positioning is not required or the overlay is not open.\n if (!this.requiresPositioning || !this.open) return;\n\n const offset = this.offset || 0;\n\n const trigger = this.triggerElement as HTMLElement;\n\n const placement = (this.placement as Placement) || 'right';\n\n const tipPadding = this.tipPadding;\n\n this.placementController.placeOverlay(this.dialogEl, {\n offset,\n placement,\n tipPadding,\n trigger,\n type: this.type,\n });\n }\n\n /**\n * Manages the process of opening the popover.\n *\n * This method handles the necessary steps to open the popover, including managing delays,\n * ensuring the popover is in the DOM, making transitions, and applying focus.\n *\n * @protected\n * @override\n * @returns {Promise<void>} A promise that resolves when the popover has been fully opened.\n */\n protected override async managePopoverOpen(): Promise<void> {\n // Call the base class method to handle any initial setup.\n super.managePopoverOpen();\n\n const targetOpenState = this.open;\n\n // Ensure the open state has not changed before proceeding.\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Manage any delays before opening the popover.\n await this.manageDelay(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Ensure the popover is in the DOM before proceeding.\n await this.ensureOnDOM(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Make any necessary transitions for opening the popover.\n const focusEl = await this.makeTransition(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Apply focus to the appropriate element after opening the popover.\n await this.applyFocus(targetOpenState, focusEl);\n }\n\n /**\n * Applies focus to the appropriate element after the popover has been opened.\n *\n * This method handles the focus management for the overlay, ensuring that the correct\n * element receives focus based on the overlay's type and state.\n *\n * @protected\n * @override\n * @param {boolean} targetOpenState - The target open state of the overlay.\n * @param {HTMLElement | null} focusEl - The element to focus after opening the popover.\n * @returns {Promise<void>} A promise that resolves when the focus has been applied.\n */\n protected override async applyFocus(\n targetOpenState: boolean,\n focusEl: HTMLElement | null\n ): Promise<void> {\n // Do not move focus when explicitly told not to or when the overlay is a \"hint\".\n if (this.receivesFocus === 'false' || this.type === 'hint') {\n return;\n }\n\n // Wait for the next two animation frames to ensure the DOM is updated.\n await nextFrame();\n await nextFrame();\n\n // If the open state has changed during the delay, do not proceed.\n if (targetOpenState === this.open && !this.open) {\n // If the overlay is closing and the trigger element is still focused, return focus to the trigger element.\n if (\n this.hasNonVirtualTrigger &&\n this.contains((this.getRootNode() as Document).activeElement)\n ) {\n (this.triggerElement as HTMLElement).focus();\n }\n return;\n }\n\n // Apply focus to the specified focus element.\n focusEl?.focus();\n }\n\n /**\n * Returns focus to the trigger element if the overlay is closed.\n *\n * This method ensures that focus is returned to the trigger element when the overlay is closed,\n * unless the overlay is of type \"hint\" or the focus is already outside the overlay.\n *\n * @protected\n * @override\n */\n protected override returnFocus(): void {\n // Do not proceed if the overlay is open or if the overlay type is \"hint\".\n if (this.open || this.type === 'hint') return;\n\n /**\n * Retrieves the ancestors of the currently focused element.\n *\n * @returns {HTMLElement[]} An array of ancestor elements.\n */\n const getAncestors = (): HTMLElement[] => {\n const ancestors: HTMLElement[] = [];\n\n // eslint-disable-next-line @spectrum-web-components/document-active-element\n let currentNode = document.activeElement;\n\n // Traverse the shadow DOM to find the active element.\n while (currentNode?.shadowRoot?.activeElement) {\n currentNode = currentNode.shadowRoot.activeElement;\n }\n\n // Traverse the DOM tree to collect ancestor elements.\n while (currentNode) {\n const ancestor =\n currentNode.assignedSlot ||\n currentNode.parentElement ||\n (currentNode.getRootNode() as ShadowRoot)?.host;\n if (ancestor) {\n ancestors.push(ancestor as HTMLElement);\n }\n currentNode = ancestor;\n }\n return ancestors;\n };\n\n // Check if focus should be returned to the trigger element.\n if (\n this.receivesFocus !== 'false' &&\n !!(this.triggerElement as HTMLElement)?.focus &&\n (this.contains((this.getRootNode() as Document).activeElement) ||\n getAncestors().includes(this) ||\n // eslint-disable-next-line @spectrum-web-components/document-active-element\n document.activeElement === document.body)\n ) {\n // Return focus to the trigger element.\n (this.triggerElement as HTMLElement).focus();\n }\n }\n\n /**\n * Handles the focus out event to close the overlay if the focus moves outside of it.\n *\n * This method ensures that the overlay is closed when the focus moves to an element\n * outside of the overlay, unless the focus is moved to a related element.\n *\n * @private\n * @param {FocusEvent} event - The focus out event.\n */\n private closeOnFocusOut = (event: FocusEvent): void => {\n // If the related target (newly focused element) is not known, do nothing.\n if (!event.relatedTarget) {\n return;\n }\n\n // Create a custom event to query the relationship of the newly focused element.\n const relationEvent = new Event('overlay-relation-query', {\n bubbles: true,\n composed: true,\n });\n\n // Add an event listener to the related target to handle the custom event.\n event.relatedTarget.addEventListener(\n relationEvent.type,\n (event: Event) => {\n // Check if the newly focused element is within the overlay or its children\n const path = event.composedPath();\n const isWithinOverlay = path.some((el) => el === this);\n\n // Only close if focus moves outside the overlay and its children\n if (!isWithinOverlay) {\n this.open = false;\n }\n }\n );\n\n // Dispatch the custom event to the related target.\n event.relatedTarget.dispatchEvent(relationEvent);\n };\n\n /**\n * Manages the process of opening or closing the overlay.\n *\n * This method handles the necessary steps to open or close the overlay, including updating the state,\n * managing the overlay stack, and handling focus events.\n *\n * @protected\n * @param {boolean} oldOpen - The previous open state of the overlay.\n * @returns {Promise<void>} A promise that resolves when the overlay has been fully managed.\n */\n protected async manageOpen(oldOpen: boolean): Promise<void> {\n // Prevent entering the manage workflow if the overlay is not connected to the DOM.\n // The `.showPopover()` and `.showModal()` events will error on content that is not connected to the DOM.\n if (!this.isConnected && this.open) return;\n\n // Wait for the component to finish updating if it has not already done so.\n if (!this.hasUpdated) {\n await this.updateComplete;\n }\n\n if (this.open) {\n // Add the overlay to the overlay stack.\n overlayStack.add(this);\n\n if (this.willPreventClose) {\n // Add an event listener to handle the pointerup event and toggle the 'not-immediately-closable' class.\n document.addEventListener(\n 'pointerup',\n () => {\n this.dialogEl.classList.toggle(\n 'not-immediately-closable',\n false\n );\n this.willPreventClose = false;\n },\n { once: true }\n );\n this.dialogEl.classList.toggle(\n 'not-immediately-closable',\n true\n );\n }\n } else {\n if (oldOpen) {\n // Dispose of the overlay if it was previously open.\n this.dispose();\n }\n\n // Remove the overlay from the overlay stack.\n overlayStack.remove(this);\n }\n\n // Update the state of the overlay based on the open property.\n if (this.open && this.state !== 'opened') {\n this.state = 'opening';\n } else if (!this.open && this.state !== 'closed') {\n this.state = 'closing';\n }\n\n // Manage the dialog or popover based on the overlay type.\n if (this.usesDialog) {\n this.manageDialogOpen();\n } else {\n this.managePopoverOpen();\n }\n\n // Handle focus events for auto type overlays.\n if (this.type === 'auto') {\n const listenerRoot = this.getRootNode() as Document;\n if (this.open) {\n listenerRoot.addEventListener(\n 'focusout',\n this.closeOnFocusOut,\n { capture: true }\n );\n } else {\n listenerRoot.removeEventListener(\n 'focusout',\n this.closeOnFocusOut,\n { capture: true }\n );\n }\n }\n }\n\n /**\n * Binds event handling strategies to the overlay based on the specified trigger interaction.\n *\n * This method sets up the appropriate event handling strategy for the overlay, ensuring that\n * it responds correctly to user interactions such as clicks, hovers, or long presses.\n *\n * @protected\n */\n protected bindEvents(): void {\n // Abort any existing strategy to ensure a clean setup.\n this.strategy?.abort();\n this.strategy = undefined;\n\n // Return early if there is no non-virtual trigger element.\n if (!this.hasNonVirtualTrigger) return;\n\n // Return early if no trigger interaction is specified.\n if (!this.triggerInteraction) return;\n\n // Set up a new event handling strategy based on the specified trigger interaction.\n this.strategy = new strategies[this.triggerInteraction](\n this.triggerElement as HTMLElement,\n {\n overlay: this,\n }\n );\n }\n\n /**\n * Handles the `beforetoggle` event to manage the overlay's state.\n *\n * This method checks the new state of the event and calls `handleBrowserClose`\n * if the new state is not 'open'.\n *\n * @protected\n * @param {Event & { newState: string }} event - The `beforetoggle` event with the new state.\n */\n protected handleBeforetoggle(event: Event & { newState: string }): void {\n if (event.newState !== 'open') {\n this.handleBrowserClose(event);\n }\n }\n\n /**\n * Handles the browser's close event to manage the overlay's state.\n *\n * This method stops the propagation of the event and closes the overlay if it is not\n * actively opening. If the overlay is actively opening, it calls `manuallyKeepOpen`.\n *\n * @protected\n * @param {Event} event - The browser's close event.\n */\n protected handleBrowserClose(event: Event): void {\n event.stopPropagation();\n if (!this.strategy?.activelyOpening) {\n this.open = false;\n return;\n }\n this.manuallyKeepOpen();\n }\n\n /**\n * Manually keeps the overlay open.\n *\n * This method sets the overlay to open, allows placement updates, and manages the open state.\n *\n * @public\n * @override\n */\n public override manuallyKeepOpen(): void {\n this.open = true;\n this.placementController.allowPlacementUpdate = true;\n this.manageOpen(false);\n }\n\n /**\n * Handles the `slotchange` event to manage the overlay's state.\n *\n * This method checks if there are any elements in the slot. If there are no elements,\n * it releases the description from the strategy. If there are elements and the trigger\n * is non-virtual, it prepares the description for the trigger element.\n *\n * @protected\n */\n protected handleSlotchange(): void {\n if (!this.elements.length) {\n // Release the description if there are no elements in the slot.\n this.strategy?.releaseDescription();\n } else if (this.hasNonVirtualTrigger) {\n // Prepare the description for the trigger element if it is non-virtual.\n this.strategy?.prepareDescription(\n this.triggerElement as HTMLElement\n );\n }\n }\n\n /**\n * Determines whether the overlay should prevent closing.\n *\n * This method checks the `willPreventClose` flag and resets it to `false`.\n * It returns the value of the `willPreventClose` flag.\n *\n * @public\n * @returns {boolean} `true` if the overlay should prevent closing, otherwise `false`.\n */\n public shouldPreventClose(): boolean {\n const shouldPreventClose = this.willPreventClose;\n this.willPreventClose = false;\n return shouldPreventClose;\n }\n\n /**\n * Requests slottable content for the overlay.\n *\n * This method dispatches a `SlottableRequestEvent` to request or remove slottable content\n * based on the current open state of the overlay. It ensures that the same state is not\n * dispatched twice in a row.\n *\n * @protected\n * @override\n */\n protected override requestSlottable(): void {\n // Do not dispatch the same state twice in a row.\n if (this.lastRequestSlottableState === this.open) {\n return;\n }\n\n // Force a reflow if the overlay is closing.\n if (!this.open) {\n document.body.offsetHeight;\n }\n\n /**\n * @ignore\n */\n // Dispatch a custom event to request or remove slottable content based on the open state.\n this.dispatchEvent(\n new SlottableRequestEvent(\n 'overlay-content',\n this.open ? {} : removeSlottableRequest\n )\n );\n\n // Update the last request slottable state.\n this.lastRequestSlottableState = this.open;\n }\n\n /**\n * Lifecycle method called before the component updates.\n *\n * This method handles various tasks before the component updates, such as setting an ID,\n * managing the open state, resolving the trigger element, and binding events.\n *\n * @override\n * @param {PropertyValues} changes - The properties that have changed.\n */\n override willUpdate(changes: PropertyValues): void {\n // Ensure the component has an ID attribute.\n if (!this.hasAttribute('id')) {\n this.setAttribute(\n 'id',\n `${this.tagName.toLowerCase()}-${randomID()}`\n );\n }\n\n // Manage the open state if the 'open' property has changed.\n if (changes.has('open') && (this.hasUpdated || this.open)) {\n this.manageOpen(changes.get('open'));\n }\n\n // Resolve the trigger element if the 'trigger' property has changed.\n if (changes.has('trigger')) {\n const [id, interaction] = this.trigger?.split('@') || [];\n this.elementResolver.selector = id ? `#${id}` : '';\n this.triggerInteraction = interaction as\n | 'click'\n | 'longpress'\n | 'hover'\n | undefined;\n }\n\n // Initialize oldTrigger to track the previous trigger element.\n let oldTrigger: HTMLElement | false | undefined = false;\n\n // Check if the element resolver has been updated.\n if (changes.has(elementResolverUpdatedSymbol)) {\n // Store the current trigger element.\n oldTrigger = this.triggerElement as HTMLElement;\n // Update the trigger element from the element resolver.\n this.triggerElement = this.elementResolver.element;\n }\n\n // Check if the 'triggerElement' property has changed.\n if (changes.has('triggerElement')) {\n // Store the old trigger element.\n oldTrigger = changes.get('triggerElement');\n }\n\n // If the trigger element has changed, bind the new events.\n if (oldTrigger !== false) {\n this.bindEvents();\n }\n }\n\n /**\n * Lifecycle method called after the component updates.\n *\n * This method handles various tasks after the component updates, such as updating the placement\n * attribute, resetting the overlay position, and clearing the overlay position based on the state.\n *\n * @override\n * @param {PropertyValues} changes - The properties that have changed.\n */\n protected override updated(changes: PropertyValues): void {\n // Call the base class method to handle any initial setup.\n super.updated(changes);\n\n // Check if the 'placement' property has changed.\n if (changes.has('placement')) {\n if (this.placement) {\n // Set the 'actual-placement' attribute on the dialog element.\n this.dialogEl.setAttribute('actual-placement', this.placement);\n } else {\n // Remove the 'actual-placement' attribute from the dialog element.\n this.dialogEl.removeAttribute('actual-placement');\n }\n\n // If the overlay is open and the 'placement' property has changed, reset the overlay position.\n if (this.open && typeof changes.get('placement') !== 'undefined') {\n this.placementController.resetOverlayPosition();\n }\n }\n\n // Check if the 'state' property has changed and the overlay is closed.\n if (\n changes.has('state') &&\n this.state === 'closed' &&\n typeof changes.get('state') !== 'undefined'\n ) {\n // Clear the overlay position.\n this.placementController.clearOverlayPosition();\n }\n }\n\n /**\n * Renders the content of the overlay.\n *\n * This method returns a template result containing a slot element. The slot element\n * listens for the `slotchange` event to manage the overlay's state.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the slot element.\n */\n protected renderContent(): TemplateResult {\n return html`\n <slot @slotchange=${this.handleSlotchange}></slot>\n `;\n }\n\n /**\n * Generates a style map for the dialog element.\n *\n * This method returns an object containing CSS custom properties for the dialog element.\n * The `--swc-overlay-open-count` custom property is set to the current open count of overlays.\n *\n * @private\n * @returns {StyleInfo} The style map for the dialog element.\n */\n private get dialogStyleMap(): StyleInfo {\n return {\n '--swc-overlay-open-count': Overlay.openCount.toString(),\n };\n }\n\n /**\n * Renders the dialog element for the overlay.\n *\n * This method returns a template result containing a dialog element. The dialog element\n * includes various attributes and event listeners to manage the overlay's state and behavior.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the dialog element.\n */\n protected renderDialog(): TemplateResult {\n /**\n * The `--swc-overlay-open-count` custom property is applied to mimic the single stack\n * nature of the top layer in browsers that do not yet support it.\n *\n * The value should always represent the total number of overlays that have ever been opened.\n * This value will be added to the `--swc-overlay-z-index-base` custom property, which can be\n * provided by a consuming developer. By default, `--swc-overlay-z-index-base` is set to 1000\n * to ensure that the overlay stacks above most other elements during fallback delivery.\n */\n return html`\n <dialog\n class=\"dialog\"\n part=\"dialog\"\n placement=${ifDefined(\n this.requiresPositioning\n ? this.placement || 'right'\n : undefined\n )}\n style=${styleMap(this.dialogStyleMap)}\n @close=${this.handleBrowserClose}\n @cancel=${this.handleBrowserClose}\n @beforetoggle=${this.handleBeforetoggle}\n ?is-visible=${this.state !== 'closed'}\n >\n ${this.renderContent()}\n </dialog>\n `;\n }\n\n /**\n * Renders the popover element for the overlay.\n *\n * This method returns a template result containing a div element styled as a popover.\n * The popover element includes various attributes and event listeners to manage the overlay's state and behavior.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the popover element.\n */\n protected renderPopover(): TemplateResult {\n /**\n * The `--swc-overlay-open-count` custom property is applied to mimic the single stack\n * nature of the top layer in browsers that do not yet support it.\n *\n * The value should always represent the total number of overlays that have ever been opened.\n * This value will be added to the `--swc-overlay-z-index-base` custom property, which can be\n * provided by a consuming developer. By default, `--swc-overlay-z-index-base` is set to 1000\n * to ensure that the overlay stacks above most other elements during fallback delivery.\n */\n return html`\n <div\n class=\"dialog\"\n part=\"dialog\"\n placement=${ifDefined(\n this.requiresPositioning\n ? this.placement || 'right'\n : undefined\n )}\n popover=${ifDefined(this.popoverValue)}\n style=${styleMap(this.dialogStyleMap)}\n @beforetoggle=${this.handleBeforetoggle}\n @close=${this.handleBrowserClose}\n ?is-visible=${this.state !== 'closed'}\n >\n ${this.renderContent()}\n </div>\n `;\n }\n\n /**\n * Renders the overlay component.\n *\n * This method returns a template result containing either a dialog or popover element\n * based on the overlay type. It also includes a slot for longpress descriptors.\n *\n * @override\n * @returns {TemplateResult} The template result containing the overlay content.\n */\n public override render(): TemplateResult {\n const isDialog = this.type === 'modal' || this.type === 'page';\n return html`\n ${isDialog ? this.renderDialog() : this.renderPopover()}\n <slot name=\"longpress-describedby-descriptor\"></slot>\n `;\n }\n\n /**\n * Lifecycle method called when the component is added to the DOM.\n *\n * This method sets up event listeners and binds events if the component has already updated.\n *\n * @override\n */\n override connectedCallback(): void {\n super.connectedCallback();\n\n // Add an event listener to handle the 'close' event and update the 'open' property.\n this.addEventListener('close', () => {\n this.open = false;\n });\n\n // Bind events if the component has already updated.\n if (this.hasUpdated) {\n this.bindEvents();\n }\n }\n\n /**\n * Lifecycle method called when the component is removed from the DOM.\n *\n * This method releases the description from the strategy and updates the 'open' property.\n *\n * @override\n */\n override disconnectedCallback(): void {\n // Release the description from the strategy.\n this.strategy?.releaseDescription();\n // Update the 'open' property to false.\n this.open = false;\n super.disconnectedCallback();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["event", "state", "_a"]
|
|
7
7
|
}
|
package/src/Overlay.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"use strict";var b=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var r=(
|
|
1
|
+
"use strict";var b=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var r=(m,a,e,t)=>{for(var o=t>1?void 0:t?E(a,e):a,s=m.length-1,l;s>=0;s--)(l=m[s])&&(o=(t?l(a,e,o):l(o))||o);return t&&o&&b(a,e,o),o};import{html as h}from"@spectrum-web-components/base";import{property as n,query as g,queryAssignedElements as C,state as P}from"@spectrum-web-components/base/src/decorators.js";import{ElementResolutionController as w,elementResolverUpdatedSymbol as T}from"@spectrum-web-components/reactive-controllers/src/ElementResolution.js";import{ifDefined as u,styleMap as f}from"@spectrum-web-components/base/src/directives.js";import{randomID as S}from"@spectrum-web-components/shared/src/random-id.js";import{AbstractOverlay as R,nextFrame as v}from"./AbstractOverlay.js";import{OverlayDialog as O}from"./OverlayDialog.js";import{OverlayPopover as L}from"./OverlayPopover.js";import{OverlayNoPopover as M}from"./OverlayNoPopover.js";import{overlayStack as y}from"./OverlayStack.js";import{VirtualTrigger as H}from"./VirtualTrigger.js";import{PlacementController as $}from"./PlacementController.js";export{LONGPRESS_INSTRUCTIONS}from"./LongpressController.js";import{strategies as D}from"./strategies.js";import{removeSlottableRequest as q,SlottableRequestEvent as N}from"./slottable-request-event.js";import B from"./overlay.css.js";const F="showPopover"in document.createElement("div");let p=O(R);F?p=L(p):p=M(p);const i=class i extends p{constructor(){super(...arguments);this._delayed=!1;this._disabled=!1;this.offset=0;this._open=!1;this.lastRequestSlottableState=!1;this.receivesFocus="auto";this._state="closed";this.triggerElement=null;this.type="auto";this.wasOpen=!1;this.closeOnFocusOut=e=>{if(!e.relatedTarget)return;const t=new Event("overlay-relation-query",{bubbles:!0,composed:!0});e.relatedTarget.addEventListener(t.type,o=>{o.composedPath().some(d=>d===this)||(this.open=!1)}),e.relatedTarget.dispatchEvent(t)}}get delayed(){var e;return((e=this.elements.at(-1))==null?void 0:e.hasAttribute("delayed"))||this._delayed}set delayed(e){this._delayed=e}get disabled(){return this._disabled}set disabled(e){var t;this._disabled=e,e?((t=this.strategy)==null||t.abort(),this.wasOpen=this.open,this.open=!1):(this.bindEvents(),this.open=this.open||this.wasOpen,this.wasOpen=!1)}get hasNonVirtualTrigger(){return!!this.triggerElement&&!(this.triggerElement instanceof H)}get placementController(){return this._placementController||(this._placementController=new $(this)),this._placementController}get open(){return this._open}set open(e){var t;e&&this.disabled||e!==this.open&&((t=this.strategy)!=null&&t.activelyOpening&&!e||(this._open=e,this.open&&(i.openCount+=1),this.requestUpdate("open",!this.open),this.open&&this.requestSlottable()))}get state(){return this._state}set state(e){var o;if(e===this.state)return;const t=this.state;this._state=e,(this.state==="opened"||this.state==="closed")&&((o=this.strategy)==null||o.shouldCompleteOpen()),this.requestUpdate("state",t)}get elementResolver(){return this._elementResolver||(this._elementResolver=new w(this)),this._elementResolver}get usesDialog(){return this.type==="modal"||this.type==="page"}get popoverValue(){if("popover"in this)switch(this.type){case"modal":case"page":return;case"hint":return"manual";default:return this.type}}get requiresPositioning(){return!(this.type==="page"||!this.open||!this.triggerElement||!this.placement&&this.type!=="hint")}managePosition(){if(!this.requiresPositioning||!this.open)return;const e=this.offset||0,t=this.triggerElement,o=this.placement||"right",s=this.tipPadding;this.placementController.placeOverlay(this.dialogEl,{offset:e,placement:o,tipPadding:s,trigger:t,type:this.type})}async managePopoverOpen(){super.managePopoverOpen();const e=this.open;if(this.open!==e||(await this.manageDelay(e),this.open!==e)||(await this.ensureOnDOM(e),this.open!==e))return;const t=await this.makeTransition(e);this.open===e&&await this.applyFocus(e,t)}async applyFocus(e,t){if(!(this.receivesFocus==="false"||this.type==="hint")){if(await v(),await v(),e===this.open&&!this.open){this.hasNonVirtualTrigger&&this.contains(this.getRootNode().activeElement)&&this.triggerElement.focus();return}t==null||t.focus()}}returnFocus(){var t;if(this.open||this.type==="hint")return;const e=()=>{var l,d;const o=[];let s=document.activeElement;for(;(l=s==null?void 0:s.shadowRoot)!=null&&l.activeElement;)s=s.shadowRoot.activeElement;for(;s;){const c=s.assignedSlot||s.parentElement||((d=s.getRootNode())==null?void 0:d.host);c&&o.push(c),s=c}return o};this.receivesFocus!=="false"&&((t=this.triggerElement)!=null&&t.focus)&&(this.contains(this.getRootNode().activeElement)||e().includes(this)||document.activeElement===document.body)&&this.triggerElement.focus()}async manageOpen(e){if(!(!this.isConnected&&this.open)&&(this.hasUpdated||await this.updateComplete,this.open?(y.add(this),this.willPreventClose&&(document.addEventListener("pointerup",()=>{this.dialogEl.classList.toggle("not-immediately-closable",!1),this.willPreventClose=!1},{once:!0}),this.dialogEl.classList.toggle("not-immediately-closable",!0))):(e&&this.dispose(),y.remove(this)),this.open&&this.state!=="opened"?this.state="opening":!this.open&&this.state!=="closed"&&(this.state="closing"),this.usesDialog?this.manageDialogOpen():this.managePopoverOpen(),this.type==="auto")){const t=this.getRootNode();this.open?t.addEventListener("focusout",this.closeOnFocusOut,{capture:!0}):t.removeEventListener("focusout",this.closeOnFocusOut,{capture:!0})}}bindEvents(){var e;(e=this.strategy)==null||e.abort(),this.strategy=void 0,this.hasNonVirtualTrigger&&this.triggerInteraction&&(this.strategy=new D[this.triggerInteraction](this.triggerElement,{overlay:this}))}handleBeforetoggle(e){e.newState!=="open"&&this.handleBrowserClose(e)}handleBrowserClose(e){var t;if(e.stopPropagation(),!((t=this.strategy)!=null&&t.activelyOpening)){this.open=!1;return}this.manuallyKeepOpen()}manuallyKeepOpen(){this.open=!0,this.placementController.allowPlacementUpdate=!0,this.manageOpen(!1)}handleSlotchange(){var e,t;this.elements.length?this.hasNonVirtualTrigger&&((t=this.strategy)==null||t.prepareDescription(this.triggerElement)):(e=this.strategy)==null||e.releaseDescription()}shouldPreventClose(){const e=this.willPreventClose;return this.willPreventClose=!1,e}requestSlottable(){this.lastRequestSlottableState!==this.open&&(this.open||document.body.offsetHeight,this.dispatchEvent(new N("overlay-content",this.open?{}:q)),this.lastRequestSlottableState=this.open)}willUpdate(e){var o;if(this.hasAttribute("id")||this.setAttribute("id",`${this.tagName.toLowerCase()}-${S()}`),e.has("open")&&(this.hasUpdated||this.open)&&this.manageOpen(e.get("open")),e.has("trigger")){const[s,l]=((o=this.trigger)==null?void 0:o.split("@"))||[];this.elementResolver.selector=s?`#${s}`:"",this.triggerInteraction=l}let t=!1;e.has(T)&&(t=this.triggerElement,this.triggerElement=this.elementResolver.element),e.has("triggerElement")&&(t=e.get("triggerElement")),t!==!1&&this.bindEvents()}updated(e){super.updated(e),e.has("placement")&&(this.placement?this.dialogEl.setAttribute("actual-placement",this.placement):this.dialogEl.removeAttribute("actual-placement"),this.open&&typeof e.get("placement")!="undefined"&&this.placementController.resetOverlayPosition()),e.has("state")&&this.state==="closed"&&typeof e.get("state")!="undefined"&&this.placementController.clearOverlayPosition()}renderContent(){return h`
|
|
2
2
|
<slot @slotchange=${this.handleSlotchange}></slot>
|
|
3
|
-
`}get dialogStyleMap(){return{"--swc-overlay-open-count":i.openCount.toString()}}renderDialog(){return
|
|
3
|
+
`}get dialogStyleMap(){return{"--swc-overlay-open-count":i.openCount.toString()}}renderDialog(){return h`
|
|
4
4
|
<dialog
|
|
5
5
|
class="dialog"
|
|
6
6
|
part="dialog"
|
|
7
|
-
placement=${
|
|
7
|
+
placement=${u(this.requiresPositioning?this.placement||"right":void 0)}
|
|
8
8
|
style=${f(this.dialogStyleMap)}
|
|
9
9
|
@close=${this.handleBrowserClose}
|
|
10
10
|
@cancel=${this.handleBrowserClose}
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
>
|
|
14
14
|
${this.renderContent()}
|
|
15
15
|
</dialog>
|
|
16
|
-
`}renderPopover(){return
|
|
16
|
+
`}renderPopover(){return h`
|
|
17
17
|
<div
|
|
18
18
|
class="dialog"
|
|
19
19
|
part="dialog"
|
|
20
|
-
placement=${
|
|
21
|
-
popover=${
|
|
20
|
+
placement=${u(this.requiresPositioning?this.placement||"right":void 0)}
|
|
21
|
+
popover=${u(this.popoverValue)}
|
|
22
22
|
style=${f(this.dialogStyleMap)}
|
|
23
23
|
@beforetoggle=${this.handleBeforetoggle}
|
|
24
24
|
@close=${this.handleBrowserClose}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
>
|
|
27
27
|
${this.renderContent()}
|
|
28
28
|
</div>
|
|
29
|
-
`}render(){const e=this.type==="modal"||this.type==="page";return
|
|
29
|
+
`}render(){const e=this.type==="modal"||this.type==="page";return h`
|
|
30
30
|
${e?this.renderDialog():this.renderPopover()}
|
|
31
31
|
<slot name="longpress-describedby-descriptor"></slot>
|
|
32
32
|
`}connectedCallback(){super.connectedCallback(),this.addEventListener("close",()=>{this.open=!1}),this.hasUpdated&&this.bindEvents()}disconnectedCallback(){var e;(e=this.strategy)==null||e.releaseDescription(),this.open=!1,super.disconnectedCallback()}};i.styles=[B],i.openCount=1,r([n({type:Boolean})],i.prototype,"delayed",1),r([g(".dialog")],i.prototype,"dialogEl",2),r([n({type:Boolean})],i.prototype,"disabled",1),r([C({flatten:!0,selector:':not([slot="longpress-describedby-descriptor"], slot)'})],i.prototype,"elements",2),r([n({type:Number})],i.prototype,"offset",2),r([n({type:Boolean,reflect:!0})],i.prototype,"open",1),r([n()],i.prototype,"placement",2),r([n({attribute:"receives-focus"})],i.prototype,"receivesFocus",2),r([g("slot")],i.prototype,"slotEl",2),r([P()],i.prototype,"state",1),r([n({type:Number,attribute:"tip-padding"})],i.prototype,"tipPadding",2),r([n()],i.prototype,"trigger",2),r([n({attribute:!1})],i.prototype,"triggerElement",2),r([n({attribute:!1})],i.prototype,"triggerInteraction",2),r([n()],i.prototype,"type",2);export let Overlay=i;
|
package/src/Overlay.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["Overlay.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2023 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport {\n html,\n PropertyValues,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport {\n property,\n query,\n queryAssignedElements,\n state,\n} from '@spectrum-web-components/base/src/decorators.js';\nimport {\n ElementResolutionController,\n elementResolverUpdatedSymbol,\n} from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';\nimport {\n ifDefined,\n StyleInfo,\n styleMap,\n} from '@spectrum-web-components/base/src/directives.js';\nimport { randomID } from '@spectrum-web-components/shared/src/random-id.js';\nimport type {\n OpenableElement,\n OverlayState,\n OverlayTypes,\n Placement,\n TriggerInteraction,\n} from './overlay-types.js';\nimport { AbstractOverlay, nextFrame } from './AbstractOverlay.js';\nimport { OverlayDialog } from './OverlayDialog.js';\nimport { OverlayPopover } from './OverlayPopover.js';\nimport { OverlayNoPopover } from './OverlayNoPopover.js';\nimport { overlayStack } from './OverlayStack.js';\nimport { VirtualTrigger } from './VirtualTrigger.js';\nimport { PlacementController } from './PlacementController.js';\nimport type { ClickController } from './ClickController.js';\nimport type { HoverController } from './HoverController.js';\nimport type { LongpressController } from './LongpressController.js';\nexport { LONGPRESS_INSTRUCTIONS } from './LongpressController.js';\nimport { strategies } from './strategies.js';\nimport {\n removeSlottableRequest,\n SlottableRequestEvent,\n} from './slottable-request-event.js';\n\nimport styles from './overlay.css.js';\n\nconst browserSupportsPopover = 'showPopover' in document.createElement('div');\n\n// Start the base class and add the popover or no-popover functionality\nlet ComputedOverlayBase = OverlayDialog(AbstractOverlay);\n\nif (browserSupportsPopover) {\n ComputedOverlayBase = OverlayPopover(ComputedOverlayBase);\n} else {\n ComputedOverlayBase = OverlayNoPopover(ComputedOverlayBase);\n}\n\n/**\n * @element sp-overlay\n *\n * @fires sp-opened - announces that an overlay has completed any entry animations\n * @fires sp-closed - announce that an overlay has compelted any exit animations\n * @fires slottable-request - requests to add or remove slottable content\n */\nexport class Overlay extends ComputedOverlayBase {\n static override styles = [styles];\n\n /**\n * An Overlay that is `delayed` will wait until a warm-up period of 1000ms\n * has completed before opening. Once the warm-up period has completed, all\n * subsequent Overlays will open immediately. When no Overlays are opened,\n * a cool-down period of 1000ms will begin. Once the cool-down has completed,\n * the next Overlay to be opened will be subject to the warm-up period if\n * provided that option.\n *\n * This behavior helps to manage the performance and user experience by\n * preventing multiple overlays from opening simultaneously and ensuring\n * a smooth transition between opening and closing overlays.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean })\n override get delayed(): boolean {\n return this.elements.at(-1)?.hasAttribute('delayed') || this._delayed;\n }\n\n override set delayed(delayed: boolean) {\n this._delayed = delayed;\n }\n\n private _delayed = false;\n\n /**\n * A reference to the dialog element within the overlay.\n * This element is expected to have `showPopover` and `hidePopover` methods.\n */\n @query('.dialog')\n override dialogEl!: HTMLDialogElement & {\n showPopover(): void;\n hidePopover(): void;\n };\n\n /**\n * Indicates whether the overlay is currently functional or not.\n *\n * When set to `true`, the overlay is disabled, and any active strategy is aborted.\n * The overlay will also close if it is currently open. When set to `false`, the\n * overlay will re-bind events and re-open if it was previously open.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean })\n override get disabled(): boolean {\n return this._disabled;\n }\n\n override set disabled(disabled: boolean) {\n this._disabled = disabled;\n if (disabled) {\n // Abort any active strategy and close the overlay if it is currently open\n this.strategy?.abort();\n this.wasOpen = this.open;\n this.open = false;\n } else {\n // Re-bind events and re-open the overlay if it was previously open\n this.bindEvents();\n this.open = this.open || this.wasOpen;\n this.wasOpen = false;\n }\n }\n\n private _disabled = false;\n\n /**\n * A query to gather all elements slotted into the default slot, excluding elements\n * with the slot name \"longpress-describedby-descriptor\".\n */\n @queryAssignedElements({\n flatten: true,\n selector: ':not([slot=\"longpress-describedby-descriptor\"], slot)',\n })\n override elements!: OpenableElement[];\n\n /**\n * A reference to the parent overlay that should be force-closed, if any.\n */\n public parentOverlayToForceClose?: Overlay;\n\n /**\n * Determines if the overlay has a non-virtual trigger element.\n *\n * @returns {boolean} `true` if the trigger element is not a virtual trigger, otherwise `false`.\n */\n private get hasNonVirtualTrigger(): boolean {\n return (\n !!this.triggerElement &&\n !(this.triggerElement instanceof VirtualTrigger)\n );\n }\n\n /**\n * The `offset` property accepts either a single number to define the offset of the\n * Overlay along the main axis from the trigger, or a 2-tuple to define the offset\n * along both the main axis and the cross axis. This option has no effect when there\n * is no trigger element.\n *\n * @type {number | [number, number]}\n * @default 0\n */\n @property({ type: Number })\n override offset: number | [number, number] = 0;\n\n /**\n * Provides an instance of the `PlacementController` for managing the positioning\n * of the overlay relative to its trigger element.\n *\n * If the `PlacementController` instance does not already exist, it is created and\n * assigned to the `_placementController` property.\n *\n * @protected\n * @returns {PlacementController} The `PlacementController` instance.\n */\n protected override get placementController(): PlacementController {\n if (!this._placementController) {\n this._placementController = new PlacementController(this);\n }\n return this._placementController;\n }\n\n /**\n * Indicates whether the Overlay is projected onto the \"top layer\" or not.\n *\n * When set to `true`, the overlay is open and visible. When set to `false`, the overlay is closed and hidden.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean, reflect: true })\n override get open(): boolean {\n return this._open;\n }\n\n override set open(open: boolean) {\n // Don't respond if the overlay is disabled.\n if (open && this.disabled) return;\n\n // Don't respond if the state is not changing.\n if (open === this.open) return;\n\n // Don't respond if the overlay is in the shadow state during a longpress.\n // The shadow state occurs when the first \"click\" would normally close the popover.\n if (this.strategy?.activelyOpening && !open) return;\n\n // Update the internal _open property.\n this._open = open;\n\n // Increment the open count if the overlay is opening.\n if (this.open) {\n Overlay.openCount += 1;\n }\n\n // Request an update to re-render the component if necessary.\n this.requestUpdate('open', !this.open);\n\n // Request slottable content if the overlay is opening.\n if (this.open) {\n this.requestSlottable();\n }\n }\n\n private _open = false;\n\n /**\n * Tracks the number of overlays that have been opened.\n *\n * This static property is used to manage the stacking context of multiple overlays.\n *\n * @type {number}\n * @default 1\n */\n static openCount = 1;\n\n /**\n * Instruct the Overlay where to place itself in relationship to the trigger element.\n *\n * @type {\"top\" | \"top-start\" | \"top-end\" | \"right\" | \"right-start\" | \"right-end\" | \"bottom\" | \"bottom-start\" | \"bottom-end\" | \"left\" | \"left-start\" | \"left-end\"}\n */\n @property()\n override placement?: Placement;\n\n /**\n * The state in which the last `request-slottable` event was dispatched.\n *\n * This property ensures that overlays do not dispatch the same state twice in a row.\n *\n * @type {boolean}\n * @default false\n */\n private lastRequestSlottableState = false;\n\n /**\n * Whether to pass focus to the overlay once opened, or\n * to the appropriate value based on the \"type\" of the overlay\n * when set to `\"auto\"`.\n *\n * @type {'true' | 'false' | 'auto'}\n * @default 'auto'\n */\n @property({ attribute: 'receives-focus' })\n override receivesFocus: 'true' | 'false' | 'auto' = 'auto';\n\n /**\n * A reference to the slot element within the overlay.\n *\n * This element is used to manage the content slotted into the overlay.\n *\n * @type {HTMLSlotElement}\n */\n @query('slot')\n slotEl!: HTMLSlotElement;\n\n /**\n * The current state of the overlay.\n *\n * This property reflects the current state of the overlay, such as 'opened' or 'closed'.\n * When the state changes, it triggers the appropriate actions and updates the component.\n *\n * @type {OverlayState}\n * @default 'closed'\n */\n @state()\n override get state(): OverlayState {\n return this._state;\n }\n\n override set state(state) {\n // Do not respond if the state is not changing.\n if (state === this.state) return;\n\n const oldState = this.state;\n\n this._state = state;\n\n // Complete the opening strategy if the state is 'opened' or 'closed'.\n if (this.state === 'opened' || this.state === 'closed') {\n this.strategy?.shouldCompleteOpen();\n }\n\n // Request an update to re-render the component if necessary.\n this.requestUpdate('state', oldState);\n }\n\n override _state: OverlayState = 'closed';\n\n /**\n * The interaction strategy for opening the overlay.\n * This can be a ClickController, HoverController, or LongpressController.\n */\n public strategy?: ClickController | HoverController | LongpressController;\n\n /**\n * The padding around the tip of the overlay.\n * This property defines the padding around the tip of the overlay, which can be used to adjust its positioning.\n *\n * @type {number}\n */\n @property({ type: Number, attribute: 'tip-padding' })\n tipPadding?: number;\n\n /**\n * An optional ID reference for the trigger element combined with the optional\n * interaction (click | hover | longpress) by which the overlay should open.\n * The format is `trigger@interaction`, e.g., `trigger@click` opens the overlay\n * when an element with the ID \"trigger\" is clicked.\n *\n * @type {string}\n */\n @property()\n trigger?: string;\n\n /**\n * An element reference for the trigger element that the overlay should relate to.\n * This property is not reflected as an attribute.\n *\n * @type {HTMLElement | VirtualTrigger | null}\n */\n @property({ attribute: false })\n override triggerElement: HTMLElement | VirtualTrigger | null = null;\n\n /**\n * The specific interaction to listen for on the `triggerElement` to open the overlay.\n * This property is not reflected as an attribute.\n *\n * @type {TriggerInteraction}\n */\n @property({ attribute: false })\n triggerInteraction?: TriggerInteraction;\n\n /**\n * Configures the open/close heuristics of the Overlay.\n *\n * @type {\"auto\" | \"hint\" | \"manual\" | \"modal\" | \"page\"}\n * @default \"auto\"\n */\n @property()\n override type: OverlayTypes = 'auto';\n\n /**\n * Tracks whether the overlay was previously open.\n * This is used to restore the open state when re-enabling the overlay.\n *\n * @type {boolean}\n * @default false\n */\n protected wasOpen = false;\n\n /**\n * Provides an instance of the `ElementResolutionController` for managing the element\n * that the overlay should be associated with. If the instance does not already exist,\n * it is created and assigned to the `_elementResolver` property.\n *\n * @protected\n * @returns {ElementResolutionController} The `ElementResolutionController` instance.\n */\n protected override get elementResolver(): ElementResolutionController {\n if (!this._elementResolver) {\n this._elementResolver = new ElementResolutionController(this);\n }\n\n return this._elementResolver;\n }\n\n /**\n * Determines if the overlay uses a dialog.\n * Returns `true` if the overlay type is \"modal\" or \"page\".\n *\n * @private\n * @returns {boolean} `true` if the overlay uses a dialog, otherwise `false`.\n */\n private get usesDialog(): boolean {\n return this.type === 'modal' || this.type === 'page';\n }\n\n /**\n * Determines the value for the popover attribute based on the overlay type.\n *\n * @private\n * @returns {'auto' | 'manual' | undefined} The popover value or undefined if not applicable.\n */\n private get popoverValue(): 'auto' | 'manual' | undefined {\n const hasPopoverAttribute = 'popover' in this;\n\n if (!hasPopoverAttribute) {\n return undefined;\n }\n\n switch (this.type) {\n case 'modal':\n case 'page':\n return undefined;\n case 'hint':\n return 'manual';\n default:\n return this.type;\n }\n }\n\n /**\n * Determines if the overlay requires positioning based on its type and state.\n *\n * @protected\n * @returns {boolean} True if the overlay requires positioning, otherwise false.\n */\n protected get requiresPositioning(): boolean {\n // Do not position \"page\" overlays as they should block the entire UI.\n if (this.type === 'page' || !this.open) return false;\n\n // Do not position content without a trigger element, as there is nothing to position it relative to.\n // Do not automatically position content unless it is a \"hint\".\n if (!this.triggerElement || (!this.placement && this.type !== 'hint'))\n return false;\n\n return true;\n }\n\n /**\n * Manages the positioning of the overlay relative to its trigger element.\n *\n * This method calculates the necessary parameters for positioning the overlay,\n * such as offset, placement, and tip padding, and then delegates the actual\n * positioning to the `PlacementController`.\n *\n * @protected\n * @override\n */\n protected override managePosition(): void {\n // Do not proceed if positioning is not required or the overlay is not open.\n if (!this.requiresPositioning || !this.open) return;\n\n const offset = this.offset || 0;\n\n const trigger = this.triggerElement as HTMLElement;\n\n const placement = (this.placement as Placement) || 'right';\n\n const tipPadding = this.tipPadding;\n\n this.placementController.placeOverlay(this.dialogEl, {\n offset,\n placement,\n tipPadding,\n trigger,\n type: this.type,\n });\n }\n\n /**\n * Manages the process of opening the popover.\n *\n * This method handles the necessary steps to open the popover, including managing delays,\n * ensuring the popover is in the DOM, making transitions, and applying focus.\n *\n * @protected\n * @override\n * @returns {Promise<void>} A promise that resolves when the popover has been fully opened.\n */\n protected override async managePopoverOpen(): Promise<void> {\n // Call the base class method to handle any initial setup.\n super.managePopoverOpen();\n\n const targetOpenState = this.open;\n\n // Ensure the open state has not changed before proceeding.\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Manage any delays before opening the popover.\n await this.manageDelay(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Ensure the popover is in the DOM before proceeding.\n await this.ensureOnDOM(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Make any necessary transitions for opening the popover.\n const focusEl = await this.makeTransition(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Apply focus to the appropriate element after opening the popover.\n await this.applyFocus(targetOpenState, focusEl);\n }\n\n /**\n * Applies focus to the appropriate element after the popover has been opened.\n *\n * This method handles the focus management for the overlay, ensuring that the correct\n * element receives focus based on the overlay's type and state.\n *\n * @protected\n * @override\n * @param {boolean} targetOpenState - The target open state of the overlay.\n * @param {HTMLElement | null} focusEl - The element to focus after opening the popover.\n * @returns {Promise<void>} A promise that resolves when the focus has been applied.\n */\n protected override async applyFocus(\n targetOpenState: boolean,\n focusEl: HTMLElement | null\n ): Promise<void> {\n // Do not move focus when explicitly told not to or when the overlay is a \"hint\".\n if (this.receivesFocus === 'false' || this.type === 'hint') {\n return;\n }\n\n // Wait for the next two animation frames to ensure the DOM is updated.\n await nextFrame();\n await nextFrame();\n\n // If the open state has changed during the delay, do not proceed.\n if (targetOpenState === this.open && !this.open) {\n // If the overlay is closing and the trigger element is still focused, return focus to the trigger element.\n if (\n this.hasNonVirtualTrigger &&\n this.contains((this.getRootNode() as Document).activeElement)\n ) {\n (this.triggerElement as HTMLElement).focus();\n }\n return;\n }\n\n // Apply focus to the specified focus element.\n focusEl?.focus();\n }\n\n /**\n * Returns focus to the trigger element if the overlay is closed.\n *\n * This method ensures that focus is returned to the trigger element when the overlay is closed,\n * unless the overlay is of type \"hint\" or the focus is already outside the overlay.\n *\n * @protected\n * @override\n */\n protected override returnFocus(): void {\n // Do not proceed if the overlay is open or if the overlay type is \"hint\".\n if (this.open || this.type === 'hint') return;\n\n /**\n * Retrieves the ancestors of the currently focused element.\n *\n * @returns {HTMLElement[]} An array of ancestor elements.\n */\n const getAncestors = (): HTMLElement[] => {\n const ancestors: HTMLElement[] = [];\n\n // eslint-disable-next-line @spectrum-web-components/document-active-element\n let currentNode = document.activeElement;\n\n // Traverse the shadow DOM to find the active element.\n while (currentNode?.shadowRoot?.activeElement) {\n currentNode = currentNode.shadowRoot.activeElement;\n }\n\n // Traverse the DOM tree to collect ancestor elements.\n while (currentNode) {\n const ancestor =\n currentNode.assignedSlot ||\n currentNode.parentElement ||\n (currentNode.getRootNode() as ShadowRoot)?.host;\n if (ancestor) {\n ancestors.push(ancestor as HTMLElement);\n }\n currentNode = ancestor;\n }\n return ancestors;\n };\n\n // Check if focus should be returned to the trigger element.\n if (\n this.receivesFocus !== 'false' &&\n !!(this.triggerElement as HTMLElement)?.focus &&\n (this.contains((this.getRootNode() as Document).activeElement) ||\n getAncestors().includes(this) ||\n // eslint-disable-next-line @spectrum-web-components/document-active-element\n document.activeElement === document.body)\n ) {\n // Return focus to the trigger element.\n (this.triggerElement as HTMLElement).focus();\n }\n }\n\n /**\n * Handles the focus out event to close the overlay if the focus moves outside of it.\n *\n * This method ensures that the overlay is closed when the focus moves to an element\n * outside of the overlay, unless the focus is moved to a related element.\n *\n * @private\n * @param {FocusEvent} event - The focus out event.\n */\n private closeOnFocusOut = (event: FocusEvent): void => {\n // If the related target (newly focused element) is not known, do nothing.\n if (!event.relatedTarget) {\n return;\n }\n\n // Create a custom event to query the relationship of the newly focused element.\n const relationEvent = new Event('overlay-relation-query', {\n bubbles: true,\n composed: true,\n });\n\n // Add an event listener to the related target to handle the custom event.\n event.relatedTarget.addEventListener(\n relationEvent.type,\n (event: Event) => {\n // If the newly focused element is not within the overlay, close the overlay.\n if (!event.composedPath().includes(this)) {\n this.open = false;\n }\n }\n );\n\n // Dispatch the custom event to the related target.\n event.relatedTarget.dispatchEvent(relationEvent);\n };\n\n /**\n * Manages the process of opening or closing the overlay.\n *\n * This method handles the necessary steps to open or close the overlay, including updating the state,\n * managing the overlay stack, and handling focus events.\n *\n * @protected\n * @param {boolean} oldOpen - The previous open state of the overlay.\n * @returns {Promise<void>} A promise that resolves when the overlay has been fully managed.\n */\n protected async manageOpen(oldOpen: boolean): Promise<void> {\n // Prevent entering the manage workflow if the overlay is not connected to the DOM.\n // The `.showPopover()` and `.showModal()` events will error on content that is not connected to the DOM.\n if (!this.isConnected && this.open) return;\n\n // Wait for the component to finish updating if it has not already done so.\n if (!this.hasUpdated) {\n await this.updateComplete;\n }\n\n if (this.open) {\n // Add the overlay to the overlay stack.\n overlayStack.add(this);\n\n if (this.willPreventClose) {\n // Add an event listener to handle the pointerup event and toggle the 'not-immediately-closable' class.\n document.addEventListener(\n 'pointerup',\n () => {\n this.dialogEl.classList.toggle(\n 'not-immediately-closable',\n false\n );\n this.willPreventClose = false;\n },\n { once: true }\n );\n this.dialogEl.classList.toggle(\n 'not-immediately-closable',\n true\n );\n }\n } else {\n if (oldOpen) {\n // Dispose of the overlay if it was previously open.\n this.dispose();\n }\n\n // Remove the overlay from the overlay stack.\n overlayStack.remove(this);\n }\n\n // Update the state of the overlay based on the open property.\n if (this.open && this.state !== 'opened') {\n this.state = 'opening';\n } else if (!this.open && this.state !== 'closed') {\n this.state = 'closing';\n }\n\n // Manage the dialog or popover based on the overlay type.\n if (this.usesDialog) {\n this.manageDialogOpen();\n } else {\n this.managePopoverOpen();\n }\n\n // Handle focus events for auto type overlays.\n if (this.type === 'auto') {\n const listenerRoot = this.getRootNode() as Document;\n if (this.open) {\n listenerRoot.addEventListener(\n 'focusout',\n this.closeOnFocusOut,\n { capture: true }\n );\n } else {\n listenerRoot.removeEventListener(\n 'focusout',\n this.closeOnFocusOut,\n { capture: true }\n );\n }\n }\n }\n\n /**\n * Binds event handling strategies to the overlay based on the specified trigger interaction.\n *\n * This method sets up the appropriate event handling strategy for the overlay, ensuring that\n * it responds correctly to user interactions such as clicks, hovers, or long presses.\n *\n * @protected\n */\n protected bindEvents(): void {\n // Abort any existing strategy to ensure a clean setup.\n this.strategy?.abort();\n this.strategy = undefined;\n\n // Return early if there is no non-virtual trigger element.\n if (!this.hasNonVirtualTrigger) return;\n\n // Return early if no trigger interaction is specified.\n if (!this.triggerInteraction) return;\n\n // Set up a new event handling strategy based on the specified trigger interaction.\n this.strategy = new strategies[this.triggerInteraction](\n this.triggerElement as HTMLElement,\n {\n overlay: this,\n }\n );\n }\n\n /**\n * Handles the `beforetoggle` event to manage the overlay's state.\n *\n * This method checks the new state of the event and calls `handleBrowserClose`\n * if the new state is not 'open'.\n *\n * @protected\n * @param {Event & { newState: string }} event - The `beforetoggle` event with the new state.\n */\n protected handleBeforetoggle(event: Event & { newState: string }): void {\n if (event.newState !== 'open') {\n this.handleBrowserClose(event);\n }\n }\n\n /**\n * Handles the browser's close event to manage the overlay's state.\n *\n * This method stops the propagation of the event and closes the overlay if it is not\n * actively opening. If the overlay is actively opening, it calls `manuallyKeepOpen`.\n *\n * @protected\n * @param {Event} event - The browser's close event.\n */\n protected handleBrowserClose(event: Event): void {\n event.stopPropagation();\n if (!this.strategy?.activelyOpening) {\n this.open = false;\n return;\n }\n this.manuallyKeepOpen();\n }\n\n /**\n * Manually keeps the overlay open.\n *\n * This method sets the overlay to open, allows placement updates, and manages the open state.\n *\n * @public\n * @override\n */\n public override manuallyKeepOpen(): void {\n this.open = true;\n this.placementController.allowPlacementUpdate = true;\n this.manageOpen(false);\n }\n\n /**\n * Handles the `slotchange` event to manage the overlay's state.\n *\n * This method checks if there are any elements in the slot. If there are no elements,\n * it releases the description from the strategy. If there are elements and the trigger\n * is non-virtual, it prepares the description for the trigger element.\n *\n * @protected\n */\n protected handleSlotchange(): void {\n if (!this.elements.length) {\n // Release the description if there are no elements in the slot.\n this.strategy?.releaseDescription();\n } else if (this.hasNonVirtualTrigger) {\n // Prepare the description for the trigger element if it is non-virtual.\n this.strategy?.prepareDescription(\n this.triggerElement as HTMLElement\n );\n }\n }\n\n /**\n * Determines whether the overlay should prevent closing.\n *\n * This method checks the `willPreventClose` flag and resets it to `false`.\n * It returns the value of the `willPreventClose` flag.\n *\n * @public\n * @returns {boolean} `true` if the overlay should prevent closing, otherwise `false`.\n */\n public shouldPreventClose(): boolean {\n const shouldPreventClose = this.willPreventClose;\n this.willPreventClose = false;\n return shouldPreventClose;\n }\n\n /**\n * Requests slottable content for the overlay.\n *\n * This method dispatches a `SlottableRequestEvent` to request or remove slottable content\n * based on the current open state of the overlay. It ensures that the same state is not\n * dispatched twice in a row.\n *\n * @protected\n * @override\n */\n protected override requestSlottable(): void {\n // Do not dispatch the same state twice in a row.\n if (this.lastRequestSlottableState === this.open) {\n return;\n }\n\n // Force a reflow if the overlay is closing.\n if (!this.open) {\n document.body.offsetHeight;\n }\n\n /**\n * @ignore\n */\n // Dispatch a custom event to request or remove slottable content based on the open state.\n this.dispatchEvent(\n new SlottableRequestEvent(\n 'overlay-content',\n this.open ? {} : removeSlottableRequest\n )\n );\n\n // Update the last request slottable state.\n this.lastRequestSlottableState = this.open;\n }\n\n /**\n * Lifecycle method called before the component updates.\n *\n * This method handles various tasks before the component updates, such as setting an ID,\n * managing the open state, resolving the trigger element, and binding events.\n *\n * @override\n * @param {PropertyValues} changes - The properties that have changed.\n */\n override willUpdate(changes: PropertyValues): void {\n // Ensure the component has an ID attribute.\n if (!this.hasAttribute('id')) {\n this.setAttribute(\n 'id',\n `${this.tagName.toLowerCase()}-${randomID()}`\n );\n }\n\n // Manage the open state if the 'open' property has changed.\n if (changes.has('open') && (this.hasUpdated || this.open)) {\n this.manageOpen(changes.get('open'));\n }\n\n // Resolve the trigger element if the 'trigger' property has changed.\n if (changes.has('trigger')) {\n const [id, interaction] = this.trigger?.split('@') || [];\n this.elementResolver.selector = id ? `#${id}` : '';\n this.triggerInteraction = interaction as\n | 'click'\n | 'longpress'\n | 'hover'\n | undefined;\n }\n\n // Initialize oldTrigger to track the previous trigger element.\n let oldTrigger: HTMLElement | false | undefined = false;\n\n // Check if the element resolver has been updated.\n if (changes.has(elementResolverUpdatedSymbol)) {\n // Store the current trigger element.\n oldTrigger = this.triggerElement as HTMLElement;\n // Update the trigger element from the element resolver.\n this.triggerElement = this.elementResolver.element;\n }\n\n // Check if the 'triggerElement' property has changed.\n if (changes.has('triggerElement')) {\n // Store the old trigger element.\n oldTrigger = changes.get('triggerElement');\n }\n\n // If the trigger element has changed, bind the new events.\n if (oldTrigger !== false) {\n this.bindEvents();\n }\n }\n\n /**\n * Lifecycle method called after the component updates.\n *\n * This method handles various tasks after the component updates, such as updating the placement\n * attribute, resetting the overlay position, and clearing the overlay position based on the state.\n *\n * @override\n * @param {PropertyValues} changes - The properties that have changed.\n */\n protected override updated(changes: PropertyValues): void {\n // Call the base class method to handle any initial setup.\n super.updated(changes);\n\n // Check if the 'placement' property has changed.\n if (changes.has('placement')) {\n if (this.placement) {\n // Set the 'actual-placement' attribute on the dialog element.\n this.dialogEl.setAttribute('actual-placement', this.placement);\n } else {\n // Remove the 'actual-placement' attribute from the dialog element.\n this.dialogEl.removeAttribute('actual-placement');\n }\n\n // If the overlay is open and the 'placement' property has changed, reset the overlay position.\n if (this.open && typeof changes.get('placement') !== 'undefined') {\n this.placementController.resetOverlayPosition();\n }\n }\n\n // Check if the 'state' property has changed and the overlay is closed.\n if (\n changes.has('state') &&\n this.state === 'closed' &&\n typeof changes.get('state') !== 'undefined'\n ) {\n // Clear the overlay position.\n this.placementController.clearOverlayPosition();\n }\n }\n\n /**\n * Renders the content of the overlay.\n *\n * This method returns a template result containing a slot element. The slot element\n * listens for the `slotchange` event to manage the overlay's state.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the slot element.\n */\n protected renderContent(): TemplateResult {\n return html`\n <slot @slotchange=${this.handleSlotchange}></slot>\n `;\n }\n\n /**\n * Generates a style map for the dialog element.\n *\n * This method returns an object containing CSS custom properties for the dialog element.\n * The `--swc-overlay-open-count` custom property is set to the current open count of overlays.\n *\n * @private\n * @returns {StyleInfo} The style map for the dialog element.\n */\n private get dialogStyleMap(): StyleInfo {\n return {\n '--swc-overlay-open-count': Overlay.openCount.toString(),\n };\n }\n\n /**\n * Renders the dialog element for the overlay.\n *\n * This method returns a template result containing a dialog element. The dialog element\n * includes various attributes and event listeners to manage the overlay's state and behavior.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the dialog element.\n */\n protected renderDialog(): TemplateResult {\n /**\n * The `--swc-overlay-open-count` custom property is applied to mimic the single stack\n * nature of the top layer in browsers that do not yet support it.\n *\n * The value should always represent the total number of overlays that have ever been opened.\n * This value will be added to the `--swc-overlay-z-index-base` custom property, which can be\n * provided by a consuming developer. By default, `--swc-overlay-z-index-base` is set to 1000\n * to ensure that the overlay stacks above most other elements during fallback delivery.\n */\n return html`\n <dialog\n class=\"dialog\"\n part=\"dialog\"\n placement=${ifDefined(\n this.requiresPositioning\n ? this.placement || 'right'\n : undefined\n )}\n style=${styleMap(this.dialogStyleMap)}\n @close=${this.handleBrowserClose}\n @cancel=${this.handleBrowserClose}\n @beforetoggle=${this.handleBeforetoggle}\n ?is-visible=${this.state !== 'closed'}\n >\n ${this.renderContent()}\n </dialog>\n `;\n }\n\n /**\n * Renders the popover element for the overlay.\n *\n * This method returns a template result containing a div element styled as a popover.\n * The popover element includes various attributes and event listeners to manage the overlay's state and behavior.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the popover element.\n */\n protected renderPopover(): TemplateResult {\n /**\n * The `--swc-overlay-open-count` custom property is applied to mimic the single stack\n * nature of the top layer in browsers that do not yet support it.\n *\n * The value should always represent the total number of overlays that have ever been opened.\n * This value will be added to the `--swc-overlay-z-index-base` custom property, which can be\n * provided by a consuming developer. By default, `--swc-overlay-z-index-base` is set to 1000\n * to ensure that the overlay stacks above most other elements during fallback delivery.\n */\n return html`\n <div\n class=\"dialog\"\n part=\"dialog\"\n placement=${ifDefined(\n this.requiresPositioning\n ? this.placement || 'right'\n : undefined\n )}\n popover=${ifDefined(this.popoverValue)}\n style=${styleMap(this.dialogStyleMap)}\n @beforetoggle=${this.handleBeforetoggle}\n @close=${this.handleBrowserClose}\n ?is-visible=${this.state !== 'closed'}\n >\n ${this.renderContent()}\n </div>\n `;\n }\n\n /**\n * Renders the overlay component.\n *\n * This method returns a template result containing either a dialog or popover element\n * based on the overlay type. It also includes a slot for longpress descriptors.\n *\n * @override\n * @returns {TemplateResult} The template result containing the overlay content.\n */\n public override render(): TemplateResult {\n const isDialog = this.type === 'modal' || this.type === 'page';\n return html`\n ${isDialog ? this.renderDialog() : this.renderPopover()}\n <slot name=\"longpress-describedby-descriptor\"></slot>\n `;\n }\n\n /**\n * Lifecycle method called when the component is added to the DOM.\n *\n * This method sets up event listeners and binds events if the component has already updated.\n *\n * @override\n */\n override connectedCallback(): void {\n super.connectedCallback();\n\n // Add an event listener to handle the 'close' event and update the 'open' property.\n this.addEventListener('close', () => {\n this.open = false;\n });\n\n // Bind events if the component has already updated.\n if (this.hasUpdated) {\n this.bindEvents();\n }\n }\n\n /**\n * Lifecycle method called when the component is removed from the DOM.\n *\n * This method releases the description from the strategy and updates the 'open' property.\n *\n * @override\n */\n override disconnectedCallback(): void {\n // Release the description from the strategy.\n this.strategy?.releaseDescription();\n // Update the 'open' property to false.\n this.open = false;\n super.disconnectedCallback();\n }\n}\n"],
|
|
5
|
-
"mappings": "qNAWA,OACI,QAAAA,MAGG,gCACP,OACI,YAAAC,EACA,SAAAC,EACA,yBAAAC,EACA,SAAAC,MACG,kDACP,OACI,+BAAAC,EACA,gCAAAC,MACG,yEACP,OACI,aAAAC,EAEA,YAAAC,MACG,kDACP,OAAS,YAAAC,MAAgB,mDAQzB,OAAS,mBAAAC,EAAiB,aAAAC,MAAiB,uBAC3C,OAAS,iBAAAC,MAAqB,qBAC9B,OAAS,kBAAAC,MAAsB,sBAC/B,OAAS,oBAAAC,MAAwB,wBACjC,OAAS,gBAAAC,MAAoB,oBAC7B,OAAS,kBAAAC,MAAsB,sBAC/B,OAAS,uBAAAC,MAA2B,2BAIpC,OAAS,2BAA8B,2BACvC,OAAS,cAAAC,MAAkB,kBAC3B,OACI,0BAAAC,EACA,yBAAAC,MACG,+BAEP,OAAOC,MAAY,mBAEnB,MAAMC,EAAyB,gBAAiB,SAAS,cAAc,KAAK,EAG5E,IAAIC,EAAsBX,EAAcF,CAAe,EAEnDY,EACAC,EAAsBV,EAAeU,CAAmB,EAExDA,EAAsBT,EAAiBS,CAAmB,EAUvD,MAAMC,EAAN,MAAMA,UAAgBD,CAAoB,CAA1C,kCA2BH,KAAQ,SAAW,GA0CnB,KAAQ,UAAY,GAuCpB,KAAS,OAAoC,EA4D7C,KAAQ,MAAQ,GA4BhB,KAAQ,0BAA4B,GAWpC,KAAS,cAA2C,OA2CpD,KAAS,OAAuB,SAmChC,KAAS,eAAsD,KAkB/D,KAAS,KAAqB,OAS9B,KAAU,QAAU,GA+PpB,KAAQ,gBAAmBE,GAA4B,CAEnD,GAAI,CAACA,EAAM,cACP,OAIJ,MAAMC,EAAgB,IAAI,MAAM,yBAA0B,CACtD,QAAS,GACT,SAAU,EACd,CAAC,EAGDD,EAAM,cAAc,iBAChBC,EAAc,KACbD,GAAiB,
|
|
6
|
-
"names": ["html", "property", "query", "queryAssignedElements", "state", "ElementResolutionController", "elementResolverUpdatedSymbol", "ifDefined", "styleMap", "randomID", "AbstractOverlay", "nextFrame", "OverlayDialog", "OverlayPopover", "OverlayNoPopover", "overlayStack", "VirtualTrigger", "PlacementController", "strategies", "removeSlottableRequest", "SlottableRequestEvent", "styles", "browserSupportsPopover", "ComputedOverlayBase", "_Overlay", "event", "relationEvent", "_a", "delayed", "disabled", "open", "oldState", "offset", "trigger", "placement", "tipPadding", "targetOpenState", "focusEl", "getAncestors", "_b", "ancestors", "currentNode", "ancestor", "oldOpen", "listenerRoot", "shouldPreventClose", "changes", "id", "interaction", "oldTrigger", "isDialog", "__decorateClass"]
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2023 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport {\n html,\n PropertyValues,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport {\n property,\n query,\n queryAssignedElements,\n state,\n} from '@spectrum-web-components/base/src/decorators.js';\nimport {\n ElementResolutionController,\n elementResolverUpdatedSymbol,\n} from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';\nimport {\n ifDefined,\n StyleInfo,\n styleMap,\n} from '@spectrum-web-components/base/src/directives.js';\nimport { randomID } from '@spectrum-web-components/shared/src/random-id.js';\nimport type {\n OpenableElement,\n OverlayState,\n OverlayTypes,\n Placement,\n TriggerInteraction,\n} from './overlay-types.js';\nimport { AbstractOverlay, nextFrame } from './AbstractOverlay.js';\nimport { OverlayDialog } from './OverlayDialog.js';\nimport { OverlayPopover } from './OverlayPopover.js';\nimport { OverlayNoPopover } from './OverlayNoPopover.js';\nimport { overlayStack } from './OverlayStack.js';\nimport { VirtualTrigger } from './VirtualTrigger.js';\nimport { PlacementController } from './PlacementController.js';\nimport type { ClickController } from './ClickController.js';\nimport type { HoverController } from './HoverController.js';\nimport type { LongpressController } from './LongpressController.js';\nexport { LONGPRESS_INSTRUCTIONS } from './LongpressController.js';\nimport { strategies } from './strategies.js';\nimport {\n removeSlottableRequest,\n SlottableRequestEvent,\n} from './slottable-request-event.js';\n\nimport styles from './overlay.css.js';\n\nconst browserSupportsPopover = 'showPopover' in document.createElement('div');\n\n// Start the base class and add the popover or no-popover functionality\nlet ComputedOverlayBase = OverlayDialog(AbstractOverlay);\n\nif (browserSupportsPopover) {\n ComputedOverlayBase = OverlayPopover(ComputedOverlayBase);\n} else {\n ComputedOverlayBase = OverlayNoPopover(ComputedOverlayBase);\n}\n\n/**\n * @element sp-overlay\n *\n * @fires sp-opened - announces that an overlay has completed any entry animations\n * @fires sp-closed - announce that an overlay has compelted any exit animations\n * @fires slottable-request - requests to add or remove slottable content\n */\nexport class Overlay extends ComputedOverlayBase {\n static override styles = [styles];\n\n /**\n * An Overlay that is `delayed` will wait until a warm-up period of 1000ms\n * has completed before opening. Once the warm-up period has completed, all\n * subsequent Overlays will open immediately. When no Overlays are opened,\n * a cool-down period of 1000ms will begin. Once the cool-down has completed,\n * the next Overlay to be opened will be subject to the warm-up period if\n * provided that option.\n *\n * This behavior helps to manage the performance and user experience by\n * preventing multiple overlays from opening simultaneously and ensuring\n * a smooth transition between opening and closing overlays.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean })\n override get delayed(): boolean {\n return this.elements.at(-1)?.hasAttribute('delayed') || this._delayed;\n }\n\n override set delayed(delayed: boolean) {\n this._delayed = delayed;\n }\n\n private _delayed = false;\n\n /**\n * A reference to the dialog element within the overlay.\n * This element is expected to have `showPopover` and `hidePopover` methods.\n */\n @query('.dialog')\n override dialogEl!: HTMLDialogElement & {\n showPopover(): void;\n hidePopover(): void;\n };\n\n /**\n * Indicates whether the overlay is currently functional or not.\n *\n * When set to `true`, the overlay is disabled, and any active strategy is aborted.\n * The overlay will also close if it is currently open. When set to `false`, the\n * overlay will re-bind events and re-open if it was previously open.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean })\n override get disabled(): boolean {\n return this._disabled;\n }\n\n override set disabled(disabled: boolean) {\n this._disabled = disabled;\n if (disabled) {\n // Abort any active strategy and close the overlay if it is currently open\n this.strategy?.abort();\n this.wasOpen = this.open;\n this.open = false;\n } else {\n // Re-bind events and re-open the overlay if it was previously open\n this.bindEvents();\n this.open = this.open || this.wasOpen;\n this.wasOpen = false;\n }\n }\n\n private _disabled = false;\n\n /**\n * A query to gather all elements slotted into the default slot, excluding elements\n * with the slot name \"longpress-describedby-descriptor\".\n */\n @queryAssignedElements({\n flatten: true,\n selector: ':not([slot=\"longpress-describedby-descriptor\"], slot)',\n })\n override elements!: OpenableElement[];\n\n /**\n * A reference to the parent overlay that should be force-closed, if any.\n */\n public parentOverlayToForceClose?: Overlay;\n\n /**\n * Determines if the overlay has a non-virtual trigger element.\n *\n * @returns {boolean} `true` if the trigger element is not a virtual trigger, otherwise `false`.\n */\n private get hasNonVirtualTrigger(): boolean {\n return (\n !!this.triggerElement &&\n !(this.triggerElement instanceof VirtualTrigger)\n );\n }\n\n /**\n * The `offset` property accepts either a single number to define the offset of the\n * Overlay along the main axis from the trigger, or a 2-tuple to define the offset\n * along both the main axis and the cross axis. This option has no effect when there\n * is no trigger element.\n *\n * @type {number | [number, number]}\n * @default 0\n */\n @property({ type: Number })\n override offset: number | [number, number] = 0;\n\n /**\n * Provides an instance of the `PlacementController` for managing the positioning\n * of the overlay relative to its trigger element.\n *\n * If the `PlacementController` instance does not already exist, it is created and\n * assigned to the `_placementController` property.\n *\n * @protected\n * @returns {PlacementController} The `PlacementController` instance.\n */\n protected override get placementController(): PlacementController {\n if (!this._placementController) {\n this._placementController = new PlacementController(this);\n }\n return this._placementController;\n }\n\n /**\n * Indicates whether the Overlay is projected onto the \"top layer\" or not.\n *\n * When set to `true`, the overlay is open and visible. When set to `false`, the overlay is closed and hidden.\n *\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean, reflect: true })\n override get open(): boolean {\n return this._open;\n }\n\n override set open(open: boolean) {\n // Don't respond if the overlay is disabled.\n if (open && this.disabled) return;\n\n // Don't respond if the state is not changing.\n if (open === this.open) return;\n\n // Don't respond if the overlay is in the shadow state during a longpress.\n // The shadow state occurs when the first \"click\" would normally close the popover.\n if (this.strategy?.activelyOpening && !open) return;\n\n // Update the internal _open property.\n this._open = open;\n\n // Increment the open count if the overlay is opening.\n if (this.open) {\n Overlay.openCount += 1;\n }\n\n // Request an update to re-render the component if necessary.\n this.requestUpdate('open', !this.open);\n\n // Request slottable content if the overlay is opening.\n if (this.open) {\n this.requestSlottable();\n }\n }\n\n private _open = false;\n\n /**\n * Tracks the number of overlays that have been opened.\n *\n * This static property is used to manage the stacking context of multiple overlays.\n *\n * @type {number}\n * @default 1\n */\n static openCount = 1;\n\n /**\n * Instruct the Overlay where to place itself in relationship to the trigger element.\n *\n * @type {\"top\" | \"top-start\" | \"top-end\" | \"right\" | \"right-start\" | \"right-end\" | \"bottom\" | \"bottom-start\" | \"bottom-end\" | \"left\" | \"left-start\" | \"left-end\"}\n */\n @property()\n override placement?: Placement;\n\n /**\n * The state in which the last `request-slottable` event was dispatched.\n *\n * This property ensures that overlays do not dispatch the same state twice in a row.\n *\n * @type {boolean}\n * @default false\n */\n private lastRequestSlottableState = false;\n\n /**\n * Whether to pass focus to the overlay once opened, or\n * to the appropriate value based on the \"type\" of the overlay\n * when set to `\"auto\"`.\n *\n * @type {'true' | 'false' | 'auto'}\n * @default 'auto'\n */\n @property({ attribute: 'receives-focus' })\n override receivesFocus: 'true' | 'false' | 'auto' = 'auto';\n\n /**\n * A reference to the slot element within the overlay.\n *\n * This element is used to manage the content slotted into the overlay.\n *\n * @type {HTMLSlotElement}\n */\n @query('slot')\n slotEl!: HTMLSlotElement;\n\n /**\n * The current state of the overlay.\n *\n * This property reflects the current state of the overlay, such as 'opened' or 'closed'.\n * When the state changes, it triggers the appropriate actions and updates the component.\n *\n * @type {OverlayState}\n * @default 'closed'\n */\n @state()\n override get state(): OverlayState {\n return this._state;\n }\n\n override set state(state) {\n // Do not respond if the state is not changing.\n if (state === this.state) return;\n\n const oldState = this.state;\n\n this._state = state;\n\n // Complete the opening strategy if the state is 'opened' or 'closed'.\n if (this.state === 'opened' || this.state === 'closed') {\n this.strategy?.shouldCompleteOpen();\n }\n\n // Request an update to re-render the component if necessary.\n this.requestUpdate('state', oldState);\n }\n\n override _state: OverlayState = 'closed';\n\n /**\n * The interaction strategy for opening the overlay.\n * This can be a ClickController, HoverController, or LongpressController.\n */\n public strategy?: ClickController | HoverController | LongpressController;\n\n /**\n * The padding around the tip of the overlay.\n * This property defines the padding around the tip of the overlay, which can be used to adjust its positioning.\n *\n * @type {number}\n */\n @property({ type: Number, attribute: 'tip-padding' })\n tipPadding?: number;\n\n /**\n * An optional ID reference for the trigger element combined with the optional\n * interaction (click | hover | longpress) by which the overlay should open.\n * The format is `trigger@interaction`, e.g., `trigger@click` opens the overlay\n * when an element with the ID \"trigger\" is clicked.\n *\n * @type {string}\n */\n @property()\n trigger?: string;\n\n /**\n * An element reference for the trigger element that the overlay should relate to.\n * This property is not reflected as an attribute.\n *\n * @type {HTMLElement | VirtualTrigger | null}\n */\n @property({ attribute: false })\n override triggerElement: HTMLElement | VirtualTrigger | null = null;\n\n /**\n * The specific interaction to listen for on the `triggerElement` to open the overlay.\n * This property is not reflected as an attribute.\n *\n * @type {TriggerInteraction}\n */\n @property({ attribute: false })\n triggerInteraction?: TriggerInteraction;\n\n /**\n * Configures the open/close heuristics of the Overlay.\n *\n * @type {\"auto\" | \"hint\" | \"manual\" | \"modal\" | \"page\"}\n * @default \"auto\"\n */\n @property()\n override type: OverlayTypes = 'auto';\n\n /**\n * Tracks whether the overlay was previously open.\n * This is used to restore the open state when re-enabling the overlay.\n *\n * @type {boolean}\n * @default false\n */\n protected wasOpen = false;\n\n /**\n * Provides an instance of the `ElementResolutionController` for managing the element\n * that the overlay should be associated with. If the instance does not already exist,\n * it is created and assigned to the `_elementResolver` property.\n *\n * @protected\n * @returns {ElementResolutionController} The `ElementResolutionController` instance.\n */\n protected override get elementResolver(): ElementResolutionController {\n if (!this._elementResolver) {\n this._elementResolver = new ElementResolutionController(this);\n }\n\n return this._elementResolver;\n }\n\n /**\n * Determines if the overlay uses a dialog.\n * Returns `true` if the overlay type is \"modal\" or \"page\".\n *\n * @private\n * @returns {boolean} `true` if the overlay uses a dialog, otherwise `false`.\n */\n private get usesDialog(): boolean {\n return this.type === 'modal' || this.type === 'page';\n }\n\n /**\n * Determines the value for the popover attribute based on the overlay type.\n *\n * @private\n * @returns {'auto' | 'manual' | undefined} The popover value or undefined if not applicable.\n */\n private get popoverValue(): 'auto' | 'manual' | undefined {\n const hasPopoverAttribute = 'popover' in this;\n\n if (!hasPopoverAttribute) {\n return undefined;\n }\n\n switch (this.type) {\n case 'modal':\n case 'page':\n return undefined;\n case 'hint':\n return 'manual';\n default:\n return this.type;\n }\n }\n\n /**\n * Determines if the overlay requires positioning based on its type and state.\n *\n * @protected\n * @returns {boolean} True if the overlay requires positioning, otherwise false.\n */\n protected get requiresPositioning(): boolean {\n // Do not position \"page\" overlays as they should block the entire UI.\n if (this.type === 'page' || !this.open) return false;\n\n // Do not position content without a trigger element, as there is nothing to position it relative to.\n // Do not automatically position content unless it is a \"hint\".\n if (!this.triggerElement || (!this.placement && this.type !== 'hint'))\n return false;\n\n return true;\n }\n\n /**\n * Manages the positioning of the overlay relative to its trigger element.\n *\n * This method calculates the necessary parameters for positioning the overlay,\n * such as offset, placement, and tip padding, and then delegates the actual\n * positioning to the `PlacementController`.\n *\n * @protected\n * @override\n */\n protected override managePosition(): void {\n // Do not proceed if positioning is not required or the overlay is not open.\n if (!this.requiresPositioning || !this.open) return;\n\n const offset = this.offset || 0;\n\n const trigger = this.triggerElement as HTMLElement;\n\n const placement = (this.placement as Placement) || 'right';\n\n const tipPadding = this.tipPadding;\n\n this.placementController.placeOverlay(this.dialogEl, {\n offset,\n placement,\n tipPadding,\n trigger,\n type: this.type,\n });\n }\n\n /**\n * Manages the process of opening the popover.\n *\n * This method handles the necessary steps to open the popover, including managing delays,\n * ensuring the popover is in the DOM, making transitions, and applying focus.\n *\n * @protected\n * @override\n * @returns {Promise<void>} A promise that resolves when the popover has been fully opened.\n */\n protected override async managePopoverOpen(): Promise<void> {\n // Call the base class method to handle any initial setup.\n super.managePopoverOpen();\n\n const targetOpenState = this.open;\n\n // Ensure the open state has not changed before proceeding.\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Manage any delays before opening the popover.\n await this.manageDelay(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Ensure the popover is in the DOM before proceeding.\n await this.ensureOnDOM(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Make any necessary transitions for opening the popover.\n const focusEl = await this.makeTransition(targetOpenState);\n\n if (this.open !== targetOpenState) {\n return;\n }\n\n // Apply focus to the appropriate element after opening the popover.\n await this.applyFocus(targetOpenState, focusEl);\n }\n\n /**\n * Applies focus to the appropriate element after the popover has been opened.\n *\n * This method handles the focus management for the overlay, ensuring that the correct\n * element receives focus based on the overlay's type and state.\n *\n * @protected\n * @override\n * @param {boolean} targetOpenState - The target open state of the overlay.\n * @param {HTMLElement | null} focusEl - The element to focus after opening the popover.\n * @returns {Promise<void>} A promise that resolves when the focus has been applied.\n */\n protected override async applyFocus(\n targetOpenState: boolean,\n focusEl: HTMLElement | null\n ): Promise<void> {\n // Do not move focus when explicitly told not to or when the overlay is a \"hint\".\n if (this.receivesFocus === 'false' || this.type === 'hint') {\n return;\n }\n\n // Wait for the next two animation frames to ensure the DOM is updated.\n await nextFrame();\n await nextFrame();\n\n // If the open state has changed during the delay, do not proceed.\n if (targetOpenState === this.open && !this.open) {\n // If the overlay is closing and the trigger element is still focused, return focus to the trigger element.\n if (\n this.hasNonVirtualTrigger &&\n this.contains((this.getRootNode() as Document).activeElement)\n ) {\n (this.triggerElement as HTMLElement).focus();\n }\n return;\n }\n\n // Apply focus to the specified focus element.\n focusEl?.focus();\n }\n\n /**\n * Returns focus to the trigger element if the overlay is closed.\n *\n * This method ensures that focus is returned to the trigger element when the overlay is closed,\n * unless the overlay is of type \"hint\" or the focus is already outside the overlay.\n *\n * @protected\n * @override\n */\n protected override returnFocus(): void {\n // Do not proceed if the overlay is open or if the overlay type is \"hint\".\n if (this.open || this.type === 'hint') return;\n\n /**\n * Retrieves the ancestors of the currently focused element.\n *\n * @returns {HTMLElement[]} An array of ancestor elements.\n */\n const getAncestors = (): HTMLElement[] => {\n const ancestors: HTMLElement[] = [];\n\n // eslint-disable-next-line @spectrum-web-components/document-active-element\n let currentNode = document.activeElement;\n\n // Traverse the shadow DOM to find the active element.\n while (currentNode?.shadowRoot?.activeElement) {\n currentNode = currentNode.shadowRoot.activeElement;\n }\n\n // Traverse the DOM tree to collect ancestor elements.\n while (currentNode) {\n const ancestor =\n currentNode.assignedSlot ||\n currentNode.parentElement ||\n (currentNode.getRootNode() as ShadowRoot)?.host;\n if (ancestor) {\n ancestors.push(ancestor as HTMLElement);\n }\n currentNode = ancestor;\n }\n return ancestors;\n };\n\n // Check if focus should be returned to the trigger element.\n if (\n this.receivesFocus !== 'false' &&\n !!(this.triggerElement as HTMLElement)?.focus &&\n (this.contains((this.getRootNode() as Document).activeElement) ||\n getAncestors().includes(this) ||\n // eslint-disable-next-line @spectrum-web-components/document-active-element\n document.activeElement === document.body)\n ) {\n // Return focus to the trigger element.\n (this.triggerElement as HTMLElement).focus();\n }\n }\n\n /**\n * Handles the focus out event to close the overlay if the focus moves outside of it.\n *\n * This method ensures that the overlay is closed when the focus moves to an element\n * outside of the overlay, unless the focus is moved to a related element.\n *\n * @private\n * @param {FocusEvent} event - The focus out event.\n */\n private closeOnFocusOut = (event: FocusEvent): void => {\n // If the related target (newly focused element) is not known, do nothing.\n if (!event.relatedTarget) {\n return;\n }\n\n // Create a custom event to query the relationship of the newly focused element.\n const relationEvent = new Event('overlay-relation-query', {\n bubbles: true,\n composed: true,\n });\n\n // Add an event listener to the related target to handle the custom event.\n event.relatedTarget.addEventListener(\n relationEvent.type,\n (event: Event) => {\n // Check if the newly focused element is within the overlay or its children\n const path = event.composedPath();\n const isWithinOverlay = path.some((el) => el === this);\n\n // Only close if focus moves outside the overlay and its children\n if (!isWithinOverlay) {\n this.open = false;\n }\n }\n );\n\n // Dispatch the custom event to the related target.\n event.relatedTarget.dispatchEvent(relationEvent);\n };\n\n /**\n * Manages the process of opening or closing the overlay.\n *\n * This method handles the necessary steps to open or close the overlay, including updating the state,\n * managing the overlay stack, and handling focus events.\n *\n * @protected\n * @param {boolean} oldOpen - The previous open state of the overlay.\n * @returns {Promise<void>} A promise that resolves when the overlay has been fully managed.\n */\n protected async manageOpen(oldOpen: boolean): Promise<void> {\n // Prevent entering the manage workflow if the overlay is not connected to the DOM.\n // The `.showPopover()` and `.showModal()` events will error on content that is not connected to the DOM.\n if (!this.isConnected && this.open) return;\n\n // Wait for the component to finish updating if it has not already done so.\n if (!this.hasUpdated) {\n await this.updateComplete;\n }\n\n if (this.open) {\n // Add the overlay to the overlay stack.\n overlayStack.add(this);\n\n if (this.willPreventClose) {\n // Add an event listener to handle the pointerup event and toggle the 'not-immediately-closable' class.\n document.addEventListener(\n 'pointerup',\n () => {\n this.dialogEl.classList.toggle(\n 'not-immediately-closable',\n false\n );\n this.willPreventClose = false;\n },\n { once: true }\n );\n this.dialogEl.classList.toggle(\n 'not-immediately-closable',\n true\n );\n }\n } else {\n if (oldOpen) {\n // Dispose of the overlay if it was previously open.\n this.dispose();\n }\n\n // Remove the overlay from the overlay stack.\n overlayStack.remove(this);\n }\n\n // Update the state of the overlay based on the open property.\n if (this.open && this.state !== 'opened') {\n this.state = 'opening';\n } else if (!this.open && this.state !== 'closed') {\n this.state = 'closing';\n }\n\n // Manage the dialog or popover based on the overlay type.\n if (this.usesDialog) {\n this.manageDialogOpen();\n } else {\n this.managePopoverOpen();\n }\n\n // Handle focus events for auto type overlays.\n if (this.type === 'auto') {\n const listenerRoot = this.getRootNode() as Document;\n if (this.open) {\n listenerRoot.addEventListener(\n 'focusout',\n this.closeOnFocusOut,\n { capture: true }\n );\n } else {\n listenerRoot.removeEventListener(\n 'focusout',\n this.closeOnFocusOut,\n { capture: true }\n );\n }\n }\n }\n\n /**\n * Binds event handling strategies to the overlay based on the specified trigger interaction.\n *\n * This method sets up the appropriate event handling strategy for the overlay, ensuring that\n * it responds correctly to user interactions such as clicks, hovers, or long presses.\n *\n * @protected\n */\n protected bindEvents(): void {\n // Abort any existing strategy to ensure a clean setup.\n this.strategy?.abort();\n this.strategy = undefined;\n\n // Return early if there is no non-virtual trigger element.\n if (!this.hasNonVirtualTrigger) return;\n\n // Return early if no trigger interaction is specified.\n if (!this.triggerInteraction) return;\n\n // Set up a new event handling strategy based on the specified trigger interaction.\n this.strategy = new strategies[this.triggerInteraction](\n this.triggerElement as HTMLElement,\n {\n overlay: this,\n }\n );\n }\n\n /**\n * Handles the `beforetoggle` event to manage the overlay's state.\n *\n * This method checks the new state of the event and calls `handleBrowserClose`\n * if the new state is not 'open'.\n *\n * @protected\n * @param {Event & { newState: string }} event - The `beforetoggle` event with the new state.\n */\n protected handleBeforetoggle(event: Event & { newState: string }): void {\n if (event.newState !== 'open') {\n this.handleBrowserClose(event);\n }\n }\n\n /**\n * Handles the browser's close event to manage the overlay's state.\n *\n * This method stops the propagation of the event and closes the overlay if it is not\n * actively opening. If the overlay is actively opening, it calls `manuallyKeepOpen`.\n *\n * @protected\n * @param {Event} event - The browser's close event.\n */\n protected handleBrowserClose(event: Event): void {\n event.stopPropagation();\n if (!this.strategy?.activelyOpening) {\n this.open = false;\n return;\n }\n this.manuallyKeepOpen();\n }\n\n /**\n * Manually keeps the overlay open.\n *\n * This method sets the overlay to open, allows placement updates, and manages the open state.\n *\n * @public\n * @override\n */\n public override manuallyKeepOpen(): void {\n this.open = true;\n this.placementController.allowPlacementUpdate = true;\n this.manageOpen(false);\n }\n\n /**\n * Handles the `slotchange` event to manage the overlay's state.\n *\n * This method checks if there are any elements in the slot. If there are no elements,\n * it releases the description from the strategy. If there are elements and the trigger\n * is non-virtual, it prepares the description for the trigger element.\n *\n * @protected\n */\n protected handleSlotchange(): void {\n if (!this.elements.length) {\n // Release the description if there are no elements in the slot.\n this.strategy?.releaseDescription();\n } else if (this.hasNonVirtualTrigger) {\n // Prepare the description for the trigger element if it is non-virtual.\n this.strategy?.prepareDescription(\n this.triggerElement as HTMLElement\n );\n }\n }\n\n /**\n * Determines whether the overlay should prevent closing.\n *\n * This method checks the `willPreventClose` flag and resets it to `false`.\n * It returns the value of the `willPreventClose` flag.\n *\n * @public\n * @returns {boolean} `true` if the overlay should prevent closing, otherwise `false`.\n */\n public shouldPreventClose(): boolean {\n const shouldPreventClose = this.willPreventClose;\n this.willPreventClose = false;\n return shouldPreventClose;\n }\n\n /**\n * Requests slottable content for the overlay.\n *\n * This method dispatches a `SlottableRequestEvent` to request or remove slottable content\n * based on the current open state of the overlay. It ensures that the same state is not\n * dispatched twice in a row.\n *\n * @protected\n * @override\n */\n protected override requestSlottable(): void {\n // Do not dispatch the same state twice in a row.\n if (this.lastRequestSlottableState === this.open) {\n return;\n }\n\n // Force a reflow if the overlay is closing.\n if (!this.open) {\n document.body.offsetHeight;\n }\n\n /**\n * @ignore\n */\n // Dispatch a custom event to request or remove slottable content based on the open state.\n this.dispatchEvent(\n new SlottableRequestEvent(\n 'overlay-content',\n this.open ? {} : removeSlottableRequest\n )\n );\n\n // Update the last request slottable state.\n this.lastRequestSlottableState = this.open;\n }\n\n /**\n * Lifecycle method called before the component updates.\n *\n * This method handles various tasks before the component updates, such as setting an ID,\n * managing the open state, resolving the trigger element, and binding events.\n *\n * @override\n * @param {PropertyValues} changes - The properties that have changed.\n */\n override willUpdate(changes: PropertyValues): void {\n // Ensure the component has an ID attribute.\n if (!this.hasAttribute('id')) {\n this.setAttribute(\n 'id',\n `${this.tagName.toLowerCase()}-${randomID()}`\n );\n }\n\n // Manage the open state if the 'open' property has changed.\n if (changes.has('open') && (this.hasUpdated || this.open)) {\n this.manageOpen(changes.get('open'));\n }\n\n // Resolve the trigger element if the 'trigger' property has changed.\n if (changes.has('trigger')) {\n const [id, interaction] = this.trigger?.split('@') || [];\n this.elementResolver.selector = id ? `#${id}` : '';\n this.triggerInteraction = interaction as\n | 'click'\n | 'longpress'\n | 'hover'\n | undefined;\n }\n\n // Initialize oldTrigger to track the previous trigger element.\n let oldTrigger: HTMLElement | false | undefined = false;\n\n // Check if the element resolver has been updated.\n if (changes.has(elementResolverUpdatedSymbol)) {\n // Store the current trigger element.\n oldTrigger = this.triggerElement as HTMLElement;\n // Update the trigger element from the element resolver.\n this.triggerElement = this.elementResolver.element;\n }\n\n // Check if the 'triggerElement' property has changed.\n if (changes.has('triggerElement')) {\n // Store the old trigger element.\n oldTrigger = changes.get('triggerElement');\n }\n\n // If the trigger element has changed, bind the new events.\n if (oldTrigger !== false) {\n this.bindEvents();\n }\n }\n\n /**\n * Lifecycle method called after the component updates.\n *\n * This method handles various tasks after the component updates, such as updating the placement\n * attribute, resetting the overlay position, and clearing the overlay position based on the state.\n *\n * @override\n * @param {PropertyValues} changes - The properties that have changed.\n */\n protected override updated(changes: PropertyValues): void {\n // Call the base class method to handle any initial setup.\n super.updated(changes);\n\n // Check if the 'placement' property has changed.\n if (changes.has('placement')) {\n if (this.placement) {\n // Set the 'actual-placement' attribute on the dialog element.\n this.dialogEl.setAttribute('actual-placement', this.placement);\n } else {\n // Remove the 'actual-placement' attribute from the dialog element.\n this.dialogEl.removeAttribute('actual-placement');\n }\n\n // If the overlay is open and the 'placement' property has changed, reset the overlay position.\n if (this.open && typeof changes.get('placement') !== 'undefined') {\n this.placementController.resetOverlayPosition();\n }\n }\n\n // Check if the 'state' property has changed and the overlay is closed.\n if (\n changes.has('state') &&\n this.state === 'closed' &&\n typeof changes.get('state') !== 'undefined'\n ) {\n // Clear the overlay position.\n this.placementController.clearOverlayPosition();\n }\n }\n\n /**\n * Renders the content of the overlay.\n *\n * This method returns a template result containing a slot element. The slot element\n * listens for the `slotchange` event to manage the overlay's state.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the slot element.\n */\n protected renderContent(): TemplateResult {\n return html`\n <slot @slotchange=${this.handleSlotchange}></slot>\n `;\n }\n\n /**\n * Generates a style map for the dialog element.\n *\n * This method returns an object containing CSS custom properties for the dialog element.\n * The `--swc-overlay-open-count` custom property is set to the current open count of overlays.\n *\n * @private\n * @returns {StyleInfo} The style map for the dialog element.\n */\n private get dialogStyleMap(): StyleInfo {\n return {\n '--swc-overlay-open-count': Overlay.openCount.toString(),\n };\n }\n\n /**\n * Renders the dialog element for the overlay.\n *\n * This method returns a template result containing a dialog element. The dialog element\n * includes various attributes and event listeners to manage the overlay's state and behavior.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the dialog element.\n */\n protected renderDialog(): TemplateResult {\n /**\n * The `--swc-overlay-open-count` custom property is applied to mimic the single stack\n * nature of the top layer in browsers that do not yet support it.\n *\n * The value should always represent the total number of overlays that have ever been opened.\n * This value will be added to the `--swc-overlay-z-index-base` custom property, which can be\n * provided by a consuming developer. By default, `--swc-overlay-z-index-base` is set to 1000\n * to ensure that the overlay stacks above most other elements during fallback delivery.\n */\n return html`\n <dialog\n class=\"dialog\"\n part=\"dialog\"\n placement=${ifDefined(\n this.requiresPositioning\n ? this.placement || 'right'\n : undefined\n )}\n style=${styleMap(this.dialogStyleMap)}\n @close=${this.handleBrowserClose}\n @cancel=${this.handleBrowserClose}\n @beforetoggle=${this.handleBeforetoggle}\n ?is-visible=${this.state !== 'closed'}\n >\n ${this.renderContent()}\n </dialog>\n `;\n }\n\n /**\n * Renders the popover element for the overlay.\n *\n * This method returns a template result containing a div element styled as a popover.\n * The popover element includes various attributes and event listeners to manage the overlay's state and behavior.\n *\n * @protected\n * @returns {TemplateResult} The template result containing the popover element.\n */\n protected renderPopover(): TemplateResult {\n /**\n * The `--swc-overlay-open-count` custom property is applied to mimic the single stack\n * nature of the top layer in browsers that do not yet support it.\n *\n * The value should always represent the total number of overlays that have ever been opened.\n * This value will be added to the `--swc-overlay-z-index-base` custom property, which can be\n * provided by a consuming developer. By default, `--swc-overlay-z-index-base` is set to 1000\n * to ensure that the overlay stacks above most other elements during fallback delivery.\n */\n return html`\n <div\n class=\"dialog\"\n part=\"dialog\"\n placement=${ifDefined(\n this.requiresPositioning\n ? this.placement || 'right'\n : undefined\n )}\n popover=${ifDefined(this.popoverValue)}\n style=${styleMap(this.dialogStyleMap)}\n @beforetoggle=${this.handleBeforetoggle}\n @close=${this.handleBrowserClose}\n ?is-visible=${this.state !== 'closed'}\n >\n ${this.renderContent()}\n </div>\n `;\n }\n\n /**\n * Renders the overlay component.\n *\n * This method returns a template result containing either a dialog or popover element\n * based on the overlay type. It also includes a slot for longpress descriptors.\n *\n * @override\n * @returns {TemplateResult} The template result containing the overlay content.\n */\n public override render(): TemplateResult {\n const isDialog = this.type === 'modal' || this.type === 'page';\n return html`\n ${isDialog ? this.renderDialog() : this.renderPopover()}\n <slot name=\"longpress-describedby-descriptor\"></slot>\n `;\n }\n\n /**\n * Lifecycle method called when the component is added to the DOM.\n *\n * This method sets up event listeners and binds events if the component has already updated.\n *\n * @override\n */\n override connectedCallback(): void {\n super.connectedCallback();\n\n // Add an event listener to handle the 'close' event and update the 'open' property.\n this.addEventListener('close', () => {\n this.open = false;\n });\n\n // Bind events if the component has already updated.\n if (this.hasUpdated) {\n this.bindEvents();\n }\n }\n\n /**\n * Lifecycle method called when the component is removed from the DOM.\n *\n * This method releases the description from the strategy and updates the 'open' property.\n *\n * @override\n */\n override disconnectedCallback(): void {\n // Release the description from the strategy.\n this.strategy?.releaseDescription();\n // Update the 'open' property to false.\n this.open = false;\n super.disconnectedCallback();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["html", "property", "query", "queryAssignedElements", "state", "ElementResolutionController", "elementResolverUpdatedSymbol", "ifDefined", "styleMap", "randomID", "AbstractOverlay", "nextFrame", "OverlayDialog", "OverlayPopover", "OverlayNoPopover", "overlayStack", "VirtualTrigger", "PlacementController", "strategies", "removeSlottableRequest", "SlottableRequestEvent", "styles", "browserSupportsPopover", "ComputedOverlayBase", "_Overlay", "event", "relationEvent", "el", "_a", "delayed", "disabled", "open", "oldState", "offset", "trigger", "placement", "tipPadding", "targetOpenState", "focusEl", "getAncestors", "_b", "ancestors", "currentNode", "ancestor", "oldOpen", "listenerRoot", "shouldPreventClose", "changes", "id", "interaction", "oldTrigger", "isDialog", "__decorateClass"]
|
|
7
7
|
}
|
package/src/OverlayDialog.dev.js
CHANGED
|
@@ -33,7 +33,6 @@ export function OverlayDialog(constructor) {
|
|
|
33
33
|
if (!targetOpenState) {
|
|
34
34
|
const close = () => {
|
|
35
35
|
el.removeEventListener("close", close);
|
|
36
|
-
this.cleanupIOSEventManagement();
|
|
37
36
|
finish(el, index);
|
|
38
37
|
};
|
|
39
38
|
el.addEventListener("close", close);
|
|
@@ -62,7 +61,6 @@ export function OverlayDialog(constructor) {
|
|
|
62
61
|
return;
|
|
63
62
|
}
|
|
64
63
|
this.dialogEl.showModal();
|
|
65
|
-
this.setupIOSEventManagement();
|
|
66
64
|
};
|
|
67
65
|
const finish = (el, index) => () => {
|
|
68
66
|
if (this.open !== targetOpenState) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["OverlayDialog.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport type { SpectrumElement } from '@spectrum-web-components/base';\nimport {\n firstFocusableIn,\n firstFocusableSlottedIn,\n} from '@spectrum-web-components/shared/src/first-focusable-in.js';\nimport { VirtualTrigger } from './VirtualTrigger.dev.js'\nimport { Constructor, OpenableElement } from './overlay-types.dev.js'\nimport { guaranteedAllTransitionend, nextFrame } from './AbstractOverlay.dev.js'\nimport {\n BeforetoggleClosedEvent,\n BeforetoggleOpenEvent,\n OverlayStateEvent,\n} from './events.dev.js'\nimport type { AbstractOverlay } from './AbstractOverlay.dev.js'\nimport { userFocusableSelector } from '@spectrum-web-components/shared';\n\nexport function OverlayDialog<T extends Constructor<AbstractOverlay>>(\n constructor: T\n): T & Constructor<SpectrumElement> {\n class OverlayWithDialog extends constructor {\n protected override async manageDialogOpen(): Promise<void> {\n const targetOpenState = this.open;\n await nextFrame();\n await this.managePosition();\n if (this.open !== targetOpenState) {\n return;\n }\n const focusEl = await this.dialogMakeTransition(targetOpenState);\n if (this.open !== targetOpenState) {\n return;\n }\n await this.dialogApplyFocus(targetOpenState, focusEl);\n }\n\n protected async dialogMakeTransition(\n targetOpenState: boolean\n ): Promise<HTMLElement | null> {\n let focusEl = null as HTMLElement | null;\n const start =\n (el: OpenableElement, index: number) =>\n async (): Promise<void> => {\n el.open = targetOpenState;\n if (!targetOpenState) {\n const close = (): void => {\n el.removeEventListener('close', close);\n
|
|
5
|
-
"mappings": ";AAYA;AAAA,EACI;AAAA,EACA;AAAA,OACG;AACP,SAAS,sBAAsB;AAE/B,SAAS,4BAA4B,iBAAiB;AACtD;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,OACG;AAEP,SAAS,6BAA6B;AAE/B,gBAAS,cACZ,aACgC;AAAA,EAChC,MAAM,0BAA0B,YAAY;AAAA,IACxC,MAAyB,mBAAkC;AACvD,YAAM,kBAAkB,KAAK;AAC7B,YAAM,UAAU;AAChB,YAAM,KAAK,eAAe;AAC1B,UAAI,KAAK,SAAS,iBAAiB;AAC/B;AAAA,MACJ;AACA,YAAM,UAAU,MAAM,KAAK,qBAAqB,eAAe;AAC/D,UAAI,KAAK,SAAS,iBAAiB;AAC/B;AAAA,MACJ;AACA,YAAM,KAAK,iBAAiB,iBAAiB,OAAO;AAAA,IACxD;AAAA,IAEA,MAAgB,qBACZ,iBAC2B;AAC3B,UAAI,UAAU;AACd,YAAM,QACF,CAAC,IAAqB,UACtB,YAA2B;AACvB,WAAG,OAAO;AACV,YAAI,CAAC,iBAAiB;AAClB,gBAAM,QAAQ,MAAY;AACtB,eAAG,oBAAoB,SAAS,KAAK;AACrC,
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport type { SpectrumElement } from '@spectrum-web-components/base';\nimport {\n firstFocusableIn,\n firstFocusableSlottedIn,\n} from '@spectrum-web-components/shared/src/first-focusable-in.js';\nimport { VirtualTrigger } from './VirtualTrigger.dev.js'\nimport { Constructor, OpenableElement } from './overlay-types.dev.js'\nimport { guaranteedAllTransitionend, nextFrame } from './AbstractOverlay.dev.js'\nimport {\n BeforetoggleClosedEvent,\n BeforetoggleOpenEvent,\n OverlayStateEvent,\n} from './events.dev.js'\nimport type { AbstractOverlay } from './AbstractOverlay.dev.js'\nimport { userFocusableSelector } from '@spectrum-web-components/shared';\n\nexport function OverlayDialog<T extends Constructor<AbstractOverlay>>(\n constructor: T\n): T & Constructor<SpectrumElement> {\n class OverlayWithDialog extends constructor {\n protected override async manageDialogOpen(): Promise<void> {\n const targetOpenState = this.open;\n await nextFrame();\n await this.managePosition();\n if (this.open !== targetOpenState) {\n return;\n }\n const focusEl = await this.dialogMakeTransition(targetOpenState);\n if (this.open !== targetOpenState) {\n return;\n }\n await this.dialogApplyFocus(targetOpenState, focusEl);\n }\n\n protected async dialogMakeTransition(\n targetOpenState: boolean\n ): Promise<HTMLElement | null> {\n let focusEl = null as HTMLElement | null;\n const start =\n (el: OpenableElement, index: number) =>\n async (): Promise<void> => {\n el.open = targetOpenState;\n if (!targetOpenState) {\n const close = (): void => {\n el.removeEventListener('close', close);\n finish(el, index);\n };\n el.addEventListener('close', close);\n }\n if (index > 0) {\n // Announce workflow on the first element _only_.\n return;\n }\n const event = targetOpenState\n ? BeforetoggleOpenEvent\n : BeforetoggleClosedEvent;\n this.dispatchEvent(new event());\n if (!targetOpenState) {\n // Show/focus workflow when opening _only_.\n return;\n }\n if (el.matches(userFocusableSelector)) {\n focusEl = el;\n }\n focusEl = focusEl || firstFocusableIn(el);\n if (!focusEl) {\n const childSlots = el.querySelectorAll('slot');\n childSlots.forEach((slot) => {\n if (!focusEl) {\n focusEl = firstFocusableSlottedIn(slot);\n }\n });\n }\n if (!this.isConnected || this.dialogEl.open) {\n // In both of these cases the browser will error.\n // You can neither \"reopen\" a <dialog> or open one that is not on the DOM.\n return;\n }\n this.dialogEl.showModal();\n };\n const finish = (el: OpenableElement, index: number) => (): void => {\n if (this.open !== targetOpenState) {\n return;\n }\n const eventName = targetOpenState ? 'sp-opened' : 'sp-closed';\n if (index > 0) {\n el.dispatchEvent(\n new OverlayStateEvent(eventName, this, {\n interaction: this.type,\n publish: false,\n })\n );\n return;\n }\n if (!this.isConnected || targetOpenState !== this.open) {\n // Don't lead into the `.close()` workflow if not connected to the DOM.\n // The browser will error in this case.\n return;\n }\n const reportChange = async (): Promise<void> => {\n const hasVirtualTrigger =\n this.triggerElement instanceof VirtualTrigger;\n this.dispatchEvent(\n new OverlayStateEvent(eventName, this, {\n interaction: this.type,\n publish: hasVirtualTrigger,\n })\n );\n el.dispatchEvent(\n new OverlayStateEvent(eventName, this, {\n interaction: this.type,\n publish: false,\n })\n );\n if (this.triggerElement && !hasVirtualTrigger) {\n (this.triggerElement as HTMLElement).dispatchEvent(\n new OverlayStateEvent(eventName, this, {\n interaction: this.type,\n publish: true,\n })\n );\n }\n this.state = targetOpenState ? 'opened' : 'closed';\n this.returnFocus();\n // Ensure layout and paint are done and the Overlay is still closed before removing the slottable request.\n await nextFrame();\n await nextFrame();\n if (\n targetOpenState === this.open &&\n targetOpenState === false\n ) {\n this.requestSlottable();\n }\n };\n if (!targetOpenState && this.dialogEl.open) {\n this.dialogEl.addEventListener(\n 'close',\n () => {\n reportChange();\n },\n { once: true }\n );\n this.dialogEl.close();\n } else {\n reportChange();\n }\n };\n this.elements.forEach((el, index) => {\n guaranteedAllTransitionend(\n el,\n start(el, index),\n finish(el, index)\n );\n });\n return focusEl;\n }\n\n protected async dialogApplyFocus(\n targetOpenState: boolean,\n focusEl: HTMLElement | null\n ): Promise<void> {\n /**\n * Focus should be handled natively in `<dialog>` elements when leveraging `.showModal()`, but it's NOT.\n * - webkit bug: https://bugs.webkit.org/show_bug.cgi?id=255507\n * - firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1828398\n **/\n this.applyFocus(targetOpenState, focusEl);\n }\n }\n return OverlayWithDialog;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/src/OverlayDialog.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";import{firstFocusableIn as u,firstFocusableSlottedIn as d}from"@spectrum-web-components/shared/src/first-focusable-in.js";import{VirtualTrigger as f}from"./VirtualTrigger.js";import{guaranteedAllTransitionend as E,nextFrame as a}from"./AbstractOverlay.js";import{BeforetoggleClosedEvent as v,BeforetoggleOpenEvent as g,OverlayStateEvent as l}from"./events.js";import{userFocusableSelector as y}from"@spectrum-web-components/shared";export function OverlayDialog(h){class p extends h{async manageDialogOpen(){const e=this.open;if(await a(),await this.managePosition(),this.open!==e)return;const i=await this.dialogMakeTransition(e);this.open===e&&await this.dialogApplyFocus(e,i)}async dialogMakeTransition(e){let i=null;const m=(t,s)=>async()=>{if(t.open=e,!e){const n=()=>{t.removeEventListener("close",n),
|
|
1
|
+
"use strict";import{firstFocusableIn as u,firstFocusableSlottedIn as d}from"@spectrum-web-components/shared/src/first-focusable-in.js";import{VirtualTrigger as f}from"./VirtualTrigger.js";import{guaranteedAllTransitionend as E,nextFrame as a}from"./AbstractOverlay.js";import{BeforetoggleClosedEvent as v,BeforetoggleOpenEvent as g,OverlayStateEvent as l}from"./events.js";import{userFocusableSelector as y}from"@spectrum-web-components/shared";export function OverlayDialog(h){class p extends h{async manageDialogOpen(){const e=this.open;if(await a(),await this.managePosition(),this.open!==e)return;const i=await this.dialogMakeTransition(e);this.open===e&&await this.dialogApplyFocus(e,i)}async dialogMakeTransition(e){let i=null;const m=(t,s)=>async()=>{if(t.open=e,!e){const n=()=>{t.removeEventListener("close",n),c(t,s)};t.addEventListener("close",n)}if(s>0)return;const o=e?g:v;this.dispatchEvent(new o),e&&(t.matches(y)&&(i=t),i=i||u(t),i||t.querySelectorAll("slot").forEach(r=>{i||(i=d(r))}),!(!this.isConnected||this.dialogEl.open)&&this.dialogEl.showModal())},c=(t,s)=>()=>{if(this.open!==e)return;const o=e?"sp-opened":"sp-closed";if(s>0){t.dispatchEvent(new l(o,this,{interaction:this.type,publish:!1}));return}if(!this.isConnected||e!==this.open)return;const n=async()=>{const r=this.triggerElement instanceof f;this.dispatchEvent(new l(o,this,{interaction:this.type,publish:r})),t.dispatchEvent(new l(o,this,{interaction:this.type,publish:!1})),this.triggerElement&&!r&&this.triggerElement.dispatchEvent(new l(o,this,{interaction:this.type,publish:!0})),this.state=e?"opened":"closed",this.returnFocus(),await a(),await a(),e===this.open&&e===!1&&this.requestSlottable()};!e&&this.dialogEl.open?(this.dialogEl.addEventListener("close",()=>{n()},{once:!0}),this.dialogEl.close()):n()};return this.elements.forEach((t,s)=>{E(t,m(t,s),c(t,s))}),i}async dialogApplyFocus(e,i){this.applyFocus(e,i)}}return p}
|
|
2
2
|
//# sourceMappingURL=OverlayDialog.js.map
|
package/src/OverlayDialog.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["OverlayDialog.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport type { SpectrumElement } from '@spectrum-web-components/base';\nimport {\n firstFocusableIn,\n firstFocusableSlottedIn,\n} from '@spectrum-web-components/shared/src/first-focusable-in.js';\nimport { VirtualTrigger } from './VirtualTrigger.js';\nimport { Constructor, OpenableElement } from './overlay-types.js';\nimport { guaranteedAllTransitionend, nextFrame } from './AbstractOverlay.js';\nimport {\n BeforetoggleClosedEvent,\n BeforetoggleOpenEvent,\n OverlayStateEvent,\n} from './events.js';\nimport type { AbstractOverlay } from './AbstractOverlay.js';\nimport { userFocusableSelector } from '@spectrum-web-components/shared';\n\nexport function OverlayDialog<T extends Constructor<AbstractOverlay>>(\n constructor: T\n): T & Constructor<SpectrumElement> {\n class OverlayWithDialog extends constructor {\n protected override async manageDialogOpen(): Promise<void> {\n const targetOpenState = this.open;\n await nextFrame();\n await this.managePosition();\n if (this.open !== targetOpenState) {\n return;\n }\n const focusEl = await this.dialogMakeTransition(targetOpenState);\n if (this.open !== targetOpenState) {\n return;\n }\n await this.dialogApplyFocus(targetOpenState, focusEl);\n }\n\n protected async dialogMakeTransition(\n targetOpenState: boolean\n ): Promise<HTMLElement | null> {\n let focusEl = null as HTMLElement | null;\n const start =\n (el: OpenableElement, index: number) =>\n async (): Promise<void> => {\n el.open = targetOpenState;\n if (!targetOpenState) {\n const close = (): void => {\n el.removeEventListener('close', close);\n
|
|
5
|
-
"mappings": "aAYA,OACI,oBAAAA,EACA,2BAAAC,MACG,4DACP,OAAS,kBAAAC,MAAsB,sBAE/B,OAAS,8BAAAC,EAA4B,aAAAC,MAAiB,uBACtD,OACI,2BAAAC,EACA,yBAAAC,EACA,qBAAAC,MACG,cAEP,OAAS,yBAAAC,MAA6B,kCAE/B,gBAAS,cACZC,EACgC,CAChC,MAAMC,UAA0BD,CAAY,CACxC,MAAyB,kBAAkC,CACvD,MAAME,EAAkB,KAAK,KAG7B,GAFA,MAAMP,EAAU,EAChB,MAAM,KAAK,eAAe,EACtB,KAAK,OAASO,EACd,OAEJ,MAAMC,EAAU,MAAM,KAAK,qBAAqBD,CAAe,EAC3D,KAAK,OAASA,GAGlB,MAAM,KAAK,iBAAiBA,EAAiBC,CAAO,CACxD,CAEA,MAAgB,qBACZD,EAC2B,CAC3B,IAAIC,EAAU,KACd,MAAMC,EACF,CAACC,EAAqBC,IACtB,SAA2B,CAEvB,GADAD,EAAG,KAAOH,EACN,CAACA,EAAiB,CAClB,MAAMK,EAAQ,IAAY,CACtBF,EAAG,oBAAoB,QAASE,CAAK,
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport type { SpectrumElement } from '@spectrum-web-components/base';\nimport {\n firstFocusableIn,\n firstFocusableSlottedIn,\n} from '@spectrum-web-components/shared/src/first-focusable-in.js';\nimport { VirtualTrigger } from './VirtualTrigger.js';\nimport { Constructor, OpenableElement } from './overlay-types.js';\nimport { guaranteedAllTransitionend, nextFrame } from './AbstractOverlay.js';\nimport {\n BeforetoggleClosedEvent,\n BeforetoggleOpenEvent,\n OverlayStateEvent,\n} from './events.js';\nimport type { AbstractOverlay } from './AbstractOverlay.js';\nimport { userFocusableSelector } from '@spectrum-web-components/shared';\n\nexport function OverlayDialog<T extends Constructor<AbstractOverlay>>(\n constructor: T\n): T & Constructor<SpectrumElement> {\n class OverlayWithDialog extends constructor {\n protected override async manageDialogOpen(): Promise<void> {\n const targetOpenState = this.open;\n await nextFrame();\n await this.managePosition();\n if (this.open !== targetOpenState) {\n return;\n }\n const focusEl = await this.dialogMakeTransition(targetOpenState);\n if (this.open !== targetOpenState) {\n return;\n }\n await this.dialogApplyFocus(targetOpenState, focusEl);\n }\n\n protected async dialogMakeTransition(\n targetOpenState: boolean\n ): Promise<HTMLElement | null> {\n let focusEl = null as HTMLElement | null;\n const start =\n (el: OpenableElement, index: number) =>\n async (): Promise<void> => {\n el.open = targetOpenState;\n if (!targetOpenState) {\n const close = (): void => {\n el.removeEventListener('close', close);\n finish(el, index);\n };\n el.addEventListener('close', close);\n }\n if (index > 0) {\n // Announce workflow on the first element _only_.\n return;\n }\n const event = targetOpenState\n ? BeforetoggleOpenEvent\n : BeforetoggleClosedEvent;\n this.dispatchEvent(new event());\n if (!targetOpenState) {\n // Show/focus workflow when opening _only_.\n return;\n }\n if (el.matches(userFocusableSelector)) {\n focusEl = el;\n }\n focusEl = focusEl || firstFocusableIn(el);\n if (!focusEl) {\n const childSlots = el.querySelectorAll('slot');\n childSlots.forEach((slot) => {\n if (!focusEl) {\n focusEl = firstFocusableSlottedIn(slot);\n }\n });\n }\n if (!this.isConnected || this.dialogEl.open) {\n // In both of these cases the browser will error.\n // You can neither \"reopen\" a <dialog> or open one that is not on the DOM.\n return;\n }\n this.dialogEl.showModal();\n };\n const finish = (el: OpenableElement, index: number) => (): void => {\n if (this.open !== targetOpenState) {\n return;\n }\n const eventName = targetOpenState ? 'sp-opened' : 'sp-closed';\n if (index > 0) {\n el.dispatchEvent(\n new OverlayStateEvent(eventName, this, {\n interaction: this.type,\n publish: false,\n })\n );\n return;\n }\n if (!this.isConnected || targetOpenState !== this.open) {\n // Don't lead into the `.close()` workflow if not connected to the DOM.\n // The browser will error in this case.\n return;\n }\n const reportChange = async (): Promise<void> => {\n const hasVirtualTrigger =\n this.triggerElement instanceof VirtualTrigger;\n this.dispatchEvent(\n new OverlayStateEvent(eventName, this, {\n interaction: this.type,\n publish: hasVirtualTrigger,\n })\n );\n el.dispatchEvent(\n new OverlayStateEvent(eventName, this, {\n interaction: this.type,\n publish: false,\n })\n );\n if (this.triggerElement && !hasVirtualTrigger) {\n (this.triggerElement as HTMLElement).dispatchEvent(\n new OverlayStateEvent(eventName, this, {\n interaction: this.type,\n publish: true,\n })\n );\n }\n this.state = targetOpenState ? 'opened' : 'closed';\n this.returnFocus();\n // Ensure layout and paint are done and the Overlay is still closed before removing the slottable request.\n await nextFrame();\n await nextFrame();\n if (\n targetOpenState === this.open &&\n targetOpenState === false\n ) {\n this.requestSlottable();\n }\n };\n if (!targetOpenState && this.dialogEl.open) {\n this.dialogEl.addEventListener(\n 'close',\n () => {\n reportChange();\n },\n { once: true }\n );\n this.dialogEl.close();\n } else {\n reportChange();\n }\n };\n this.elements.forEach((el, index) => {\n guaranteedAllTransitionend(\n el,\n start(el, index),\n finish(el, index)\n );\n });\n return focusEl;\n }\n\n protected async dialogApplyFocus(\n targetOpenState: boolean,\n focusEl: HTMLElement | null\n ): Promise<void> {\n /**\n * Focus should be handled natively in `<dialog>` elements when leveraging `.showModal()`, but it's NOT.\n * - webkit bug: https://bugs.webkit.org/show_bug.cgi?id=255507\n * - firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1828398\n **/\n this.applyFocus(targetOpenState, focusEl);\n }\n }\n return OverlayWithDialog;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["firstFocusableIn", "firstFocusableSlottedIn", "VirtualTrigger", "guaranteedAllTransitionend", "nextFrame", "BeforetoggleClosedEvent", "BeforetoggleOpenEvent", "OverlayStateEvent", "userFocusableSelector", "constructor", "OverlayWithDialog", "targetOpenState", "focusEl", "start", "el", "index", "close", "finish", "event", "slot", "eventName", "reportChange", "hasVirtualTrigger"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
import { css } from "@spectrum-web-components/base";
|
|
3
3
|
const styles = css`
|
|
4
|
-
|
|
4
|
+
slot[name=longpress-describedby-descriptor]{display:none}
|
|
5
5
|
`;
|
|
6
6
|
export default styles;
|
|
7
7
|
//# sourceMappingURL=overlay-trigger.css.dev.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["overlay-trigger.css.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2025 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport { css } from '@spectrum-web-components/base';\nconst styles = css`\n
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2025 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport { css } from '@spectrum-web-components/base';\nconst styles = css`\n slot[name=longpress-describedby-descriptor]{display:none}\n`;\nexport default styles;"],
|
|
5
5
|
"mappings": ";AAWA,SAAS,WAAW;AACpB,MAAM,SAAS;AAAA;AAAA;AAGf,eAAe;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";import{css as
|
|
2
|
-
|
|
3
|
-
`;export default
|
|
1
|
+
"use strict";import{css as s}from"@spectrum-web-components/base";const e=s`
|
|
2
|
+
slot[name=longpress-describedby-descriptor]{display:none}
|
|
3
|
+
`;export default e;
|
|
4
4
|
//# sourceMappingURL=overlay-trigger.css.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["overlay-trigger.css.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2025 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport { css } from '@spectrum-web-components/base';\nconst styles = css`\n
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2025 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport { css } from '@spectrum-web-components/base';\nconst styles = css`\n slot[name=longpress-describedby-descriptor]{display:none}\n`;\nexport default styles;"],
|
|
5
5
|
"mappings": "aAWA,OAAS,OAAAA,MAAW,gCACpB,MAAMC,EAASD;AAAA;AAAA,EAGf,eAAeC",
|
|
6
6
|
"names": ["css", "styles"]
|
|
7
7
|
}
|