@spectrum-web-components/overlay 0.0.0-20241209155954

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.
Files changed (148) hide show
  1. package/README.md +465 -0
  2. package/local.d.ts +56 -0
  3. package/overlay-trigger.d.ts +6 -0
  4. package/overlay-trigger.dev.js +5 -0
  5. package/overlay-trigger.dev.js.map +7 -0
  6. package/overlay-trigger.js +2 -0
  7. package/overlay-trigger.js.map +7 -0
  8. package/package.json +179 -0
  9. package/sp-overlay.d.ts +6 -0
  10. package/sp-overlay.dev.js +5 -0
  11. package/sp-overlay.dev.js.map +7 -0
  12. package/sp-overlay.js +2 -0
  13. package/sp-overlay.js.map +7 -0
  14. package/src/AbstractOverlay.d.ts +72 -0
  15. package/src/AbstractOverlay.dev.js +234 -0
  16. package/src/AbstractOverlay.dev.js.map +7 -0
  17. package/src/AbstractOverlay.js +2 -0
  18. package/src/AbstractOverlay.js.map +7 -0
  19. package/src/ClickController.d.ts +14 -0
  20. package/src/ClickController.dev.js +42 -0
  21. package/src/ClickController.dev.js.map +7 -0
  22. package/src/ClickController.js +2 -0
  23. package/src/ClickController.js.map +7 -0
  24. package/src/HoverController.d.ts +20 -0
  25. package/src/HoverController.dev.js +153 -0
  26. package/src/HoverController.dev.js.map +7 -0
  27. package/src/HoverController.js +2 -0
  28. package/src/HoverController.js.map +7 -0
  29. package/src/InteractionController.d.ts +38 -0
  30. package/src/InteractionController.dev.js +90 -0
  31. package/src/InteractionController.dev.js.map +7 -0
  32. package/src/InteractionController.js +2 -0
  33. package/src/InteractionController.js.map +7 -0
  34. package/src/LongpressController.d.ts +21 -0
  35. package/src/LongpressController.dev.js +156 -0
  36. package/src/LongpressController.dev.js.map +7 -0
  37. package/src/LongpressController.js +2 -0
  38. package/src/LongpressController.js.map +7 -0
  39. package/src/Overlay.d.ts +134 -0
  40. package/src/Overlay.dev.js +535 -0
  41. package/src/Overlay.dev.js.map +7 -0
  42. package/src/Overlay.js +33 -0
  43. package/src/Overlay.js.map +7 -0
  44. package/src/OverlayDialog.d.ts +4 -0
  45. package/src/OverlayDialog.dev.js +140 -0
  46. package/src/OverlayDialog.dev.js.map +7 -0
  47. package/src/OverlayDialog.js +2 -0
  48. package/src/OverlayDialog.js.map +7 -0
  49. package/src/OverlayNoPopover.d.ts +4 -0
  50. package/src/OverlayNoPopover.dev.js +117 -0
  51. package/src/OverlayNoPopover.dev.js.map +7 -0
  52. package/src/OverlayNoPopover.js +2 -0
  53. package/src/OverlayNoPopover.js.map +7 -0
  54. package/src/OverlayPopover.d.ts +4 -0
  55. package/src/OverlayPopover.dev.js +199 -0
  56. package/src/OverlayPopover.dev.js.map +7 -0
  57. package/src/OverlayPopover.js +2 -0
  58. package/src/OverlayPopover.js.map +7 -0
  59. package/src/OverlayStack.d.ts +44 -0
  60. package/src/OverlayStack.dev.js +163 -0
  61. package/src/OverlayStack.dev.js.map +7 -0
  62. package/src/OverlayStack.js +2 -0
  63. package/src/OverlayStack.js.map +7 -0
  64. package/src/OverlayTrigger.d.ts +52 -0
  65. package/src/OverlayTrigger.dev.js +243 -0
  66. package/src/OverlayTrigger.dev.js.map +7 -0
  67. package/src/OverlayTrigger.js +57 -0
  68. package/src/OverlayTrigger.js.map +7 -0
  69. package/src/PlacementController.d.ts +40 -0
  70. package/src/PlacementController.dev.js +212 -0
  71. package/src/PlacementController.dev.js.map +7 -0
  72. package/src/PlacementController.js +2 -0
  73. package/src/PlacementController.js.map +7 -0
  74. package/src/VirtualTrigger.d.ts +7 -0
  75. package/src/VirtualTrigger.dev.js +32 -0
  76. package/src/VirtualTrigger.dev.js.map +7 -0
  77. package/src/VirtualTrigger.js +2 -0
  78. package/src/VirtualTrigger.js.map +7 -0
  79. package/src/events.d.ts +23 -0
  80. package/src/events.dev.js +39 -0
  81. package/src/events.dev.js.map +7 -0
  82. package/src/events.js +2 -0
  83. package/src/events.js.map +7 -0
  84. package/src/fullSizePlugin.d.ts +12 -0
  85. package/src/fullSizePlugin.dev.js +39 -0
  86. package/src/fullSizePlugin.dev.js.map +7 -0
  87. package/src/fullSizePlugin.js +2 -0
  88. package/src/fullSizePlugin.js.map +7 -0
  89. package/src/index.d.ts +6 -0
  90. package/src/index.dev.js +8 -0
  91. package/src/index.dev.js.map +7 -0
  92. package/src/index.js +2 -0
  93. package/src/index.js.map +7 -0
  94. package/src/loader.d.ts +4 -0
  95. package/src/loader.dev.js +11 -0
  96. package/src/loader.dev.js.map +7 -0
  97. package/src/loader.js +2 -0
  98. package/src/loader.js.map +7 -0
  99. package/src/overlay-events.d.ts +11 -0
  100. package/src/overlay-events.dev.js +8 -0
  101. package/src/overlay-events.dev.js.map +7 -0
  102. package/src/overlay-events.js +2 -0
  103. package/src/overlay-events.js.map +7 -0
  104. package/src/overlay-timer.d.ts +22 -0
  105. package/src/overlay-timer.dev.js +72 -0
  106. package/src/overlay-timer.dev.js.map +7 -0
  107. package/src/overlay-timer.js +2 -0
  108. package/src/overlay-timer.js.map +7 -0
  109. package/src/overlay-trigger-directive.d.ts +26 -0
  110. package/src/overlay-trigger-directive.dev.js +87 -0
  111. package/src/overlay-trigger-directive.dev.js.map +7 -0
  112. package/src/overlay-trigger-directive.js +2 -0
  113. package/src/overlay-trigger-directive.js.map +7 -0
  114. package/src/overlay-trigger.css.d.ts +2 -0
  115. package/src/overlay-trigger.css.dev.js +7 -0
  116. package/src/overlay-trigger.css.dev.js.map +7 -0
  117. package/src/overlay-trigger.css.js +4 -0
  118. package/src/overlay-trigger.css.js.map +7 -0
  119. package/src/overlay-types.d.ts +50 -0
  120. package/src/overlay-types.dev.js +3 -0
  121. package/src/overlay-types.dev.js.map +7 -0
  122. package/src/overlay-types.js +2 -0
  123. package/src/overlay-types.js.map +7 -0
  124. package/src/overlay.css.d.ts +2 -0
  125. package/src/overlay.css.dev.js +7 -0
  126. package/src/overlay.css.dev.js.map +7 -0
  127. package/src/overlay.css.js +4 -0
  128. package/src/overlay.css.js.map +7 -0
  129. package/src/slottable-request-directive.d.ts +17 -0
  130. package/src/slottable-request-directive.dev.js +66 -0
  131. package/src/slottable-request-directive.dev.js.map +7 -0
  132. package/src/slottable-request-directive.js +2 -0
  133. package/src/slottable-request-directive.js.map +7 -0
  134. package/src/slottable-request-event.d.ts +12 -0
  135. package/src/slottable-request-event.dev.js +28 -0
  136. package/src/slottable-request-event.dev.js.map +7 -0
  137. package/src/slottable-request-event.js +2 -0
  138. package/src/slottable-request-event.js.map +7 -0
  139. package/src/strategies.d.ts +8 -0
  140. package/src/strategies.dev.js +10 -0
  141. package/src/strategies.dev.js.map +7 -0
  142. package/src/strategies.js +2 -0
  143. package/src/strategies.js.map +7 -0
  144. package/sync/overlay-trigger.d.ts +6 -0
  145. package/sync/overlay-trigger.dev.js +6 -0
  146. package/sync/overlay-trigger.dev.js.map +7 -0
  147. package/sync/overlay-trigger.js +2 -0
  148. package/sync/overlay-trigger.js.map +7 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["LongpressController.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 {\n isAndroid,\n isIOS,\n} from '@spectrum-web-components/shared/src/platform.js';\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 { noop } from './AbstractOverlay.dev.js'\nimport {\n InteractionController,\n InteractionTypes,\n} from './InteractionController.dev.js'\n\nconst LONGPRESS_DURATION = 300;\nexport const LONGPRESS_INSTRUCTIONS = {\n touch: 'Double tap and long press for additional options',\n keyboard: 'Press Space or Alt+Down Arrow for additional options',\n mouse: 'Click and hold for additional options',\n};\n\ntype LongpressEvent = {\n source: 'pointer' | 'keyboard';\n};\n\nexport class LongpressController extends InteractionController {\n override type = InteractionTypes.longpress;\n\n override get activelyOpening(): boolean {\n return (\n this.longpressState === 'opening' ||\n this.longpressState === 'pressed'\n );\n }\n\n protected longpressState: null | 'potential' | 'opening' | 'pressed' = null;\n\n override releaseDescription = noop;\n\n private timeout!: ReturnType<typeof setTimeout>;\n\n handleLongpress(): void {\n this.open = true;\n this.longpressState =\n this.longpressState === 'potential' ? 'opening' : 'pressed';\n }\n\n handlePointerdown(event: PointerEvent): void {\n if (!this.target) return;\n if (event.button !== 0) return;\n this.longpressState = 'potential';\n document.addEventListener('pointerup', this.handlePointerup);\n document.addEventListener('pointercancel', this.handlePointerup);\n // Only dispatch longpress event if the trigger element isn't doing it for us.\n const triggerHandlesLongpress = 'holdAffordance' in this.target;\n if (triggerHandlesLongpress) return;\n this.timeout = setTimeout(() => {\n if (!this.target) return;\n this.target.dispatchEvent(\n new CustomEvent<LongpressEvent>('longpress', {\n bubbles: true,\n composed: true,\n detail: {\n source: 'pointer',\n },\n })\n );\n }, LONGPRESS_DURATION);\n }\n\n private handlePointerup = (): void => {\n clearTimeout(this.timeout);\n if (!this.target) return;\n // When triggered by the pointer, the last of `opened`\n // or `pointerup` should move the `longpressState` to\n // `null` so that the earlier event can void the \"light\n // dismiss\" and keep the Overlay open.\n this.longpressState =\n this.overlay?.state === 'opening' ? 'pressed' : null;\n document.removeEventListener('pointerup', this.handlePointerup);\n document.removeEventListener('pointercancel', this.handlePointerup);\n };\n\n private handleKeydown(event: KeyboardEvent): void {\n const { code, altKey } = event;\n if (altKey && code === 'ArrowDown') {\n event.stopPropagation();\n event.stopImmediatePropagation();\n }\n }\n\n private handleKeyup(event: KeyboardEvent): void {\n const { code, altKey } = event;\n if (code === 'Space' || (altKey && code === 'ArrowDown')) {\n if (!this.target) {\n return;\n }\n event.stopPropagation();\n this.target.dispatchEvent(\n new CustomEvent<LongpressEvent>('longpress', {\n bubbles: true,\n composed: true,\n detail: {\n source: 'keyboard',\n },\n })\n );\n setTimeout(() => {\n this.longpressState = null;\n });\n }\n }\n\n override prepareDescription(trigger: HTMLElement): void {\n if (\n // do not reapply until target is recycled\n this.releaseDescription !== noop ||\n // require \"longpress content\" to apply relationship\n !this.overlay.elements.length\n ) {\n return;\n }\n\n const longpressDescription = document.createElement('div');\n longpressDescription.id = `longpress-describedby-descriptor-${randomID()}`;\n const messageType = isIOS() || isAndroid() ? 'touch' : 'keyboard';\n longpressDescription.textContent = LONGPRESS_INSTRUCTIONS[messageType];\n longpressDescription.slot = 'longpress-describedby-descriptor';\n const triggerParent = trigger.getRootNode() as HTMLElement;\n const overlayParent = this.overlay.getRootNode() as HTMLElement;\n // Manage the placement of the helper element in an accessible place with\n // the lowest chance of negatively affecting the layout of the page.\n if (triggerParent === overlayParent) {\n // Trigger and Overlay in same DOM tree...\n // Append helper element to Overlay.\n this.overlay.append(longpressDescription);\n } else {\n // If Trigger in <body>, hide helper\n longpressDescription.hidden = !('host' in triggerParent);\n // Trigger and Overlay in different DOM tree, Trigger in shadow tree...\n // Insert helper element after Trigger.\n trigger.insertAdjacentElement('afterend', longpressDescription);\n }\n\n const releaseDescription = conditionAttributeWithId(\n trigger,\n 'aria-describedby',\n [longpressDescription.id]\n );\n this.releaseDescription = () => {\n releaseDescription();\n longpressDescription.remove();\n this.releaseDescription = noop;\n };\n }\n\n override shouldCompleteOpen(): void {\n // When triggered by the pointer, the last of `opened`\n // or `pointerup` should move the `longpressState` to\n // `null` so that the earlier event can void the \"light\n // dismiss\" and keep the Overlay open.\n this.longpressState =\n this.longpressState === 'pressed' ? null : this.longpressState;\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 'longpress',\n () => this.handleLongpress(),\n { signal }\n );\n this.target.addEventListener(\n 'pointerdown',\n (event: PointerEvent) => this.handlePointerdown(event),\n { signal }\n );\n\n this.prepareDescription(this.target);\n if (\n (this.target as HTMLElement & { holdAffordance: boolean })\n .holdAffordance\n ) {\n // Only bind keyboard events when the trigger element isn't doing it for us.\n return;\n }\n this.target.addEventListener(\n 'keydown',\n (event: KeyboardEvent) => this.handleKeydown(event),\n { signal }\n );\n this.target.addEventListener(\n 'keyup',\n (event: KeyboardEvent) => this.handleKeyup(event),\n { signal }\n );\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";import{isAndroid as a,isIOS as d}from"@spectrum-web-components/shared/src/platform.js";import{conditionAttributeWithId as p}from"@spectrum-web-components/base/src/condition-attribute-with-id.js";import{randomID as l}from"@spectrum-web-components/shared/src/random-id.js";import{noop as r}from"./AbstractOverlay.js";import{InteractionController as h,InteractionTypes as c}from"./InteractionController.js";const g=300;export const LONGPRESS_INSTRUCTIONS={touch:"Double tap and long press for additional options",keyboard:"Press Space or Alt+Down Arrow for additional options",mouse:"Click and hold for additional options"};export class LongpressController extends h{constructor(){super(...arguments);this.type=c.longpress;this.longpressState=null;this.releaseDescription=r;this.handlePointerup=()=>{var e;clearTimeout(this.timeout),this.target&&(this.longpressState=((e=this.overlay)==null?void 0:e.state)==="opening"?"pressed":null,document.removeEventListener("pointerup",this.handlePointerup),document.removeEventListener("pointercancel",this.handlePointerup))}}get activelyOpening(){return this.longpressState==="opening"||this.longpressState==="pressed"}handleLongpress(){this.open=!0,this.longpressState=this.longpressState==="potential"?"opening":"pressed"}handlePointerdown(e){!this.target||e.button!==0||(this.longpressState="potential",document.addEventListener("pointerup",this.handlePointerup),document.addEventListener("pointercancel",this.handlePointerup),"holdAffordance"in this.target)||(this.timeout=setTimeout(()=>{this.target&&this.target.dispatchEvent(new CustomEvent("longpress",{bubbles:!0,composed:!0,detail:{source:"pointer"}}))},g))}handleKeydown(e){const{code:t,altKey:o}=e;o&&t==="ArrowDown"&&(e.stopPropagation(),e.stopImmediatePropagation())}handleKeyup(e){const{code:t,altKey:o}=e;if(t==="Space"||o&&t==="ArrowDown"){if(!this.target)return;e.stopPropagation(),this.target.dispatchEvent(new CustomEvent("longpress",{bubbles:!0,composed:!0,detail:{source:"keyboard"}})),setTimeout(()=>{this.longpressState=null})}}prepareDescription(e){if(this.releaseDescription!==r||!this.overlay.elements.length)return;const t=document.createElement("div");t.id=`longpress-describedby-descriptor-${l()}`;const o=d()||a()?"touch":"keyboard";t.textContent=LONGPRESS_INSTRUCTIONS[o],t.slot="longpress-describedby-descriptor";const n=e.getRootNode(),s=this.overlay.getRootNode();n===s?this.overlay.append(t):(t.hidden=!("host"in n),e.insertAdjacentElement("afterend",t));const i=p(e,"aria-describedby",[t.id]);this.releaseDescription=()=>{i(),t.remove(),this.releaseDescription=r}}shouldCompleteOpen(){this.longpressState=this.longpressState==="pressed"?null:this.longpressState}init(){var t;(t=this.abortController)==null||t.abort(),this.abortController=new AbortController;const{signal:e}=this.abortController;this.target.addEventListener("longpress",()=>this.handleLongpress(),{signal:e}),this.target.addEventListener("pointerdown",o=>this.handlePointerdown(o),{signal:e}),this.prepareDescription(this.target),!this.target.holdAffordance&&(this.target.addEventListener("keydown",o=>this.handleKeydown(o),{signal:e}),this.target.addEventListener("keyup",o=>this.handleKeyup(o),{signal:e}))}}
2
+ //# sourceMappingURL=LongpressController.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["LongpressController.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 {\n isAndroid,\n isIOS,\n} from '@spectrum-web-components/shared/src/platform.js';\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 { noop } from './AbstractOverlay.js';\nimport {\n InteractionController,\n InteractionTypes,\n} from './InteractionController.js';\n\nconst LONGPRESS_DURATION = 300;\nexport const LONGPRESS_INSTRUCTIONS = {\n touch: 'Double tap and long press for additional options',\n keyboard: 'Press Space or Alt+Down Arrow for additional options',\n mouse: 'Click and hold for additional options',\n};\n\ntype LongpressEvent = {\n source: 'pointer' | 'keyboard';\n};\n\nexport class LongpressController extends InteractionController {\n override type = InteractionTypes.longpress;\n\n override get activelyOpening(): boolean {\n return (\n this.longpressState === 'opening' ||\n this.longpressState === 'pressed'\n );\n }\n\n protected longpressState: null | 'potential' | 'opening' | 'pressed' = null;\n\n override releaseDescription = noop;\n\n private timeout!: ReturnType<typeof setTimeout>;\n\n handleLongpress(): void {\n this.open = true;\n this.longpressState =\n this.longpressState === 'potential' ? 'opening' : 'pressed';\n }\n\n handlePointerdown(event: PointerEvent): void {\n if (!this.target) return;\n if (event.button !== 0) return;\n this.longpressState = 'potential';\n document.addEventListener('pointerup', this.handlePointerup);\n document.addEventListener('pointercancel', this.handlePointerup);\n // Only dispatch longpress event if the trigger element isn't doing it for us.\n const triggerHandlesLongpress = 'holdAffordance' in this.target;\n if (triggerHandlesLongpress) return;\n this.timeout = setTimeout(() => {\n if (!this.target) return;\n this.target.dispatchEvent(\n new CustomEvent<LongpressEvent>('longpress', {\n bubbles: true,\n composed: true,\n detail: {\n source: 'pointer',\n },\n })\n );\n }, LONGPRESS_DURATION);\n }\n\n private handlePointerup = (): void => {\n clearTimeout(this.timeout);\n if (!this.target) return;\n // When triggered by the pointer, the last of `opened`\n // or `pointerup` should move the `longpressState` to\n // `null` so that the earlier event can void the \"light\n // dismiss\" and keep the Overlay open.\n this.longpressState =\n this.overlay?.state === 'opening' ? 'pressed' : null;\n document.removeEventListener('pointerup', this.handlePointerup);\n document.removeEventListener('pointercancel', this.handlePointerup);\n };\n\n private handleKeydown(event: KeyboardEvent): void {\n const { code, altKey } = event;\n if (altKey && code === 'ArrowDown') {\n event.stopPropagation();\n event.stopImmediatePropagation();\n }\n }\n\n private handleKeyup(event: KeyboardEvent): void {\n const { code, altKey } = event;\n if (code === 'Space' || (altKey && code === 'ArrowDown')) {\n if (!this.target) {\n return;\n }\n event.stopPropagation();\n this.target.dispatchEvent(\n new CustomEvent<LongpressEvent>('longpress', {\n bubbles: true,\n composed: true,\n detail: {\n source: 'keyboard',\n },\n })\n );\n setTimeout(() => {\n this.longpressState = null;\n });\n }\n }\n\n override prepareDescription(trigger: HTMLElement): void {\n if (\n // do not reapply until target is recycled\n this.releaseDescription !== noop ||\n // require \"longpress content\" to apply relationship\n !this.overlay.elements.length\n ) {\n return;\n }\n\n const longpressDescription = document.createElement('div');\n longpressDescription.id = `longpress-describedby-descriptor-${randomID()}`;\n const messageType = isIOS() || isAndroid() ? 'touch' : 'keyboard';\n longpressDescription.textContent = LONGPRESS_INSTRUCTIONS[messageType];\n longpressDescription.slot = 'longpress-describedby-descriptor';\n const triggerParent = trigger.getRootNode() as HTMLElement;\n const overlayParent = this.overlay.getRootNode() as HTMLElement;\n // Manage the placement of the helper element in an accessible place with\n // the lowest chance of negatively affecting the layout of the page.\n if (triggerParent === overlayParent) {\n // Trigger and Overlay in same DOM tree...\n // Append helper element to Overlay.\n this.overlay.append(longpressDescription);\n } else {\n // If Trigger in <body>, hide helper\n longpressDescription.hidden = !('host' in triggerParent);\n // Trigger and Overlay in different DOM tree, Trigger in shadow tree...\n // Insert helper element after Trigger.\n trigger.insertAdjacentElement('afterend', longpressDescription);\n }\n\n const releaseDescription = conditionAttributeWithId(\n trigger,\n 'aria-describedby',\n [longpressDescription.id]\n );\n this.releaseDescription = () => {\n releaseDescription();\n longpressDescription.remove();\n this.releaseDescription = noop;\n };\n }\n\n override shouldCompleteOpen(): void {\n // When triggered by the pointer, the last of `opened`\n // or `pointerup` should move the `longpressState` to\n // `null` so that the earlier event can void the \"light\n // dismiss\" and keep the Overlay open.\n this.longpressState =\n this.longpressState === 'pressed' ? null : this.longpressState;\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 'longpress',\n () => this.handleLongpress(),\n { signal }\n );\n this.target.addEventListener(\n 'pointerdown',\n (event: PointerEvent) => this.handlePointerdown(event),\n { signal }\n );\n\n this.prepareDescription(this.target);\n if (\n (this.target as HTMLElement & { holdAffordance: boolean })\n .holdAffordance\n ) {\n // Only bind keyboard events when the trigger element isn't doing it for us.\n return;\n }\n this.target.addEventListener(\n 'keydown',\n (event: KeyboardEvent) => this.handleKeydown(event),\n { signal }\n );\n this.target.addEventListener(\n 'keyup',\n (event: KeyboardEvent) => this.handleKeyup(event),\n { signal }\n );\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["isAndroid", "isIOS", "conditionAttributeWithId", "randomID", "noop", "InteractionController", "InteractionTypes", "LONGPRESS_DURATION", "_a", "event", "code", "altKey", "trigger", "longpressDescription", "messageType", "triggerParent", "overlayParent", "releaseDescription", "signal"]
7
+ }
@@ -0,0 +1,134 @@
1
+ import { PropertyValues, TemplateResult } from '@spectrum-web-components/base';
2
+ import { ElementResolutionController } from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';
3
+ import type { OpenableElement, OverlayState, OverlayTypes, Placement, TriggerInteraction } from './overlay-types.js';
4
+ import { AbstractOverlay } from './AbstractOverlay.js';
5
+ import { VirtualTrigger } from './VirtualTrigger.js';
6
+ import { PlacementController } from './PlacementController.js';
7
+ import type { ClickController } from './ClickController.js';
8
+ import type { HoverController } from './HoverController.js';
9
+ import type { LongpressController } from './LongpressController.js';
10
+ export { LONGPRESS_INSTRUCTIONS } from './LongpressController.js';
11
+ declare let OverlayFeatures: typeof AbstractOverlay & import("./overlay-types.js").Constructor<import("@spectrum-web-components/base").SpectrumElement>;
12
+ /**
13
+ * @element sp-overlay
14
+ *
15
+ * @fires sp-opened - announces that an overlay has completed any entry animations
16
+ * @fires sp-closed - announce that an overlay has compelted any exit animations
17
+ * @fires slottable-request - requests to add or remove slottable content
18
+ */
19
+ export declare class Overlay extends OverlayFeatures {
20
+ static styles: import("@spectrum-web-components/base").CSSResult[];
21
+ /**
22
+ * An Overlay that is `delayed` will wait until a warm-up period of 1000ms
23
+ * has completed before opening. Once the warmup period has completed, all
24
+ * subsequent Overlays will open immediately. When no Overlays are opened,
25
+ * a cooldown period of 1000ms will begin. Once the cooldown has completed,
26
+ * the next Overlay to be opened will be subject to the warm-up period if
27
+ * provided that option.
28
+ */
29
+ get delayed(): boolean;
30
+ set delayed(delayed: boolean);
31
+ private _delayed;
32
+ dialogEl: HTMLDialogElement & {
33
+ showPopover(): void;
34
+ hidePopover(): void;
35
+ };
36
+ /**
37
+ * Whether the overlay is currently functional or not
38
+ */
39
+ get disabled(): boolean;
40
+ set disabled(disabled: boolean);
41
+ private _disabled;
42
+ elements: OpenableElement[];
43
+ parentOverlayToForceClose?: Overlay;
44
+ private get hasNonVirtualTrigger();
45
+ /**
46
+ * The `offset` property accepts either a single number, to
47
+ * define the offset of the Overlay along the main axis from
48
+ * the trigger, or 2-tuple, to define the offset along the
49
+ * main axis and the cross axis. This option has no effect
50
+ * when there is no trigger element.
51
+ */
52
+ offset: number | [number, number];
53
+ protected get placementController(): PlacementController;
54
+ /**
55
+ * Whether the Overlay is projected onto the "top layer" or not.
56
+ */
57
+ get open(): boolean;
58
+ set open(open: boolean);
59
+ private _open;
60
+ static openCount: number;
61
+ /**
62
+ * Instruct the Overlay where to place itself in
63
+ * relationship to the trigger element.
64
+ * @type {"top" | "top-start" | "top-end" | "right" | "right-start" | "right-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end"}
65
+ */
66
+ placement?: Placement;
67
+ /**
68
+ * The state in which the last `request-slottable` event was dispatched.
69
+ * Do not allow overlays from dispatching the same state twice in a row.
70
+ */
71
+ private lastRequestSlottableState;
72
+ /**
73
+ * Whether to pass focus to the overlay once opened, or
74
+ * to the appropriate value based on the "type" of the overlay
75
+ * when set to `"auto"`.
76
+ *
77
+ */
78
+ receivesFocus: 'true' | 'false' | 'auto';
79
+ slotEl: HTMLSlotElement;
80
+ get state(): OverlayState;
81
+ set state(state: OverlayState);
82
+ _state: OverlayState;
83
+ strategy?: ClickController | HoverController | LongpressController;
84
+ tipPadding?: number;
85
+ /**
86
+ * An optional ID reference for the trigger element combined with the optional
87
+ * interaction (click | hover | longpress) by which the overlay shold open
88
+ * the overlay with an `@`: e.g. `trigger@click` opens the overlay when an
89
+ * element with the ID "trigger" is clicked.
90
+ */
91
+ trigger?: string;
92
+ /**
93
+ * An element reference for the trigger element that the overlay should relate to.
94
+ */
95
+ triggerElement: HTMLElement | VirtualTrigger | null;
96
+ /**
97
+ * The specific interaction to listen for on the `triggerElement` to open the overlay.
98
+ */
99
+ triggerInteraction?: TriggerInteraction;
100
+ /**
101
+ * Configures the open/close heuristics of the Overlay.
102
+ * @type {"auto" | "hint" | "manual" | "modal" | "page"}
103
+ */
104
+ type: OverlayTypes;
105
+ protected wasOpen: boolean;
106
+ protected get elementResolver(): ElementResolutionController;
107
+ private get usesDialog();
108
+ private get popoverValue();
109
+ protected get requiresPosition(): boolean;
110
+ protected managePosition(): void;
111
+ protected managePopoverOpen(): Promise<void>;
112
+ protected applyFocus(targetOpenState: boolean, focusEl: HTMLElement | null): Promise<void>;
113
+ protected returnFocus(): void;
114
+ private closeOnFocusOut;
115
+ protected manageOpen(oldOpen: boolean): Promise<void>;
116
+ protected bindEvents(): void;
117
+ protected handleBeforetoggle(event: Event & {
118
+ newState: string;
119
+ }): void;
120
+ protected handleBrowserClose(event: Event): void;
121
+ manuallyKeepOpen(): void;
122
+ protected handleSlotchange(): void;
123
+ shouldPreventClose(): boolean;
124
+ protected requestSlottable(): void;
125
+ willUpdate(changes: PropertyValues): void;
126
+ protected updated(changes: PropertyValues): void;
127
+ protected renderContent(): TemplateResult;
128
+ private get dialogStyleMap();
129
+ protected renderDialog(): TemplateResult;
130
+ protected renderPopover(): TemplateResult;
131
+ render(): TemplateResult;
132
+ connectedCallback(): void;
133
+ disconnectedCallback(): void;
134
+ }