@swisspost/design-system-components 10.0.0-next.50 → 10.0.0-next.52

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 (208) hide show
  1. package/dist/cjs/focusable-D6snQLqS.js +5020 -0
  2. package/dist/cjs/get-focusable-children-Bx63XUQg.js +67 -0
  3. package/dist/cjs/{index-CpDyH7Ww.js → index-Cb8CTrOz.js} +13 -9
  4. package/dist/cjs/loader.cjs.js +2 -2
  5. package/dist/cjs/{package-qtH-QrKv.js → package-B7Ni5Tuu.js} +1 -1
  6. package/dist/cjs/post-accordion_2.cjs.entry.js +3 -3
  7. package/dist/cjs/post-avatar.cjs.entry.js +2 -2
  8. package/dist/cjs/post-back-to-top.cjs.entry.js +3 -3
  9. package/dist/cjs/post-banner.cjs.entry.js +2 -2
  10. package/dist/cjs/post-breadcrumb-item_2.cjs.entry.js +5 -5
  11. package/dist/cjs/post-breadcrumbs.cjs.entry.js +12 -11
  12. package/dist/cjs/post-card-control.cjs.entry.js +2 -2
  13. package/dist/cjs/post-closebutton_15.cjs.entry.js +128 -110
  14. package/dist/cjs/post-collapsible_2.cjs.entry.js +2 -2
  15. package/dist/cjs/post-components.cjs.js +2 -2
  16. package/dist/cjs/post-footer.cjs.entry.js +2 -2
  17. package/dist/cjs/post-linkarea.cjs.entry.js +2 -2
  18. package/dist/cjs/post-popover-trigger.cjs.entry.js +109 -0
  19. package/dist/cjs/post-popover.cjs.entry.js +22 -104
  20. package/dist/cjs/post-rating.cjs.entry.js +4 -8
  21. package/dist/cjs/post-tab-header.cjs.entry.js +3 -3
  22. package/dist/cjs/post-tab-panel.cjs.entry.js +3 -3
  23. package/dist/cjs/post-tabs.cjs.entry.js +3 -3
  24. package/dist/cjs/post-tooltip-trigger.cjs.entry.js +6 -5022
  25. package/dist/cjs/post-tooltip.cjs.entry.js +3 -3
  26. package/dist/collection/collection-manifest.json +1 -0
  27. package/dist/collection/components/post-accordion-item/post-accordion-item.js +1 -1
  28. package/dist/collection/components/post-back-to-top/post-back-to-top.js +1 -1
  29. package/dist/collection/components/post-breadcrumb-item/post-breadcrumb-item.js +1 -1
  30. package/dist/collection/components/post-breadcrumbs/post-breadcrumbs.js +34 -13
  31. package/dist/collection/components/post-closebutton/post-closebutton.css +1 -1
  32. package/dist/collection/components/post-mainnavigation/post-mainnavigation.css +1 -1
  33. package/dist/collection/components/post-megadropdown/post-megadropdown.css +1 -1
  34. package/dist/collection/components/post-megadropdown/post-megadropdown.js +9 -2
  35. package/dist/collection/components/post-megadropdown-trigger/post-megadropdown-trigger.js +1 -1
  36. package/dist/collection/components/post-menu/post-menu.js +29 -33
  37. package/dist/collection/components/post-menu-item/post-menu-item.css +1 -1
  38. package/dist/collection/components/post-menu-item/post-menu-item.js +1 -1
  39. package/dist/collection/components/post-menu-trigger/post-menu-trigger.js +1 -1
  40. package/dist/collection/components/post-popover/post-popover.js +21 -77
  41. package/dist/collection/components/post-popover-trigger/post-popover-trigger.css +1 -0
  42. package/dist/collection/components/post-popover-trigger/post-popover-trigger.js +145 -0
  43. package/dist/collection/components/post-popovercontainer/post-popovercontainer.js +153 -32
  44. package/dist/collection/components/post-rating/post-rating.js +4 -9
  45. package/dist/collection/components/post-tab-header/post-tab-header.js +1 -1
  46. package/dist/collection/components/post-tab-panel/post-tab-panel.js +1 -1
  47. package/dist/collection/components/post-tabs/post-tabs.js +1 -1
  48. package/dist/collection/components/post-togglebutton/post-togglebutton.js +1 -1
  49. package/dist/collection/components/post-tooltip/post-tooltip.js +2 -2
  50. package/dist/collection/components/post-tooltip-trigger/post-tooltip-trigger.css +1 -1
  51. package/dist/collection/components/post-tooltip-trigger/post-tooltip-trigger.js +1 -1
  52. package/dist/collection/utils/get-focusable-children.js +34 -5
  53. package/dist/component-names.json +1 -0
  54. package/dist/components/focusable.js +5018 -0
  55. package/dist/components/get-focusable-children.js +35 -6
  56. package/dist/components/index.d.ts +2 -0
  57. package/dist/components/index.js +1 -0
  58. package/dist/components/package.js +1 -1
  59. package/dist/components/post-accordion-item2.js +1 -1
  60. package/dist/components/post-back-to-top.js +1 -1
  61. package/dist/components/post-breadcrumb-item2.js +1 -1
  62. package/dist/components/post-breadcrumbs.js +14 -11
  63. package/dist/components/post-closebutton2.js +1 -1
  64. package/dist/components/post-mainnavigation.js +1 -1
  65. package/dist/components/post-megadropdown-trigger.js +1 -1
  66. package/dist/components/post-megadropdown.js +10 -3
  67. package/dist/components/post-menu-item2.js +2 -2
  68. package/dist/components/post-menu-trigger2.js +1 -1
  69. package/dist/components/post-menu2.js +27 -31
  70. package/dist/components/post-popover-trigger.d.ts +11 -0
  71. package/dist/components/post-popover-trigger.js +132 -0
  72. package/dist/components/post-popover.js +17 -99
  73. package/dist/components/post-popovercontainer2.js +82 -32
  74. package/dist/components/post-rating.js +2 -6
  75. package/dist/components/post-tab-header.js +1 -1
  76. package/dist/components/post-tab-panel.js +1 -1
  77. package/dist/components/post-tabs.js +1 -1
  78. package/dist/components/post-togglebutton.js +1 -1
  79. package/dist/components/post-tooltip-trigger.js +6 -5022
  80. package/dist/components/post-tooltip.js +1 -1
  81. package/dist/components/react/index.js +1 -1
  82. package/dist/components/react/{p-CDsgZHvX.js → p-B35HsBxh.js} +83 -33
  83. package/dist/components/react/{p-BuKAaKXE.js → p-BL8WEb6K.js} +3 -3
  84. package/dist/components/react/p-BVXiQdHq.js +64 -0
  85. package/dist/components/react/{p-BmpB1vs4.js → p-By7jk8fL.js} +1 -1
  86. package/dist/components/react/{p-BXPcgIqO.js → p-C4zJkcAb.js} +3 -3
  87. package/dist/components/react/{p-U9MTjvRU.js → p-CQhnMei5.js} +2 -2
  88. package/dist/components/react/{p-BlOv-NDA.js → p-CrEdcwed.js} +5 -5
  89. package/dist/components/react/{p-DnHwlsBi.js → p-Dl8clYLV.js} +3 -3
  90. package/dist/components/react/{p-B9Y7UQKI.js → p-DnhWNGb-.js} +1 -1
  91. package/dist/components/react/{p-BcVKzjda.js → p-DnqwBx5e.js} +1 -1
  92. package/dist/components/react/{p-Bw6vnK1I.js → p-Due3yZDR.js} +30 -34
  93. package/dist/components/react/p-HygIVKXC.js +5018 -0
  94. package/dist/components/react/p-kxuZ8mOU.js +3 -0
  95. package/dist/components/react/{p-B392lG2N.js → p-lC8Sp5tg.js} +1 -1
  96. package/dist/components/react/post-accordion-item.js +1 -1
  97. package/dist/components/react/post-accordion.js +1 -1
  98. package/dist/components/react/post-avatar.js +1 -1
  99. package/dist/components/react/post-back-to-top.js +3 -3
  100. package/dist/components/react/post-banner.js +1 -1
  101. package/dist/components/react/post-breadcrumb-item.js +1 -1
  102. package/dist/components/react/post-breadcrumbs.js +21 -18
  103. package/dist/components/react/post-card-control.js +2 -2
  104. package/dist/components/react/post-closebutton.js +1 -1
  105. package/dist/components/react/post-collapsible-trigger.js +1 -1
  106. package/dist/components/react/post-collapsible.js +1 -1
  107. package/dist/components/react/post-footer.js +6 -6
  108. package/dist/components/react/post-header.js +2 -2
  109. package/dist/components/react/post-icon.js +1 -1
  110. package/dist/components/react/post-language-option.js +1 -1
  111. package/dist/components/react/post-language-switch.js +5 -5
  112. package/dist/components/react/post-linkarea.js +1 -1
  113. package/dist/components/react/post-list-item.js +1 -1
  114. package/dist/components/react/post-list.js +1 -1
  115. package/dist/components/react/post-logo.js +1 -1
  116. package/dist/components/react/post-mainnavigation.js +3 -3
  117. package/dist/components/react/post-megadropdown-trigger.js +2 -2
  118. package/dist/components/react/post-megadropdown.js +12 -5
  119. package/dist/components/react/post-menu-item.js +1 -1
  120. package/dist/components/react/post-menu-trigger.js +1 -1
  121. package/dist/components/react/post-menu.js +1 -1
  122. package/dist/components/react/post-popover-trigger.d.ts +11 -0
  123. package/dist/components/react/post-popover-trigger.js +133 -0
  124. package/dist/components/react/post-popover.js +21 -103
  125. package/dist/components/react/post-popovercontainer.js +1 -1
  126. package/dist/components/react/post-rating.js +4 -8
  127. package/dist/components/react/post-tab-header.js +2 -2
  128. package/dist/components/react/post-tab-panel.js +2 -2
  129. package/dist/components/react/post-tabs.js +2 -2
  130. package/dist/components/react/post-togglebutton.js +2 -2
  131. package/dist/components/react/post-tooltip-trigger.js +4 -5020
  132. package/dist/components/react/post-tooltip.js +3 -3
  133. package/dist/docs.json +206 -42
  134. package/dist/esm/focusable-HygIVKXC.js +5018 -0
  135. package/dist/esm/get-focusable-children-D9ZHp2FP.js +64 -0
  136. package/dist/esm/{index-C8a0ddDa.js → index-CFNKgUjL.js} +13 -9
  137. package/dist/esm/loader.js +3 -3
  138. package/dist/esm/package-kxuZ8mOU.js +3 -0
  139. package/dist/esm/post-accordion_2.entry.js +3 -3
  140. package/dist/esm/post-avatar.entry.js +2 -2
  141. package/dist/esm/post-back-to-top.entry.js +3 -3
  142. package/dist/esm/post-banner.entry.js +2 -2
  143. package/dist/esm/post-breadcrumb-item_2.entry.js +5 -5
  144. package/dist/esm/post-breadcrumbs.entry.js +13 -12
  145. package/dist/esm/post-card-control.entry.js +2 -2
  146. package/dist/esm/post-closebutton_15.entry.js +125 -107
  147. package/dist/esm/post-collapsible_2.entry.js +2 -2
  148. package/dist/esm/post-components.js +3 -3
  149. package/dist/esm/post-footer.entry.js +2 -2
  150. package/dist/esm/post-linkarea.entry.js +2 -2
  151. package/dist/esm/post-popover-trigger.entry.js +107 -0
  152. package/dist/esm/post-popover.entry.js +19 -101
  153. package/dist/esm/post-rating.entry.js +4 -8
  154. package/dist/esm/post-tab-header.entry.js +3 -3
  155. package/dist/esm/post-tab-panel.entry.js +3 -3
  156. package/dist/esm/post-tabs.entry.js +3 -3
  157. package/dist/esm/post-tooltip-trigger.entry.js +5 -5021
  158. package/dist/esm/post-tooltip.entry.js +3 -3
  159. package/dist/post-components/{p-1253185c.entry.js → p-1096ed89.entry.js} +1 -1
  160. package/dist/post-components/{p-0a4d9f33.entry.js → p-12183522.entry.js} +1 -1
  161. package/dist/post-components/{p-b82e7cbe.entry.js → p-173dcaab.entry.js} +1 -1
  162. package/dist/post-components/p-1d7418ce.entry.js +1 -0
  163. package/dist/post-components/p-244a47db.entry.js +1 -0
  164. package/dist/post-components/p-264c5f97.entry.js +1 -0
  165. package/dist/post-components/{p-e7fbb03d.entry.js → p-290ea78f.entry.js} +1 -1
  166. package/dist/post-components/p-2f8cad6c.entry.js +1 -0
  167. package/dist/post-components/p-47e43863.entry.js +1 -0
  168. package/dist/post-components/{p-5ddde390.entry.js → p-50a5c57f.entry.js} +1 -1
  169. package/dist/post-components/p-6d8f95de.entry.js +1 -0
  170. package/dist/post-components/p-72e56701.entry.js +1 -0
  171. package/dist/post-components/p-81d78878.entry.js +1 -0
  172. package/dist/post-components/p-8a6467b4.entry.js +1 -0
  173. package/dist/post-components/{p-15e0d4b8.entry.js → p-9e461598.entry.js} +1 -1
  174. package/dist/post-components/p-CFNKgUjL.js +2 -0
  175. package/dist/post-components/p-D9ZHp2FP.js +1 -0
  176. package/dist/post-components/p-HygIVKXC.js +1 -0
  177. package/dist/post-components/p-a92b241a.entry.js +1 -0
  178. package/dist/post-components/{p-f9d044a3.entry.js → p-c84e7f02.entry.js} +1 -1
  179. package/dist/post-components/{p-048d2c1a.entry.js → p-e37d9a31.entry.js} +1 -1
  180. package/dist/post-components/p-f62f52d7.entry.js +1 -0
  181. package/dist/post-components/p-kxuZ8mOU.js +1 -0
  182. package/dist/post-components/post-components.css +1 -1
  183. package/dist/post-components/post-components.esm.js +1 -1
  184. package/dist/types/components/post-breadcrumbs/post-breadcrumbs.d.ts +6 -1
  185. package/dist/types/components/post-menu/post-menu.d.ts +4 -3
  186. package/dist/types/components/post-popover/post-popover.d.ts +5 -10
  187. package/dist/types/components/post-popover-trigger/post-popover-trigger.d.ts +37 -0
  188. package/dist/types/components/post-popovercontainer/post-popovercontainer.d.ts +34 -5
  189. package/dist/types/components.d.ts +66 -13
  190. package/dist/types/utils/get-focusable-children.d.ts +1 -0
  191. package/hydrate/index.js +6708 -6595
  192. package/hydrate/index.mjs +6708 -6595
  193. package/package.json +7 -7
  194. package/dist/components/react/p-C35MCWIp.js +0 -35
  195. package/dist/components/react/p-DimG3b3P.js +0 -3
  196. package/dist/esm/package-DimG3b3P.js +0 -3
  197. package/dist/post-components/p-11abb64f.entry.js +0 -1
  198. package/dist/post-components/p-1d4252ba.entry.js +0 -1
  199. package/dist/post-components/p-3d30eafa.entry.js +0 -1
  200. package/dist/post-components/p-4114fc83.entry.js +0 -1
  201. package/dist/post-components/p-89411986.entry.js +0 -1
  202. package/dist/post-components/p-9bbf7271.entry.js +0 -1
  203. package/dist/post-components/p-C8a0ddDa.js +0 -2
  204. package/dist/post-components/p-DimG3b3P.js +0 -1
  205. package/dist/post-components/p-b034d196.entry.js +0 -1
  206. package/dist/post-components/p-b36c129a.entry.js +0 -1
  207. package/dist/post-components/p-f1d53256.entry.js +0 -1
  208. package/dist/post-components/p-f97f3a19.entry.js +0 -1
@@ -1,38 +1,12 @@
1
1
  import { h, Host } from "@stencil/core";
2
2
  import { PLACEMENT_TYPES } from "../../types/index";
3
3
  import { version } from "../../../../package";
4
- import { IS_BROWSER, getAttributeObserver, checkRequiredAndType, checkEmptyOrOneOf } from "../../utils/index";
4
+ import { checkRequiredAndType, checkEmptyOrOneOf, getDeepFocusableChildren } from "../../utils/index";
5
5
  /**
6
6
  * @slot default - Slot for placing content inside the popover.
7
7
  */
8
- let popoverInstances = 0;
9
- const popoverTargetAttribute = 'data-popover-target';
10
- const globalToggleHandler = (e) => {
11
- let currentElement = e.target;
12
- // Traverse up the DOM tree to find if any parent has the popover target attribute
13
- while (currentElement && !currentElement.getAttribute(popoverTargetAttribute)) {
14
- if (currentElement === document.body || !currentElement.parentElement)
15
- break;
16
- currentElement = currentElement.parentElement;
17
- }
18
- const popoverTarget = currentElement?.getAttribute(popoverTargetAttribute);
19
- if (!popoverTarget || ('key' in e && e.key !== 'Enter'))
20
- return;
21
- const popover = document.getElementById(popoverTarget);
22
- popover?.toggle(currentElement);
23
- };
24
8
  export class PostPopover {
25
- validatePlacement() {
26
- checkEmptyOrOneOf(this, 'placement', PLACEMENT_TYPES);
27
- }
28
- validateCloseButtonCaption() {
29
- checkRequiredAndType(this, 'closeButtonCaption', 'string');
30
- }
31
9
  constructor() {
32
- // Initialize a mutation observer for patching accessibility features
33
- this.triggerObserver = IS_BROWSER
34
- ? getAttributeObserver(popoverTargetAttribute, this.patchAccessibilityFeatures)
35
- : null;
36
10
  /**
37
11
  * Defines the position of the popover relative to its trigger.
38
12
  * Popovers are automatically flipped to the opposite side if there is not enough available space and are shifted towards the viewport if they would overlap edge boundaries.
@@ -44,76 +18,46 @@ export class PostPopover {
44
18
  */
45
19
  // eslint-disable-next-line @stencil-community/ban-default-true
46
20
  this.arrow = true;
47
- this.localBeforeToggleHandler = this.beforeToggleHandler.bind(this);
48
21
  }
49
- connectedCallback() {
50
- // Set up accessibility patcher and event listeners for the first component
51
- if (popoverInstances === 0) {
52
- window.addEventListener('pointerup', globalToggleHandler);
53
- window.addEventListener('keydown', globalToggleHandler);
54
- this.triggerObserver?.observe(document.body, {
55
- subtree: true,
56
- childList: true,
57
- attributeFilter: [popoverTargetAttribute],
58
- });
59
- }
60
- popoverInstances++;
61
- this.triggers.forEach(trigger => trigger.setAttribute('aria-expanded', 'false'));
22
+ validatePlacement() {
23
+ checkEmptyOrOneOf(this, 'placement', PLACEMENT_TYPES);
24
+ }
25
+ validateCloseButtonCaption() {
26
+ checkRequiredAndType(this, 'closeButtonCaption', 'string');
62
27
  }
63
28
  componentDidLoad() {
64
29
  this.validatePlacement();
65
30
  this.validateCloseButtonCaption();
66
- this.popoverRef.addEventListener('beforetoggle', this.localBeforeToggleHandler);
67
- }
68
- disconnectedCallback() {
69
- popoverInstances--;
70
- // Remove listeners and observer after the last popover has been destructed
71
- if (popoverInstances === 0) {
72
- window.removeEventListener('click', globalToggleHandler);
73
- window.removeEventListener('keydown', globalToggleHandler);
74
- this.triggerObserver?.disconnect();
75
- }
76
- this.popoverRef.removeEventListener('beforetoggle', this.localBeforeToggleHandler);
77
- this.triggers.forEach(trigger => trigger.removeAttribute('aria-expanded'));
78
31
  }
79
32
  /**
80
33
  * Programmatically display the popover
81
- * @param target An element with [data-popover-target="id"] where the popover should be shown
34
+ * @param target A focusable element inside the <post-popover-trigger> component that controls the popover
82
35
  */
83
36
  async show(target) {
84
37
  this.popoverRef.show(target);
85
- console.log(this.popoverRef);
86
- target.setAttribute('aria-expanded', 'true');
87
38
  }
88
39
  /**
89
40
  * Programmatically hide this popover
90
41
  */
91
42
  async hide() {
92
43
  this.popoverRef.hide();
93
- this.triggers.forEach(trigger => trigger.setAttribute('aria-expanded', 'false'));
94
44
  }
95
45
  /**
96
46
  * Toggle popover display
97
- * @param target An element with [data-popover-target="id"] where the popover should be anchored to
47
+ * @param target A focusable element inside the <post-popover-trigger> component that controls the popover
98
48
  * @param force Pass true to always show or false to always hide
99
49
  */
100
50
  async toggle(target, force) {
101
- const newState = await this.popoverRef.toggle(target, force);
102
- this.triggers.forEach(trigger => trigger.setAttribute('aria-expanded', 'false'));
103
- target.setAttribute('aria-expanded', `${newState}`);
104
- }
105
- get triggers() {
106
- return document.querySelectorAll(`[${popoverTargetAttribute}="${this.host.id}"]`);
107
- }
108
- beforeToggleHandler() {
109
- this.triggers.forEach(trigger => trigger.setAttribute('aria-expanded', 'false'));
110
- }
111
- patchAccessibilityFeatures(trigger) {
112
- const force = trigger.hasAttribute(popoverTargetAttribute);
113
- trigger.setAttribute('aria-expanded', force ? 'false' : null);
51
+ await this.popoverRef.toggle(target, force);
52
+ const focusableChildren = getDeepFocusableChildren(this.host);
53
+ // find first focusable element
54
+ const firstFocusable = focusableChildren[0];
55
+ if (firstFocusable) {
56
+ firstFocusable.focus();
57
+ }
114
58
  }
115
59
  render() {
116
- return (h(Host, { key: '4224bfe1dc1bdb7fdfb86da67b54816e8cc6fce4', "data-version": version }, h("post-popovercontainer", { key: '3d7e370a89214878d33598cafd3d118c74d16312', arrow: this.arrow, placement: this.placement, ref: e => (this.popoverRef = e) }, h("div", { key: 'ed806f93ddec2656a15a1b242246c9c09b34f58a', class: "popover-container" }, h("div", { key: 'd60dd75153f88fc65d56dc9ec7387363e78cb835', class: "popover-content" }, h("slot", { key: 'f37005a225ecde32a80dd5efc3e61ccea7ab6dc5' })), h("post-closebutton", { key: 'c440bc94fb2832a8b8fcc0dd545b5f9d65cf834a', onClick: () => this.hide() }, this.closeButtonCaption)))));
60
+ return (h(Host, { key: '82f8d89013b8ddb37fb924c9608ba394c669f35a', "data-version": version }, h("post-popovercontainer", { key: 'cf276e5faf65ae27bc0d8e51779de5470a1e49a3', arrow: this.arrow, placement: this.placement, ref: e => (this.popoverRef = e) }, h("div", { key: '9ab455b2ee7d7f082dc6fc588d519d7a362cad8c', class: "popover-container" }, h("div", { key: 'b3b468da2ff7ccb2a47d69a1841488359763e927', class: "popover-content" }, h("slot", { key: 'a32099475baaca02ce41350e36d363614a6f83ef' })), h("post-closebutton", { key: 'eac806bd1e6652cacce58fb7e915d66e82c24980', onClick: () => this.hide() }, this.closeButtonCaption)))));
117
61
  }
118
62
  static get is() { return "post-popover"; }
119
63
  static get encapsulation() { return "shadow"; }
@@ -140,7 +84,7 @@ export class PostPopover {
140
84
  "Placement": {
141
85
  "location": "import",
142
86
  "path": "@floating-ui/dom",
143
- "id": "../../node_modules/.pnpm/@floating-ui+dom@1.7.3/node_modules/@floating-ui/dom/dist/floating-ui.dom.d.ts::Placement"
87
+ "id": "../../node_modules/.pnpm/@floating-ui+dom@1.7.4/node_modules/@floating-ui/dom/dist/floating-ui.dom.d.ts::Placement"
144
88
  }
145
89
  }
146
90
  },
@@ -204,7 +148,7 @@ export class PostPopover {
204
148
  "parameters": [{
205
149
  "name": "target",
206
150
  "type": "HTMLElement",
207
- "docs": "An element with [data-popover-target=\"id\"] where the popover should be shown"
151
+ "docs": "A focusable element inside the <post-popover-trigger> component that controls the popover"
208
152
  }],
209
153
  "references": {
210
154
  "Promise": {
@@ -222,7 +166,7 @@ export class PostPopover {
222
166
  "text": "Programmatically display the popover",
223
167
  "tags": [{
224
168
  "name": "param",
225
- "text": "target An element with [data-popover-target=\"id\"] where the popover should be shown"
169
+ "text": "target A focusable element inside the <post-popover-trigger> component that controls the popover"
226
170
  }]
227
171
  }
228
172
  },
@@ -249,7 +193,7 @@ export class PostPopover {
249
193
  "parameters": [{
250
194
  "name": "target",
251
195
  "type": "HTMLElement",
252
- "docs": "An element with [data-popover-target=\"id\"] where the popover should be anchored to"
196
+ "docs": "A focusable element inside the <post-popover-trigger> component that controls the popover"
253
197
  }, {
254
198
  "name": "force",
255
199
  "type": "boolean",
@@ -271,7 +215,7 @@ export class PostPopover {
271
215
  "text": "Toggle popover display",
272
216
  "tags": [{
273
217
  "name": "param",
274
- "text": "target An element with [data-popover-target=\"id\"] where the popover should be anchored to"
218
+ "text": "target A focusable element inside the <post-popover-trigger> component that controls the popover"
275
219
  }, {
276
220
  "name": "param",
277
221
  "text": "force Pass true to always show or false to always hide"
@@ -0,0 +1,145 @@
1
+ import { h, Host } from "@stencil/core";
2
+ import { version } from "../../../../package";
3
+ import isFocusable from "ally.js/is/focusable";
4
+ import { checkRequiredAndType } from "../../utils/index";
5
+ export class PostPopoverTrigger {
6
+ syncAriaExpanded(newValue) {
7
+ this.ariaExpanded = newValue;
8
+ if (this.trigger) {
9
+ this.trigger.setAttribute('aria-expanded', String(newValue));
10
+ }
11
+ }
12
+ /**
13
+ * Watch for changes to the `for` property to validate its type and ensure it is a string.
14
+ * @param forValue - The new value of the `for` property.
15
+ */
16
+ validateFor() {
17
+ checkRequiredAndType(this, 'for', 'string');
18
+ }
19
+ // Gets the associated popover element to the trigger based on 'for'
20
+ get popover() {
21
+ const ref = document.getElementById(this.for);
22
+ return ref?.localName === 'post-popover' ? ref : null;
23
+ }
24
+ setupTrigger() {
25
+ this.trigger = this.host.querySelector('*');
26
+ if (this.trigger) {
27
+ this.trigger.setAttribute('aria-expanded', this.ariaExpanded.toString());
28
+ // check if its not focusable and add aria role and tabindex
29
+ if (!isFocusable(this.trigger)) {
30
+ this.trigger.setAttribute('tabindex', '0');
31
+ this.trigger.setAttribute('role', 'button');
32
+ }
33
+ // Set aria attributes
34
+ this.trigger.setAttribute('aria-haspopup', 'true');
35
+ this.trigger.setAttribute('aria-controls', this.for);
36
+ this.trigger.addEventListener('click', this.boundHandleToggle);
37
+ this.trigger.addEventListener('keydown', this.boundHandleKeyDown);
38
+ }
39
+ else {
40
+ console.error('No content found in the post-popover-trigger slot. Please insert a focusable element or content that can receive focus.');
41
+ }
42
+ }
43
+ handleToggle() {
44
+ const popoverEl = this.popover;
45
+ if (popoverEl) {
46
+ popoverEl.toggle(this.trigger);
47
+ this.focusTrigger();
48
+ }
49
+ else {
50
+ console.warn(`No post-popover found with ID: ${this.for}`);
51
+ }
52
+ }
53
+ focusTrigger() {
54
+ // Restores focus to the trigger
55
+ if (!this.popoverOpen && this.trigger) {
56
+ this.trigger.focus();
57
+ }
58
+ }
59
+ constructor() {
60
+ /**
61
+ * Manages the accessibility attribute `aria-expanded` to indicate whether the associated popover is expanded or collapsed.
62
+ */
63
+ this.ariaExpanded = false;
64
+ /**
65
+ * Holds the state of the popover toggle
66
+ */
67
+ this.popoverOpen = false;
68
+ this.handleKeyDown = (e) => {
69
+ if (e.key === 'Enter' || e.key === ' ') {
70
+ e.preventDefault();
71
+ this.handleToggle();
72
+ }
73
+ };
74
+ this.boundHandleToggle = this.handleToggle.bind(this);
75
+ this.boundHandleKeyDown = this.handleKeyDown.bind(this);
76
+ this.boundHandlePostToggle = (event) => {
77
+ this.popoverOpen = event.detail.isOpen;
78
+ this.focusTrigger();
79
+ };
80
+ }
81
+ componentDidLoad() {
82
+ this.validateFor();
83
+ this.setupTrigger();
84
+ this.popover?.addEventListener('postToggle', this.boundHandlePostToggle);
85
+ }
86
+ disconnectedCallback() {
87
+ this.trigger.removeEventListener('click', this.boundHandleToggle);
88
+ this.trigger.removeEventListener('keydown', this.boundHandleKeyDown);
89
+ this.popover?.removeEventListener('postToggle', this.boundHandlePostToggle);
90
+ }
91
+ render() {
92
+ return (h(Host, { key: 'd7467aa400f407d76df06e8bbc84210e5f016073', "data-version": version }, h("slot", { key: '618f3d14fb89b3ad3c101a58f8519c337d9f1721', onSlotchange: () => this.setupTrigger() })));
93
+ }
94
+ static get is() { return "post-popover-trigger"; }
95
+ static get encapsulation() { return "shadow"; }
96
+ static get originalStyleUrls() {
97
+ return {
98
+ "$": ["post-popover-trigger.scss"]
99
+ };
100
+ }
101
+ static get styleUrls() {
102
+ return {
103
+ "$": ["post-popover-trigger.css"]
104
+ };
105
+ }
106
+ static get properties() {
107
+ return {
108
+ "for": {
109
+ "type": "string",
110
+ "attribute": "for",
111
+ "mutable": false,
112
+ "complexType": {
113
+ "original": "string",
114
+ "resolved": "string",
115
+ "references": {}
116
+ },
117
+ "required": true,
118
+ "optional": false,
119
+ "docs": {
120
+ "tags": [],
121
+ "text": "ID of the popover element that this trigger is linked to. Used to open and close the popover."
122
+ },
123
+ "getter": false,
124
+ "setter": false,
125
+ "reflect": true
126
+ }
127
+ };
128
+ }
129
+ static get states() {
130
+ return {
131
+ "ariaExpanded": {},
132
+ "popoverOpen": {}
133
+ };
134
+ }
135
+ static get elementRef() { return "host"; }
136
+ static get watchers() {
137
+ return [{
138
+ "propName": "popoverOpen",
139
+ "methodName": "syncAriaExpanded"
140
+ }, {
141
+ "propName": "for",
142
+ "methodName": "validateFor"
143
+ }];
144
+ }
145
+ }
@@ -11,7 +11,7 @@ import { popIn } from "../../animations/pop-in";
11
11
  */
12
12
  export class PostPopovercontainer {
13
13
  constructor() {
14
- this.firstOpen = true;
14
+ this.hasOpenedOnce = true;
15
15
  /**
16
16
  * Defines the placement of the popovercontainer according to the floating-ui options available at https://floating-ui.com/docs/computePosition#placement.
17
17
  * Popovercontainers are automatically flipped to the opposite side if there is not enough available space and are shifted
@@ -65,36 +65,79 @@ export class PostPopovercontainer {
65
65
  if (typeof this.clearAutoUpdate === 'function') {
66
66
  this.clearAutoUpdate();
67
67
  }
68
+ this.host.removeEventListener('beforetoggle', this.handleToggle.bind(this));
68
69
  }
69
70
  /**
70
71
  * Programmatically display the popovercontainer
71
- * @param target An element with [data-popover-target="id"] where the popovercontainer should be shown
72
+ * @param target A focusable element inside the <post-popover-trigger> component that controls the popover
72
73
  */
73
74
  async show(target) {
74
75
  if (this.toggleTimeoutId)
75
76
  return;
76
77
  this.eventTarget = target;
78
+ if (this.toggleTimeoutId)
79
+ return;
77
80
  this.calculatePosition();
78
81
  this.host.showPopover();
79
82
  }
83
+ /**
84
+ * Handles the popover opening process and emits related events.
85
+ */
86
+ async open() {
87
+ const content = this.host.querySelector('.popover-content');
88
+ this.startAutoupdates();
89
+ if (content) {
90
+ const animation = popIn(content);
91
+ if (animation?.playState === 'running') {
92
+ this.postBeforeToggle.emit({ willOpen: true });
93
+ this.postBeforeShow.emit({ first: this.hasOpenedOnce });
94
+ }
95
+ animation?.finished.then(() => {
96
+ this.postToggle.emit({ isOpen: true });
97
+ this.postShow.emit({ first: this.hasOpenedOnce });
98
+ if (this.hasOpenedOnce)
99
+ this.hasOpenedOnce = false;
100
+ });
101
+ }
102
+ if (this.safeSpace) {
103
+ window.addEventListener('mousemove', this.mouseTrackingHandler.bind(this));
104
+ }
105
+ }
106
+ /**
107
+ * Handles the popover closing process and emits related events.
108
+ */
109
+ async close() {
110
+ if (typeof this.clearAutoUpdate === 'function') {
111
+ this.clearAutoUpdate();
112
+ }
113
+ if (this.safeSpace) {
114
+ window.removeEventListener('mousemove', this.mouseTrackingHandler.bind(this));
115
+ }
116
+ this.postToggle.emit({ isOpen: false });
117
+ this.postHide.emit();
118
+ }
80
119
  /**
81
120
  * Programmatically hide the popovercontainer
82
121
  */
83
122
  async hide() {
84
123
  if (!this.toggleTimeoutId) {
124
+ if (this.eventTarget && this.eventTarget instanceof HTMLElement) {
125
+ this.eventTarget.focus();
126
+ }
85
127
  this.eventTarget = null;
86
128
  this.host.hidePopover();
129
+ this.postHide.emit();
87
130
  }
88
131
  }
89
132
  /**
90
133
  * Toggle popovercontainer display
91
- * @param target An element with [data-popover-target="id"] where the popovercontainer should be shown
134
+ * @param target A focusable element inside the <post-popover-trigger> component that controls the popover
92
135
  * @param force Pass true to always show or false to always hide
93
136
  */
94
137
  async toggle(target, force) {
138
+ this.eventTarget = target;
95
139
  // Prevent instant double toggle
96
140
  if (!this.toggleTimeoutId) {
97
- this.eventTarget = target;
98
141
  this.calculatePosition();
99
142
  this.host.togglePopover(force);
100
143
  this.toggleTimeoutId = null;
@@ -111,27 +154,11 @@ export class PostPopovercontainer {
111
154
  this.toggleTimeoutId = window.setTimeout(() => (this.toggleTimeoutId = null), 10);
112
155
  const isOpen = e.newState === 'open';
113
156
  if (isOpen) {
114
- const content = this.host.querySelector('.popover-content');
115
- this.startAutoupdates();
116
- if (content && this.animation === 'pop-in') {
117
- popIn(content);
118
- }
119
- if (this.safeSpace)
120
- window.addEventListener('mousemove', this.mouseTrackingHandler.bind(this));
121
- // Emit event with `first` flag only true on the first open
122
- if (this.firstOpen) {
123
- this.postToggle.emit({ isOpen, first: this.firstOpen });
124
- this.firstOpen = false;
125
- return;
126
- }
157
+ this.open();
127
158
  }
128
159
  else {
129
- if (typeof this.clearAutoUpdate === 'function')
130
- this.clearAutoUpdate();
131
- if (this.safeSpace)
132
- window.removeEventListener('mousemove', this.mouseTrackingHandler.bind(this));
160
+ this.close();
133
161
  }
134
- this.postToggle.emit({ isOpen: isOpen, first: false });
135
162
  }
136
163
  /**
137
164
  * Start listening for DOM updates, scroll events etc. that have
@@ -262,9 +289,9 @@ export class PostPopovercontainer {
262
289
  }
263
290
  }
264
291
  render() {
265
- return (h(Host, { key: '493d032d16ace815b6c031e77dbcc673f26d149b', "data-version": version, popover: this.manualClose ? 'manual' : 'auto' }, h("div", { key: '97bb357cada0456b3aa458e12768d9ad5458ef24', class: "popover-content" }, this.arrow && (h("span", { key: 'f5f2256470edad5a8ca89c32b3a44ef0fe388eea', class: "arrow", ref: el => {
292
+ return (h(Host, { key: 'cdb25a25fbd5e411e380175a8d3789cec83e2755', "data-version": version, popover: this.manualClose ? 'manual' : 'auto' }, h("div", { key: 'e99bcc4d5123b335b4b8be7044a80b2913ab6fce', class: "popover-content" }, this.arrow && (h("span", { key: '3c228829cc7e5bd83d7f1759ef163407ebcd10c5', class: "arrow", ref: el => {
266
293
  this.arrowRef = el;
267
- } })), h("slot", { key: 'f259b6ad624cf392e0d41026b4eab586009cb3c7' }))));
294
+ } })), h("slot", { key: '6a213deed5ccfec47d4dee903c7544d30a3f5748' }))));
268
295
  }
269
296
  static get is() { return "post-popovercontainer"; }
270
297
  static get originalStyleUrls() {
@@ -290,7 +317,7 @@ export class PostPopovercontainer {
290
317
  "Placement": {
291
318
  "location": "import",
292
319
  "path": "@floating-ui/dom",
293
- "id": "../../node_modules/.pnpm/@floating-ui+dom@1.7.3/node_modules/@floating-ui/dom/dist/floating-ui.dom.d.ts::Placement"
320
+ "id": "../../node_modules/.pnpm/@floating-ui+dom@1.7.4/node_modules/@floating-ui/dom/dist/floating-ui.dom.d.ts::Placement"
294
321
  }
295
322
  }
296
323
  },
@@ -408,6 +435,66 @@ export class PostPopovercontainer {
408
435
  }
409
436
  static get events() {
410
437
  return [{
438
+ "method": "postBeforeShow",
439
+ "name": "postBeforeShow",
440
+ "bubbles": true,
441
+ "cancelable": true,
442
+ "composed": true,
443
+ "docs": {
444
+ "tags": [],
445
+ "text": "Fires whenever the popovercontainer is about to be shown, passing in event.detail a `first` boolean, which is true if it is to be shown for the first time."
446
+ },
447
+ "complexType": {
448
+ "original": "{ first?: boolean }",
449
+ "resolved": "{ first?: boolean; }",
450
+ "references": {}
451
+ }
452
+ }, {
453
+ "method": "postShow",
454
+ "name": "postShow",
455
+ "bubbles": true,
456
+ "cancelable": true,
457
+ "composed": true,
458
+ "docs": {
459
+ "tags": [],
460
+ "text": "Fires whenever the popovercontainer is shown, passing in event.detail a `first` boolean, which is true if it is shown for the first time."
461
+ },
462
+ "complexType": {
463
+ "original": "{ first?: boolean }",
464
+ "resolved": "{ first?: boolean; }",
465
+ "references": {}
466
+ }
467
+ }, {
468
+ "method": "postHide",
469
+ "name": "postHide",
470
+ "bubbles": true,
471
+ "cancelable": true,
472
+ "composed": true,
473
+ "docs": {
474
+ "tags": [],
475
+ "text": "Fires whenever the popovercontainer is hidden."
476
+ },
477
+ "complexType": {
478
+ "original": "any",
479
+ "resolved": "any",
480
+ "references": {}
481
+ }
482
+ }, {
483
+ "method": "postBeforeToggle",
484
+ "name": "postBeforeToggle",
485
+ "bubbles": true,
486
+ "cancelable": true,
487
+ "composed": true,
488
+ "docs": {
489
+ "tags": [],
490
+ "text": "Fires whenever the popovercontainer is about to be shown or hidden, passing in event.detail a `willOpen` boolean, which is true if the popovercontainer is about to be opened and false if it is about to be closed."
491
+ },
492
+ "complexType": {
493
+ "original": "{ willOpen: boolean }",
494
+ "resolved": "{ willOpen: boolean; }",
495
+ "references": {}
496
+ }
497
+ }, {
411
498
  "method": "postToggle",
412
499
  "name": "postToggle",
413
500
  "bubbles": true,
@@ -415,11 +502,11 @@ export class PostPopovercontainer {
415
502
  "composed": true,
416
503
  "docs": {
417
504
  "tags": [],
418
- "text": "Fires whenever the popovercontainer gets shown or hidden, passing in event.detail an object containing two booleans: `isOpen`, which is true if the popovercontainer was opened and false if it was closed, and `first`, which is true if it was opened for the first time."
505
+ "text": "Fires whenever the popovercontainer gets shown or hidden, passing in event.detail an object containing a `isOpen`boolean, which is true if the popovercontainer was opened and false if it was closed."
419
506
  },
420
507
  "complexType": {
421
- "original": "{ isOpen: boolean; first?: boolean }",
422
- "resolved": "{ isOpen: boolean; first?: boolean; }",
508
+ "original": "{ isOpen: boolean }",
509
+ "resolved": "{ isOpen: boolean; }",
423
510
  "references": {}
424
511
  }
425
512
  }];
@@ -432,7 +519,7 @@ export class PostPopovercontainer {
432
519
  "parameters": [{
433
520
  "name": "target",
434
521
  "type": "HTMLElement",
435
- "docs": "An element with [data-popover-target=\"id\"] where the popovercontainer should be shown"
522
+ "docs": "A focusable element inside the <post-popover-trigger> component that controls the popover"
436
523
  }],
437
524
  "references": {
438
525
  "Promise": {
@@ -450,10 +537,44 @@ export class PostPopovercontainer {
450
537
  "text": "Programmatically display the popovercontainer",
451
538
  "tags": [{
452
539
  "name": "param",
453
- "text": "target An element with [data-popover-target=\"id\"] where the popovercontainer should be shown"
540
+ "text": "target A focusable element inside the <post-popover-trigger> component that controls the popover"
454
541
  }]
455
542
  }
456
543
  },
544
+ "open": {
545
+ "complexType": {
546
+ "signature": "() => Promise<void>",
547
+ "parameters": [],
548
+ "references": {
549
+ "Promise": {
550
+ "location": "global",
551
+ "id": "global::Promise"
552
+ }
553
+ },
554
+ "return": "Promise<void>"
555
+ },
556
+ "docs": {
557
+ "text": "Handles the popover opening process and emits related events.",
558
+ "tags": []
559
+ }
560
+ },
561
+ "close": {
562
+ "complexType": {
563
+ "signature": "() => Promise<void>",
564
+ "parameters": [],
565
+ "references": {
566
+ "Promise": {
567
+ "location": "global",
568
+ "id": "global::Promise"
569
+ }
570
+ },
571
+ "return": "Promise<void>"
572
+ },
573
+ "docs": {
574
+ "text": "Handles the popover closing process and emits related events.",
575
+ "tags": []
576
+ }
577
+ },
457
578
  "hide": {
458
579
  "complexType": {
459
580
  "signature": "() => Promise<void>",
@@ -477,7 +598,7 @@ export class PostPopovercontainer {
477
598
  "parameters": [{
478
599
  "name": "target",
479
600
  "type": "HTMLElement",
480
- "docs": "An element with [data-popover-target=\"id\"] where the popovercontainer should be shown"
601
+ "docs": "A focusable element inside the <post-popover-trigger> component that controls the popover"
481
602
  }, {
482
603
  "name": "force",
483
604
  "type": "boolean",
@@ -499,7 +620,7 @@ export class PostPopovercontainer {
499
620
  "text": "Toggle popovercontainer display",
500
621
  "tags": [{
501
622
  "name": "param",
502
- "text": "target An element with [data-popover-target=\"id\"] where the popovercontainer should be shown"
623
+ "text": "target A focusable element inside the <post-popover-trigger> component that controls the popover"
503
624
  }, {
504
625
  "name": "param",
505
626
  "text": "force Pass true to always show or false to always hide"