@spectrum-web-components/overlay 1.0.2 → 1.0.3
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/LICENSE +201 -0
- package/custom-elements.json +189 -73
- package/package.json +8 -7
- package/src/Overlay.d.ts +348 -18
- package/src/Overlay.dev.js +271 -12
- package/src/Overlay.dev.js.map +2 -2
- package/src/Overlay.js +4 -4
- package/src/Overlay.js.map +3 -3
- package/src/PlacementController.d.ts +118 -1
- package/src/PlacementController.dev.js +75 -0
- package/src/PlacementController.dev.js.map +2 -2
- package/src/PlacementController.js.map +2 -2
- package/src/overlay.css.dev.js +1 -1
- package/src/overlay.css.dev.js.map +1 -1
- package/src/overlay.css.js +1 -1
- package/src/overlay.css.js.map +1 -1
- package/stories/index.js +48 -0
- package/stories/index.js.map +7 -0
- package/stories/overlay-directive.stories.js +324 -0
- package/stories/overlay-directive.stories.js.map +7 -0
- package/stories/overlay-element.stories.js +675 -0
- package/stories/overlay-element.stories.js.map +7 -0
- package/stories/overlay-story-components.js +338 -0
- package/stories/overlay-story-components.js.map +7 -0
- package/stories/overlay.stories.js +1397 -0
- package/stories/overlay.stories.js.map +7 -0
- package/test/benchmark/basic-test.js +40 -0
- package/test/benchmark/basic-test.js.map +7 -0
- package/test/benchmark/directive-test.js +43 -0
- package/test/benchmark/directive-test.js.map +7 -0
- package/test/benchmark/element-test.js +40 -0
- package/test/benchmark/element-test.js.map +7 -0
- package/test/benchmark/lazy-test.js +47 -0
- package/test/benchmark/lazy-test.js.map +7 -0
- package/test/index.js +605 -0
- package/test/index.js.map +7 -0
- package/test/overlay-directive.test-vrt.js +5 -0
- package/test/overlay-directive.test-vrt.js.map +7 -0
- package/test/overlay-directive.test.js +162 -0
- package/test/overlay-directive.test.js.map +7 -0
- package/test/overlay-element.test-vrt.js +5 -0
- package/test/overlay-element.test-vrt.js.map +7 -0
- package/test/overlay-element.test.js +934 -0
- package/test/overlay-element.test.js.map +7 -0
- package/test/overlay-lifecycle.test.js +139 -0
- package/test/overlay-lifecycle.test.js.map +7 -0
- package/test/overlay-memory.test.js +10 -0
- package/test/overlay-memory.test.js.map +7 -0
- package/test/overlay-timer.test.js +118 -0
- package/test/overlay-timer.test.js.map +7 -0
- package/test/overlay-trigger-click.test.js +164 -0
- package/test/overlay-trigger-click.test.js.map +7 -0
- package/test/overlay-trigger-directive.test.js +75 -0
- package/test/overlay-trigger-directive.test.js.map +7 -0
- package/test/overlay-trigger-extended.test.js +235 -0
- package/test/overlay-trigger-extended.test.js.map +7 -0
- package/test/overlay-trigger-hover-click.test.js +225 -0
- package/test/overlay-trigger-hover-click.test.js.map +7 -0
- package/test/overlay-trigger-hover.test.js +308 -0
- package/test/overlay-trigger-hover.test.js.map +7 -0
- package/test/overlay-trigger-longpress.test.js +549 -0
- package/test/overlay-trigger-longpress.test.js.map +7 -0
- package/test/overlay-trigger-sync.test.js +5 -0
- package/test/overlay-trigger-sync.test.js.map +7 -0
- package/test/overlay-trigger.test.js +5 -0
- package/test/overlay-trigger.test.js.map +7 -0
- package/test/overlay-update.test.js +28 -0
- package/test/overlay-update.test.js.map +7 -0
- package/test/overlay-v1.test.js +569 -0
- package/test/overlay-v1.test.js.map +7 -0
- package/test/overlay.test-vrt.js +5 -0
- package/test/overlay.test-vrt.js.map +7 -0
- package/test/overlay.test.js +776 -0
- package/test/overlay.test.js.map +7 -0
|
@@ -14,27 +14,144 @@ type OverlayOptionsV1 = {
|
|
|
14
14
|
trigger: HTMLElement | VirtualTrigger;
|
|
15
15
|
type?: 'modal' | 'page' | 'hint' | 'auto' | 'manual';
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Symbol used to indicate that the placement has been updated.
|
|
19
|
+
*/
|
|
17
20
|
export declare const placementUpdatedSymbol: unique symbol;
|
|
21
|
+
/**
|
|
22
|
+
* Controller for managing the placement of an overlay.
|
|
23
|
+
*
|
|
24
|
+
* This class implements the ReactiveController interface and provides methods
|
|
25
|
+
* for managing the positioning and constraints of an overlay element.
|
|
26
|
+
*/
|
|
18
27
|
export declare class PlacementController implements ReactiveController {
|
|
28
|
+
/**
|
|
29
|
+
* Function to clean up resources when the controller is no longer needed.
|
|
30
|
+
*
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
19
33
|
private cleanup?;
|
|
34
|
+
/**
|
|
35
|
+
* Initial height of the overlay.
|
|
36
|
+
*
|
|
37
|
+
* @type {number}
|
|
38
|
+
*/
|
|
20
39
|
initialHeight?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Indicates whether the overlay is constrained by available space.
|
|
42
|
+
*
|
|
43
|
+
* @type {boolean}
|
|
44
|
+
*/
|
|
21
45
|
isConstrained?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* The host element that uses this controller.
|
|
48
|
+
*
|
|
49
|
+
* @private
|
|
50
|
+
* @type {ReactiveElement & { elements: OpenableElement[] }}
|
|
51
|
+
*/
|
|
22
52
|
private host;
|
|
53
|
+
/**
|
|
54
|
+
* Options for configuring the overlay placement.
|
|
55
|
+
*
|
|
56
|
+
* @private
|
|
57
|
+
* @type {OverlayOptionsV1}
|
|
58
|
+
*/
|
|
23
59
|
private options;
|
|
60
|
+
/**
|
|
61
|
+
* A WeakMap to store the original placements of overlay elements.
|
|
62
|
+
*
|
|
63
|
+
* @private
|
|
64
|
+
* @type {WeakMap<HTMLElement, Placement>}
|
|
65
|
+
*/
|
|
24
66
|
private originalPlacements;
|
|
67
|
+
/**
|
|
68
|
+
* The target element for the overlay.
|
|
69
|
+
*
|
|
70
|
+
* @private
|
|
71
|
+
* @type {HTMLElement}
|
|
72
|
+
*/
|
|
25
73
|
private target;
|
|
74
|
+
/**
|
|
75
|
+
* Creates an instance of the PlacementController.
|
|
76
|
+
*
|
|
77
|
+
* @param {ReactiveElement & { elements: OpenableElement[] }} host - The host element that uses this controller.
|
|
78
|
+
*/
|
|
26
79
|
constructor(host: ReactiveElement & {
|
|
27
80
|
elements: OpenableElement[];
|
|
28
81
|
});
|
|
82
|
+
/**
|
|
83
|
+
* Places the overlay relative to the target element.
|
|
84
|
+
*
|
|
85
|
+
* This method sets up the necessary configurations and event listeners to manage the
|
|
86
|
+
* positioning and constraints of the overlay element.
|
|
87
|
+
*
|
|
88
|
+
* @param {HTMLElement} [target=this.target] - The target element for the overlay.
|
|
89
|
+
* @param {OverlayOptionsV1} [options=this.options] - The options for configuring the overlay placement.
|
|
90
|
+
* @returns {Promise<void>} A promise that resolves when the overlay has been placed.
|
|
91
|
+
*/
|
|
29
92
|
placeOverlay(target?: HTMLElement, options?: OverlayOptionsV1): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Flag to allow or disallow placement updates.
|
|
95
|
+
*
|
|
96
|
+
* @type {boolean}
|
|
97
|
+
*/
|
|
30
98
|
allowPlacementUpdate: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Closes the overlay if an ancestor element is updated.
|
|
101
|
+
*
|
|
102
|
+
* This method checks if placement updates are allowed and if the overlay type is not 'modal'.
|
|
103
|
+
* If these conditions are met and a cleanup function is defined, it dispatches a 'close' event
|
|
104
|
+
* on the target element to close the overlay.
|
|
105
|
+
*/
|
|
31
106
|
closeForAncestorUpdate: () => void;
|
|
32
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Updates the placement of the overlay.
|
|
109
|
+
*
|
|
110
|
+
* This method calls the computePlacement method to recalculate the overlay's position.
|
|
111
|
+
*
|
|
112
|
+
* @private
|
|
113
|
+
*/
|
|
114
|
+
private updatePlacement;
|
|
115
|
+
/**
|
|
116
|
+
* Computes the placement of the overlay relative to the target element.
|
|
117
|
+
*
|
|
118
|
+
* This method calculates the necessary positioning and constraints for the overlay element
|
|
119
|
+
* using various middleware functions. It updates the overlay's style and attributes based
|
|
120
|
+
* on the computed position.
|
|
121
|
+
*
|
|
122
|
+
* @returns {Promise<void>} A promise that resolves when the placement has been computed.
|
|
123
|
+
*/
|
|
33
124
|
computePlacement(): Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* Clears the overlay's position styles.
|
|
127
|
+
*
|
|
128
|
+
* This method removes the max-height and max-width styles from the target element,
|
|
129
|
+
* and resets the initial height and constrained state of the overlay.
|
|
130
|
+
*/
|
|
34
131
|
clearOverlayPosition(): void;
|
|
132
|
+
/**
|
|
133
|
+
* Resets the overlay's position.
|
|
134
|
+
*
|
|
135
|
+
* This method clears the overlay's position, forces a reflow, and recomputes the placement.
|
|
136
|
+
*/
|
|
35
137
|
resetOverlayPosition: () => void;
|
|
138
|
+
/**
|
|
139
|
+
* Lifecycle method called when the host element is connected to the DOM.
|
|
140
|
+
*
|
|
141
|
+
* This method sets up an event listener to reset the overlay's position when the 'sp-update-overlays' event is dispatched.
|
|
142
|
+
*/
|
|
36
143
|
hostConnected(): void;
|
|
144
|
+
/**
|
|
145
|
+
* Lifecycle method called when the host element is updated.
|
|
146
|
+
*
|
|
147
|
+
* This method cleans up resources if the overlay is not open.
|
|
148
|
+
*/
|
|
37
149
|
hostUpdated(): void;
|
|
150
|
+
/**
|
|
151
|
+
* Lifecycle method called when the host element is disconnected from the DOM.
|
|
152
|
+
*
|
|
153
|
+
* This method removes the event listener and cleans up resources.
|
|
154
|
+
*/
|
|
38
155
|
hostDisconnected(): void;
|
|
39
156
|
}
|
|
40
157
|
export {};
|
|
@@ -35,18 +35,53 @@ const getFallbackPlacements = (placement) => {
|
|
|
35
35
|
};
|
|
36
36
|
export const placementUpdatedSymbol = Symbol("placement updated");
|
|
37
37
|
export class PlacementController {
|
|
38
|
+
/**
|
|
39
|
+
* Creates an instance of the PlacementController.
|
|
40
|
+
*
|
|
41
|
+
* @param {ReactiveElement & { elements: OpenableElement[] }} host - The host element that uses this controller.
|
|
42
|
+
*/
|
|
38
43
|
constructor(host) {
|
|
44
|
+
/**
|
|
45
|
+
* A WeakMap to store the original placements of overlay elements.
|
|
46
|
+
*
|
|
47
|
+
* @private
|
|
48
|
+
* @type {WeakMap<HTMLElement, Placement>}
|
|
49
|
+
*/
|
|
39
50
|
this.originalPlacements = /* @__PURE__ */ new WeakMap();
|
|
51
|
+
/**
|
|
52
|
+
* Flag to allow or disallow placement updates.
|
|
53
|
+
*
|
|
54
|
+
* @type {boolean}
|
|
55
|
+
*/
|
|
40
56
|
this.allowPlacementUpdate = false;
|
|
57
|
+
/**
|
|
58
|
+
* Closes the overlay if an ancestor element is updated.
|
|
59
|
+
*
|
|
60
|
+
* This method checks if placement updates are allowed and if the overlay type is not 'modal'.
|
|
61
|
+
* If these conditions are met and a cleanup function is defined, it dispatches a 'close' event
|
|
62
|
+
* on the target element to close the overlay.
|
|
63
|
+
*/
|
|
41
64
|
this.closeForAncestorUpdate = () => {
|
|
42
65
|
if (!this.allowPlacementUpdate && this.options.type !== "modal" && this.cleanup) {
|
|
43
66
|
this.target.dispatchEvent(new Event("close", { bubbles: true }));
|
|
44
67
|
}
|
|
45
68
|
this.allowPlacementUpdate = false;
|
|
46
69
|
};
|
|
70
|
+
/**
|
|
71
|
+
* Updates the placement of the overlay.
|
|
72
|
+
*
|
|
73
|
+
* This method calls the computePlacement method to recalculate the overlay's position.
|
|
74
|
+
*
|
|
75
|
+
* @private
|
|
76
|
+
*/
|
|
47
77
|
this.updatePlacement = () => {
|
|
48
78
|
this.computePlacement();
|
|
49
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Resets the overlay's position.
|
|
82
|
+
*
|
|
83
|
+
* This method clears the overlay's position, forces a reflow, and recomputes the placement.
|
|
84
|
+
*/
|
|
50
85
|
this.resetOverlayPosition = () => {
|
|
51
86
|
if (!this.target || !this.options) return;
|
|
52
87
|
this.clearOverlayPosition();
|
|
@@ -56,6 +91,16 @@ export class PlacementController {
|
|
|
56
91
|
this.host = host;
|
|
57
92
|
this.host.addController(this);
|
|
58
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Places the overlay relative to the target element.
|
|
96
|
+
*
|
|
97
|
+
* This method sets up the necessary configurations and event listeners to manage the
|
|
98
|
+
* positioning and constraints of the overlay element.
|
|
99
|
+
*
|
|
100
|
+
* @param {HTMLElement} [target=this.target] - The target element for the overlay.
|
|
101
|
+
* @param {OverlayOptionsV1} [options=this.options] - The options for configuring the overlay placement.
|
|
102
|
+
* @returns {Promise<void>} A promise that resolves when the overlay has been placed.
|
|
103
|
+
*/
|
|
59
104
|
async placeOverlay(target = this.target, options = this.options) {
|
|
60
105
|
this.target = target;
|
|
61
106
|
this.options = options;
|
|
@@ -97,6 +142,15 @@ export class PlacementController {
|
|
|
97
142
|
cleanupElementResize();
|
|
98
143
|
};
|
|
99
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Computes the placement of the overlay relative to the target element.
|
|
147
|
+
*
|
|
148
|
+
* This method calculates the necessary positioning and constraints for the overlay element
|
|
149
|
+
* using various middleware functions. It updates the overlay's style and attributes based
|
|
150
|
+
* on the computed position.
|
|
151
|
+
*
|
|
152
|
+
* @returns {Promise<void>} A promise that resolves when the placement has been computed.
|
|
153
|
+
*/
|
|
100
154
|
async computePlacement() {
|
|
101
155
|
var _a, _b;
|
|
102
156
|
const { options, target } = this;
|
|
@@ -177,6 +231,12 @@ export class PlacementController {
|
|
|
177
231
|
});
|
|
178
232
|
}
|
|
179
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Clears the overlay's position styles.
|
|
236
|
+
*
|
|
237
|
+
* This method removes the max-height and max-width styles from the target element,
|
|
238
|
+
* and resets the initial height and constrained state of the overlay.
|
|
239
|
+
*/
|
|
180
240
|
clearOverlayPosition() {
|
|
181
241
|
if (!this.target) {
|
|
182
242
|
return;
|
|
@@ -186,12 +246,22 @@ export class PlacementController {
|
|
|
186
246
|
this.initialHeight = void 0;
|
|
187
247
|
this.isConstrained = false;
|
|
188
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Lifecycle method called when the host element is connected to the DOM.
|
|
251
|
+
*
|
|
252
|
+
* This method sets up an event listener to reset the overlay's position when the 'sp-update-overlays' event is dispatched.
|
|
253
|
+
*/
|
|
189
254
|
hostConnected() {
|
|
190
255
|
document.addEventListener(
|
|
191
256
|
"sp-update-overlays",
|
|
192
257
|
this.resetOverlayPosition
|
|
193
258
|
);
|
|
194
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* Lifecycle method called when the host element is updated.
|
|
262
|
+
*
|
|
263
|
+
* This method cleans up resources if the overlay is not open.
|
|
264
|
+
*/
|
|
195
265
|
hostUpdated() {
|
|
196
266
|
var _a;
|
|
197
267
|
if (!this.host.open) {
|
|
@@ -199,6 +269,11 @@ export class PlacementController {
|
|
|
199
269
|
this.cleanup = void 0;
|
|
200
270
|
}
|
|
201
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Lifecycle method called when the host element is disconnected from the DOM.
|
|
274
|
+
*
|
|
275
|
+
* This method removes the event listener and cleans up resources.
|
|
276
|
+
*/
|
|
202
277
|
hostDisconnected() {
|
|
203
278
|
var _a;
|
|
204
279
|
(_a = this.cleanup) == null ? void 0 : _a.call(this);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["PlacementController.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2022 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*/\n\nimport type {\n ReactiveController,\n ReactiveElement,\n} from '@spectrum-web-components/base';\nimport {\n arrow,\n autoUpdate,\n computePosition,\n flip,\n offset,\n Placement,\n shift,\n size,\n} from '@floating-ui/dom';\nimport type { VirtualTrigger } from './VirtualTrigger.dev.js'\nimport type { OpenableElement } from './overlay-types.dev.js'\nimport type { Overlay } from './Overlay.dev.js'\n\ntype OverlayOptionsV1 = {\n abortPromise?: Promise<boolean>;\n delayed?: boolean;\n offset?: number | [number, number]; // supporting multi-axis\n placement: Placement;\n notImmediatelyClosable?: boolean; // rename or place behind other API options\n receivesFocus?: 'auto';\n root?: HTMLElement;\n tipPadding?: number;\n trigger: HTMLElement | VirtualTrigger;\n type?: 'modal' | 'page' | 'hint' | 'auto' | 'manual';\n};\n\nfunction roundByDPR(num?: number): number {\n if (typeof num === 'undefined') return 0;\n const dpr = window.devicePixelRatio || 1;\n return Math.round(num * dpr) / dpr ?? -10000;\n}\n\n// See: https://spectrum.adobe.com/page/popover/#Container-padding\nconst REQUIRED_DISTANCE_TO_EDGE = 8;\n// See: https://github.com/adobe/spectrum-web-components/issues/910\nconst MIN_OVERLAY_HEIGHT = 100;\n\nconst getFallbackPlacements = (placement: Placement): Placement[] => {\n const fallbacks: Record<Placement, Placement[]> = {\n left: ['right', 'bottom', 'top'],\n 'left-start': ['right-start', 'bottom', 'top'],\n 'left-end': ['right-end', 'bottom', 'top'],\n right: ['left', 'bottom', 'top'],\n 'right-start': ['left-start', 'bottom', 'top'],\n 'right-end': ['left-end', 'bottom', 'top'],\n top: ['bottom', 'left', 'right'],\n 'top-start': ['bottom-start', 'left', 'right'],\n 'top-end': ['bottom-end', 'left', 'right'],\n bottom: ['top', 'left', 'right'],\n 'bottom-start': ['top-start', 'left', 'right'],\n 'bottom-end': ['top-end', 'left', 'right'],\n };\n return fallbacks[placement] ?? [placement];\n};\n\nexport const placementUpdatedSymbol = Symbol('placement updated');\n\nexport class PlacementController implements ReactiveController {\n private cleanup?: () => void;\n\n initialHeight?: number;\n\n isConstrained?: boolean;\n\n private host!: ReactiveElement & { elements: OpenableElement[] };\n\n private options!: OverlayOptionsV1;\n\n private originalPlacements = new WeakMap<HTMLElement, Placement>();\n\n private target!: HTMLElement;\n\n constructor(host: ReactiveElement & { elements: OpenableElement[] }) {\n this.host = host;\n // Add the controller after the MutationObserver has been created in preparation\n // for the `hostConnected`/`hostDisconnected` callbacks to be run.\n this.host.addController(this);\n }\n\n public async placeOverlay(\n target: HTMLElement = this.target,\n options: OverlayOptionsV1 = this.options\n ): Promise<void> {\n this.target = target;\n this.options = options;\n if (!target || !options) return;\n\n const cleanupAncestorResize = autoUpdate(\n options.trigger,\n target,\n this.closeForAncestorUpdate,\n {\n ancestorResize: false,\n elementResize: false,\n layoutShift: false,\n }\n );\n const cleanupElementResize = autoUpdate(\n options.trigger,\n target,\n this.updatePlacement,\n {\n ancestorScroll: false,\n }\n );\n this.cleanup = () => {\n this.host.elements?.forEach((element) => {\n element.addEventListener(\n 'sp-closed',\n () => {\n const placement = this.originalPlacements.get(element);\n if (placement) {\n element.setAttribute('placement', placement);\n }\n this.originalPlacements.delete(element);\n },\n { once: true }\n );\n });\n cleanupAncestorResize();\n cleanupElementResize();\n };\n }\n\n allowPlacementUpdate = false;\n\n closeForAncestorUpdate = (): void => {\n if (\n !this.allowPlacementUpdate &&\n this.options.type !== 'modal' &&\n this.cleanup\n ) {\n this.target.dispatchEvent(new Event('close', { bubbles: true }));\n }\n this.allowPlacementUpdate = false;\n };\n\n updatePlacement = (): void => {\n this.computePlacement();\n };\n\n async computePlacement(): Promise<void> {\n const { options, target } = this;\n\n await (document.fonts ? document.fonts.ready : Promise.resolve());\n\n const flipMiddleware = !(options.trigger instanceof HTMLElement)\n ? flip({\n padding: REQUIRED_DISTANCE_TO_EDGE,\n fallbackPlacements: getFallbackPlacements(options.placement),\n })\n : flip();\n\n const [mainAxis = 0, crossAxis = 0] = Array.isArray(options?.offset)\n ? options.offset\n : [options.offset, 0];\n\n const tipElement = this.host.elements.find(\n (el) => el.tipElement\n )?.tipElement;\n\n const middleware = [\n offset({\n mainAxis,\n crossAxis,\n }),\n shift({ padding: REQUIRED_DISTANCE_TO_EDGE }),\n flipMiddleware,\n size({\n padding: REQUIRED_DISTANCE_TO_EDGE,\n apply: ({\n availableWidth,\n availableHeight,\n rects: { floating },\n }) => {\n const maxHeight = Math.max(\n MIN_OVERLAY_HEIGHT,\n Math.floor(availableHeight)\n );\n const actualHeight = floating.height;\n this.initialHeight = !this.isConstrained // && !this.virtualTrigger\n ? actualHeight\n : this.initialHeight || actualHeight;\n this.isConstrained =\n actualHeight < this.initialHeight ||\n maxHeight <= actualHeight;\n const appliedHeight = this.isConstrained\n ? `${maxHeight}px`\n : '';\n Object.assign(target.style, {\n maxWidth: `${Math.floor(availableWidth)}px`,\n maxHeight: appliedHeight,\n });\n },\n }),\n ...(tipElement\n ? [\n arrow({\n element: tipElement,\n padding:\n options.tipPadding || REQUIRED_DISTANCE_TO_EDGE,\n }),\n ]\n : []),\n ];\n const { x, y, placement, middlewareData } = await computePosition(\n options.trigger,\n target,\n {\n placement: options.placement,\n middleware,\n strategy: 'fixed',\n }\n );\n Object.assign(target.style, {\n top: '0px',\n left: '0px',\n translate: `${roundByDPR(x)}px ${roundByDPR(y)}px`,\n });\n\n target.setAttribute('actual-placement', placement);\n this.host.elements?.forEach((element) => {\n if (!this.originalPlacements.has(element)) {\n this.originalPlacements.set(\n element,\n element.getAttribute('placement') as Placement\n );\n }\n element.setAttribute('placement', placement);\n });\n\n if (tipElement && middlewareData.arrow) {\n const { x: arrowX, y: arrowY } = middlewareData.arrow;\n\n Object.assign(tipElement.style, {\n top:\n placement.startsWith('right') ||\n placement.startsWith('left')\n ? '0px'\n : '',\n left:\n placement.startsWith('bottom') ||\n placement.startsWith('top')\n ? '0px'\n : '',\n translate: `${roundByDPR(arrowX)}px ${roundByDPR(arrowY)}px`,\n });\n }\n }\n\n public clearOverlayPosition(): void {\n if (!this.target) {\n return;\n }\n this.target.style.removeProperty('max-height');\n this.target.style.removeProperty('max-width');\n this.initialHeight = undefined;\n this.isConstrained = false;\n }\n\n public resetOverlayPosition = (): void => {\n if (!this.target || !this.options) return;\n this.clearOverlayPosition();\n\n // force paint\n this.host.offsetHeight;\n this.computePlacement();\n };\n\n hostConnected(): void {\n document.addEventListener(\n 'sp-update-overlays',\n this.resetOverlayPosition\n );\n }\n\n hostUpdated(): void {\n if (!(this.host as Overlay).open) {\n this.cleanup?.();\n this.cleanup = undefined;\n }\n }\n\n hostDisconnected(): void {\n this.cleanup?.();\n this.cleanup = undefined;\n document.removeEventListener(\n 'sp-update-overlays',\n this.resetOverlayPosition\n );\n }\n}\n"],
|
|
5
|
-
"mappings": ";AAgBA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,OACG;
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2022 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*/\n\nimport type {\n ReactiveController,\n ReactiveElement,\n} from '@spectrum-web-components/base';\nimport {\n arrow,\n autoUpdate,\n computePosition,\n flip,\n offset,\n Placement,\n shift,\n size,\n} from '@floating-ui/dom';\nimport type { VirtualTrigger } from './VirtualTrigger.dev.js'\nimport type { OpenableElement } from './overlay-types.dev.js'\nimport type { Overlay } from './Overlay.dev.js'\n\ntype OverlayOptionsV1 = {\n abortPromise?: Promise<boolean>;\n delayed?: boolean;\n offset?: number | [number, number]; // supporting multi-axis\n placement: Placement;\n notImmediatelyClosable?: boolean; // rename or place behind other API options\n receivesFocus?: 'auto';\n root?: HTMLElement;\n tipPadding?: number;\n trigger: HTMLElement | VirtualTrigger;\n type?: 'modal' | 'page' | 'hint' | 'auto' | 'manual';\n};\n\n/**\n * Rounds a number by the device pixel ratio (DPR).\n *\n * @param {number} [num] - The number to round.\n * @returns {number} The rounded number.\n */\nfunction roundByDPR(num?: number): number {\n if (typeof num === 'undefined') return 0;\n const dpr = window.devicePixelRatio || 1;\n return Math.round(num * dpr) / dpr;\n}\n\n// Minimum distance required between the overlay and the edge of the container.\n// See: https://spectrum.adobe.com/page/popover/#Container-padding\nconst REQUIRED_DISTANCE_TO_EDGE = 8;\n// Minimum height for the overlay.\n// See: https://github.com/adobe/spectrum-web-components/issues/910\nconst MIN_OVERLAY_HEIGHT = 100;\n\n/**\n * Gets fallback placements for the overlay based on the initial placement.\n *\n * @param {Placement} placement - The initial placement of the overlay.\n * @returns {Placement[]} An array of fallback placements.\n */\nconst getFallbackPlacements = (placement: Placement): Placement[] => {\n const fallbacks: Record<Placement, Placement[]> = {\n left: ['right', 'bottom', 'top'],\n 'left-start': ['right-start', 'bottom', 'top'],\n 'left-end': ['right-end', 'bottom', 'top'],\n right: ['left', 'bottom', 'top'],\n 'right-start': ['left-start', 'bottom', 'top'],\n 'right-end': ['left-end', 'bottom', 'top'],\n top: ['bottom', 'left', 'right'],\n 'top-start': ['bottom-start', 'left', 'right'],\n 'top-end': ['bottom-end', 'left', 'right'],\n bottom: ['top', 'left', 'right'],\n 'bottom-start': ['top-start', 'left', 'right'],\n 'bottom-end': ['top-end', 'left', 'right'],\n };\n return fallbacks[placement] ?? [placement];\n};\n\n/**\n * Symbol used to indicate that the placement has been updated.\n */\nexport const placementUpdatedSymbol = Symbol('placement updated');\n\n/**\n * Controller for managing the placement of an overlay.\n *\n * This class implements the ReactiveController interface and provides methods\n * for managing the positioning and constraints of an overlay element.\n */\nexport class PlacementController implements ReactiveController {\n /**\n * Function to clean up resources when the controller is no longer needed.\n *\n * @private\n */\n private cleanup?: () => void;\n\n /**\n * Initial height of the overlay.\n *\n * @type {number}\n */\n initialHeight?: number;\n\n /**\n * Indicates whether the overlay is constrained by available space.\n *\n * @type {boolean}\n */\n isConstrained?: boolean;\n\n /**\n * The host element that uses this controller.\n *\n * @private\n * @type {ReactiveElement & { elements: OpenableElement[] }}\n */\n private host!: ReactiveElement & { elements: OpenableElement[] };\n\n /**\n * Options for configuring the overlay placement.\n *\n * @private\n * @type {OverlayOptionsV1}\n */\n private options!: OverlayOptionsV1;\n\n /**\n * A WeakMap to store the original placements of overlay elements.\n *\n * @private\n * @type {WeakMap<HTMLElement, Placement>}\n */\n private originalPlacements = new WeakMap<HTMLElement, Placement>();\n\n /**\n * The target element for the overlay.\n *\n * @private\n * @type {HTMLElement}\n */\n private target!: HTMLElement;\n\n /**\n * Creates an instance of the PlacementController.\n *\n * @param {ReactiveElement & { elements: OpenableElement[] }} host - The host element that uses this controller.\n */\n constructor(host: ReactiveElement & { elements: OpenableElement[] }) {\n this.host = host;\n // Add the controller after the MutationObserver has been created in preparation\n // for the `hostConnected`/`hostDisconnected` callbacks to be run.\n this.host.addController(this);\n }\n\n /**\n * Places the overlay relative to the target element.\n *\n * This method sets up the necessary configurations and event listeners to manage the\n * positioning and constraints of the overlay element.\n *\n * @param {HTMLElement} [target=this.target] - The target element for the overlay.\n * @param {OverlayOptionsV1} [options=this.options] - The options for configuring the overlay placement.\n * @returns {Promise<void>} A promise that resolves when the overlay has been placed.\n */\n public async placeOverlay(\n target: HTMLElement = this.target,\n options: OverlayOptionsV1 = this.options\n ): Promise<void> {\n // Set the target and options for the overlay.\n this.target = target;\n this.options = options;\n if (!target || !options) return;\n\n // Set up auto-update for ancestor resize events.\n const cleanupAncestorResize = autoUpdate(\n options.trigger,\n target,\n this.closeForAncestorUpdate,\n {\n ancestorResize: false,\n elementResize: false,\n layoutShift: false,\n }\n );\n\n // Set up auto-update for element resize events.\n const cleanupElementResize = autoUpdate(\n options.trigger,\n target,\n this.updatePlacement,\n {\n ancestorScroll: false,\n }\n );\n\n // Define the cleanup function to remove event listeners and reset placements.\n this.cleanup = () => {\n this.host.elements?.forEach((element) => {\n element.addEventListener(\n 'sp-closed',\n () => {\n const placement = this.originalPlacements.get(element);\n\n if (placement) {\n element.setAttribute('placement', placement);\n }\n\n this.originalPlacements.delete(element);\n },\n { once: true }\n );\n });\n cleanupAncestorResize();\n cleanupElementResize();\n };\n }\n\n /**\n * Flag to allow or disallow placement updates.\n *\n * @type {boolean}\n */\n public allowPlacementUpdate = false;\n\n /**\n * Closes the overlay if an ancestor element is updated.\n *\n * This method checks if placement updates are allowed and if the overlay type is not 'modal'.\n * If these conditions are met and a cleanup function is defined, it dispatches a 'close' event\n * on the target element to close the overlay.\n */\n closeForAncestorUpdate = (): void => {\n if (\n !this.allowPlacementUpdate &&\n this.options.type !== 'modal' &&\n this.cleanup\n ) {\n // Dispatch a 'close' event to close the overlay.\n this.target.dispatchEvent(new Event('close', { bubbles: true }));\n }\n\n // Reset the flag to disallow placement updates.\n this.allowPlacementUpdate = false;\n };\n\n /**\n * Updates the placement of the overlay.\n *\n * This method calls the computePlacement method to recalculate the overlay's position.\n *\n * @private\n */\n private updatePlacement = (): void => {\n this.computePlacement();\n };\n\n /**\n * Computes the placement of the overlay relative to the target element.\n *\n * This method calculates the necessary positioning and constraints for the overlay element\n * using various middleware functions. It updates the overlay's style and attributes based\n * on the computed position.\n *\n * @returns {Promise<void>} A promise that resolves when the placement has been computed.\n */\n async computePlacement(): Promise<void> {\n const { options, target } = this;\n\n // Wait for document fonts to be ready before computing placement.\n await (document.fonts ? document.fonts.ready : Promise.resolve());\n\n // Determine the flip middleware based on the type of trigger element.\n const flipMiddleware = !(options.trigger instanceof HTMLElement)\n ? flip({\n padding: REQUIRED_DISTANCE_TO_EDGE,\n fallbackPlacements: getFallbackPlacements(options.placement),\n })\n : flip();\n\n // Extract main axis and cross axis offsets from options.\n const [mainAxis = 0, crossAxis = 0] = Array.isArray(options?.offset)\n ? options.offset\n : [options.offset, 0];\n\n // Find the tip element within the host elements.\n const tipElement = this.host.elements.find(\n (el) => el.tipElement\n )?.tipElement;\n\n // Define middleware functions for positioning and constraints.\n const middleware = [\n offset({\n mainAxis,\n crossAxis,\n }),\n shift({ padding: REQUIRED_DISTANCE_TO_EDGE }),\n flipMiddleware,\n size({\n padding: REQUIRED_DISTANCE_TO_EDGE,\n apply: ({\n availableWidth,\n availableHeight,\n rects: { floating },\n }) => {\n const maxHeight = Math.max(\n MIN_OVERLAY_HEIGHT,\n Math.floor(availableHeight)\n );\n const actualHeight = floating.height;\n this.initialHeight = !this.isConstrained // && !this.virtualTrigger\n ? actualHeight\n : this.initialHeight || actualHeight;\n this.isConstrained =\n actualHeight < this.initialHeight ||\n maxHeight <= actualHeight;\n const appliedHeight = this.isConstrained\n ? `${maxHeight}px`\n : '';\n Object.assign(target.style, {\n maxWidth: `${Math.floor(availableWidth)}px`,\n maxHeight: appliedHeight,\n });\n },\n }),\n ...(tipElement\n ? [\n arrow({\n element: tipElement,\n padding:\n options.tipPadding || REQUIRED_DISTANCE_TO_EDGE,\n }),\n ]\n : []),\n ];\n\n // Compute the position of the overlay using the defined middleware.\n const { x, y, placement, middlewareData } = await computePosition(\n options.trigger,\n target,\n {\n placement: options.placement,\n middleware,\n strategy: 'fixed',\n }\n );\n\n // Update the overlay's style with the computed position.\n Object.assign(target.style, {\n top: '0px',\n left: '0px',\n translate: `${roundByDPR(x)}px ${roundByDPR(y)}px`,\n });\n\n // Set the 'actual-placement' attribute on the target element.\n target.setAttribute('actual-placement', placement);\n\n // Update the placement attribute for each host element.\n this.host.elements?.forEach((element) => {\n if (!this.originalPlacements.has(element)) {\n this.originalPlacements.set(\n element,\n element.getAttribute('placement') as Placement\n );\n }\n element.setAttribute('placement', placement);\n });\n\n // Update the tip element's style with the computed arrow position.\n if (tipElement && middlewareData.arrow) {\n const { x: arrowX, y: arrowY } = middlewareData.arrow;\n\n Object.assign(tipElement.style, {\n top:\n placement.startsWith('right') ||\n placement.startsWith('left')\n ? '0px'\n : '',\n left:\n placement.startsWith('bottom') ||\n placement.startsWith('top')\n ? '0px'\n : '',\n translate: `${roundByDPR(arrowX)}px ${roundByDPR(arrowY)}px`,\n });\n }\n }\n\n /**\n * Clears the overlay's position styles.\n *\n * This method removes the max-height and max-width styles from the target element,\n * and resets the initial height and constrained state of the overlay.\n */\n public clearOverlayPosition(): void {\n if (!this.target) {\n return;\n }\n // Remove max-height and max-width styles from the target element.\n this.target.style.removeProperty('max-height');\n this.target.style.removeProperty('max-width');\n // Reset the initial height and constrained state.\n this.initialHeight = undefined;\n this.isConstrained = false;\n }\n\n /**\n * Resets the overlay's position.\n *\n * This method clears the overlay's position, forces a reflow, and recomputes the placement.\n */\n public resetOverlayPosition = (): void => {\n if (!this.target || !this.options) return;\n // Clear the overlay's position.\n this.clearOverlayPosition();\n\n // Force a reflow.\n this.host.offsetHeight;\n // Recompute the placement.\n this.computePlacement();\n };\n\n /**\n * Lifecycle method called when the host element is connected to the DOM.\n *\n * This method sets up an event listener to reset the overlay's position when the 'sp-update-overlays' event is dispatched.\n */\n hostConnected(): void {\n document.addEventListener(\n 'sp-update-overlays',\n this.resetOverlayPosition\n );\n }\n\n /**\n * Lifecycle method called when the host element is updated.\n *\n * This method cleans up resources if the overlay is not open.\n */\n hostUpdated(): void {\n if (!(this.host as Overlay).open) {\n // Clean up resources if the overlay is not open.\n this.cleanup?.();\n this.cleanup = undefined;\n }\n }\n\n /**\n * Lifecycle method called when the host element is disconnected from the DOM.\n *\n * This method removes the event listener and cleans up resources.\n */\n hostDisconnected(): void {\n // Clean up resources.\n this.cleanup?.();\n this.cleanup = undefined;\n // Remove the event listener.\n document.removeEventListener(\n 'sp-update-overlays',\n this.resetOverlayPosition\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["PlacementController.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2022 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*/\n\nimport type {\n ReactiveController,\n ReactiveElement,\n} from '@spectrum-web-components/base';\nimport {\n arrow,\n autoUpdate,\n computePosition,\n flip,\n offset,\n Placement,\n shift,\n size,\n} from '@floating-ui/dom';\nimport type { VirtualTrigger } from './VirtualTrigger.js';\nimport type { OpenableElement } from './overlay-types.js';\nimport type { Overlay } from './Overlay.js';\n\ntype OverlayOptionsV1 = {\n abortPromise?: Promise<boolean>;\n delayed?: boolean;\n offset?: number | [number, number]; // supporting multi-axis\n placement: Placement;\n notImmediatelyClosable?: boolean; // rename or place behind other API options\n receivesFocus?: 'auto';\n root?: HTMLElement;\n tipPadding?: number;\n trigger: HTMLElement | VirtualTrigger;\n type?: 'modal' | 'page' | 'hint' | 'auto' | 'manual';\n};\n\nfunction roundByDPR(num?: number): number {\n if (typeof num === 'undefined') return 0;\n const dpr = window.devicePixelRatio || 1;\n return Math.round(num * dpr) / dpr ?? -10000;\n}\n\n// See: https://spectrum.adobe.com/page/popover/#Container-padding\nconst REQUIRED_DISTANCE_TO_EDGE = 8;\n// See: https://github.com/adobe/spectrum-web-components/issues/910\nconst MIN_OVERLAY_HEIGHT = 100;\n\nconst getFallbackPlacements = (placement: Placement): Placement[] => {\n const fallbacks: Record<Placement, Placement[]> = {\n left: ['right', 'bottom', 'top'],\n 'left-start': ['right-start', 'bottom', 'top'],\n 'left-end': ['right-end', 'bottom', 'top'],\n right: ['left', 'bottom', 'top'],\n 'right-start': ['left-start', 'bottom', 'top'],\n 'right-end': ['left-end', 'bottom', 'top'],\n top: ['bottom', 'left', 'right'],\n 'top-start': ['bottom-start', 'left', 'right'],\n 'top-end': ['bottom-end', 'left', 'right'],\n bottom: ['top', 'left', 'right'],\n 'bottom-start': ['top-start', 'left', 'right'],\n 'bottom-end': ['top-end', 'left', 'right'],\n };\n return fallbacks[placement] ?? [placement];\n};\n\nexport const placementUpdatedSymbol = Symbol('placement updated');\n\nexport class PlacementController implements ReactiveController {\n private cleanup?: () => void;\n\n initialHeight?: number;\n\n isConstrained?: boolean;\n\n private host!: ReactiveElement & { elements: OpenableElement[] };\n\n private options!: OverlayOptionsV1;\n\n private originalPlacements = new WeakMap<HTMLElement, Placement>();\n\n private target!: HTMLElement;\n\n constructor(host: ReactiveElement & { elements: OpenableElement[] }) {\n this.host = host;\n // Add the controller after the MutationObserver has been created in preparation\n // for the `hostConnected`/`hostDisconnected` callbacks to be run.\n this.host.addController(this);\n }\n\n public async placeOverlay(\n target: HTMLElement = this.target,\n options: OverlayOptionsV1 = this.options\n ): Promise<void> {\n this.target = target;\n this.options = options;\n if (!target || !options) return;\n\n const cleanupAncestorResize = autoUpdate(\n options.trigger,\n target,\n this.closeForAncestorUpdate,\n {\n ancestorResize: false,\n elementResize: false,\n layoutShift: false,\n }\n );\n const cleanupElementResize = autoUpdate(\n options.trigger,\n target,\n this.updatePlacement,\n {\n ancestorScroll: false,\n }\n );\n this.cleanup = () => {\n this.host.elements?.forEach((element) => {\n element.addEventListener(\n 'sp-closed',\n () => {\n const placement = this.originalPlacements.get(element);\n if (placement) {\n element.setAttribute('placement', placement);\n }\n this.originalPlacements.delete(element);\n },\n { once: true }\n );\n });\n cleanupAncestorResize();\n cleanupElementResize();\n };\n }\n\n allowPlacementUpdate = false;\n\n closeForAncestorUpdate = (): void => {\n if (\n !this.allowPlacementUpdate &&\n this.options.type !== 'modal' &&\n this.cleanup\n ) {\n this.target.dispatchEvent(new Event('close', { bubbles: true }));\n }\n this.allowPlacementUpdate = false;\n };\n\n updatePlacement = (): void => {\n this.computePlacement();\n };\n\n async computePlacement(): Promise<void> {\n const { options, target } = this;\n\n await (document.fonts ? document.fonts.ready : Promise.resolve());\n\n const flipMiddleware = !(options.trigger instanceof HTMLElement)\n ? flip({\n padding: REQUIRED_DISTANCE_TO_EDGE,\n fallbackPlacements: getFallbackPlacements(options.placement),\n })\n : flip();\n\n const [mainAxis = 0, crossAxis = 0] = Array.isArray(options?.offset)\n ? options.offset\n : [options.offset, 0];\n\n const tipElement = this.host.elements.find(\n (el) => el.tipElement\n )?.tipElement;\n\n const middleware = [\n offset({\n mainAxis,\n crossAxis,\n }),\n shift({ padding: REQUIRED_DISTANCE_TO_EDGE }),\n flipMiddleware,\n size({\n padding: REQUIRED_DISTANCE_TO_EDGE,\n apply: ({\n availableWidth,\n availableHeight,\n rects: { floating },\n }) => {\n const maxHeight = Math.max(\n MIN_OVERLAY_HEIGHT,\n Math.floor(availableHeight)\n );\n const actualHeight = floating.height;\n this.initialHeight = !this.isConstrained // && !this.virtualTrigger\n ? actualHeight\n : this.initialHeight || actualHeight;\n this.isConstrained =\n actualHeight < this.initialHeight ||\n maxHeight <= actualHeight;\n const appliedHeight = this.isConstrained\n ? `${maxHeight}px`\n : '';\n Object.assign(target.style, {\n maxWidth: `${Math.floor(availableWidth)}px`,\n maxHeight: appliedHeight,\n });\n },\n }),\n ...(tipElement\n ? [\n arrow({\n element: tipElement,\n padding:\n options.tipPadding || REQUIRED_DISTANCE_TO_EDGE,\n }),\n ]\n : []),\n ];\n const { x, y, placement, middlewareData } = await computePosition(\n options.trigger,\n target,\n {\n placement: options.placement,\n middleware,\n strategy: 'fixed',\n }\n );\n Object.assign(target.style, {\n top: '0px',\n left: '0px',\n translate: `${roundByDPR(x)}px ${roundByDPR(y)}px`,\n });\n\n target.setAttribute('actual-placement', placement);\n this.host.elements?.forEach((element) => {\n if (!this.originalPlacements.has(element)) {\n this.originalPlacements.set(\n element,\n element.getAttribute('placement') as Placement\n );\n }\n element.setAttribute('placement', placement);\n });\n\n if (tipElement && middlewareData.arrow) {\n const { x: arrowX, y: arrowY } = middlewareData.arrow;\n\n Object.assign(tipElement.style, {\n top:\n placement.startsWith('right') ||\n placement.startsWith('left')\n ? '0px'\n : '',\n left:\n placement.startsWith('bottom') ||\n placement.startsWith('top')\n ? '0px'\n : '',\n translate: `${roundByDPR(arrowX)}px ${roundByDPR(arrowY)}px`,\n });\n }\n }\n\n public clearOverlayPosition(): void {\n if (!this.target) {\n return;\n }\n this.target.style.removeProperty('max-height');\n this.target.style.removeProperty('max-width');\n this.initialHeight = undefined;\n this.isConstrained = false;\n }\n\n public resetOverlayPosition = (): void => {\n if (!this.target || !this.options) return;\n this.clearOverlayPosition();\n\n // force paint\n this.host.offsetHeight;\n this.computePlacement();\n };\n\n hostConnected(): void {\n document.addEventListener(\n 'sp-update-overlays',\n this.resetOverlayPosition\n );\n }\n\n hostUpdated(): void {\n if (!(this.host as Overlay).open) {\n this.cleanup?.();\n this.cleanup = undefined;\n }\n }\n\n hostDisconnected(): void {\n this.cleanup?.();\n this.cleanup = undefined;\n document.removeEventListener(\n 'sp-update-overlays',\n this.resetOverlayPosition\n );\n }\n}\n"],
|
|
5
|
-
"mappings": "aAgBA,OACI,SAAAA,EACA,cAAAC,EACA,mBAAAC,EACA,QAAAC,EACA,UAAAC,EAEA,SAAAC,EACA,QAAAC,MACG,
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2022 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*/\n\nimport type {\n ReactiveController,\n ReactiveElement,\n} from '@spectrum-web-components/base';\nimport {\n arrow,\n autoUpdate,\n computePosition,\n flip,\n offset,\n Placement,\n shift,\n size,\n} from '@floating-ui/dom';\nimport type { VirtualTrigger } from './VirtualTrigger.js';\nimport type { OpenableElement } from './overlay-types.js';\nimport type { Overlay } from './Overlay.js';\n\ntype OverlayOptionsV1 = {\n abortPromise?: Promise<boolean>;\n delayed?: boolean;\n offset?: number | [number, number]; // supporting multi-axis\n placement: Placement;\n notImmediatelyClosable?: boolean; // rename or place behind other API options\n receivesFocus?: 'auto';\n root?: HTMLElement;\n tipPadding?: number;\n trigger: HTMLElement | VirtualTrigger;\n type?: 'modal' | 'page' | 'hint' | 'auto' | 'manual';\n};\n\n/**\n * Rounds a number by the device pixel ratio (DPR).\n *\n * @param {number} [num] - The number to round.\n * @returns {number} The rounded number.\n */\nfunction roundByDPR(num?: number): number {\n if (typeof num === 'undefined') return 0;\n const dpr = window.devicePixelRatio || 1;\n return Math.round(num * dpr) / dpr;\n}\n\n// Minimum distance required between the overlay and the edge of the container.\n// See: https://spectrum.adobe.com/page/popover/#Container-padding\nconst REQUIRED_DISTANCE_TO_EDGE = 8;\n// Minimum height for the overlay.\n// See: https://github.com/adobe/spectrum-web-components/issues/910\nconst MIN_OVERLAY_HEIGHT = 100;\n\n/**\n * Gets fallback placements for the overlay based on the initial placement.\n *\n * @param {Placement} placement - The initial placement of the overlay.\n * @returns {Placement[]} An array of fallback placements.\n */\nconst getFallbackPlacements = (placement: Placement): Placement[] => {\n const fallbacks: Record<Placement, Placement[]> = {\n left: ['right', 'bottom', 'top'],\n 'left-start': ['right-start', 'bottom', 'top'],\n 'left-end': ['right-end', 'bottom', 'top'],\n right: ['left', 'bottom', 'top'],\n 'right-start': ['left-start', 'bottom', 'top'],\n 'right-end': ['left-end', 'bottom', 'top'],\n top: ['bottom', 'left', 'right'],\n 'top-start': ['bottom-start', 'left', 'right'],\n 'top-end': ['bottom-end', 'left', 'right'],\n bottom: ['top', 'left', 'right'],\n 'bottom-start': ['top-start', 'left', 'right'],\n 'bottom-end': ['top-end', 'left', 'right'],\n };\n return fallbacks[placement] ?? [placement];\n};\n\n/**\n * Symbol used to indicate that the placement has been updated.\n */\nexport const placementUpdatedSymbol = Symbol('placement updated');\n\n/**\n * Controller for managing the placement of an overlay.\n *\n * This class implements the ReactiveController interface and provides methods\n * for managing the positioning and constraints of an overlay element.\n */\nexport class PlacementController implements ReactiveController {\n /**\n * Function to clean up resources when the controller is no longer needed.\n *\n * @private\n */\n private cleanup?: () => void;\n\n /**\n * Initial height of the overlay.\n *\n * @type {number}\n */\n initialHeight?: number;\n\n /**\n * Indicates whether the overlay is constrained by available space.\n *\n * @type {boolean}\n */\n isConstrained?: boolean;\n\n /**\n * The host element that uses this controller.\n *\n * @private\n * @type {ReactiveElement & { elements: OpenableElement[] }}\n */\n private host!: ReactiveElement & { elements: OpenableElement[] };\n\n /**\n * Options for configuring the overlay placement.\n *\n * @private\n * @type {OverlayOptionsV1}\n */\n private options!: OverlayOptionsV1;\n\n /**\n * A WeakMap to store the original placements of overlay elements.\n *\n * @private\n * @type {WeakMap<HTMLElement, Placement>}\n */\n private originalPlacements = new WeakMap<HTMLElement, Placement>();\n\n /**\n * The target element for the overlay.\n *\n * @private\n * @type {HTMLElement}\n */\n private target!: HTMLElement;\n\n /**\n * Creates an instance of the PlacementController.\n *\n * @param {ReactiveElement & { elements: OpenableElement[] }} host - The host element that uses this controller.\n */\n constructor(host: ReactiveElement & { elements: OpenableElement[] }) {\n this.host = host;\n // Add the controller after the MutationObserver has been created in preparation\n // for the `hostConnected`/`hostDisconnected` callbacks to be run.\n this.host.addController(this);\n }\n\n /**\n * Places the overlay relative to the target element.\n *\n * This method sets up the necessary configurations and event listeners to manage the\n * positioning and constraints of the overlay element.\n *\n * @param {HTMLElement} [target=this.target] - The target element for the overlay.\n * @param {OverlayOptionsV1} [options=this.options] - The options for configuring the overlay placement.\n * @returns {Promise<void>} A promise that resolves when the overlay has been placed.\n */\n public async placeOverlay(\n target: HTMLElement = this.target,\n options: OverlayOptionsV1 = this.options\n ): Promise<void> {\n // Set the target and options for the overlay.\n this.target = target;\n this.options = options;\n if (!target || !options) return;\n\n // Set up auto-update for ancestor resize events.\n const cleanupAncestorResize = autoUpdate(\n options.trigger,\n target,\n this.closeForAncestorUpdate,\n {\n ancestorResize: false,\n elementResize: false,\n layoutShift: false,\n }\n );\n\n // Set up auto-update for element resize events.\n const cleanupElementResize = autoUpdate(\n options.trigger,\n target,\n this.updatePlacement,\n {\n ancestorScroll: false,\n }\n );\n\n // Define the cleanup function to remove event listeners and reset placements.\n this.cleanup = () => {\n this.host.elements?.forEach((element) => {\n element.addEventListener(\n 'sp-closed',\n () => {\n const placement = this.originalPlacements.get(element);\n\n if (placement) {\n element.setAttribute('placement', placement);\n }\n\n this.originalPlacements.delete(element);\n },\n { once: true }\n );\n });\n cleanupAncestorResize();\n cleanupElementResize();\n };\n }\n\n /**\n * Flag to allow or disallow placement updates.\n *\n * @type {boolean}\n */\n public allowPlacementUpdate = false;\n\n /**\n * Closes the overlay if an ancestor element is updated.\n *\n * This method checks if placement updates are allowed and if the overlay type is not 'modal'.\n * If these conditions are met and a cleanup function is defined, it dispatches a 'close' event\n * on the target element to close the overlay.\n */\n closeForAncestorUpdate = (): void => {\n if (\n !this.allowPlacementUpdate &&\n this.options.type !== 'modal' &&\n this.cleanup\n ) {\n // Dispatch a 'close' event to close the overlay.\n this.target.dispatchEvent(new Event('close', { bubbles: true }));\n }\n\n // Reset the flag to disallow placement updates.\n this.allowPlacementUpdate = false;\n };\n\n /**\n * Updates the placement of the overlay.\n *\n * This method calls the computePlacement method to recalculate the overlay's position.\n *\n * @private\n */\n private updatePlacement = (): void => {\n this.computePlacement();\n };\n\n /**\n * Computes the placement of the overlay relative to the target element.\n *\n * This method calculates the necessary positioning and constraints for the overlay element\n * using various middleware functions. It updates the overlay's style and attributes based\n * on the computed position.\n *\n * @returns {Promise<void>} A promise that resolves when the placement has been computed.\n */\n async computePlacement(): Promise<void> {\n const { options, target } = this;\n\n // Wait for document fonts to be ready before computing placement.\n await (document.fonts ? document.fonts.ready : Promise.resolve());\n\n // Determine the flip middleware based on the type of trigger element.\n const flipMiddleware = !(options.trigger instanceof HTMLElement)\n ? flip({\n padding: REQUIRED_DISTANCE_TO_EDGE,\n fallbackPlacements: getFallbackPlacements(options.placement),\n })\n : flip();\n\n // Extract main axis and cross axis offsets from options.\n const [mainAxis = 0, crossAxis = 0] = Array.isArray(options?.offset)\n ? options.offset\n : [options.offset, 0];\n\n // Find the tip element within the host elements.\n const tipElement = this.host.elements.find(\n (el) => el.tipElement\n )?.tipElement;\n\n // Define middleware functions for positioning and constraints.\n const middleware = [\n offset({\n mainAxis,\n crossAxis,\n }),\n shift({ padding: REQUIRED_DISTANCE_TO_EDGE }),\n flipMiddleware,\n size({\n padding: REQUIRED_DISTANCE_TO_EDGE,\n apply: ({\n availableWidth,\n availableHeight,\n rects: { floating },\n }) => {\n const maxHeight = Math.max(\n MIN_OVERLAY_HEIGHT,\n Math.floor(availableHeight)\n );\n const actualHeight = floating.height;\n this.initialHeight = !this.isConstrained // && !this.virtualTrigger\n ? actualHeight\n : this.initialHeight || actualHeight;\n this.isConstrained =\n actualHeight < this.initialHeight ||\n maxHeight <= actualHeight;\n const appliedHeight = this.isConstrained\n ? `${maxHeight}px`\n : '';\n Object.assign(target.style, {\n maxWidth: `${Math.floor(availableWidth)}px`,\n maxHeight: appliedHeight,\n });\n },\n }),\n ...(tipElement\n ? [\n arrow({\n element: tipElement,\n padding:\n options.tipPadding || REQUIRED_DISTANCE_TO_EDGE,\n }),\n ]\n : []),\n ];\n\n // Compute the position of the overlay using the defined middleware.\n const { x, y, placement, middlewareData } = await computePosition(\n options.trigger,\n target,\n {\n placement: options.placement,\n middleware,\n strategy: 'fixed',\n }\n );\n\n // Update the overlay's style with the computed position.\n Object.assign(target.style, {\n top: '0px',\n left: '0px',\n translate: `${roundByDPR(x)}px ${roundByDPR(y)}px`,\n });\n\n // Set the 'actual-placement' attribute on the target element.\n target.setAttribute('actual-placement', placement);\n\n // Update the placement attribute for each host element.\n this.host.elements?.forEach((element) => {\n if (!this.originalPlacements.has(element)) {\n this.originalPlacements.set(\n element,\n element.getAttribute('placement') as Placement\n );\n }\n element.setAttribute('placement', placement);\n });\n\n // Update the tip element's style with the computed arrow position.\n if (tipElement && middlewareData.arrow) {\n const { x: arrowX, y: arrowY } = middlewareData.arrow;\n\n Object.assign(tipElement.style, {\n top:\n placement.startsWith('right') ||\n placement.startsWith('left')\n ? '0px'\n : '',\n left:\n placement.startsWith('bottom') ||\n placement.startsWith('top')\n ? '0px'\n : '',\n translate: `${roundByDPR(arrowX)}px ${roundByDPR(arrowY)}px`,\n });\n }\n }\n\n /**\n * Clears the overlay's position styles.\n *\n * This method removes the max-height and max-width styles from the target element,\n * and resets the initial height and constrained state of the overlay.\n */\n public clearOverlayPosition(): void {\n if (!this.target) {\n return;\n }\n // Remove max-height and max-width styles from the target element.\n this.target.style.removeProperty('max-height');\n this.target.style.removeProperty('max-width');\n // Reset the initial height and constrained state.\n this.initialHeight = undefined;\n this.isConstrained = false;\n }\n\n /**\n * Resets the overlay's position.\n *\n * This method clears the overlay's position, forces a reflow, and recomputes the placement.\n */\n public resetOverlayPosition = (): void => {\n if (!this.target || !this.options) return;\n // Clear the overlay's position.\n this.clearOverlayPosition();\n\n // Force a reflow.\n this.host.offsetHeight;\n // Recompute the placement.\n this.computePlacement();\n };\n\n /**\n * Lifecycle method called when the host element is connected to the DOM.\n *\n * This method sets up an event listener to reset the overlay's position when the 'sp-update-overlays' event is dispatched.\n */\n hostConnected(): void {\n document.addEventListener(\n 'sp-update-overlays',\n this.resetOverlayPosition\n );\n }\n\n /**\n * Lifecycle method called when the host element is updated.\n *\n * This method cleans up resources if the overlay is not open.\n */\n hostUpdated(): void {\n if (!(this.host as Overlay).open) {\n // Clean up resources if the overlay is not open.\n this.cleanup?.();\n this.cleanup = undefined;\n }\n }\n\n /**\n * Lifecycle method called when the host element is disconnected from the DOM.\n *\n * This method removes the event listener and cleans up resources.\n */\n hostDisconnected(): void {\n // Clean up resources.\n this.cleanup?.();\n this.cleanup = undefined;\n // Remove the event listener.\n document.removeEventListener(\n 'sp-update-overlays',\n this.resetOverlayPosition\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["arrow", "autoUpdate", "computePosition", "flip", "offset", "shift", "size", "roundByDPR", "num", "dpr", "REQUIRED_DISTANCE_TO_EDGE", "MIN_OVERLAY_HEIGHT", "getFallbackPlacements", "placement", "_a", "host", "target", "options", "cleanupAncestorResize", "cleanupElementResize", "element", "_b", "flipMiddleware", "mainAxis", "crossAxis", "tipElement", "el", "middleware", "availableWidth", "availableHeight", "floating", "maxHeight", "actualHeight", "appliedHeight", "x", "y", "middlewareData", "arrowX", "arrowY"]
|
|
7
7
|
}
|
package/src/overlay.css.dev.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
import { css } from "@spectrum-web-components/base";
|
|
3
3
|
const styles = css`
|
|
4
|
-
:host{pointer-events:none;--swc-overlay-animation-distance:var(--spectrum-spacing-100);display:contents}:host(:has(>sp-tooltip)){--swc-overlay-animation-distance:var(--spectrum-tooltip-animation-distance)}.dialog{box-sizing:border-box;max-height:calc(100vh - 16px);max-height:calc(100dvh - 16px);max-width:calc(100vw - 16px);height:auto;--sp-overlay-open:true;background:0 0;border:0;margin:0;padding:0;position:fixed;inset:0 auto auto 0;overflow:visible;opacity:1!important}.dialog:not([is-visible]){display:none}.dialog:focus{outline:none}dialog:modal{--mod-popover-filter:var(--spectrum-popover-filter)}:host(:not([open])) .dialog{--sp-overlay-open:false}.dialog::backdrop{display:none}.dialog:before{content:"";position:absolute;inset:-999em;pointer-events:auto!important}.dialog:not(.not-immediately-closable):before{display:none}.dialog>div{width:100%}::slotted(*){pointer-events:auto;visibility:visible!important}::slotted(sp-popover){position:static}.dialog:not([actual-placement])[placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog:not([actual-placement])[placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}slot[name=longpress-describedby-descriptor]{display:none}@supports selector(:open){.dialog{opacity:0}.dialog:open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports selector(:popover-open){.dialog{opacity:0}.dialog:popover-open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports (overlay:auto){.dialog{transition:all var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s)),translate 0s,display var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s));transition-behavior:allow-discrete;display:none}.dialog:popover-open,.dialog:modal{display:flex}}@supports (not selector(:open)) and (not selector(:popover-open)){:host:not([open]) .dialog{pointer-events:none}.dialog[actual-placement]{z-index:calc(var(--swc-overlay-z-index-base,1000) + var(--swc-overlay-open-count))}}
|
|
4
|
+
:host{pointer-events:none;--swc-overlay-animation-distance:var(--spectrum-spacing-100);display:contents}:host(:has(>sp-tooltip)){--swc-overlay-animation-distance:var(--spectrum-tooltip-animation-distance)}.dialog{box-sizing:border-box;max-height:calc(100vh - 16px);max-height:calc(100dvh - 16px);max-width:calc(100vw - 16px);height:auto;--sp-overlay-open:true;background:0 0;border:0;margin:0;padding:0;display:flex;position:fixed;inset:0 auto auto 0;overflow:visible;opacity:1!important}.dialog:not([is-visible]){display:none}.dialog:focus{outline:none}dialog:modal{--mod-popover-filter:var(--spectrum-popover-filter)}:host(:not([open])) .dialog{--sp-overlay-open:false}.dialog::backdrop{display:none}.dialog:before{content:"";position:absolute;inset:-999em;pointer-events:auto!important}.dialog:not(.not-immediately-closable):before{display:none}.dialog>div{width:100%}::slotted(*){pointer-events:auto;visibility:visible!important}::slotted(sp-popover){position:static}.dialog:not([actual-placement])[placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog:not([actual-placement])[placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}slot[name=longpress-describedby-descriptor]{display:none}@supports selector(:open){.dialog{opacity:0}.dialog:open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports selector(:popover-open){.dialog{opacity:0}.dialog:popover-open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports (overlay:auto){.dialog{transition:all var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s)),translate 0s,display var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s));transition-behavior:allow-discrete;display:none}.dialog:popover-open,.dialog:modal{display:flex}}@supports (not selector(:open)) and (not selector(:popover-open)){:host:not([open]) .dialog{pointer-events:none}.dialog[actual-placement]{z-index:calc(var(--swc-overlay-z-index-base,1000) + var(--swc-overlay-open-count))}}
|
|
5
5
|
`;
|
|
6
6
|
export default styles;
|
|
7
7
|
//# sourceMappingURL=overlay.css.dev.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["overlay.css.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2024 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 :host{pointer-events:none;--swc-overlay-animation-distance:var(--spectrum-spacing-100);display:contents}:host(:has(>sp-tooltip)){--swc-overlay-animation-distance:var(--spectrum-tooltip-animation-distance)}.dialog{box-sizing:border-box;max-height:calc(100vh - 16px);max-height:calc(100dvh - 16px);max-width:calc(100vw - 16px);height:auto;--sp-overlay-open:true;background:0 0;border:0;margin:0;padding:0;position:fixed;inset:0 auto auto 0;overflow:visible;opacity:1!important}.dialog:not([is-visible]){display:none}.dialog:focus{outline:none}dialog:modal{--mod-popover-filter:var(--spectrum-popover-filter)}:host(:not([open])) .dialog{--sp-overlay-open:false}.dialog::backdrop{display:none}.dialog:before{content:\"\";position:absolute;inset:-999em;pointer-events:auto!important}.dialog:not(.not-immediately-closable):before{display:none}.dialog>div{width:100%}::slotted(*){pointer-events:auto;visibility:visible!important}::slotted(sp-popover){position:static}.dialog:not([actual-placement])[placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog:not([actual-placement])[placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}slot[name=longpress-describedby-descriptor]{display:none}@supports selector(:open){.dialog{opacity:0}.dialog:open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports selector(:popover-open){.dialog{opacity:0}.dialog:popover-open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports (overlay:auto){.dialog{transition:all var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s)),translate 0s,display var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s));transition-behavior:allow-discrete;display:none}.dialog:popover-open,.dialog:modal{display:flex}}@supports (not selector(:open)) and (not selector(:popover-open)){:host:not([open]) .dialog{pointer-events:none}.dialog[actual-placement]{z-index:calc(var(--swc-overlay-z-index-base,1000) + var(--swc-overlay-open-count))}}\n`;\nexport default styles;"],
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2024 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 :host{pointer-events:none;--swc-overlay-animation-distance:var(--spectrum-spacing-100);display:contents}:host(:has(>sp-tooltip)){--swc-overlay-animation-distance:var(--spectrum-tooltip-animation-distance)}.dialog{box-sizing:border-box;max-height:calc(100vh - 16px);max-height:calc(100dvh - 16px);max-width:calc(100vw - 16px);height:auto;--sp-overlay-open:true;background:0 0;border:0;margin:0;padding:0;display:flex;position:fixed;inset:0 auto auto 0;overflow:visible;opacity:1!important}.dialog:not([is-visible]){display:none}.dialog:focus{outline:none}dialog:modal{--mod-popover-filter:var(--spectrum-popover-filter)}:host(:not([open])) .dialog{--sp-overlay-open:false}.dialog::backdrop{display:none}.dialog:before{content:\"\";position:absolute;inset:-999em;pointer-events:auto!important}.dialog:not(.not-immediately-closable):before{display:none}.dialog>div{width:100%}::slotted(*){pointer-events:auto;visibility:visible!important}::slotted(sp-popover){position:static}.dialog:not([actual-placement])[placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog:not([actual-placement])[placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}slot[name=longpress-describedby-descriptor]{display:none}@supports selector(:open){.dialog{opacity:0}.dialog:open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports selector(:popover-open){.dialog{opacity:0}.dialog:popover-open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports (overlay:auto){.dialog{transition:all var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s)),translate 0s,display var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s));transition-behavior:allow-discrete;display:none}.dialog:popover-open,.dialog:modal{display:flex}}@supports (not selector(:open)) and (not selector(:popover-open)){:host:not([open]) .dialog{pointer-events:none}.dialog[actual-placement]{z-index:calc(var(--swc-overlay-z-index-base,1000) + var(--swc-overlay-open-count))}}\n`;\nexport default styles;"],
|
|
5
5
|
"mappings": ";AAWA,SAAS,WAAW;AACpB,MAAM,SAAS;AAAA;AAAA;AAGf,eAAe;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/src/overlay.css.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use strict";import{css as a}from"@spectrum-web-components/base";const o=a`
|
|
2
|
-
:host{pointer-events:none;--swc-overlay-animation-distance:var(--spectrum-spacing-100);display:contents}:host(:has(>sp-tooltip)){--swc-overlay-animation-distance:var(--spectrum-tooltip-animation-distance)}.dialog{box-sizing:border-box;max-height:calc(100vh - 16px);max-height:calc(100dvh - 16px);max-width:calc(100vw - 16px);height:auto;--sp-overlay-open:true;background:0 0;border:0;margin:0;padding:0;position:fixed;inset:0 auto auto 0;overflow:visible;opacity:1!important}.dialog:not([is-visible]){display:none}.dialog:focus{outline:none}dialog:modal{--mod-popover-filter:var(--spectrum-popover-filter)}:host(:not([open])) .dialog{--sp-overlay-open:false}.dialog::backdrop{display:none}.dialog:before{content:"";position:absolute;inset:-999em;pointer-events:auto!important}.dialog:not(.not-immediately-closable):before{display:none}.dialog>div{width:100%}::slotted(*){pointer-events:auto;visibility:visible!important}::slotted(sp-popover){position:static}.dialog:not([actual-placement])[placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog:not([actual-placement])[placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}slot[name=longpress-describedby-descriptor]{display:none}@supports selector(:open){.dialog{opacity:0}.dialog:open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports selector(:popover-open){.dialog{opacity:0}.dialog:popover-open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports (overlay:auto){.dialog{transition:all var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s)),translate 0s,display var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s));transition-behavior:allow-discrete;display:none}.dialog:popover-open,.dialog:modal{display:flex}}@supports (not selector(:open)) and (not selector(:popover-open)){:host:not([open]) .dialog{pointer-events:none}.dialog[actual-placement]{z-index:calc(var(--swc-overlay-z-index-base,1000) + var(--swc-overlay-open-count))}}
|
|
2
|
+
:host{pointer-events:none;--swc-overlay-animation-distance:var(--spectrum-spacing-100);display:contents}:host(:has(>sp-tooltip)){--swc-overlay-animation-distance:var(--spectrum-tooltip-animation-distance)}.dialog{box-sizing:border-box;max-height:calc(100vh - 16px);max-height:calc(100dvh - 16px);max-width:calc(100vw - 16px);height:auto;--sp-overlay-open:true;background:0 0;border:0;margin:0;padding:0;display:flex;position:fixed;inset:0 auto auto 0;overflow:visible;opacity:1!important}.dialog:not([is-visible]){display:none}.dialog:focus{outline:none}dialog:modal{--mod-popover-filter:var(--spectrum-popover-filter)}:host(:not([open])) .dialog{--sp-overlay-open:false}.dialog::backdrop{display:none}.dialog:before{content:"";position:absolute;inset:-999em;pointer-events:auto!important}.dialog:not(.not-immediately-closable):before{display:none}.dialog>div{width:100%}::slotted(*){pointer-events:auto;visibility:visible!important}::slotted(sp-popover){position:static}.dialog:not([actual-placement])[placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog:not([actual-placement])[placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}slot[name=longpress-describedby-descriptor]{display:none}@supports selector(:open){.dialog{opacity:0}.dialog:open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports selector(:popover-open){.dialog{opacity:0}.dialog:popover-open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports (overlay:auto){.dialog{transition:all var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s)),translate 0s,display var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s));transition-behavior:allow-discrete;display:none}.dialog:popover-open,.dialog:modal{display:flex}}@supports (not selector(:open)) and (not selector(:popover-open)){:host:not([open]) .dialog{pointer-events:none}.dialog[actual-placement]{z-index:calc(var(--swc-overlay-z-index-base,1000) + var(--swc-overlay-open-count))}}
|
|
3
3
|
`;export default o;
|
|
4
4
|
//# sourceMappingURL=overlay.css.js.map
|
package/src/overlay.css.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["overlay.css.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2024 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 :host{pointer-events:none;--swc-overlay-animation-distance:var(--spectrum-spacing-100);display:contents}:host(:has(>sp-tooltip)){--swc-overlay-animation-distance:var(--spectrum-tooltip-animation-distance)}.dialog{box-sizing:border-box;max-height:calc(100vh - 16px);max-height:calc(100dvh - 16px);max-width:calc(100vw - 16px);height:auto;--sp-overlay-open:true;background:0 0;border:0;margin:0;padding:0;position:fixed;inset:0 auto auto 0;overflow:visible;opacity:1!important}.dialog:not([is-visible]){display:none}.dialog:focus{outline:none}dialog:modal{--mod-popover-filter:var(--spectrum-popover-filter)}:host(:not([open])) .dialog{--sp-overlay-open:false}.dialog::backdrop{display:none}.dialog:before{content:\"\";position:absolute;inset:-999em;pointer-events:auto!important}.dialog:not(.not-immediately-closable):before{display:none}.dialog>div{width:100%}::slotted(*){pointer-events:auto;visibility:visible!important}::slotted(sp-popover){position:static}.dialog:not([actual-placement])[placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog:not([actual-placement])[placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}slot[name=longpress-describedby-descriptor]{display:none}@supports selector(:open){.dialog{opacity:0}.dialog:open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports selector(:popover-open){.dialog{opacity:0}.dialog:popover-open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports (overlay:auto){.dialog{transition:all var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s)),translate 0s,display var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s));transition-behavior:allow-discrete;display:none}.dialog:popover-open,.dialog:modal{display:flex}}@supports (not selector(:open)) and (not selector(:popover-open)){:host:not([open]) .dialog{pointer-events:none}.dialog[actual-placement]{z-index:calc(var(--swc-overlay-z-index-base,1000) + var(--swc-overlay-open-count))}}\n`;\nexport default styles;"],
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2024 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 :host{pointer-events:none;--swc-overlay-animation-distance:var(--spectrum-spacing-100);display:contents}:host(:has(>sp-tooltip)){--swc-overlay-animation-distance:var(--spectrum-tooltip-animation-distance)}.dialog{box-sizing:border-box;max-height:calc(100vh - 16px);max-height:calc(100dvh - 16px);max-width:calc(100vw - 16px);height:auto;--sp-overlay-open:true;background:0 0;border:0;margin:0;padding:0;display:flex;position:fixed;inset:0 auto auto 0;overflow:visible;opacity:1!important}.dialog:not([is-visible]){display:none}.dialog:focus{outline:none}dialog:modal{--mod-popover-filter:var(--spectrum-popover-filter)}:host(:not([open])) .dialog{--sp-overlay-open:false}.dialog::backdrop{display:none}.dialog:before{content:\"\";position:absolute;inset:-999em;pointer-events:auto!important}.dialog:not(.not-immediately-closable):before{display:none}.dialog>div{width:100%}::slotted(*){pointer-events:auto;visibility:visible!important}::slotted(sp-popover){position:static}.dialog:not([actual-placement])[placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog:not([actual-placement])[placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog:not([actual-placement])[placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=top]{padding-block:var(--swc-overlay-animation-distance);margin-top:var(--swc-overlay-animation-distance)}.dialog[actual-placement*=right]{padding-inline:var(--swc-overlay-animation-distance);margin-left:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=bottom]{padding-block:var(--swc-overlay-animation-distance);margin-top:calc(-1*var(--swc-overlay-animation-distance))}.dialog[actual-placement*=left]{padding-inline:var(--swc-overlay-animation-distance);margin-left:var(--swc-overlay-animation-distance)}slot[name=longpress-describedby-descriptor]{display:none}@supports selector(:open){.dialog{opacity:0}.dialog:open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports selector(:popover-open){.dialog{opacity:0}.dialog:popover-open{opacity:1;--mod-popover-filter:var(--spectrum-popover-filter)}}@supports (overlay:auto){.dialog{transition:all var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s)),translate 0s,display var(--mod-overlay-animation-duration,var(--spectrum-animation-duration-100,.13s));transition-behavior:allow-discrete;display:none}.dialog:popover-open,.dialog:modal{display:flex}}@supports (not selector(:open)) and (not selector(:popover-open)){:host:not([open]) .dialog{pointer-events:none}.dialog[actual-placement]{z-index:calc(var(--swc-overlay-z-index-base,1000) + var(--swc-overlay-open-count))}}\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
|
}
|
package/stories/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { html } from "@spectrum-web-components/base";
|
|
3
|
+
function nextFrame() {
|
|
4
|
+
return new Promise((res) => requestAnimationFrame(() => res()));
|
|
5
|
+
}
|
|
6
|
+
class IsOverlayOpen extends HTMLElement {
|
|
7
|
+
constructor() {
|
|
8
|
+
super();
|
|
9
|
+
this.sendFocus = async () => {
|
|
10
|
+
var _a;
|
|
11
|
+
const selectedItem = (_a = document.querySelector("[focusable]")) == null ? void 0 : _a.querySelector("[selected]");
|
|
12
|
+
if (selectedItem) {
|
|
13
|
+
selectedItem.focus();
|
|
14
|
+
selectedItem.focused = true;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
this.handleOpened = async (event) => {
|
|
18
|
+
const overlay = event.target;
|
|
19
|
+
const actions = [nextFrame(), overlay.updateComplete, this.sendFocus()];
|
|
20
|
+
await Promise.all(actions);
|
|
21
|
+
await nextFrame();
|
|
22
|
+
await nextFrame();
|
|
23
|
+
await nextFrame();
|
|
24
|
+
await nextFrame();
|
|
25
|
+
this.ready(true);
|
|
26
|
+
};
|
|
27
|
+
this.readyPromise = Promise.resolve(false);
|
|
28
|
+
this.readyPromise = new Promise((res) => {
|
|
29
|
+
this.ready = res;
|
|
30
|
+
this.setup();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async setup() {
|
|
34
|
+
await nextFrame();
|
|
35
|
+
document.addEventListener("sp-opened", this.handleOpened);
|
|
36
|
+
}
|
|
37
|
+
get updateComplete() {
|
|
38
|
+
return this.readyPromise;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
customElements.define("is-overlay-open", IsOverlayOpen);
|
|
42
|
+
export const isOverlayOpen = (story) => {
|
|
43
|
+
return html`
|
|
44
|
+
${story()}
|
|
45
|
+
<is-overlay-open></is-overlay-open>
|
|
46
|
+
`;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["index.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*/\n\nimport { html, TemplateResult } from '@spectrum-web-components/base';\nimport type { Overlay } from '@spectrum-web-components/overlay';\n\nfunction nextFrame(): Promise<void> {\n return new Promise((res) => requestAnimationFrame(() => res()));\n}\n\nclass IsOverlayOpen extends HTMLElement {\n ready!: (value: boolean | PromiseLike<boolean>) => void;\n\n constructor() {\n super();\n this.readyPromise = new Promise((res) => {\n this.ready = res;\n this.setup();\n });\n }\n\n async setup(): Promise<void> {\n await nextFrame();\n document.addEventListener('sp-opened', this.handleOpened);\n }\n\n private sendFocus = async (): Promise<void> => {\n const selectedItem = document\n .querySelector('[focusable]')\n ?.querySelector('[selected]') as HTMLElement & {\n focused?: boolean;\n };\n\n if (selectedItem) {\n selectedItem.focus();\n selectedItem.focused = true;\n }\n };\n\n handleOpened = async (event: Event): Promise<void> => {\n const overlay = event.target as Overlay;\n const actions = [nextFrame(), overlay.updateComplete, this.sendFocus()];\n\n await Promise.all(actions);\n // Focus happens _after_ `sp-opened` by at least two frames.\n await nextFrame();\n await nextFrame();\n await nextFrame();\n await nextFrame();\n\n this.ready(true);\n };\n\n private readyPromise: Promise<boolean> = Promise.resolve(false);\n\n get updateComplete(): Promise<boolean> {\n return this.readyPromise;\n }\n}\n\ncustomElements.define('is-overlay-open', IsOverlayOpen);\n\nexport const isOverlayOpen = (story: () => TemplateResult): TemplateResult => {\n return html`\n ${story()}\n <is-overlay-open></is-overlay-open>\n `;\n};\n"],
|
|
5
|
+
"mappings": ";AAYA,SAAS,YAA4B;AAGrC,SAAS,YAA2B;AAChC,SAAO,IAAI,QAAQ,CAAC,QAAQ,sBAAsB,MAAM,IAAI,CAAC,CAAC;AAClE;AAEA,MAAM,sBAAsB,YAAY;AAAA,EAGpC,cAAc;AACV,UAAM;AAYV,SAAQ,YAAY,YAA2B;AAnCnD;AAoCQ,YAAM,gBAAe,cAChB,cAAc,aAAa,MADX,mBAEf,cAAc;AAIpB,UAAI,cAAc;AACd,qBAAa,MAAM;AACnB,qBAAa,UAAU;AAAA,MAC3B;AAAA,IACJ;AAEA,wBAAe,OAAO,UAAgC;AAClD,YAAM,UAAU,MAAM;AACtB,YAAM,UAAU,CAAC,UAAU,GAAG,QAAQ,gBAAgB,KAAK,UAAU,CAAC;AAEtE,YAAM,QAAQ,IAAI,OAAO;AAEzB,YAAM,UAAU;AAChB,YAAM,UAAU;AAChB,YAAM,UAAU;AAChB,YAAM,UAAU;AAEhB,WAAK,MAAM,IAAI;AAAA,IACnB;AAEA,SAAQ,eAAiC,QAAQ,QAAQ,KAAK;AAtC1D,SAAK,eAAe,IAAI,QAAQ,CAAC,QAAQ;AACrC,WAAK,QAAQ;AACb,WAAK,MAAM;AAAA,IACf,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,QAAuB;AACzB,UAAM,UAAU;AAChB,aAAS,iBAAiB,aAAa,KAAK,YAAY;AAAA,EAC5D;AAAA,EA+BA,IAAI,iBAAmC;AACnC,WAAO,KAAK;AAAA,EAChB;AACJ;AAEA,eAAe,OAAO,mBAAmB,aAAa;AAE/C,aAAM,gBAAgB,CAAC,UAAgD;AAC1E,SAAO;AAAA,UACD,MAAM,CAAC;AAAA;AAAA;AAGjB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|