@spectrum-web-components/overlay 0.41.2 → 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +11 -7
- package/src/HoverController.dev.js +8 -1
- package/src/HoverController.dev.js.map +2 -2
- package/src/HoverController.js +1 -1
- package/src/HoverController.js.map +3 -3
- package/src/OverlayStack.d.ts +1 -1
- package/src/OverlayStack.dev.js +8 -1
- package/src/OverlayStack.dev.js.map +2 -2
- package/src/OverlayStack.js +1 -1
- package/src/OverlayStack.js.map +3 -3
- package/src/overlay-trigger-directive.d.ts +3 -8
- package/src/overlay-trigger-directive.dev.js +7 -33
- package/src/overlay-trigger-directive.dev.js.map +2 -2
- package/src/overlay-trigger-directive.js +1 -1
- package/src/overlay-trigger-directive.js.map +3 -3
- package/src/slottable-request-directive.d.ts +17 -0
- package/src/slottable-request-directive.dev.js +63 -0
- package/src/slottable-request-directive.dev.js.map +7 -0
- package/src/slottable-request-directive.js +2 -0
- package/src/slottable-request-directive.js.map +7 -0
- package/src/slottable-request-event.d.ts +5 -0
- package/src/slottable-request-event.dev.js.map +1 -1
- package/src/slottable-request-event.js.map +1 -1
- package/stories/overlay-directive.stories.js +36 -7
- package/stories/overlay-directive.stories.js.map +3 -3
- package/stories/overlay-element.stories.js +2 -2
- package/stories/overlay-element.stories.js.map +1 -1
- package/stories/overlay-story-components.js +1 -1
- package/stories/overlay-story-components.js.map +1 -1
- package/stories/overlay.stories.js +12 -24
- package/stories/overlay.stories.js.map +2 -2
- package/test/benchmark/directive-test.js +29 -28
- package/test/benchmark/directive-test.js.map +2 -2
- package/test/benchmark/lazy-test.js +6 -7
- package/test/benchmark/lazy-test.js.map +2 -2
- package/test/overlay-directive.test.js +17 -5
- package/test/overlay-directive.test.js.map +2 -2
- package/test/overlay-element.test.js +0 -3
- package/test/overlay-element.test.js.map +2 -2
- package/test/overlay-lifecycle.test.js +11 -4
- package/test/overlay-lifecycle.test.js.map +2 -2
- package/test/overlay-trigger-hover-click.test.js +17 -4
- package/test/overlay-trigger-hover-click.test.js.map +2 -2
- package/test/overlay-trigger-longpress.test.js +6 -1
- package/test/overlay-trigger-longpress.test.js.map +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spectrum-web-components/overlay",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.42.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -107,6 +107,10 @@
|
|
|
107
107
|
"default": "./src/overlay-types.js"
|
|
108
108
|
},
|
|
109
109
|
"./src/overlay.css.js": "./src/overlay.css.js",
|
|
110
|
+
"./src/slottable-request-directive.js": {
|
|
111
|
+
"development": "./src/slottable-request-directive.dev.js",
|
|
112
|
+
"default": "./src/slottable-request-directive.js"
|
|
113
|
+
},
|
|
110
114
|
"./src/slottable-request-event.js": {
|
|
111
115
|
"development": "./src/slottable-request-event.dev.js",
|
|
112
116
|
"default": "./src/slottable-request-event.js"
|
|
@@ -148,11 +152,11 @@
|
|
|
148
152
|
"dependencies": {
|
|
149
153
|
"@floating-ui/dom": "^1.6.1",
|
|
150
154
|
"@floating-ui/utils": "^0.2.1",
|
|
151
|
-
"@spectrum-web-components/action-button": "^0.
|
|
152
|
-
"@spectrum-web-components/base": "^0.
|
|
153
|
-
"@spectrum-web-components/reactive-controllers": "^0.
|
|
154
|
-
"@spectrum-web-components/shared": "^0.
|
|
155
|
-
"@spectrum-web-components/theme": "^0.
|
|
155
|
+
"@spectrum-web-components/action-button": "^0.42.0",
|
|
156
|
+
"@spectrum-web-components/base": "^0.42.0",
|
|
157
|
+
"@spectrum-web-components/reactive-controllers": "^0.42.0",
|
|
158
|
+
"@spectrum-web-components/shared": "^0.42.0",
|
|
159
|
+
"@spectrum-web-components/theme": "^0.42.0"
|
|
156
160
|
},
|
|
157
161
|
"types": "./src/index.d.ts",
|
|
158
162
|
"customElements": "custom-elements.json",
|
|
@@ -164,5 +168,5 @@
|
|
|
164
168
|
"./stories/overlay-story-components.js",
|
|
165
169
|
"./**/*.dev.js"
|
|
166
170
|
],
|
|
167
|
-
"gitHead": "
|
|
171
|
+
"gitHead": "9b3bd55ff8e8f9438817255976e77fd456b19d72"
|
|
168
172
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
import { conditionAttributeWithId } from "@spectrum-web-components/base/src/condition-attribute-with-id.js";
|
|
3
3
|
import { randomID } from "@spectrum-web-components/shared/src/random-id.js";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
InteractionController,
|
|
6
|
+
InteractionTypes
|
|
7
|
+
} from "./InteractionController.dev.js";
|
|
5
8
|
import { noop } from "./AbstractOverlay.dev.js";
|
|
6
9
|
const HOVER_DELAY = 300;
|
|
7
10
|
export class HoverController extends InteractionController {
|
|
@@ -13,6 +16,10 @@ export class HoverController extends InteractionController {
|
|
|
13
16
|
this.pointerentered = false;
|
|
14
17
|
}
|
|
15
18
|
handleTargetFocusin() {
|
|
19
|
+
var _a;
|
|
20
|
+
if (!((_a = document.activeElement) == null ? void 0 : _a.matches(":focus-visible"))) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
16
23
|
this.host.open = true;
|
|
17
24
|
this.focusedin = true;
|
|
18
25
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["HoverController.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*/\n\nimport { conditionAttributeWithId } from '@spectrum-web-components/base/src/condition-attribute-with-id.js';\nimport { randomID } from '@spectrum-web-components/shared/src/random-id.js';\n\nimport {
|
|
5
|
-
"mappings": ";AAYA,SAAS,gCAAgC;AACzC,SAAS,gBAAgB;AAEzB,
|
|
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*/\n\nimport { conditionAttributeWithId } from '@spectrum-web-components/base/src/condition-attribute-with-id.js';\nimport { randomID } from '@spectrum-web-components/shared/src/random-id.js';\n\nimport {\n InteractionController,\n InteractionTypes,\n} from './InteractionController.dev.js'\nimport { noop } from './AbstractOverlay.dev.js'\n\nconst HOVER_DELAY = 300;\n\nexport class HoverController extends InteractionController {\n override type = InteractionTypes.hover;\n\n private elementIds: string[] = [];\n\n focusedin = false;\n\n private hoverTimeout?: ReturnType<typeof setTimeout>;\n\n pointerentered = false;\n\n handleTargetFocusin(): void {\n // eslint-disable-next-line @spectrum-web-components/document-active-element\n if (!document.activeElement?.matches(':focus-visible')) {\n return;\n }\n this.host.open = true;\n this.focusedin = true;\n }\n\n handleTargetFocusout(): void {\n this.focusedin = false;\n if (this.pointerentered) return;\n this.host.open = false;\n }\n\n handleTargetPointerenter(): void {\n if (this.hoverTimeout) {\n clearTimeout(this.hoverTimeout);\n this.hoverTimeout = undefined;\n }\n if (this.host.disabled) return;\n this.host.open = true;\n this.pointerentered = true;\n }\n\n handleTargetPointerleave(): void {\n this.doPointerleave();\n }\n\n // set a timeout once the pointer enters and the overlay is shown\n // give the user time to enter the overlay\n handleHostPointerenter(): void {\n if (this.hoverTimeout) {\n clearTimeout(this.hoverTimeout);\n this.hoverTimeout = undefined;\n }\n }\n\n handleHostPointerleave(): void {\n this.doPointerleave();\n }\n\n override prepareDescription(): void {\n // require \"content\" to apply relationship\n if (!this.host.elements.length) return;\n\n const triggerRoot = this.target.getRootNode();\n const contentRoot = this.host.elements[0].getRootNode();\n const overlayRoot = this.host.getRootNode();\n if (triggerRoot === overlayRoot) {\n this.prepareOverlayRelativeDescription();\n } else if (triggerRoot === contentRoot) {\n this.prepareContentRelativeDescription();\n }\n }\n\n private prepareOverlayRelativeDescription(): void {\n const releaseDescription = conditionAttributeWithId(\n this.target,\n 'aria-describedby',\n [this.host.id]\n );\n this.releaseDescription = () => {\n releaseDescription();\n this.releaseDescription = noop;\n };\n }\n\n private prepareContentRelativeDescription(): void {\n const elementIds: string[] = [];\n const appliedIds = this.host.elements.map((el) => {\n elementIds.push(el.id);\n if (!el.id) {\n el.id = `${this.host.tagName.toLowerCase()}-helper-${randomID()}`;\n }\n return el.id;\n });\n this.elementIds = elementIds;\n const releaseDescription = conditionAttributeWithId(\n this.target,\n 'aria-describedby',\n appliedIds\n );\n this.releaseDescription = () => {\n releaseDescription();\n this.host.elements.map((el, index) => {\n el.id = this.elementIds[index];\n });\n this.releaseDescription = noop;\n };\n }\n\n protected doPointerleave(): void {\n this.pointerentered = false;\n const triggerElement = this.target as HTMLElement;\n if (this.focusedin && triggerElement.matches(':focus-visible')) return;\n\n this.hoverTimeout = setTimeout(() => {\n this.host.open = false;\n }, HOVER_DELAY);\n }\n\n override init(): void {\n // Clean up listeners if they've already been bound\n this.abortController?.abort();\n this.abortController = new AbortController();\n const { signal } = this.abortController;\n this.target.addEventListener(\n 'focusin',\n () => this.handleTargetFocusin(),\n { signal }\n );\n this.target.addEventListener(\n 'focusout',\n () => this.handleTargetFocusout(),\n { signal }\n );\n this.target.addEventListener(\n 'pointerenter',\n () => this.handleTargetPointerenter(),\n { signal }\n );\n this.target.addEventListener(\n 'pointerleave',\n () => this.handleTargetPointerleave(),\n { signal }\n );\n this.host.addEventListener(\n 'pointerenter',\n () => this.handleHostPointerenter(),\n { signal }\n );\n this.host.addEventListener(\n 'pointerleave',\n () => this.handleHostPointerleave(),\n { signal }\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/src/HoverController.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";import{conditionAttributeWithId as r}from"@spectrum-web-components/base/src/condition-attribute-with-id.js";import{randomID as a}from"@spectrum-web-components/shared/src/random-id.js";import{InteractionController as h,InteractionTypes as d}from"./InteractionController.js";import{noop as s}from"./AbstractOverlay.js";const l=300;export class HoverController extends h{constructor(){super(...arguments);this.type=d.hover;this.elementIds=[];this.focusedin=!1;this.pointerentered=!1}handleTargetFocusin(){this.host.open=!0,this.focusedin=!0}handleTargetFocusout(){this.focusedin=!1,!this.pointerentered&&(this.host.open=!1)}handleTargetPointerenter(){this.hoverTimeout&&(clearTimeout(this.hoverTimeout),this.hoverTimeout=void 0),!this.host.disabled&&(this.host.open=!0,this.pointerentered=!0)}handleTargetPointerleave(){this.doPointerleave()}handleHostPointerenter(){this.hoverTimeout&&(clearTimeout(this.hoverTimeout),this.hoverTimeout=void 0)}handleHostPointerleave(){this.doPointerleave()}prepareDescription(){if(!this.host.elements.length)return;const e=this.target.getRootNode(),t=this.host.elements[0].getRootNode(),o=this.host.getRootNode();e===o?this.prepareOverlayRelativeDescription():e===t&&this.prepareContentRelativeDescription()}prepareOverlayRelativeDescription(){const e=r(this.target,"aria-describedby",[this.host.id]);this.releaseDescription=()=>{e(),this.releaseDescription=s}}prepareContentRelativeDescription(){const e=[],t=this.host.elements.map(i=>(e.push(i.id),i.id||(i.id=`${this.host.tagName.toLowerCase()}-helper-${a()}`),i.id));this.elementIds=e;const o=r(this.target,"aria-describedby",t);this.releaseDescription=()=>{o(),this.host.elements.map((i,n)=>{i.id=this.elementIds[n]}),this.releaseDescription=s}}doPointerleave(){this.pointerentered=!1;const e=this.target;this.focusedin&&e.matches(":focus-visible")||(this.hoverTimeout=setTimeout(()=>{this.host.open=!1},l))}init(){var t;(t=this.abortController)==null||t.abort(),this.abortController=new AbortController;const{signal:e}=this.abortController;this.target.addEventListener("focusin",()=>this.handleTargetFocusin(),{signal:e}),this.target.addEventListener("focusout",()=>this.handleTargetFocusout(),{signal:e}),this.target.addEventListener("pointerenter",()=>this.handleTargetPointerenter(),{signal:e}),this.target.addEventListener("pointerleave",()=>this.handleTargetPointerleave(),{signal:e}),this.host.addEventListener("pointerenter",()=>this.handleHostPointerenter(),{signal:e}),this.host.addEventListener("pointerleave",()=>this.handleHostPointerleave(),{signal:e})}}
|
|
1
|
+
"use strict";import{conditionAttributeWithId as r}from"@spectrum-web-components/base/src/condition-attribute-with-id.js";import{randomID as a}from"@spectrum-web-components/shared/src/random-id.js";import{InteractionController as h,InteractionTypes as d}from"./InteractionController.js";import{noop as s}from"./AbstractOverlay.js";const l=300;export class HoverController extends h{constructor(){super(...arguments);this.type=d.hover;this.elementIds=[];this.focusedin=!1;this.pointerentered=!1}handleTargetFocusin(){var e;(e=document.activeElement)!=null&&e.matches(":focus-visible")&&(this.host.open=!0,this.focusedin=!0)}handleTargetFocusout(){this.focusedin=!1,!this.pointerentered&&(this.host.open=!1)}handleTargetPointerenter(){this.hoverTimeout&&(clearTimeout(this.hoverTimeout),this.hoverTimeout=void 0),!this.host.disabled&&(this.host.open=!0,this.pointerentered=!0)}handleTargetPointerleave(){this.doPointerleave()}handleHostPointerenter(){this.hoverTimeout&&(clearTimeout(this.hoverTimeout),this.hoverTimeout=void 0)}handleHostPointerleave(){this.doPointerleave()}prepareDescription(){if(!this.host.elements.length)return;const e=this.target.getRootNode(),t=this.host.elements[0].getRootNode(),o=this.host.getRootNode();e===o?this.prepareOverlayRelativeDescription():e===t&&this.prepareContentRelativeDescription()}prepareOverlayRelativeDescription(){const e=r(this.target,"aria-describedby",[this.host.id]);this.releaseDescription=()=>{e(),this.releaseDescription=s}}prepareContentRelativeDescription(){const e=[],t=this.host.elements.map(i=>(e.push(i.id),i.id||(i.id=`${this.host.tagName.toLowerCase()}-helper-${a()}`),i.id));this.elementIds=e;const o=r(this.target,"aria-describedby",t);this.releaseDescription=()=>{o(),this.host.elements.map((i,n)=>{i.id=this.elementIds[n]}),this.releaseDescription=s}}doPointerleave(){this.pointerentered=!1;const e=this.target;this.focusedin&&e.matches(":focus-visible")||(this.hoverTimeout=setTimeout(()=>{this.host.open=!1},l))}init(){var t;(t=this.abortController)==null||t.abort(),this.abortController=new AbortController;const{signal:e}=this.abortController;this.target.addEventListener("focusin",()=>this.handleTargetFocusin(),{signal:e}),this.target.addEventListener("focusout",()=>this.handleTargetFocusout(),{signal:e}),this.target.addEventListener("pointerenter",()=>this.handleTargetPointerenter(),{signal:e}),this.target.addEventListener("pointerleave",()=>this.handleTargetPointerleave(),{signal:e}),this.host.addEventListener("pointerenter",()=>this.handleHostPointerenter(),{signal:e}),this.host.addEventListener("pointerleave",()=>this.handleHostPointerleave(),{signal:e})}}
|
|
2
2
|
//# sourceMappingURL=HoverController.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["HoverController.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*/\n\nimport { conditionAttributeWithId } from '@spectrum-web-components/base/src/condition-attribute-with-id.js';\nimport { randomID } from '@spectrum-web-components/shared/src/random-id.js';\n\nimport {
|
|
5
|
-
"mappings": "aAYA,OAAS,4BAAAA,MAAgC,mEACzC,OAAS,YAAAC,MAAgB,mDAEzB,
|
|
6
|
-
"names": ["conditionAttributeWithId", "randomID", "InteractionController", "InteractionTypes", "noop", "HOVER_DELAY", "triggerRoot", "contentRoot", "overlayRoot", "releaseDescription", "elementIds", "appliedIds", "el", "index", "triggerElement", "
|
|
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*/\n\nimport { conditionAttributeWithId } from '@spectrum-web-components/base/src/condition-attribute-with-id.js';\nimport { randomID } from '@spectrum-web-components/shared/src/random-id.js';\n\nimport {\n InteractionController,\n InteractionTypes,\n} from './InteractionController.js';\nimport { noop } from './AbstractOverlay.js';\n\nconst HOVER_DELAY = 300;\n\nexport class HoverController extends InteractionController {\n override type = InteractionTypes.hover;\n\n private elementIds: string[] = [];\n\n focusedin = false;\n\n private hoverTimeout?: ReturnType<typeof setTimeout>;\n\n pointerentered = false;\n\n handleTargetFocusin(): void {\n // eslint-disable-next-line @spectrum-web-components/document-active-element\n if (!document.activeElement?.matches(':focus-visible')) {\n return;\n }\n this.host.open = true;\n this.focusedin = true;\n }\n\n handleTargetFocusout(): void {\n this.focusedin = false;\n if (this.pointerentered) return;\n this.host.open = false;\n }\n\n handleTargetPointerenter(): void {\n if (this.hoverTimeout) {\n clearTimeout(this.hoverTimeout);\n this.hoverTimeout = undefined;\n }\n if (this.host.disabled) return;\n this.host.open = true;\n this.pointerentered = true;\n }\n\n handleTargetPointerleave(): void {\n this.doPointerleave();\n }\n\n // set a timeout once the pointer enters and the overlay is shown\n // give the user time to enter the overlay\n handleHostPointerenter(): void {\n if (this.hoverTimeout) {\n clearTimeout(this.hoverTimeout);\n this.hoverTimeout = undefined;\n }\n }\n\n handleHostPointerleave(): void {\n this.doPointerleave();\n }\n\n override prepareDescription(): void {\n // require \"content\" to apply relationship\n if (!this.host.elements.length) return;\n\n const triggerRoot = this.target.getRootNode();\n const contentRoot = this.host.elements[0].getRootNode();\n const overlayRoot = this.host.getRootNode();\n if (triggerRoot === overlayRoot) {\n this.prepareOverlayRelativeDescription();\n } else if (triggerRoot === contentRoot) {\n this.prepareContentRelativeDescription();\n }\n }\n\n private prepareOverlayRelativeDescription(): void {\n const releaseDescription = conditionAttributeWithId(\n this.target,\n 'aria-describedby',\n [this.host.id]\n );\n this.releaseDescription = () => {\n releaseDescription();\n this.releaseDescription = noop;\n };\n }\n\n private prepareContentRelativeDescription(): void {\n const elementIds: string[] = [];\n const appliedIds = this.host.elements.map((el) => {\n elementIds.push(el.id);\n if (!el.id) {\n el.id = `${this.host.tagName.toLowerCase()}-helper-${randomID()}`;\n }\n return el.id;\n });\n this.elementIds = elementIds;\n const releaseDescription = conditionAttributeWithId(\n this.target,\n 'aria-describedby',\n appliedIds\n );\n this.releaseDescription = () => {\n releaseDescription();\n this.host.elements.map((el, index) => {\n el.id = this.elementIds[index];\n });\n this.releaseDescription = noop;\n };\n }\n\n protected doPointerleave(): void {\n this.pointerentered = false;\n const triggerElement = this.target as HTMLElement;\n if (this.focusedin && triggerElement.matches(':focus-visible')) return;\n\n this.hoverTimeout = setTimeout(() => {\n this.host.open = false;\n }, HOVER_DELAY);\n }\n\n override init(): void {\n // Clean up listeners if they've already been bound\n this.abortController?.abort();\n this.abortController = new AbortController();\n const { signal } = this.abortController;\n this.target.addEventListener(\n 'focusin',\n () => this.handleTargetFocusin(),\n { signal }\n );\n this.target.addEventListener(\n 'focusout',\n () => this.handleTargetFocusout(),\n { signal }\n );\n this.target.addEventListener(\n 'pointerenter',\n () => this.handleTargetPointerenter(),\n { signal }\n );\n this.target.addEventListener(\n 'pointerleave',\n () => this.handleTargetPointerleave(),\n { signal }\n );\n this.host.addEventListener(\n 'pointerenter',\n () => this.handleHostPointerenter(),\n { signal }\n );\n this.host.addEventListener(\n 'pointerleave',\n () => this.handleHostPointerleave(),\n { signal }\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["conditionAttributeWithId", "randomID", "InteractionController", "InteractionTypes", "noop", "HOVER_DELAY", "_a", "triggerRoot", "contentRoot", "overlayRoot", "releaseDescription", "elementIds", "appliedIds", "el", "index", "triggerElement", "signal"]
|
|
7
7
|
}
|
package/src/OverlayStack.d.ts
CHANGED
|
@@ -33,9 +33,9 @@ declare class OverlayStack {
|
|
|
33
33
|
* When overlays are added manage the open state of exisiting overlays appropriately:
|
|
34
34
|
* - 'modal': should close other overlays
|
|
35
35
|
* - 'page': should close other overlays
|
|
36
|
-
* - 'hint': shouldn't close other overlays
|
|
37
36
|
* - 'auto': should close other 'auto' overlays and other 'hint' overlays, but not 'manual' overlays
|
|
38
37
|
* - 'manual': shouldn't close other overlays
|
|
38
|
+
* - 'hint': shouldn't close other overlays and give way to all other overlays on a trigger
|
|
39
39
|
*/
|
|
40
40
|
add(overlay: Overlay): void;
|
|
41
41
|
remove(overlay: Overlay): void;
|
package/src/OverlayStack.dev.js
CHANGED
|
@@ -106,9 +106,9 @@ class OverlayStack {
|
|
|
106
106
|
* When overlays are added manage the open state of exisiting overlays appropriately:
|
|
107
107
|
* - 'modal': should close other overlays
|
|
108
108
|
* - 'page': should close other overlays
|
|
109
|
-
* - 'hint': shouldn't close other overlays
|
|
110
109
|
* - 'auto': should close other 'auto' overlays and other 'hint' overlays, but not 'manual' overlays
|
|
111
110
|
* - 'manual': shouldn't close other overlays
|
|
111
|
+
* - 'hint': shouldn't close other overlays and give way to all other overlays on a trigger
|
|
112
112
|
*/
|
|
113
113
|
add(overlay) {
|
|
114
114
|
if (this.stack.includes(overlay)) {
|
|
@@ -140,6 +140,13 @@ class OverlayStack {
|
|
|
140
140
|
);
|
|
141
141
|
overlay.dispatchEvent(queryPathEvent);
|
|
142
142
|
} else if (overlay.type === "hint") {
|
|
143
|
+
const hasPrevious = this.stack.some((overlayEl) => {
|
|
144
|
+
return overlayEl.type !== "manual" && overlayEl.triggerElement && overlayEl.triggerElement === overlay.triggerElement;
|
|
145
|
+
});
|
|
146
|
+
if (hasPrevious) {
|
|
147
|
+
overlay.open = false;
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
143
150
|
this.stack.forEach((overlayEl) => {
|
|
144
151
|
if (overlayEl.type === "hint") {
|
|
145
152
|
this.closeOverlay(overlayEl);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["OverlayStack.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\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 { Overlay } from './Overlay.dev.js'\n\nconst supportsPopover = 'showPopover' in document.createElement('div');\n\nclass OverlayStack {\n private get document(): Document {\n return this.root.ownerDocument /* c8 ignore next */ || document;\n }\n\n private pointerdownPath?: EventTarget[];\n\n private lastOverlay?: Overlay;\n\n private root: HTMLElement = document.body;\n\n stack: Overlay[] = [];\n\n constructor() {\n this.bindEvents();\n }\n\n bindEvents(): void {\n this.document.addEventListener('pointerdown', this.handlePointerdown);\n this.document.addEventListener('pointerup', this.handlePointerup);\n this.document.addEventListener('keydown', this.handleKeydown);\n }\n\n private closeOverlay(overlay: Overlay): void {\n const overlayIndex = this.stack.indexOf(overlay);\n if (overlayIndex > -1) {\n this.stack.splice(overlayIndex, 1);\n }\n overlay.open = false;\n }\n\n /**\n * Cach the `pointerdownTarget` for later testing\n *\n * @param event {ClickEvent}\n */\n handlePointerdown = (event: Event): void => {\n this.pointerdownPath = event.composedPath();\n this.lastOverlay = this.stack.at(-1);\n };\n\n /**\n * Close all overlays that are not ancestors of this click event\n *\n * @param event {ClickEvent}\n */\n handlePointerup = (): void => {\n if (!this.stack.length) return;\n if (!this.pointerdownPath?.length) return;\n\n // Test against the composed path in `pointerdown` in case the visitor moved their\n // pointer during the course of the interaction.\n const composedPath = this.pointerdownPath;\n this.pointerdownPath = undefined;\n const lastIndex = this.stack.length - 1;\n const nonAncestorOverlays = this.stack.filter((overlay, i) => {\n const inStack = composedPath.find(\n (el) =>\n // The Overlay is in the stack\n el === overlay ||\n // The Overlay trigger is in the stack and the Overlay is a \"hint\"\n (el === overlay?.triggerElement &&\n 'hint' === overlay?.type) ||\n // The last Overlay in the stack is not the last Overlay at `pointerdown` time and has a\n // `triggerInteraction` of \"longpress\", meaning it was opened by this poitner interaction\n (i === lastIndex &&\n overlay !== this.lastOverlay &&\n overlay.triggerInteraction === 'longpress')\n );\n return (\n !inStack &&\n !overlay.shouldPreventClose() &&\n overlay.type !== 'manual'\n );\n }) as Overlay[];\n nonAncestorOverlays.reverse();\n nonAncestorOverlays.forEach((overlay) => {\n this.closeOverlay(overlay);\n let parentToClose = overlay.parentOverlayToForceClose;\n while (parentToClose) {\n this.closeOverlay(parentToClose);\n parentToClose = parentToClose.parentOverlayToForceClose;\n }\n });\n };\n\n handleBeforetoggle = (event: Event): void => {\n const { target, newState: open } = event as Event & {\n newState: string;\n };\n if (open === 'open') return;\n this.closeOverlay(target as Overlay);\n };\n\n private handleKeydown = (event: KeyboardEvent): void => {\n if (event.code !== 'Escape') return;\n if (!this.stack.length) return;\n const last = this.stack.at(-1);\n if (last?.type === 'page') {\n event.preventDefault();\n return;\n }\n if (supportsPopover) return;\n if (last?.type === 'manual') {\n // Manual Overlays should not close on \"light dismiss\".\n return;\n }\n\n if (!last) return;\n this.closeOverlay(last);\n };\n\n /**\n * Get an array of Overlays that all share the same trigger element.\n *\n * @param triggerElement {HTMLELement}\n * @returns {Overlay[]}\n */\n overlaysByTriggerElement(triggerElement: HTMLElement): Overlay[] {\n return this.stack.filter(\n (overlay) => overlay.triggerElement === triggerElement\n );\n }\n\n /**\n * When overlays are added manage the open state of exisiting overlays appropriately:\n * - 'modal': should close other overlays\n * - 'page': should close other overlays\n * - '
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2023 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\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 { Overlay } from './Overlay.dev.js'\n\nconst supportsPopover = 'showPopover' in document.createElement('div');\n\nclass OverlayStack {\n private get document(): Document {\n return this.root.ownerDocument /* c8 ignore next */ || document;\n }\n\n private pointerdownPath?: EventTarget[];\n\n private lastOverlay?: Overlay;\n\n private root: HTMLElement = document.body;\n\n stack: Overlay[] = [];\n\n constructor() {\n this.bindEvents();\n }\n\n bindEvents(): void {\n this.document.addEventListener('pointerdown', this.handlePointerdown);\n this.document.addEventListener('pointerup', this.handlePointerup);\n this.document.addEventListener('keydown', this.handleKeydown);\n }\n\n private closeOverlay(overlay: Overlay): void {\n const overlayIndex = this.stack.indexOf(overlay);\n if (overlayIndex > -1) {\n this.stack.splice(overlayIndex, 1);\n }\n overlay.open = false;\n }\n\n /**\n * Cach the `pointerdownTarget` for later testing\n *\n * @param event {ClickEvent}\n */\n handlePointerdown = (event: Event): void => {\n this.pointerdownPath = event.composedPath();\n this.lastOverlay = this.stack.at(-1);\n };\n\n /**\n * Close all overlays that are not ancestors of this click event\n *\n * @param event {ClickEvent}\n */\n handlePointerup = (): void => {\n if (!this.stack.length) return;\n if (!this.pointerdownPath?.length) return;\n\n // Test against the composed path in `pointerdown` in case the visitor moved their\n // pointer during the course of the interaction.\n const composedPath = this.pointerdownPath;\n this.pointerdownPath = undefined;\n const lastIndex = this.stack.length - 1;\n const nonAncestorOverlays = this.stack.filter((overlay, i) => {\n const inStack = composedPath.find(\n (el) =>\n // The Overlay is in the stack\n el === overlay ||\n // The Overlay trigger is in the stack and the Overlay is a \"hint\"\n (el === overlay?.triggerElement &&\n 'hint' === overlay?.type) ||\n // The last Overlay in the stack is not the last Overlay at `pointerdown` time and has a\n // `triggerInteraction` of \"longpress\", meaning it was opened by this poitner interaction\n (i === lastIndex &&\n overlay !== this.lastOverlay &&\n overlay.triggerInteraction === 'longpress')\n );\n return (\n !inStack &&\n !overlay.shouldPreventClose() &&\n overlay.type !== 'manual'\n );\n }) as Overlay[];\n nonAncestorOverlays.reverse();\n nonAncestorOverlays.forEach((overlay) => {\n this.closeOverlay(overlay);\n let parentToClose = overlay.parentOverlayToForceClose;\n while (parentToClose) {\n this.closeOverlay(parentToClose);\n parentToClose = parentToClose.parentOverlayToForceClose;\n }\n });\n };\n\n handleBeforetoggle = (event: Event): void => {\n const { target, newState: open } = event as Event & {\n newState: string;\n };\n if (open === 'open') return;\n this.closeOverlay(target as Overlay);\n };\n\n private handleKeydown = (event: KeyboardEvent): void => {\n if (event.code !== 'Escape') return;\n if (!this.stack.length) return;\n const last = this.stack.at(-1);\n if (last?.type === 'page') {\n event.preventDefault();\n return;\n }\n if (supportsPopover) return;\n if (last?.type === 'manual') {\n // Manual Overlays should not close on \"light dismiss\".\n return;\n }\n\n if (!last) return;\n this.closeOverlay(last);\n };\n\n /**\n * Get an array of Overlays that all share the same trigger element.\n *\n * @param triggerElement {HTMLELement}\n * @returns {Overlay[]}\n */\n overlaysByTriggerElement(triggerElement: HTMLElement): Overlay[] {\n return this.stack.filter(\n (overlay) => overlay.triggerElement === triggerElement\n );\n }\n\n /**\n * When overlays are added manage the open state of exisiting overlays appropriately:\n * - 'modal': should close other overlays\n * - 'page': should close other overlays\n * - 'auto': should close other 'auto' overlays and other 'hint' overlays, but not 'manual' overlays\n * - 'manual': shouldn't close other overlays\n * - 'hint': shouldn't close other overlays and give way to all other overlays on a trigger\n */\n add(overlay: Overlay): void {\n if (this.stack.includes(overlay)) {\n const overlayIndex = this.stack.indexOf(overlay);\n if (overlayIndex > -1) {\n this.stack.splice(overlayIndex, 1);\n this.stack.push(overlay);\n }\n return;\n }\n if (\n overlay.type === 'auto' ||\n overlay.type === 'modal' ||\n overlay.type === 'page'\n ) {\n // manage closing open overlays\n const queryPathEventName = 'sp-overlay-query-path';\n const queryPathEvent = new Event(queryPathEventName, {\n composed: true,\n bubbles: true,\n });\n overlay.addEventListener(\n queryPathEventName,\n (event: Event) => {\n const path = event.composedPath();\n this.stack.forEach((overlayEl) => {\n const inPath = path.find((el) => el === overlayEl);\n if (!inPath && overlayEl.type !== 'manual') {\n this.closeOverlay(overlayEl);\n }\n });\n },\n { once: true }\n );\n overlay.dispatchEvent(queryPathEvent);\n } else if (overlay.type === 'hint') {\n const hasPrevious = this.stack.some((overlayEl) => {\n return (\n overlayEl.type !== 'manual' &&\n overlayEl.triggerElement &&\n overlayEl.triggerElement === overlay.triggerElement\n );\n });\n if (hasPrevious) {\n overlay.open = false;\n return;\n }\n this.stack.forEach((overlayEl) => {\n if (overlayEl.type === 'hint') {\n this.closeOverlay(overlayEl);\n }\n });\n }\n requestAnimationFrame(() => {\n this.stack.push(overlay);\n overlay.addEventListener('beforetoggle', this.handleBeforetoggle, {\n once: true,\n });\n });\n }\n\n remove(overlay: Overlay): void {\n this.closeOverlay(overlay);\n }\n}\n\nexport const overlayStack = new OverlayStack();\n"],
|
|
5
|
+
"mappings": ";AAaA,MAAM,kBAAkB,iBAAiB,SAAS,cAAc,KAAK;AAErE,MAAM,aAAa;AAAA,EAaf,cAAc;AAJd,SAAQ,OAAoB,SAAS;AAErC,iBAAmB,CAAC;AAyBpB;AAAA;AAAA;AAAA;AAAA;AAAA,6BAAoB,CAAC,UAAuB;AACxC,WAAK,kBAAkB,MAAM,aAAa;AAC1C,WAAK,cAAc,KAAK,MAAM,GAAG,EAAE;AAAA,IACvC;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAAkB,MAAY;AA7DlC;AA8DQ,UAAI,CAAC,KAAK,MAAM;AAAQ;AACxB,UAAI,GAAC,UAAK,oBAAL,mBAAsB;AAAQ;AAInC,YAAM,eAAe,KAAK;AAC1B,WAAK,kBAAkB;AACvB,YAAM,YAAY,KAAK,MAAM,SAAS;AACtC,YAAM,sBAAsB,KAAK,MAAM,OAAO,CAAC,SAAS,MAAM;AAC1D,cAAM,UAAU,aAAa;AAAA,UACzB,CAAC;AAAA;AAAA,YAEG,OAAO;AAAA,YAEN,QAAO,mCAAS,mBACb,YAAW,mCAAS;AAAA;AAAA,YAGvB,MAAM,aACH,YAAY,KAAK,eACjB,QAAQ,uBAAuB;AAAA;AAAA,QAC3C;AACA,eACI,CAAC,WACD,CAAC,QAAQ,mBAAmB,KAC5B,QAAQ,SAAS;AAAA,MAEzB,CAAC;AACD,0BAAoB,QAAQ;AAC5B,0BAAoB,QAAQ,CAAC,YAAY;AACrC,aAAK,aAAa,OAAO;AACzB,YAAI,gBAAgB,QAAQ;AAC5B,eAAO,eAAe;AAClB,eAAK,aAAa,aAAa;AAC/B,0BAAgB,cAAc;AAAA,QAClC;AAAA,MACJ,CAAC;AAAA,IACL;AAEA,8BAAqB,CAAC,UAAuB;AACzC,YAAM,EAAE,QAAQ,UAAU,KAAK,IAAI;AAGnC,UAAI,SAAS;AAAQ;AACrB,WAAK,aAAa,MAAiB;AAAA,IACvC;AAEA,SAAQ,gBAAgB,CAAC,UAA+B;AACpD,UAAI,MAAM,SAAS;AAAU;AAC7B,UAAI,CAAC,KAAK,MAAM;AAAQ;AACxB,YAAM,OAAO,KAAK,MAAM,GAAG,EAAE;AAC7B,WAAI,6BAAM,UAAS,QAAQ;AACvB,cAAM,eAAe;AACrB;AAAA,MACJ;AACA,UAAI;AAAiB;AACrB,WAAI,6BAAM,UAAS,UAAU;AAEzB;AAAA,MACJ;AAEA,UAAI,CAAC;AAAM;AACX,WAAK,aAAa,IAAI;AAAA,IAC1B;AAhGI,SAAK,WAAW;AAAA,EACpB;AAAA,EAdA,IAAY,WAAqB;AAC7B,WAAO,KAAK,KAAK,iBAAsC;AAAA,EAC3D;AAAA,EAcA,aAAmB;AACf,SAAK,SAAS,iBAAiB,eAAe,KAAK,iBAAiB;AACpE,SAAK,SAAS,iBAAiB,aAAa,KAAK,eAAe;AAChE,SAAK,SAAS,iBAAiB,WAAW,KAAK,aAAa;AAAA,EAChE;AAAA,EAEQ,aAAa,SAAwB;AACzC,UAAM,eAAe,KAAK,MAAM,QAAQ,OAAO;AAC/C,QAAI,eAAe,IAAI;AACnB,WAAK,MAAM,OAAO,cAAc,CAAC;AAAA,IACrC;AACA,YAAQ,OAAO;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyFA,yBAAyB,gBAAwC;AAC7D,WAAO,KAAK,MAAM;AAAA,MACd,CAAC,YAAY,QAAQ,mBAAmB;AAAA,IAC5C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,IAAI,SAAwB;AACxB,QAAI,KAAK,MAAM,SAAS,OAAO,GAAG;AAC9B,YAAM,eAAe,KAAK,MAAM,QAAQ,OAAO;AAC/C,UAAI,eAAe,IAAI;AACnB,aAAK,MAAM,OAAO,cAAc,CAAC;AACjC,aAAK,MAAM,KAAK,OAAO;AAAA,MAC3B;AACA;AAAA,IACJ;AACA,QACI,QAAQ,SAAS,UACjB,QAAQ,SAAS,WACjB,QAAQ,SAAS,QACnB;AAEE,YAAM,qBAAqB;AAC3B,YAAM,iBAAiB,IAAI,MAAM,oBAAoB;AAAA,QACjD,UAAU;AAAA,QACV,SAAS;AAAA,MACb,CAAC;AACD,cAAQ;AAAA,QACJ;AAAA,QACA,CAAC,UAAiB;AACd,gBAAM,OAAO,MAAM,aAAa;AAChC,eAAK,MAAM,QAAQ,CAAC,cAAc;AAC9B,kBAAM,SAAS,KAAK,KAAK,CAAC,OAAO,OAAO,SAAS;AACjD,gBAAI,CAAC,UAAU,UAAU,SAAS,UAAU;AACxC,mBAAK,aAAa,SAAS;AAAA,YAC/B;AAAA,UACJ,CAAC;AAAA,QACL;AAAA,QACA,EAAE,MAAM,KAAK;AAAA,MACjB;AACA,cAAQ,cAAc,cAAc;AAAA,IACxC,WAAW,QAAQ,SAAS,QAAQ;AAChC,YAAM,cAAc,KAAK,MAAM,KAAK,CAAC,cAAc;AAC/C,eACI,UAAU,SAAS,YACnB,UAAU,kBACV,UAAU,mBAAmB,QAAQ;AAAA,MAE7C,CAAC;AACD,UAAI,aAAa;AACb,gBAAQ,OAAO;AACf;AAAA,MACJ;AACA,WAAK,MAAM,QAAQ,CAAC,cAAc;AAC9B,YAAI,UAAU,SAAS,QAAQ;AAC3B,eAAK,aAAa,SAAS;AAAA,QAC/B;AAAA,MACJ,CAAC;AAAA,IACL;AACA,0BAAsB,MAAM;AACxB,WAAK,MAAM,KAAK,OAAO;AACvB,cAAQ,iBAAiB,gBAAgB,KAAK,oBAAoB;AAAA,QAC9D,MAAM;AAAA,MACV,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AAAA,EAEA,OAAO,SAAwB;AAC3B,SAAK,aAAa,OAAO;AAAA,EAC7B;AACJ;AAEO,aAAM,eAAe,IAAI,aAAa;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/src/OverlayStack.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const h="showPopover"in document.createElement("div");class c{constructor(){this.root=document.body;this.stack=[];this.handlePointerdown=t=>{this.pointerdownPath=t.composedPath(),this.lastOverlay=this.stack.at(-1)};this.handlePointerup=()=>{var r;if(!this.stack.length||!((r=this.pointerdownPath)!=null&&r.length))return;const t=this.pointerdownPath;this.pointerdownPath=void 0;const e=this.stack.length-1,
|
|
1
|
+
"use strict";const h="showPopover"in document.createElement("div");class c{constructor(){this.root=document.body;this.stack=[];this.handlePointerdown=t=>{this.pointerdownPath=t.composedPath(),this.lastOverlay=this.stack.at(-1)};this.handlePointerup=()=>{var r;if(!this.stack.length||!((r=this.pointerdownPath)!=null&&r.length))return;const t=this.pointerdownPath;this.pointerdownPath=void 0;const e=this.stack.length-1,s=this.stack.filter((n,i)=>!t.find(o=>o===n||o===(n==null?void 0:n.triggerElement)&&(n==null?void 0:n.type)==="hint"||i===e&&n!==this.lastOverlay&&n.triggerInteraction==="longpress")&&!n.shouldPreventClose()&&n.type!=="manual");s.reverse(),s.forEach(n=>{this.closeOverlay(n);let i=n.parentOverlayToForceClose;for(;i;)this.closeOverlay(i),i=i.parentOverlayToForceClose})};this.handleBeforetoggle=t=>{const{target:e,newState:s}=t;s!=="open"&&this.closeOverlay(e)};this.handleKeydown=t=>{if(t.code!=="Escape"||!this.stack.length)return;const e=this.stack.at(-1);if((e==null?void 0:e.type)==="page"){t.preventDefault();return}h||(e==null?void 0:e.type)!=="manual"&&e&&this.closeOverlay(e)};this.bindEvents()}get document(){return this.root.ownerDocument||document}bindEvents(){this.document.addEventListener("pointerdown",this.handlePointerdown),this.document.addEventListener("pointerup",this.handlePointerup),this.document.addEventListener("keydown",this.handleKeydown)}closeOverlay(t){const e=this.stack.indexOf(t);e>-1&&this.stack.splice(e,1),t.open=!1}overlaysByTriggerElement(t){return this.stack.filter(e=>e.triggerElement===t)}add(t){if(this.stack.includes(t)){const e=this.stack.indexOf(t);e>-1&&(this.stack.splice(e,1),this.stack.push(t));return}if(t.type==="auto"||t.type==="modal"||t.type==="page"){const e="sp-overlay-query-path",s=new Event(e,{composed:!0,bubbles:!0});t.addEventListener(e,r=>{const n=r.composedPath();this.stack.forEach(i=>{!n.find(o=>o===i)&&i.type!=="manual"&&this.closeOverlay(i)})},{once:!0}),t.dispatchEvent(s)}else if(t.type==="hint"){if(this.stack.some(s=>s.type!=="manual"&&s.triggerElement&&s.triggerElement===t.triggerElement)){t.open=!1;return}this.stack.forEach(s=>{s.type==="hint"&&this.closeOverlay(s)})}requestAnimationFrame(()=>{this.stack.push(t),t.addEventListener("beforetoggle",this.handleBeforetoggle,{once:!0})})}remove(t){this.closeOverlay(t)}}export const overlayStack=new c;
|
|
2
2
|
//# sourceMappingURL=OverlayStack.js.map
|
package/src/OverlayStack.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["OverlayStack.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\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 { Overlay } from './Overlay.js';\n\nconst supportsPopover = 'showPopover' in document.createElement('div');\n\nclass OverlayStack {\n private get document(): Document {\n return this.root.ownerDocument /* c8 ignore next */ || document;\n }\n\n private pointerdownPath?: EventTarget[];\n\n private lastOverlay?: Overlay;\n\n private root: HTMLElement = document.body;\n\n stack: Overlay[] = [];\n\n constructor() {\n this.bindEvents();\n }\n\n bindEvents(): void {\n this.document.addEventListener('pointerdown', this.handlePointerdown);\n this.document.addEventListener('pointerup', this.handlePointerup);\n this.document.addEventListener('keydown', this.handleKeydown);\n }\n\n private closeOverlay(overlay: Overlay): void {\n const overlayIndex = this.stack.indexOf(overlay);\n if (overlayIndex > -1) {\n this.stack.splice(overlayIndex, 1);\n }\n overlay.open = false;\n }\n\n /**\n * Cach the `pointerdownTarget` for later testing\n *\n * @param event {ClickEvent}\n */\n handlePointerdown = (event: Event): void => {\n this.pointerdownPath = event.composedPath();\n this.lastOverlay = this.stack.at(-1);\n };\n\n /**\n * Close all overlays that are not ancestors of this click event\n *\n * @param event {ClickEvent}\n */\n handlePointerup = (): void => {\n if (!this.stack.length) return;\n if (!this.pointerdownPath?.length) return;\n\n // Test against the composed path in `pointerdown` in case the visitor moved their\n // pointer during the course of the interaction.\n const composedPath = this.pointerdownPath;\n this.pointerdownPath = undefined;\n const lastIndex = this.stack.length - 1;\n const nonAncestorOverlays = this.stack.filter((overlay, i) => {\n const inStack = composedPath.find(\n (el) =>\n // The Overlay is in the stack\n el === overlay ||\n // The Overlay trigger is in the stack and the Overlay is a \"hint\"\n (el === overlay?.triggerElement &&\n 'hint' === overlay?.type) ||\n // The last Overlay in the stack is not the last Overlay at `pointerdown` time and has a\n // `triggerInteraction` of \"longpress\", meaning it was opened by this poitner interaction\n (i === lastIndex &&\n overlay !== this.lastOverlay &&\n overlay.triggerInteraction === 'longpress')\n );\n return (\n !inStack &&\n !overlay.shouldPreventClose() &&\n overlay.type !== 'manual'\n );\n }) as Overlay[];\n nonAncestorOverlays.reverse();\n nonAncestorOverlays.forEach((overlay) => {\n this.closeOverlay(overlay);\n let parentToClose = overlay.parentOverlayToForceClose;\n while (parentToClose) {\n this.closeOverlay(parentToClose);\n parentToClose = parentToClose.parentOverlayToForceClose;\n }\n });\n };\n\n handleBeforetoggle = (event: Event): void => {\n const { target, newState: open } = event as Event & {\n newState: string;\n };\n if (open === 'open') return;\n this.closeOverlay(target as Overlay);\n };\n\n private handleKeydown = (event: KeyboardEvent): void => {\n if (event.code !== 'Escape') return;\n if (!this.stack.length) return;\n const last = this.stack.at(-1);\n if (last?.type === 'page') {\n event.preventDefault();\n return;\n }\n if (supportsPopover) return;\n if (last?.type === 'manual') {\n // Manual Overlays should not close on \"light dismiss\".\n return;\n }\n\n if (!last) return;\n this.closeOverlay(last);\n };\n\n /**\n * Get an array of Overlays that all share the same trigger element.\n *\n * @param triggerElement {HTMLELement}\n * @returns {Overlay[]}\n */\n overlaysByTriggerElement(triggerElement: HTMLElement): Overlay[] {\n return this.stack.filter(\n (overlay) => overlay.triggerElement === triggerElement\n );\n }\n\n /**\n * When overlays are added manage the open state of exisiting overlays appropriately:\n * - 'modal': should close other overlays\n * - 'page': should close other overlays\n * - '
|
|
5
|
-
"mappings": "aAaA,MAAMA,EAAkB,gBAAiB,SAAS,cAAc,KAAK,EAErE,MAAMC,CAAa,CAaf,aAAc,CAJd,KAAQ,KAAoB,SAAS,KAErC,WAAmB,CAAC,EAyBpB,uBAAqBC,GAAuB,CACxC,KAAK,gBAAkBA,EAAM,aAAa,EAC1C,KAAK,YAAc,KAAK,MAAM,GAAG,EAAE,CACvC,EAOA,qBAAkB,IAAY,CA7DlC,IAAAC,EA+DQ,GADI,CAAC,KAAK,MAAM,QACZ,GAACA,EAAA,KAAK,kBAAL,MAAAA,EAAsB,QAAQ,OAInC,MAAMC,EAAe,KAAK,gBAC1B,KAAK,gBAAkB,OACvB,MAAMC,EAAY,KAAK,MAAM,OAAS,EAChCC,EAAsB,KAAK,MAAM,OAAO,CAACC,
|
|
6
|
-
"names": ["supportsPopover", "OverlayStack", "event", "_a", "composedPath", "lastIndex", "nonAncestorOverlays", "overlay", "
|
|
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\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 { Overlay } from './Overlay.js';\n\nconst supportsPopover = 'showPopover' in document.createElement('div');\n\nclass OverlayStack {\n private get document(): Document {\n return this.root.ownerDocument /* c8 ignore next */ || document;\n }\n\n private pointerdownPath?: EventTarget[];\n\n private lastOverlay?: Overlay;\n\n private root: HTMLElement = document.body;\n\n stack: Overlay[] = [];\n\n constructor() {\n this.bindEvents();\n }\n\n bindEvents(): void {\n this.document.addEventListener('pointerdown', this.handlePointerdown);\n this.document.addEventListener('pointerup', this.handlePointerup);\n this.document.addEventListener('keydown', this.handleKeydown);\n }\n\n private closeOverlay(overlay: Overlay): void {\n const overlayIndex = this.stack.indexOf(overlay);\n if (overlayIndex > -1) {\n this.stack.splice(overlayIndex, 1);\n }\n overlay.open = false;\n }\n\n /**\n * Cach the `pointerdownTarget` for later testing\n *\n * @param event {ClickEvent}\n */\n handlePointerdown = (event: Event): void => {\n this.pointerdownPath = event.composedPath();\n this.lastOverlay = this.stack.at(-1);\n };\n\n /**\n * Close all overlays that are not ancestors of this click event\n *\n * @param event {ClickEvent}\n */\n handlePointerup = (): void => {\n if (!this.stack.length) return;\n if (!this.pointerdownPath?.length) return;\n\n // Test against the composed path in `pointerdown` in case the visitor moved their\n // pointer during the course of the interaction.\n const composedPath = this.pointerdownPath;\n this.pointerdownPath = undefined;\n const lastIndex = this.stack.length - 1;\n const nonAncestorOverlays = this.stack.filter((overlay, i) => {\n const inStack = composedPath.find(\n (el) =>\n // The Overlay is in the stack\n el === overlay ||\n // The Overlay trigger is in the stack and the Overlay is a \"hint\"\n (el === overlay?.triggerElement &&\n 'hint' === overlay?.type) ||\n // The last Overlay in the stack is not the last Overlay at `pointerdown` time and has a\n // `triggerInteraction` of \"longpress\", meaning it was opened by this poitner interaction\n (i === lastIndex &&\n overlay !== this.lastOverlay &&\n overlay.triggerInteraction === 'longpress')\n );\n return (\n !inStack &&\n !overlay.shouldPreventClose() &&\n overlay.type !== 'manual'\n );\n }) as Overlay[];\n nonAncestorOverlays.reverse();\n nonAncestorOverlays.forEach((overlay) => {\n this.closeOverlay(overlay);\n let parentToClose = overlay.parentOverlayToForceClose;\n while (parentToClose) {\n this.closeOverlay(parentToClose);\n parentToClose = parentToClose.parentOverlayToForceClose;\n }\n });\n };\n\n handleBeforetoggle = (event: Event): void => {\n const { target, newState: open } = event as Event & {\n newState: string;\n };\n if (open === 'open') return;\n this.closeOverlay(target as Overlay);\n };\n\n private handleKeydown = (event: KeyboardEvent): void => {\n if (event.code !== 'Escape') return;\n if (!this.stack.length) return;\n const last = this.stack.at(-1);\n if (last?.type === 'page') {\n event.preventDefault();\n return;\n }\n if (supportsPopover) return;\n if (last?.type === 'manual') {\n // Manual Overlays should not close on \"light dismiss\".\n return;\n }\n\n if (!last) return;\n this.closeOverlay(last);\n };\n\n /**\n * Get an array of Overlays that all share the same trigger element.\n *\n * @param triggerElement {HTMLELement}\n * @returns {Overlay[]}\n */\n overlaysByTriggerElement(triggerElement: HTMLElement): Overlay[] {\n return this.stack.filter(\n (overlay) => overlay.triggerElement === triggerElement\n );\n }\n\n /**\n * When overlays are added manage the open state of exisiting overlays appropriately:\n * - 'modal': should close other overlays\n * - 'page': should close other overlays\n * - 'auto': should close other 'auto' overlays and other 'hint' overlays, but not 'manual' overlays\n * - 'manual': shouldn't close other overlays\n * - 'hint': shouldn't close other overlays and give way to all other overlays on a trigger\n */\n add(overlay: Overlay): void {\n if (this.stack.includes(overlay)) {\n const overlayIndex = this.stack.indexOf(overlay);\n if (overlayIndex > -1) {\n this.stack.splice(overlayIndex, 1);\n this.stack.push(overlay);\n }\n return;\n }\n if (\n overlay.type === 'auto' ||\n overlay.type === 'modal' ||\n overlay.type === 'page'\n ) {\n // manage closing open overlays\n const queryPathEventName = 'sp-overlay-query-path';\n const queryPathEvent = new Event(queryPathEventName, {\n composed: true,\n bubbles: true,\n });\n overlay.addEventListener(\n queryPathEventName,\n (event: Event) => {\n const path = event.composedPath();\n this.stack.forEach((overlayEl) => {\n const inPath = path.find((el) => el === overlayEl);\n if (!inPath && overlayEl.type !== 'manual') {\n this.closeOverlay(overlayEl);\n }\n });\n },\n { once: true }\n );\n overlay.dispatchEvent(queryPathEvent);\n } else if (overlay.type === 'hint') {\n const hasPrevious = this.stack.some((overlayEl) => {\n return (\n overlayEl.type !== 'manual' &&\n overlayEl.triggerElement &&\n overlayEl.triggerElement === overlay.triggerElement\n );\n });\n if (hasPrevious) {\n overlay.open = false;\n return;\n }\n this.stack.forEach((overlayEl) => {\n if (overlayEl.type === 'hint') {\n this.closeOverlay(overlayEl);\n }\n });\n }\n requestAnimationFrame(() => {\n this.stack.push(overlay);\n overlay.addEventListener('beforetoggle', this.handleBeforetoggle, {\n once: true,\n });\n });\n }\n\n remove(overlay: Overlay): void {\n this.closeOverlay(overlay);\n }\n}\n\nexport const overlayStack = new OverlayStack();\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["supportsPopover", "OverlayStack", "event", "_a", "composedPath", "lastIndex", "nonAncestorOverlays", "overlay", "el", "parentToClose", "target", "open", "last", "overlayIndex", "triggerElement", "queryPathEventName", "queryPathEvent", "path", "overlayEl"]
|
|
7
7
|
}
|
|
@@ -1,31 +1,26 @@
|
|
|
1
1
|
import { ElementPart, TemplateResult } from '@spectrum-web-components/base';
|
|
2
|
-
import { AsyncDirective } from 'lit/async-directive.js';
|
|
3
2
|
import { OverlayOptions, TriggerInteraction } from './overlay-types.js';
|
|
4
3
|
import '../sp-overlay.js';
|
|
5
4
|
import { SlottableRequestEvent } from './slottable-request-event.js';
|
|
5
|
+
import { SlottableRequestDirective } from './slottable-request-directive.js';
|
|
6
6
|
export declare type InsertionOptions = {
|
|
7
7
|
el: HTMLElement | (() => HTMLElement);
|
|
8
8
|
where: InsertPosition;
|
|
9
9
|
};
|
|
10
10
|
export declare type OverlayTriggerOptions = {
|
|
11
|
+
open?: boolean;
|
|
11
12
|
triggerInteraction: TriggerInteraction;
|
|
12
13
|
overlayOptions: OverlayOptions;
|
|
13
14
|
insertionOptions?: InsertionOptions;
|
|
14
15
|
};
|
|
15
|
-
export declare class OverlayTriggerDirective extends
|
|
16
|
-
private template;
|
|
17
|
-
private target;
|
|
16
|
+
export declare class OverlayTriggerDirective extends SlottableRequestDirective {
|
|
18
17
|
private overlay;
|
|
19
18
|
private strategy?;
|
|
20
|
-
private abortController;
|
|
21
19
|
protected defaultOptions: OverlayTriggerOptions;
|
|
22
20
|
protected options: OverlayOptions;
|
|
23
21
|
protected insertionOptions?: InsertionOptions;
|
|
24
22
|
render(_template: () => TemplateResult, _options?: Partial<OverlayTriggerOptions>): unknown;
|
|
25
23
|
update(part: ElementPart, [template, options]: Parameters<this['render']>): void;
|
|
26
24
|
handleSlottableRequest(event: SlottableRequestEvent): void;
|
|
27
|
-
init(): void;
|
|
28
|
-
disconnected(): void;
|
|
29
|
-
reconnected(): void;
|
|
30
25
|
}
|
|
31
26
|
export declare const trigger: (_template: () => TemplateResult, _options?: Partial<OverlayTriggerOptions> | undefined) => import("lit-html/directive.js").DirectiveResult<typeof OverlayTriggerDirective>;
|
|
@@ -3,18 +3,19 @@ import {
|
|
|
3
3
|
nothing,
|
|
4
4
|
render
|
|
5
5
|
} from "@spectrum-web-components/base";
|
|
6
|
-
import {
|
|
6
|
+
import { directive } from "lit/async-directive.js";
|
|
7
7
|
import { Overlay, strategies } from "./Overlay.dev.js";
|
|
8
8
|
import "../sp-overlay.dev.js";
|
|
9
9
|
import {
|
|
10
10
|
removeSlottableRequest
|
|
11
11
|
} from "./slottable-request-event.dev.js";
|
|
12
|
-
|
|
12
|
+
import { SlottableRequestDirective } from "./slottable-request-directive.dev.js";
|
|
13
|
+
export class OverlayTriggerDirective extends SlottableRequestDirective {
|
|
13
14
|
constructor() {
|
|
14
15
|
super(...arguments);
|
|
15
16
|
this.overlay = new Overlay();
|
|
16
17
|
this.defaultOptions = {
|
|
17
|
-
triggerInteraction: "
|
|
18
|
+
triggerInteraction: "click",
|
|
18
19
|
overlayOptions: {
|
|
19
20
|
placement: "top-start",
|
|
20
21
|
type: "auto",
|
|
@@ -30,7 +31,7 @@ export class OverlayTriggerDirective extends AsyncDirective {
|
|
|
30
31
|
return nothing;
|
|
31
32
|
}
|
|
32
33
|
update(part, [template, options]) {
|
|
33
|
-
var _a, _b;
|
|
34
|
+
var _a, _b, _c;
|
|
34
35
|
this.options = {
|
|
35
36
|
...this.defaultOptions.overlayOptions,
|
|
36
37
|
...options == null ? void 0 : options.overlayOptions
|
|
@@ -48,18 +49,9 @@ export class OverlayTriggerDirective extends AsyncDirective {
|
|
|
48
49
|
(_b = this.strategy) == null ? void 0 : _b.abort();
|
|
49
50
|
this.strategy = new strategies[triggerInteraction](this.overlay, this.target, true);
|
|
50
51
|
}
|
|
52
|
+
this.listenerHost = this.overlay;
|
|
51
53
|
this.init();
|
|
52
|
-
|
|
53
|
-
window.__swc.warn(
|
|
54
|
-
void 0,
|
|
55
|
-
`\u26A0\uFE0F WARNING \u26A0\uFE0F : The Overlay Trigger Directive is experimental and there is no guarantees behind its usage in an application!! Its API and presence within the library could be changed at anytime. See "sp-overlay" or "Overlay.open()" for a stable API for overlaying content on your application.`,
|
|
56
|
-
"https://opensource.adobe.com/spectrum-web-components/components/overlay",
|
|
57
|
-
{
|
|
58
|
-
level: "high",
|
|
59
|
-
type: "api"
|
|
60
|
-
}
|
|
61
|
-
);
|
|
62
|
-
}
|
|
54
|
+
this.overlay.open = (_c = options == null ? void 0 : options.open) != null ? _c : false;
|
|
63
55
|
}
|
|
64
56
|
handleSlottableRequest(event) {
|
|
65
57
|
var _a, _b;
|
|
@@ -79,24 +71,6 @@ export class OverlayTriggerDirective extends AsyncDirective {
|
|
|
79
71
|
insertionEl.insertAdjacentElement(where, this.overlay);
|
|
80
72
|
}
|
|
81
73
|
}
|
|
82
|
-
init() {
|
|
83
|
-
var _a;
|
|
84
|
-
(_a = this.abortController) == null ? void 0 : _a.abort();
|
|
85
|
-
this.abortController = new AbortController();
|
|
86
|
-
const { signal } = this.abortController;
|
|
87
|
-
this.overlay.addEventListener(
|
|
88
|
-
"slottable-request",
|
|
89
|
-
(event) => this.handleSlottableRequest(event),
|
|
90
|
-
{ signal }
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
disconnected() {
|
|
94
|
-
this.abortController.abort();
|
|
95
|
-
}
|
|
96
|
-
/* c8 ignore next 3 */
|
|
97
|
-
reconnected() {
|
|
98
|
-
this.init();
|
|
99
|
-
}
|
|
100
74
|
}
|
|
101
75
|
export const trigger = directive(OverlayTriggerDirective);
|
|
102
76
|
//# sourceMappingURL=overlay-trigger-directive.dev.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["overlay-trigger-directive.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2023 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport {\n ElementPart,\n nothing,\n render,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport {
|
|
5
|
-
"mappings": ";AAWA;AAAA,EAEI;AAAA,EACA;AAAA,OAEG;AACP,SAAS,
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2023 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport {\n ElementPart,\n nothing,\n render,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport { directive } from 'lit/async-directive.js';\nimport { Overlay, strategies } from './Overlay.dev.js'\nimport { OverlayOptions, TriggerInteraction } from './overlay-types.dev.js'\nimport { ClickController } from './ClickController.dev.js'\nimport { HoverController } from './HoverController.dev.js'\nimport { LongpressController } from './LongpressController.dev.js'\nimport '../sp-overlay.dev.js'\nimport {\n removeSlottableRequest,\n SlottableRequestEvent,\n} from './slottable-request-event.dev.js'\nimport { SlottableRequestDirective } from './slottable-request-directive.dev.js'\n\nexport type InsertionOptions = {\n el: HTMLElement | (() => HTMLElement);\n where: InsertPosition;\n};\n\nexport type OverlayTriggerOptions = {\n open?: boolean;\n triggerInteraction: TriggerInteraction;\n overlayOptions: OverlayOptions;\n insertionOptions?: InsertionOptions;\n};\n\nexport class OverlayTriggerDirective extends SlottableRequestDirective {\n private overlay = new Overlay();\n private strategy?: ClickController | HoverController | LongpressController;\n\n protected defaultOptions: OverlayTriggerOptions = {\n triggerInteraction: 'click',\n overlayOptions: {\n placement: 'top-start',\n type: 'auto',\n offset: 0,\n },\n };\n protected options: OverlayOptions = {\n ...this.defaultOptions.overlayOptions,\n };\n protected insertionOptions?: InsertionOptions;\n\n /* c8 ignore next 9 */\n override render(\n _template: () => TemplateResult,\n _options?: Partial<OverlayTriggerOptions>\n ): unknown {\n // render function here just defines the interface to the update call later\n // we don't have anything to render since this is intended to be an ElementPart directive\n // so will be used on an element and is not itself rendered\n return nothing;\n }\n\n override update(\n part: ElementPart,\n [template, options]: Parameters<this['render']>\n ): void {\n this.options = {\n ...this.defaultOptions.overlayOptions,\n ...options?.overlayOptions,\n };\n this.insertionOptions = options?.insertionOptions;\n this.template = template;\n let newTarget = false;\n const triggerInteraction = (options?.triggerInteraction ||\n this.defaultOptions.triggerInteraction) as TriggerInteraction;\n const newStrategy =\n (this.strategy?.type as unknown as TriggerInteraction) !==\n triggerInteraction;\n if (this.target !== part.element) {\n this.target = part.element as HTMLElement;\n newTarget = true;\n }\n if (newTarget || newStrategy) {\n this.strategy?.abort();\n this.strategy = new strategies[\n triggerInteraction as TriggerInteraction\n ](this.overlay, this.target, true);\n }\n this.listenerHost = this.overlay;\n this.init();\n this.overlay.open = options?.open ?? false;\n }\n\n override handleSlottableRequest(event: SlottableRequestEvent): void {\n /* c8 ignore next 1 */\n if (event.target !== event.currentTarget) return;\n\n const willRemoveSlottable = event.data === removeSlottableRequest;\n render(willRemoveSlottable ? undefined : this.template(), this.overlay);\n\n if (willRemoveSlottable) {\n this.overlay.remove();\n } else {\n Overlay.applyOptions(this.overlay, {\n ...this.options,\n trigger: this.target,\n });\n const insertionEl =\n typeof this.insertionOptions?.el === 'function'\n ? this.insertionOptions.el()\n : this.insertionOptions?.el || this.target;\n const { where = 'afterend' } = this.insertionOptions || {};\n insertionEl.insertAdjacentElement(where, this.overlay);\n }\n }\n}\n\nexport const trigger = directive(OverlayTriggerDirective);\n"],
|
|
5
|
+
"mappings": ";AAWA;AAAA,EAEI;AAAA,EACA;AAAA,OAEG;AACP,SAAS,iBAAiB;AAC1B,SAAS,SAAS,kBAAkB;AAKpC,OAAO;AACP;AAAA,EACI;AAAA,OAEG;AACP,SAAS,iCAAiC;AAcnC,aAAM,gCAAgC,0BAA0B;AAAA,EAAhE;AAAA;AACH,SAAQ,UAAU,IAAI,QAAQ;AAG9B,SAAU,iBAAwC;AAAA,MAC9C,oBAAoB;AAAA,MACpB,gBAAgB;AAAA,QACZ,WAAW;AAAA,QACX,MAAM;AAAA,QACN,QAAQ;AAAA,MACZ;AAAA,IACJ;AACA,SAAU,UAA0B;AAAA,MAChC,GAAG,KAAK,eAAe;AAAA,IAC3B;AAAA;AAAA;AAAA,EAIS,OACL,WACA,UACO;AAIP,WAAO;AAAA,EACX;AAAA,EAES,OACL,MACA,CAAC,UAAU,OAAO,GACd;AAzEZ;AA0EQ,SAAK,UAAU;AAAA,MACX,GAAG,KAAK,eAAe;AAAA,MACvB,GAAG,mCAAS;AAAA,IAChB;AACA,SAAK,mBAAmB,mCAAS;AACjC,SAAK,WAAW;AAChB,QAAI,YAAY;AAChB,UAAM,sBAAsB,mCAAS,uBACjC,KAAK,eAAe;AACxB,UAAM,gBACD,UAAK,aAAL,mBAAe,UAChB;AACJ,QAAI,KAAK,WAAW,KAAK,SAAS;AAC9B,WAAK,SAAS,KAAK;AACnB,kBAAY;AAAA,IAChB;AACA,QAAI,aAAa,aAAa;AAC1B,iBAAK,aAAL,mBAAe;AACf,WAAK,WAAW,IAAI,WAChB,kBACJ,EAAE,KAAK,SAAS,KAAK,QAAQ,IAAI;AAAA,IACrC;AACA,SAAK,eAAe,KAAK;AACzB,SAAK,KAAK;AACV,SAAK,QAAQ,QAAO,wCAAS,SAAT,YAAiB;AAAA,EACzC;AAAA,EAES,uBAAuB,OAAoC;AArGxE;AAuGQ,QAAI,MAAM,WAAW,MAAM;AAAe;AAE1C,UAAM,sBAAsB,MAAM,SAAS;AAC3C,WAAO,sBAAsB,SAAY,KAAK,SAAS,GAAG,KAAK,OAAO;AAEtE,QAAI,qBAAqB;AACrB,WAAK,QAAQ,OAAO;AAAA,IACxB,OAAO;AACH,cAAQ,aAAa,KAAK,SAAS;AAAA,QAC/B,GAAG,KAAK;AAAA,QACR,SAAS,KAAK;AAAA,MAClB,CAAC;AACD,YAAM,cACF,SAAO,UAAK,qBAAL,mBAAuB,QAAO,aAC/B,KAAK,iBAAiB,GAAG,MACzB,UAAK,qBAAL,mBAAuB,OAAM,KAAK;AAC5C,YAAM,EAAE,QAAQ,WAAW,IAAI,KAAK,oBAAoB,CAAC;AACzD,kBAAY,sBAAsB,OAAO,KAAK,OAAO;AAAA,IACzD;AAAA,EACJ;AACJ;AAEO,aAAM,UAAU,UAAU,uBAAuB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";import{nothing as
|
|
1
|
+
"use strict";import{nothing as g,render as m}from"@spectrum-web-components/base";import{directive as v}from"lit/async-directive.js";import{Overlay as p,strategies as O}from"./Overlay.js";import"../sp-overlay.js";import{removeSlottableRequest as h}from"./slottable-request-event.js";import{SlottableRequestDirective as y}from"./slottable-request-directive.js";export class OverlayTriggerDirective extends y{constructor(){super(...arguments);this.overlay=new p;this.defaultOptions={triggerInteraction:"click",overlayOptions:{placement:"top-start",type:"auto",offset:0}};this.options={...this.defaultOptions.overlayOptions}}render(t,r){return g}update(t,[r,e]){var s,a,l;this.options={...this.defaultOptions.overlayOptions,...e==null?void 0:e.overlayOptions},this.insertionOptions=e==null?void 0:e.insertionOptions,this.template=r;let i=!1;const n=(e==null?void 0:e.triggerInteraction)||this.defaultOptions.triggerInteraction,o=((s=this.strategy)==null?void 0:s.type)!==n;this.target!==t.element&&(this.target=t.element,i=!0),(i||o)&&((a=this.strategy)==null||a.abort(),this.strategy=new O[n](this.overlay,this.target,!0)),this.listenerHost=this.overlay,this.init(),this.overlay.open=(l=e==null?void 0:e.open)!=null?l:!1}handleSlottableRequest(t){var e,i;if(t.target!==t.currentTarget)return;const r=t.data===h;if(m(r?void 0:this.template(),this.overlay),r)this.overlay.remove();else{p.applyOptions(this.overlay,{...this.options,trigger:this.target});const n=typeof((e=this.insertionOptions)==null?void 0:e.el)=="function"?this.insertionOptions.el():((i=this.insertionOptions)==null?void 0:i.el)||this.target,{where:o="afterend"}=this.insertionOptions||{};n.insertAdjacentElement(o,this.overlay)}}}export const trigger=v(OverlayTriggerDirective);
|
|
2
2
|
//# sourceMappingURL=overlay-trigger-directive.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["overlay-trigger-directive.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2023 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport {\n ElementPart,\n nothing,\n render,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport {
|
|
5
|
-
"mappings": "aAWA,OAEI,WAAAA,EACA,UAAAC,MAEG,gCACP,OAAS,
|
|
6
|
-
"names": ["nothing", "render", "
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2023 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport {\n ElementPart,\n nothing,\n render,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport { directive } from 'lit/async-directive.js';\nimport { Overlay, strategies } from './Overlay.js';\nimport { OverlayOptions, TriggerInteraction } from './overlay-types.js';\nimport { ClickController } from './ClickController.js';\nimport { HoverController } from './HoverController.js';\nimport { LongpressController } from './LongpressController.js';\nimport '../sp-overlay.js';\nimport {\n removeSlottableRequest,\n SlottableRequestEvent,\n} from './slottable-request-event.js';\nimport { SlottableRequestDirective } from './slottable-request-directive.js';\n\nexport type InsertionOptions = {\n el: HTMLElement | (() => HTMLElement);\n where: InsertPosition;\n};\n\nexport type OverlayTriggerOptions = {\n open?: boolean;\n triggerInteraction: TriggerInteraction;\n overlayOptions: OverlayOptions;\n insertionOptions?: InsertionOptions;\n};\n\nexport class OverlayTriggerDirective extends SlottableRequestDirective {\n private overlay = new Overlay();\n private strategy?: ClickController | HoverController | LongpressController;\n\n protected defaultOptions: OverlayTriggerOptions = {\n triggerInteraction: 'click',\n overlayOptions: {\n placement: 'top-start',\n type: 'auto',\n offset: 0,\n },\n };\n protected options: OverlayOptions = {\n ...this.defaultOptions.overlayOptions,\n };\n protected insertionOptions?: InsertionOptions;\n\n /* c8 ignore next 9 */\n override render(\n _template: () => TemplateResult,\n _options?: Partial<OverlayTriggerOptions>\n ): unknown {\n // render function here just defines the interface to the update call later\n // we don't have anything to render since this is intended to be an ElementPart directive\n // so will be used on an element and is not itself rendered\n return nothing;\n }\n\n override update(\n part: ElementPart,\n [template, options]: Parameters<this['render']>\n ): void {\n this.options = {\n ...this.defaultOptions.overlayOptions,\n ...options?.overlayOptions,\n };\n this.insertionOptions = options?.insertionOptions;\n this.template = template;\n let newTarget = false;\n const triggerInteraction = (options?.triggerInteraction ||\n this.defaultOptions.triggerInteraction) as TriggerInteraction;\n const newStrategy =\n (this.strategy?.type as unknown as TriggerInteraction) !==\n triggerInteraction;\n if (this.target !== part.element) {\n this.target = part.element as HTMLElement;\n newTarget = true;\n }\n if (newTarget || newStrategy) {\n this.strategy?.abort();\n this.strategy = new strategies[\n triggerInteraction as TriggerInteraction\n ](this.overlay, this.target, true);\n }\n this.listenerHost = this.overlay;\n this.init();\n this.overlay.open = options?.open ?? false;\n }\n\n override handleSlottableRequest(event: SlottableRequestEvent): void {\n /* c8 ignore next 1 */\n if (event.target !== event.currentTarget) return;\n\n const willRemoveSlottable = event.data === removeSlottableRequest;\n render(willRemoveSlottable ? undefined : this.template(), this.overlay);\n\n if (willRemoveSlottable) {\n this.overlay.remove();\n } else {\n Overlay.applyOptions(this.overlay, {\n ...this.options,\n trigger: this.target,\n });\n const insertionEl =\n typeof this.insertionOptions?.el === 'function'\n ? this.insertionOptions.el()\n : this.insertionOptions?.el || this.target;\n const { where = 'afterend' } = this.insertionOptions || {};\n insertionEl.insertAdjacentElement(where, this.overlay);\n }\n }\n}\n\nexport const trigger = directive(OverlayTriggerDirective);\n"],
|
|
5
|
+
"mappings": "aAWA,OAEI,WAAAA,EACA,UAAAC,MAEG,gCACP,OAAS,aAAAC,MAAiB,yBAC1B,OAAS,WAAAC,EAAS,cAAAC,MAAkB,eAKpC,MAAO,mBACP,OACI,0BAAAC,MAEG,+BACP,OAAS,6BAAAC,MAAiC,mCAcnC,aAAM,gCAAgCA,CAA0B,CAAhE,kCACH,KAAQ,QAAU,IAAIH,EAGtB,KAAU,eAAwC,CAC9C,mBAAoB,QACpB,eAAgB,CACZ,UAAW,YACX,KAAM,OACN,OAAQ,CACZ,CACJ,EACA,KAAU,QAA0B,CAChC,GAAG,KAAK,eAAe,cAC3B,EAIS,OACLI,EACAC,EACO,CAIP,OAAOR,CACX,CAES,OACLS,EACA,CAACC,EAAUC,CAAO,EACd,CAzEZ,IAAAC,EAAAC,EAAAC,EA0EQ,KAAK,QAAU,CACX,GAAG,KAAK,eAAe,eACvB,GAAGH,GAAA,YAAAA,EAAS,cAChB,EACA,KAAK,iBAAmBA,GAAA,YAAAA,EAAS,iBACjC,KAAK,SAAWD,EAChB,IAAIK,EAAY,GAChB,MAAMC,GAAsBL,GAAA,YAAAA,EAAS,qBACjC,KAAK,eAAe,mBAClBM,IACDL,EAAA,KAAK,WAAL,YAAAA,EAAe,QAChBI,EACA,KAAK,SAAWP,EAAK,UACrB,KAAK,OAASA,EAAK,QACnBM,EAAY,KAEZA,GAAaE,MACbJ,EAAA,KAAK,WAAL,MAAAA,EAAe,QACf,KAAK,SAAW,IAAIT,EAChBY,CACJ,EAAE,KAAK,QAAS,KAAK,OAAQ,EAAI,GAErC,KAAK,aAAe,KAAK,QACzB,KAAK,KAAK,EACV,KAAK,QAAQ,MAAOF,EAAAH,GAAA,YAAAA,EAAS,OAAT,KAAAG,EAAiB,EACzC,CAES,uBAAuBI,EAAoC,CArGxE,IAAAN,EAAAC,EAuGQ,GAAIK,EAAM,SAAWA,EAAM,cAAe,OAE1C,MAAMC,EAAsBD,EAAM,OAASb,EAG3C,GAFAJ,EAAOkB,EAAsB,OAAY,KAAK,SAAS,EAAG,KAAK,OAAO,EAElEA,EACA,KAAK,QAAQ,OAAO,MACjB,CACHhB,EAAQ,aAAa,KAAK,QAAS,CAC/B,GAAG,KAAK,QACR,QAAS,KAAK,MAClB,CAAC,EACD,MAAMiB,EACF,QAAOR,EAAA,KAAK,mBAAL,YAAAA,EAAuB,KAAO,WAC/B,KAAK,iBAAiB,GAAG,IACzBC,EAAA,KAAK,mBAAL,YAAAA,EAAuB,KAAM,KAAK,OACtC,CAAE,MAAAQ,EAAQ,UAAW,EAAI,KAAK,kBAAoB,CAAC,EACzDD,EAAY,sBAAsBC,EAAO,KAAK,OAAO,CACzD,CACJ,CACJ,CAEO,aAAM,QAAUnB,EAAU,uBAAuB",
|
|
6
|
+
"names": ["nothing", "render", "directive", "Overlay", "strategies", "removeSlottableRequest", "SlottableRequestDirective", "_template", "_options", "part", "template", "options", "_a", "_b", "_c", "newTarget", "triggerInteraction", "newStrategy", "event", "willRemoveSlottable", "insertionEl", "where"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ElementPart, TemplateResult } from '@spectrum-web-components/base';
|
|
2
|
+
import { AsyncDirective } from 'lit/async-directive.js';
|
|
3
|
+
import { SlottableRequestEvent } from './slottable-request-event.js';
|
|
4
|
+
export declare class SlottableRequestDirective extends AsyncDirective {
|
|
5
|
+
protected template: () => TemplateResult;
|
|
6
|
+
protected target: HTMLElement;
|
|
7
|
+
private renderBefore;
|
|
8
|
+
protected listenerHost: HTMLElement;
|
|
9
|
+
protected listeners: AbortController;
|
|
10
|
+
render(_template: () => TemplateResult): unknown;
|
|
11
|
+
update(part: ElementPart, [template]: Parameters<this['render']>): void;
|
|
12
|
+
handleSlottableRequest(event: SlottableRequestEvent): void;
|
|
13
|
+
init(): void;
|
|
14
|
+
disconnected(): void;
|
|
15
|
+
reconnected(): void;
|
|
16
|
+
}
|
|
17
|
+
export declare const slottableRequest: (_template: () => TemplateResult) => import("lit-html/directive.js").DirectiveResult<typeof SlottableRequestDirective>;
|