@crowdstrike/glide-core 0.9.6 → 0.11.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.
Files changed (216) hide show
  1. package/README.md +17 -53
  2. package/dist/accordion.d.ts +10 -10
  3. package/dist/accordion.js +1 -1
  4. package/dist/accordion.stories.d.ts +0 -1
  5. package/dist/accordion.styles.js +36 -38
  6. package/dist/accordion.test.basics.js +13 -95
  7. package/dist/accordion.test.events.js +21 -33
  8. package/dist/accordion.test.focus.d.ts +1 -0
  9. package/dist/accordion.test.focus.js +11 -0
  10. package/dist/accordion.test.interactions.d.ts +1 -0
  11. package/dist/accordion.test.interactions.js +75 -0
  12. package/dist/button-group.button.d.ts +2 -4
  13. package/dist/button-group.button.js +1 -1
  14. package/dist/button-group.button.styles.js +6 -14
  15. package/dist/button-group.button.test.basics.js +8 -17
  16. package/dist/button-group.button.test.interactions.js +4 -4
  17. package/dist/button-group.d.ts +0 -2
  18. package/dist/button-group.test.basics.js +10 -10
  19. package/dist/button-group.test.events.js +2 -2
  20. package/dist/button-group.test.interactions.js +1 -1
  21. package/dist/button.d.ts +7 -10
  22. package/dist/button.js +1 -1
  23. package/dist/button.styles.js +4 -7
  24. package/dist/button.test.basics.js +10 -26
  25. package/dist/button.test.events.js +9 -9
  26. package/dist/checkbox-group.d.ts +3 -4
  27. package/dist/checkbox-group.js +1 -1
  28. package/dist/checkbox-group.styles.js +13 -1
  29. package/dist/checkbox-group.test.basics.js +8 -12
  30. package/dist/checkbox-group.test.focus.js +7 -7
  31. package/dist/checkbox-group.test.interactions.d.ts +1 -0
  32. package/dist/checkbox-group.test.interactions.js +82 -0
  33. package/dist/checkbox.d.ts +5 -4
  34. package/dist/checkbox.js +1 -1
  35. package/dist/checkbox.styles.js +35 -15
  36. package/dist/checkbox.test.basics.js +6 -15
  37. package/dist/checkbox.test.events.js +9 -0
  38. package/dist/checkbox.test.focus.js +4 -2
  39. package/dist/checkbox.test.interactions.js +11 -11
  40. package/dist/drawer.d.ts +2 -5
  41. package/dist/drawer.js +1 -1
  42. package/dist/drawer.test.accessibility.js +8 -8
  43. package/dist/drawer.test.basics.js +16 -16
  44. package/dist/drawer.test.closing.js +18 -16
  45. package/dist/drawer.test.events.js +13 -24
  46. package/dist/drawer.test.methods.js +22 -22
  47. package/dist/dropdown.d.ts +7 -5
  48. package/dist/dropdown.js +1 -1
  49. package/dist/dropdown.option.d.ts +2 -3
  50. package/dist/dropdown.option.js +1 -1
  51. package/dist/dropdown.option.styles.js +31 -19
  52. package/dist/dropdown.option.test.basics.js +4 -4
  53. package/dist/dropdown.option.test.events.js +9 -1
  54. package/dist/dropdown.option.test.interactions.single.js +2 -2
  55. package/dist/dropdown.styles.js +39 -3
  56. package/dist/dropdown.test.basics.d.ts +1 -1
  57. package/dist/dropdown.test.basics.js +27 -14
  58. package/dist/dropdown.test.basics.multiple.js +65 -32
  59. package/dist/dropdown.test.basics.single.js +49 -0
  60. package/dist/dropdown.test.events.filterable.js +13 -2
  61. package/dist/dropdown.test.focus.filterable.js +12 -3
  62. package/dist/dropdown.test.focus.js +18 -2
  63. package/dist/dropdown.test.form.multiple.js +3 -2
  64. package/dist/dropdown.test.interactions.filterable.js +141 -45
  65. package/dist/dropdown.test.interactions.js +24 -0
  66. package/dist/dropdown.test.interactions.multiple.js +87 -30
  67. package/dist/dropdown.test.interactions.single.js +40 -4
  68. package/dist/form-controls-layout.d.ts +0 -2
  69. package/dist/icon-button.d.ts +2 -4
  70. package/dist/icon-button.js +1 -1
  71. package/dist/icon-button.test.basics.js +14 -82
  72. package/dist/icon-button.test.focus.d.ts +1 -0
  73. package/dist/icon-button.test.focus.js +13 -0
  74. package/dist/input.d.ts +4 -5
  75. package/dist/input.js +1 -1
  76. package/dist/input.styles.js +4 -4
  77. package/dist/input.test.basics.js +0 -52
  78. package/dist/input.test.events.js +27 -27
  79. package/dist/input.test.focus.js +27 -26
  80. package/dist/input.test.form.js +6 -6
  81. package/dist/input.test.validity.js +130 -130
  82. package/dist/label.d.ts +1 -3
  83. package/dist/label.js +1 -1
  84. package/dist/label.styles.js +5 -6
  85. package/dist/label.test.basics.js +4 -4
  86. package/dist/library/ow.js +1 -1
  87. package/dist/menu.button.d.ts +0 -2
  88. package/dist/menu.button.test.basics.js +3 -3
  89. package/dist/menu.d.ts +1 -4
  90. package/dist/menu.js +1 -1
  91. package/dist/menu.link.d.ts +1 -2
  92. package/dist/menu.link.js +1 -1
  93. package/dist/menu.options.d.ts +0 -2
  94. package/dist/menu.test.events.js +6 -6
  95. package/dist/menu.test.focus.js +5 -18
  96. package/dist/menu.test.interactions.js +48 -24
  97. package/dist/modal.d.ts +6 -17
  98. package/dist/modal.icon-button.d.ts +0 -2
  99. package/dist/modal.icon-button.test.basics.js +3 -3
  100. package/dist/modal.js +1 -1
  101. package/dist/modal.styles.js +13 -19
  102. package/dist/modal.tertiary-icon.d.ts +0 -3
  103. package/dist/modal.tertiary-icon.test.basics.js +3 -3
  104. package/dist/modal.test.basics.js +9 -5
  105. package/dist/modal.test.close.js +2 -2
  106. package/dist/modal.test.events.js +2 -2
  107. package/dist/radio-group.d.ts +0 -3
  108. package/dist/radio-group.js +1 -1
  109. package/dist/radio-group.test.basics.js +61 -61
  110. package/dist/radio-group.test.events.js +13 -13
  111. package/dist/radio-group.test.focus.js +1 -1
  112. package/dist/radio-group.test.form.js +2 -2
  113. package/dist/radio-group.test.validity.js +12 -12
  114. package/dist/radio.d.ts +0 -3
  115. package/dist/radio.styles.js +4 -12
  116. package/dist/split-button.d.ts +8 -11
  117. package/dist/split-button.js +1 -1
  118. package/dist/split-button.primary-button.d.ts +21 -0
  119. package/dist/split-button.primary-button.js +1 -0
  120. package/dist/split-button.primary-button.styles.js +96 -0
  121. package/dist/split-button.primary-button.test.basics.d.ts +1 -0
  122. package/dist/split-button.primary-button.test.basics.js +31 -0
  123. package/dist/split-button.primary-button.test.focus.d.ts +1 -0
  124. package/dist/split-button.primary-button.test.focus.js +14 -0
  125. package/dist/split-button.primary-link.d.ts +19 -0
  126. package/dist/split-button.primary-link.js +1 -0
  127. package/dist/split-button.primary-link.test.basics.d.ts +1 -0
  128. package/dist/split-button.primary-link.test.basics.js +30 -0
  129. package/dist/split-button.primary-link.test.focus.d.ts +1 -0
  130. package/dist/split-button.primary-link.test.focus.js +15 -0
  131. package/dist/split-button.secondary-button.d.ts +25 -0
  132. package/dist/split-button.secondary-button.js +1 -0
  133. package/dist/split-button.secondary-button.styles.js +103 -0
  134. package/dist/split-button.secondary-button.test.basics.d.ts +1 -0
  135. package/dist/split-button.secondary-button.test.basics.js +58 -0
  136. package/dist/split-button.secondary-button.test.focus.d.ts +1 -0
  137. package/dist/split-button.secondary-button.test.focus.js +14 -0
  138. package/dist/split-button.secondary-button.test.interactions.d.ts +2 -0
  139. package/dist/split-button.secondary-button.test.interactions.js +30 -0
  140. package/dist/split-button.stories.d.ts +4 -3
  141. package/dist/split-button.styles.js +1 -94
  142. package/dist/split-button.test.basics.d.ts +2 -1
  143. package/dist/split-button.test.basics.js +67 -80
  144. package/dist/split-button.test.interactions.d.ts +4 -0
  145. package/dist/split-button.test.interactions.js +51 -0
  146. package/dist/styles/opacity-and-scale-animation.js +2 -6
  147. package/dist/styles/variables.css +1 -1
  148. package/dist/tab.d.ts +2 -11
  149. package/dist/tab.group.d.ts +3 -5
  150. package/dist/tab.group.js +1 -1
  151. package/dist/tab.group.styles.js +18 -15
  152. package/dist/tab.group.test.basics.js +49 -34
  153. package/dist/tab.group.test.interactions.js +17 -14
  154. package/dist/tab.panel.d.ts +0 -3
  155. package/dist/tab.test.basics.js +6 -5
  156. package/dist/tag.d.ts +5 -4
  157. package/dist/tag.js +1 -1
  158. package/dist/tag.styles.js +47 -38
  159. package/dist/tag.test.basics.js +18 -110
  160. package/dist/tag.test.events.js +12 -8
  161. package/dist/tag.test.focus.js +2 -3
  162. package/dist/tag.test.interactions.d.ts +1 -0
  163. package/dist/tag.test.interactions.js +36 -0
  164. package/dist/textarea.d.ts +2 -3
  165. package/dist/textarea.js +2 -2
  166. package/dist/textarea.test.basics.js +8 -8
  167. package/dist/textarea.test.events.js +55 -55
  168. package/dist/textarea.test.form.js +9 -9
  169. package/dist/textarea.test.validity.js +167 -135
  170. package/dist/toasts.d.ts +1 -5
  171. package/dist/toasts.test.basics.js +2 -1
  172. package/dist/toasts.toast.d.ts +1 -4
  173. package/dist/toasts.toast.js +1 -1
  174. package/dist/toasts.toast.styles.js +12 -0
  175. package/dist/toggle.d.ts +0 -2
  176. package/dist/toggle.styles.js +1 -5
  177. package/dist/toggle.test.basics.js +2 -2
  178. package/dist/toggle.test.interactions.js +7 -7
  179. package/dist/tooltip.d.ts +2 -1
  180. package/dist/tooltip.js +1 -1
  181. package/dist/tooltip.styles.js +37 -13
  182. package/dist/tooltip.test.basics.d.ts +1 -1
  183. package/dist/tooltip.test.basics.js +19 -19
  184. package/dist/tree.d.ts +0 -2
  185. package/dist/tree.item.d.ts +5 -7
  186. package/dist/tree.item.icon-button.d.ts +1 -4
  187. package/dist/tree.item.js +1 -1
  188. package/dist/tree.item.menu.d.ts +1 -2
  189. package/dist/tree.item.menu.js +1 -1
  190. package/dist/tree.item.menu.test.basics.js +31 -10
  191. package/dist/tree.item.styles.js +7 -9
  192. package/dist/tree.item.test.basics.js +43 -31
  193. package/dist/tree.test.basics.js +29 -29
  194. package/dist/tree.test.focus.js +77 -74
  195. package/package.json +12 -14
  196. package/dist/split-container.d.ts +0 -31
  197. package/dist/split-container.js +0 -1
  198. package/dist/split-container.styles.js +0 -132
  199. package/dist/split-container.test.basics.d.ts +0 -3
  200. package/dist/split-container.test.basics.js +0 -445
  201. package/dist/split-container.test.interactions.d.ts +0 -1
  202. package/dist/split-container.test.interactions.js +0 -20
  203. package/dist/split-link.d.ts +0 -25
  204. package/dist/split-link.js +0 -1
  205. package/dist/split-link.test.basics.d.ts +0 -1
  206. package/dist/split-link.test.basics.js +0 -93
  207. package/dist/split-link.test.interactions.d.ts +0 -1
  208. package/dist/split-link.test.interactions.js +0 -20
  209. package/dist/status-indicator.d.ts +0 -30
  210. package/dist/status-indicator.js +0 -1
  211. package/dist/status-indicator.stories.d.ts +0 -5
  212. package/dist/status-indicator.styles.js +0 -58
  213. package/dist/status-indicator.test.basics.d.ts +0 -1
  214. package/dist/status-indicator.test.basics.js +0 -102
  215. /package/dist/{split-container.styles.d.ts → split-button.primary-button.styles.d.ts} +0 -0
  216. /package/dist/{status-indicator.styles.d.ts → split-button.secondary-button.styles.d.ts} +0 -0
@@ -13,9 +13,9 @@ it('has defaults', async () => {
13
13
  <input id="input" slot="control" />
14
14
  </glide-core-private-label>`);
15
15
  expect(component.getAttribute('error')).to.equal(null);
16
- expect(component.error).to.equal(false);
16
+ expect(component.error).to.be.false;
17
17
  expect(component.getAttribute('hide')).to.equal(null);
18
- expect(component.hide).to.equal(false);
18
+ expect(component.hide).to.be.false;
19
19
  expect(component.getAttribute('orientation')).to.equal('horizontal');
20
20
  expect(component.orientation).to.equal('horizontal');
21
21
  expect(component.hasAttribute('required')).to.be.false;
@@ -68,7 +68,7 @@ it('can be required', async () => {
68
68
  <input id="input" slot="control" />
69
69
  </glide-core-private-label>`);
70
70
  expect(component.hasAttribute('required')).to.be.true;
71
- expect(component.required).to.equal(true);
71
+ expect(component.required).to.be.true;
72
72
  const label = component.shadowRoot?.querySelector('[data-test="label"]');
73
73
  expect(label?.textContent?.includes('*')).to.be.true;
74
74
  });
@@ -78,7 +78,7 @@ it('can have an `error`', async () => {
78
78
  <input id="input" slot="control" />
79
79
  </glide-core-private-label>`);
80
80
  expect(component.hasAttribute('error')).to.be.true;
81
- expect(component.error).to.equal(true);
81
+ expect(component.error).to.be.true;
82
82
  });
83
83
  it('places the tooltip on the bottom when horizontal', async () => {
84
84
  const component = await fixture(html `<glide-core-private-label>
@@ -1 +1 @@
1
- import ow,{}from"ow";const isDevelopment=window.location.host.startsWith("localhost")||window.location.host.startsWith("127.0.0.1");export function owSlot(e){isDevelopment&&(ow(e,ow.object.is((e=>e instanceof HTMLSlotElement))),ow(e.assignedNodes().length,ow.number.is((e=>e>0)).message(e.name?`Expected a "${e.name}" slot.`:"Expected a default slot.")))}export function owSlotType(e,o=[]){if(isDevelopment&&(ow(e,ow.object.is((e=>e instanceof HTMLSlotElement))),0!==e.assignedNodes().length&&o.length>0)){const t=e.assignedNodes({flatten:!0}).filter((e=>!!(e instanceof Text&&o.includes(Text))||!(e instanceof Text)));ow(t.length,ow.number.is((e=>e>0)).message(`Expected a slotted node that extends ${o.map((({name:e})=>e)).join(" or ")}.`));for(const e of t){const t=`Expected slotted node to extend ${o.map((({name:e})=>e)).join(" or ")}. Extends ${e.constructor.name} instead.`,n=o.some((o=>e instanceof o));ow(n,ow.boolean.true.message(t))}}}const shim=new Proxy((()=>{}),{get:()=>shim,apply:()=>shim}),owOrShim=isDevelopment?ow:shim;export default owOrShim;
1
+ import ow,{}from"ow";const isDevelopment=window.location.host.startsWith("localhost")||window.location.host.startsWith("127.0.0.1");export function owSlot(e){isDevelopment&&(ow(e,ow.object.is((e=>e instanceof HTMLSlotElement))),ow(e.assignedNodes().length,ow.number.is((e=>e>0)).message(e.name?`Expected a "${e.name}" slot.`:"Expected a default slot.")))}export function owSlotType(e,o=[]){if(isDevelopment&&(ow(e,ow.object.is((e=>e instanceof HTMLSlotElement))),0!==e.assignedNodes().length&&o.length>0)){const t=e.assignedNodes({flatten:!0}).filter((e=>!!(e instanceof Text&&o.includes(Text))||!(e instanceof Text)));ow(t.length,ow.number.is((e=>e>0)).message(`Expected a slotted element that extends ${o.map((({name:e})=>e)).join(" or ")}.`));for(const e of t){const t=`Expected slotted element to extend ${o.map((({name:e})=>e)).join(" or ")}. Extends ${e.constructor.name} instead.`,n=o.some((o=>e instanceof o));ow(n,ow.boolean.true.message(t))}}}const shim=new Proxy((()=>{}),{get:()=>shim,apply:()=>shim}),owOrShim=isDevelopment?ow:shim;export default owOrShim;
@@ -5,8 +5,6 @@ declare global {
5
5
  }
6
6
  }
7
7
  /**
8
- * @description A button for use within a <glide-core-menu>.
9
- *
10
8
  * @slot icon - An icon.
11
9
  */
12
10
  export default class GlideCoreMenuButton extends LitElement {
@@ -11,11 +11,11 @@ it('has defaults', async () => {
11
11
  // typechecked, which means supplying required attributes up front.
12
12
  const component = await fixture(html `<glide-core-menu-button label="Label"></glide-core-menu-button>`);
13
13
  // Not reflected. So no attribute assertions are necessary.
14
- expect(component.privateActive).to.equal(false);
14
+ expect(component.privateActive).to.be.false;
15
15
  });
16
16
  it('can have a label', async () => {
17
- const button = await fixture(html `<glide-core-menu-button label="Label"></glide-core-menu-button>`);
18
- expect(button.shadowRoot?.textContent?.trim()).to.equal('Label');
17
+ const component = await fixture(html `<glide-core-menu-button label="Label"></glide-core-menu-button>`);
18
+ expect(component.shadowRoot?.textContent?.trim()).to.equal('Label');
19
19
  });
20
20
  it('can have an icon', async () => {
21
21
  const component = await fixture(html `<glide-core-menu-button label="Label">
package/dist/menu.d.ts CHANGED
@@ -6,9 +6,7 @@ declare global {
6
6
  }
7
7
  }
8
8
  /**
9
- * @description A basic menu.
10
- *
11
- * @slot - `<glide-core-menu-options>`.
9
+ * @slot - One of `<glide-core-menu-options>`.
12
10
  * @slot target - A focusable element against which Menu will be positioned. Opens and closes Menu when interacted with.
13
11
  */
14
12
  export default class GlideCoreMenu extends LitElement {
@@ -24,7 +22,6 @@ export default class GlideCoreMenu extends LitElement {
24
22
  createRenderRoot(): ShadowRoot;
25
23
  disconnectedCallback(): void;
26
24
  firstUpdated(): void;
27
- focus(options?: FocusOptions): void;
28
25
  private get isTargetDisabled();
29
26
  render(): import("lit").TemplateResult<1>;
30
27
  }
package/dist/menu.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,i,o){var n,s=arguments.length,l=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(l=(s<3?n(l):s>3?n(t,i,l):n(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{nanoid}from"nanoid";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import GlideCoreMenuOptions from"./menu.options.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./menu.styles.js";let GlideCoreMenu=class GlideCoreMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.#e=createRef(),this.#t=createRef(),this.#i=!1,this.#o=!1,this.#n="large",this.#s=createRef(),this.#l=e=>{e.target&&e.target instanceof Node&&this.contains(e.target)||(this.open=!1,this.#a&&(this.#a.ariaActivedescendant=""))}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get open(){return this.#o}set open(e){this.#o=e,e&&!this.isTargetDisabled?this.#r():this.#c()}get size(){return this.#n}set size(e){this.#n=e,this.#a&&(this.#a.privateSize=e)}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#l,{capture:!0})}createRenderRoot(){return this.#d=super.createRenderRoot(),this.#d}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.#l,{capture:!0})}firstUpdated(){ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlot(this.#s.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#t.value.popover="manual";const e=this.#h?.at(0);this.open&&e&&!this.isTargetDisabled&&(e.privateActive=!0,this.#r())}focus(e){this.#p&&"focus"in this.#p&&this.#p?.focus(e)}get isTargetDisabled(){const e=this.#p&&"disabled"in this.#p&&this.#p.disabled,t=this.#p&&"true"===this.#p.ariaDisabled;return Boolean(e)||Boolean(t)}render(){return html`<div class="component" @focusout="${this.#u}" ${ref(this.#e)}><slot class="target-slot" name="target" @click="${this.#m}" @keydown="${this.#f}" @slotchange="${this.#E}" ${ref(this.#s)}></slot><slot class="default-slot" @click="${this.#v}" @focusin="${this.#g}" @keydown="${this.#f}" @mouseover="${this.#w}" @slotchange="${this.#S}" ${ref(this.#t)}></slot></div>`}#C;#e;#t;#i;#o;#d;#n;#s;get#y(){return this.#h?.find((({privateActive:e})=>e))}#l;#c(){this.#C?.(),this.#a&&(this.#a.ariaActivedescendant=""),this.#p&&(this.#p.ariaExpanded="false"),this.#t.value?.hidePopover()}get#a(){const e=this.#t.value?.assignedElements().at(0);return e instanceof GlideCoreMenuOptions?e:null}#S(){ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]);const e=this.#h?.at(0);e&&(e.privateActive=!0),this.#a.privateSize=this.size}#v(){this.open=!1}#g(e){(e.target instanceof GlideCoreMenuButton||e.target instanceof GlideCoreMenuLink)&&this.#y&&this.#a&&(this.#y.privateActive=!1,e.target.privateActive=!0,this.#a.ariaActivedescendant=e.target.id)}#w(e){if(e.target instanceof GlideCoreMenuLink||e.target instanceof GlideCoreMenuButton){if(this.#h)for(const t of this.#h)t.privateActive=t===e.target;this.#a&&(this.#a.ariaActivedescendant=e.target.id)}}#u(e){const t=e.relatedTarget instanceof HTMLElement&&this.#d?.contains(e.relatedTarget),i=e.relatedTarget instanceof GlideCoreMenuOptions,o=e.relatedTarget instanceof GlideCoreMenuButton||e.relatedTarget instanceof GlideCoreMenuLink;t||i||o||(this.open=!1)}#f(e){if(ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),[" ","Enter"].includes(e.key)&&this.open)return this.open=!1,this.focus(),this.#y?.dispatchEvent(new PointerEvent("click",{bubbles:!0})),void(this.#i=!0);if(["Escape"].includes(e.key)&&this.open)return this.open=!1,void this.focus();if(["ArrowUp","ArrowDown"].includes(e.key)&&!this.open&&this.#y)return e.preventDefault(),this.open=!0,void(this.#a.ariaActivedescendant=this.#y.id);if(this.open){ow(this.#h,ow.array),ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),ow(this.#y,ow.object.is((e=>e instanceof GlideCoreMenuButton||e instanceof GlideCoreMenuLink)));const t=this.#h.indexOf(this.#y);if("ArrowUp"===e.key&&!e.metaKey){e.preventDefault();const i=this.#h.at(t-1);return void(i&&0!==t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowDown"===e.key&&!e.metaKey){e.preventDefault();const i=this.#h.at(t+1);return void(i&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowUp"===e.key&&e.metaKey||"Home"===e.key||"PageUp"===e.key){e.preventDefault();const t=this.#h.at(0);return void(t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=t.id,t.privateActive=!0))}if("ArrowDown"===e.key&&e.metaKey||"End"===e.key||"PageDown"===e.key){e.preventDefault();const t=this.#h.at(-1);return void(t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=t.id,t.privateActive=!0))}}}#E(){owSlot(this.#s.value),ow(this.#p,ow.object.instanceOf(Element)),ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions));new MutationObserver((e=>{e.some((e=>"disabled"===e.attributeName||"aria-disabled"===e.attributeName))&&(this.open&&!this.isTargetDisabled?this.#r():this.#c())})).observe(this.#p,{attributes:!0}),this.#p.ariaHasPopup="true",this.#p.id=nanoid(),this.#p.setAttribute("aria-controls",this.#a.id),this.#a.ariaLabelledby=this.#p.id,this.open&&!this.isTargetDisabled?this.#r():this.#c()}#m(){this.isTargetDisabled?this.#c():this.#i?this.#i=!1:this.#h&&this.#h.length>0&&(this.open=!this.open)}get#h(){let e=this.#t.value?.assignedElements()?.at(0)?.children;const t=e?.[0];if(t instanceof HTMLSlotElement&&(e=t.assignedElements()),e)return[...e].filter((e=>e instanceof GlideCoreMenuLink||e instanceof GlideCoreMenuButton))}#r(){this.#C?.(),this.#p&&this.#t.value&&(this.#C=autoUpdate(this.#p,this.#t.value,(()=>{(async()=>{if(this.#p&&this.#t.value){const{x:e,y:t,placement:i}=await computePosition(this.#p,this.#t.value,{placement:this.placement,middleware:[offset({mainAxis:Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}),flip()]});this.#t.value.dataset.placement=i,Object.assign(this.#t.value.style,{left:`${e}px`,top:`${t}px`})}this.#t.value?.showPopover(),this.#a&&this.#y?.id&&(this.#a.ariaActivedescendant=this.#y.id),this.#p&&(this.#p.ariaExpanded="true")})()})))}get#p(){return this.#s.value?.assignedElements().at(0)}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreMenu.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"placement",void 0),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"size",null),GlideCoreMenu=__decorate([customElement("glide-core-menu")],GlideCoreMenu);export default GlideCoreMenu;
1
+ var __decorate=this&&this.__decorate||function(e,t,i,o){var n,s=arguments.length,l=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(l=(s<3?n(l):s>3?n(t,i,l):n(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{nanoid}from"nanoid";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import GlideCoreMenuOptions from"./menu.options.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./menu.styles.js";let GlideCoreMenu=class GlideCoreMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.#e=createRef(),this.#t=createRef(),this.#i=!1,this.#o=!1,this.#n=!1,this.#s="large",this.#l=createRef(),this.#a=()=>{this.#n?this.#n=!1:(this.open=!1,this.#r&&(this.#r.ariaActivedescendant=""))}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get open(){return this.#o}set open(e){this.#o=e,e&&!this.isTargetDisabled?this.#c():this.#h()}get size(){return this.#s}set size(e){this.#s=e,this.#r&&(this.#r.privateSize=e)}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#a,{capture:!0})}createRenderRoot(){return this.#d=super.createRenderRoot(),this.#d}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.#a,{capture:!0})}firstUpdated(){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlot(this.#l.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#t.value.popover="manual";const e=this.#p?.at(0);this.open&&e&&!this.isTargetDisabled&&(e.privateActive=!0,this.#c()),this.#l.value.addEventListener("mouseup",(()=>{this.#n=!0}))}get isTargetDisabled(){const e=this.#u&&"disabled"in this.#u&&this.#u.disabled,t=this.#u&&"true"===this.#u.ariaDisabled;return Boolean(e)||Boolean(t)}render(){return html`<div class="component" @focusout="${this.#m}" ${ref(this.#e)}><slot class="target-slot" name="target" @click="${this.#f}" @keydown="${this.#E}" @slotchange="${this.#v}" ${ref(this.#l)}></slot><slot class="default-slot" @click="${this.#g}" @focusin="${this.#S}" @keydown="${this.#E}" @mouseover="${this.#w}" @slotchange="${this.#C}" ${ref(this.#t)}></slot></div>`}#y;#e;#t;#i;#o;#n;#d;#s;#l;get#R(){return this.#p?.find((({privateActive:e})=>e))}#a;#k(e){this.#u&&"focus"in this.#u&&this.#u?.focus(e)}#h(){this.#y?.(),this.#r&&(this.#r.ariaActivedescendant=""),this.#u&&(this.#u.ariaExpanded="false"),this.#t.value?.hidePopover()}get#r(){const e=this.#t.value?.assignedElements().at(0);return e instanceof GlideCoreMenuOptions?e:null}#C(){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]);const e=this.#p?.at(0);e&&(e.privateActive=!0),this.#r.privateSize=this.size}#g(){this.open=!1}#S(e){(e.target instanceof GlideCoreMenuButton||e.target instanceof GlideCoreMenuLink)&&this.#R&&this.#r&&(this.#R.privateActive=!1,e.target.privateActive=!0,this.#r.ariaActivedescendant=e.target.id)}#w(e){if(e.target instanceof GlideCoreMenuLink||e.target instanceof GlideCoreMenuButton){if(this.#p)for(const t of this.#p)t.privateActive=t===e.target;this.#r&&(this.#r.ariaActivedescendant=e.target.id)}}#m(e){const t=e.relatedTarget instanceof HTMLElement&&this.#d?.contains(e.relatedTarget),i=e.relatedTarget instanceof GlideCoreMenuOptions,o=e.relatedTarget instanceof GlideCoreMenuButton||e.relatedTarget instanceof GlideCoreMenuLink;t||i||o||(this.open=!1)}#E(e){if(ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),[" ","Enter"].includes(e.key)&&this.open)return this.open=!1,this.#k(),this.#R?.click(),void(this.#i=!0);if(["Escape"].includes(e.key)&&this.open)return this.open=!1,void this.#k();if(["ArrowUp","ArrowDown"].includes(e.key)&&!this.open&&this.#R)return e.preventDefault(),this.open=!0,void(this.#r.ariaActivedescendant=this.#R.id);if(this.open){ow(this.#p,ow.array),ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),ow(this.#R,ow.object.is((e=>e instanceof GlideCoreMenuButton||e instanceof GlideCoreMenuLink)));const t=this.#p.indexOf(this.#R);if("ArrowUp"===e.key&&!e.metaKey){e.preventDefault();const i=this.#p.at(t-1);return void(i&&0!==t&&(this.#R.privateActive=!1,this.#r.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowDown"===e.key&&!e.metaKey){e.preventDefault();const i=this.#p.at(t+1);return void(i&&(this.#R.privateActive=!1,this.#r.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowUp"===e.key&&e.metaKey||"Home"===e.key||"PageUp"===e.key){e.preventDefault();const t=this.#p.at(0);return void(t&&(this.#R.privateActive=!1,this.#r.ariaActivedescendant=t.id,t.privateActive=!0))}if("ArrowDown"===e.key&&e.metaKey||"End"===e.key||"PageDown"===e.key){e.preventDefault();const t=this.#p.at(-1);return void(t&&(this.#R.privateActive=!1,this.#r.ariaActivedescendant=t.id,t.privateActive=!0))}}}#v(){owSlot(this.#l.value),ow(this.#u,ow.object.instanceOf(Element)),ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions));new MutationObserver((()=>{this.open&&!this.isTargetDisabled?this.#c():this.#h()})).observe(this.#u,{attributes:!0,attributeFilter:["aria-disabled","disabled"]}),this.#u.ariaHasPopup="true",this.#u.id=nanoid(),this.#u.setAttribute("aria-controls",this.#r.id),this.#r.ariaLabelledby=this.#u.id,this.open&&!this.isTargetDisabled?this.#c():this.#h()}#f(){this.isTargetDisabled?this.#h():this.#i?this.#i=!1:this.#p&&this.#p.length>0&&(this.open=!this.open)}get#p(){let e=this.#t.value?.assignedElements()?.at(0)?.children;const t=e?.[0];if(t instanceof HTMLSlotElement&&(e=t.assignedElements()),e)return[...e].filter((e=>e instanceof GlideCoreMenuLink||e instanceof GlideCoreMenuButton))}#c(){this.#y?.(),this.#u&&this.#t.value&&(this.#y=autoUpdate(this.#u,this.#t.value,(()=>{(async()=>{if(this.#u&&this.#t.value){const{x:e,y:t,placement:i}=await computePosition(this.#u,this.#t.value,{placement:this.placement,middleware:[offset({mainAxis:Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}),flip()]});this.#t.value.dataset.placement=i,Object.assign(this.#t.value.style,{left:`${e}px`,top:`${t}px`})}this.#t.value?.showPopover(),this.#r&&this.#R?.id&&(this.#r.ariaActivedescendant=this.#R.id),this.#u&&(this.#u.ariaExpanded="true")})()})))}get#u(){return this.#l.value?.assignedElements().at(0)}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreMenu.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"placement",void 0),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"size",null),GlideCoreMenu=__decorate([customElement("glide-core-menu")],GlideCoreMenu);export default GlideCoreMenu;
@@ -5,8 +5,6 @@ declare global {
5
5
  }
6
6
  }
7
7
  /**
8
- * @description A link for use within a <glide-core-menu>.
9
- *
10
8
  * @slot icon - An icon.
11
9
  */
12
10
  export default class GlideCoreMenuLink extends LitElement {
@@ -16,6 +14,7 @@ export default class GlideCoreMenuLink extends LitElement {
16
14
  label?: string;
17
15
  url?: string;
18
16
  privateActive: boolean;
17
+ click(): void;
19
18
  connectedCallback(): void;
20
19
  render(): import("lit").TemplateResult<1>;
21
20
  }
package/dist/menu.link.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,i,o){var r,n=arguments.length,l=n<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var s=e.length-1;s>=0;s--)(r=e[s])&&(l=(n<3?r(l):n>3?r(t,i,l):r(t,i))||l);return n>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{customElement,property}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{nanoid}from"nanoid";import styles from"./menu.link.styles.js";let GlideCoreMenuLink=class GlideCoreMenuLink extends LitElement{constructor(){super(...arguments),this.privateActive=!1,this.#e=nanoid()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}connectedCallback(){super.connectedCallback(),this.id=this.#e,this.role="menuitem",this.tabIndex=-1}render(){return html`<a class="${classMap({component:!0,active:this.privateActive})}" data-test="component" href="${ifDefined(this.url)}"><slot name="icon"></slot>${this.label}</a>`}#e};__decorate([property({reflect:!0})],GlideCoreMenuLink.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreMenuLink.prototype,"url",void 0),__decorate([property({type:Boolean})],GlideCoreMenuLink.prototype,"privateActive",void 0),GlideCoreMenuLink=__decorate([customElement("glide-core-menu-link")],GlideCoreMenuLink);export default GlideCoreMenuLink;
1
+ var __decorate=this&&this.__decorate||function(e,t,i,o){var r,n=arguments.length,l=n<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var s=e.length-1;s>=0;s--)(r=e[s])&&(l=(n<3?r(l):n>3?r(t,i,l):r(t,i))||l);return n>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{nanoid}from"nanoid";import styles from"./menu.link.styles.js";let GlideCoreMenuLink=class GlideCoreMenuLink extends LitElement{constructor(){super(...arguments),this.privateActive=!1,this.#e=createRef(),this.#t=nanoid()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}click(){this.#e.value?.click()}connectedCallback(){super.connectedCallback(),this.id=this.#t,this.role="menuitem",this.tabIndex=-1}render(){return html`<a class="${classMap({component:!0,active:this.privateActive})}" data-test="component" href="${ifDefined(this.url)}" ${ref(this.#e)}><slot name="icon"></slot>${this.label}</a>`}#e;#t};__decorate([property({reflect:!0})],GlideCoreMenuLink.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreMenuLink.prototype,"url",void 0),__decorate([property({type:Boolean})],GlideCoreMenuLink.prototype,"privateActive",void 0),GlideCoreMenuLink=__decorate([customElement("glide-core-menu-link")],GlideCoreMenuLink);export default GlideCoreMenuLink;
@@ -5,8 +5,6 @@ declare global {
5
5
  }
6
6
  }
7
7
  /**
8
- * @description An options container for use within a <glide-core-menu>.
9
- *
10
8
  * @slot - One or more of <glide-core-menu-link> or <glide-core-menu-button>.
11
9
  */
12
10
  export default class GlideCoreMenuOptions extends LitElement {
@@ -55,8 +55,8 @@ it('dispatches one link "click" event when a link is selected via Space', async
55
55
  const link = component.querySelector('glide-core-menu-link');
56
56
  assert(link);
57
57
  link.addEventListener('click', spy);
58
- component.focus();
59
- sendKeys({ press: 'Space' });
58
+ component.querySelector('button')?.focus();
59
+ sendKeys({ press: ' ' });
60
60
  const event = await oneEvent(link, 'click');
61
61
  expect(event instanceof PointerEvent).to.be.true;
62
62
  expect(event.bubbles).to.be.true;
@@ -75,8 +75,8 @@ it('dispatches one button "click" event when a button is selected via Space', as
75
75
  const button = component.querySelector('glide-core-menu-button');
76
76
  assert(button);
77
77
  button.addEventListener('click', spy);
78
- component.focus();
79
- sendKeys({ press: 'Space' });
78
+ component.querySelector('button')?.focus();
79
+ sendKeys({ press: ' ' });
80
80
  const event = await oneEvent(button, 'click');
81
81
  expect(event instanceof PointerEvent).to.be.true;
82
82
  expect(event.bubbles).to.be.true;
@@ -95,7 +95,7 @@ it('dispatches one link "click" event when a link is selected via Enter', async
95
95
  const link = component.querySelector('glide-core-menu-link');
96
96
  assert(link);
97
97
  link.addEventListener('click', spy);
98
- component.focus();
98
+ component.querySelector('button')?.focus();
99
99
  sendKeys({ press: 'Enter' });
100
100
  const event = await oneEvent(link, 'click');
101
101
  expect(event instanceof PointerEvent).to.be.true;
@@ -115,7 +115,7 @@ it('dispatches one button "click" event when a button is selected via Enter', as
115
115
  const button = component.querySelector('glide-core-menu-button');
116
116
  assert(button);
117
117
  button.addEventListener('click', spy);
118
- component.focus();
118
+ component.querySelector('button')?.focus();
119
119
  sendKeys({ press: 'Enter' });
120
120
  const event = await oneEvent(button, 'click');
121
121
  expect(event instanceof PointerEvent).to.be.true;
@@ -5,19 +5,6 @@ import { aTimeout, assert, elementUpdated, expect, fixture, html, } from '@open-
5
5
  import { sendKeys } from '@web/test-runner-commands';
6
6
  import GlideCoreMenu from './menu.js';
7
7
  GlideCoreMenu.shadowRootOptions.mode = 'open';
8
- it('focuses the target on `focus()`', async () => {
9
- const component = await fixture(html `<glide-core-menu>
10
- <button slot="target">Target</button>
11
-
12
- <glide-core-menu-options>
13
- <glide-core-menu-link label="Link"></glide-core-menu-link>
14
- </glide-core-menu-options>
15
- </glide-core-menu>`);
16
- component.focus();
17
- const target = component.querySelector('button');
18
- assert(target);
19
- expect(document.activeElement).to.equal(target);
20
- });
21
8
  it('closes when it loses focus', async () => {
22
9
  const component = await fixture(html `<glide-core-menu open>
23
10
  <button slot="target">Target</button>
@@ -26,7 +13,7 @@ it('closes when it loses focus', async () => {
26
13
  <glide-core-menu-link label="Link"></glide-core-menu-link>
27
14
  </glide-core-menu-options>
28
15
  </glide-core-menu>`);
29
- component.focus();
16
+ component.querySelector('button')?.focus();
30
17
  await sendKeys({ press: 'Tab' });
31
18
  const defaultSlot = component?.shadowRoot?.querySelector('slot:not([name])');
32
19
  const options = component.querySelector('glide-core-menu-options');
@@ -44,7 +31,7 @@ it('remains open when the options component is focused', async () => {
44
31
  </glide-core-menu>`);
45
32
  // Wait for Floating UI.
46
33
  await aTimeout(0);
47
- component.focus();
34
+ component.querySelector('button')?.focus();
48
35
  const options = component.querySelector('glide-core-menu-options');
49
36
  const defaultSlot = component?.shadowRoot?.querySelector('slot:not([name])');
50
37
  options?.focus();
@@ -61,7 +48,7 @@ it('remains open when an option is focused', async () => {
61
48
  </glide-core-menu>`);
62
49
  // Wait for Floating UI.
63
50
  await aTimeout(0);
64
- component.focus();
51
+ component.querySelector('button')?.focus();
65
52
  const defaultSlot = component?.shadowRoot?.querySelector('slot:not([name])');
66
53
  const option = component.querySelector('glide-core-menu-link');
67
54
  assert(option);
@@ -80,7 +67,7 @@ it('sets an inactive option as active when focused', async () => {
80
67
  </glide-core-menu>`);
81
68
  // Wait for Floating UI.
82
69
  await aTimeout(0);
83
- component.focus();
70
+ component.querySelector('button')?.focus();
84
71
  const button = component.querySelector('glide-core-menu-button');
85
72
  const link = component.querySelector('glide-core-menu-link');
86
73
  const options = component.querySelector('glide-core-menu-options');
@@ -103,7 +90,7 @@ it('sets an already active option as active when focused', async () => {
103
90
  </glide-core-menu>`);
104
91
  // Wait for Floating UI.
105
92
  await aTimeout(0);
106
- component.focus();
93
+ component.querySelector('button')?.focus();
107
94
  const button = component.querySelector('glide-core-menu-button');
108
95
  const link = component.querySelector('glide-core-menu-link');
109
96
  const options = component.querySelector('glide-core-menu-options');
@@ -11,6 +11,7 @@ import { LitElement } from 'lit';
11
11
  import { aTimeout, assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
12
12
  import { customElement } from 'lit/decorators.js';
13
13
  import { sendKeys } from '@web/test-runner-commands';
14
+ import { sendMouse } from '@web/test-runner-commands';
14
15
  import GlideCoreMenu from './menu.js';
15
16
  let GlideCoreNestedSlot = class GlideCoreNestedSlot extends LitElement {
16
17
  static { this.shadowRootOptions = {
@@ -30,8 +31,27 @@ let GlideCoreNestedSlot = class GlideCoreNestedSlot extends LitElement {
30
31
  GlideCoreNestedSlot = __decorate([
31
32
  customElement('glide-core-nested-slot')
32
33
  ], GlideCoreNestedSlot);
34
+ let GlideCoreMenuInAnotherComponent = class GlideCoreMenuInAnotherComponent extends LitElement {
35
+ static { this.shadowRootOptions = {
36
+ ...LitElement.shadowRootOptions,
37
+ mode: 'closed',
38
+ }; }
39
+ render() {
40
+ return html `<glide-core-menu open>
41
+ <button slot="target">Target</button>
42
+
43
+ <glide-core-menu-options>
44
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
45
+ </glide-core-menu-options>
46
+ </glide-core-menu>`;
47
+ }
48
+ };
49
+ GlideCoreMenuInAnotherComponent = __decorate([
50
+ customElement('glide-core-menu-in-another-component')
51
+ ], GlideCoreMenuInAnotherComponent);
33
52
  GlideCoreMenu.shadowRootOptions.mode = 'open';
34
53
  GlideCoreNestedSlot.shadowRootOptions.mode = 'open';
54
+ GlideCoreMenuInAnotherComponent.shadowRootOptions.mode = 'open';
35
55
  it('opens on click', async () => {
36
56
  const component = await fixture(html `<glide-core-menu>
37
57
  <button slot="target">Target</button>
@@ -377,19 +397,23 @@ it('sets `privateSize` on the options component when `size` is changed programma
377
397
  const options = component.querySelector('glide-core-menu-options');
378
398
  expect(options?.privateSize).to.equal('small');
379
399
  });
380
- it('closes when clicked', async () => {
381
- const component = await fixture(html `<glide-core-menu open>
382
- <button slot="target">Target</button>
383
-
384
- <glide-core-menu-options>
385
- <glide-core-menu-link label="Link"></glide-core-menu-link>
386
- </glide-core-menu-options>
387
- </glide-core-menu>`);
388
- component.querySelector('button')?.click();
389
- const defaultSlot = component?.shadowRoot?.querySelector('slot:not([name])');
390
- const options = component.querySelector('glide-core-menu-options');
391
- const target = component.querySelector('button');
392
- expect(component.open).to.be.false;
400
+ it('closes when its target clicked', async () => {
401
+ const component = await fixture(html `<glide-core-menu-in-another-component></glide-core-menu-in-another-component>`);
402
+ // Wait for it to open.
403
+ await aTimeout(0);
404
+ const target = component.shadowRoot?.querySelector('button');
405
+ assert(target);
406
+ const { x, y } = target.getBoundingClientRect();
407
+ // Calling `click()` won't do because Menu relies on a "mouseup" event to
408
+ // decide if it should close.
409
+ await sendMouse({
410
+ type: 'click',
411
+ position: [Math.ceil(x), Math.ceil(y)],
412
+ });
413
+ const menu = component.shadowRoot?.querySelector('glide-core-menu');
414
+ const defaultSlot = menu?.shadowRoot?.querySelector('slot:not([name])');
415
+ const options = menu?.querySelector('glide-core-menu-options');
416
+ expect(menu?.open).to.be.false;
393
417
  expect(defaultSlot?.checkVisibility()).to.be.false;
394
418
  expect(options?.getAttribute('aria-activedescendant')).to.equal('');
395
419
  expect(target?.ariaExpanded).to.equal('false');
@@ -422,7 +446,7 @@ it('closes on Escape', async () => {
422
446
  </glide-core-menu>`);
423
447
  // Wait for it to open
424
448
  await aTimeout(0);
425
- component.focus();
449
+ component.querySelector('button')?.focus();
426
450
  await sendKeys({ press: 'Escape' });
427
451
  const defaultSlot = component?.shadowRoot?.querySelector('slot:not([name])');
428
452
  const options = component.querySelector('glide-core-menu-options');
@@ -457,7 +481,7 @@ it('closes when an option is selected via Enter', async () => {
457
481
  <glide-core-menu-link label="Link"></glide-core-menu-link>
458
482
  </glide-core-menu-options>
459
483
  </glide-core-menu>`);
460
- component.focus();
484
+ component.querySelector('button')?.focus();
461
485
  component
462
486
  .querySelector('glide-core-menu-link')
463
487
  ?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
@@ -478,7 +502,7 @@ it('closes when an option is selected via Space', async () => {
478
502
  <glide-core-menu-link label="Link"></glide-core-menu-link>
479
503
  </glide-core-menu-options>
480
504
  </glide-core-menu>`);
481
- component.focus();
505
+ component.querySelector('button')?.focus();
482
506
  await sendKeys({ press: ' ' });
483
507
  const defaultSlot = component?.shadowRoot?.querySelector('slot:not([name])');
484
508
  const options = component.querySelector('glide-core-menu-options');
@@ -617,7 +641,7 @@ it('activates the next option on ArrowDown', async () => {
617
641
  `);
618
642
  // Wait for Floating UI.
619
643
  await aTimeout(0);
620
- component.focus();
644
+ component.querySelector('button')?.focus();
621
645
  const links = component.querySelectorAll('glide-core-menu-link');
622
646
  const options = component.querySelector('glide-core-menu-options');
623
647
  links[1].dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
@@ -640,7 +664,7 @@ it('activates the previous option on ArrowUp', async () => {
640
664
  `);
641
665
  // Wait for Floating UI.
642
666
  await aTimeout(0);
643
- component.focus();
667
+ component.querySelector('button')?.focus();
644
668
  const links = component.querySelectorAll('glide-core-menu-link');
645
669
  const options = component.querySelector('glide-core-menu-options');
646
670
  links[1].dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
@@ -662,7 +686,7 @@ it('activates the first option on Home', async () => {
662
686
  `);
663
687
  // Wait for Floating UI.
664
688
  await aTimeout(0);
665
- component.focus();
689
+ component.querySelector('button')?.focus();
666
690
  const links = component.querySelectorAll('glide-core-menu-link');
667
691
  const options = component.querySelector('glide-core-menu-options');
668
692
  links[1].dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
@@ -684,7 +708,7 @@ it('activates the first option on PageUp', async () => {
684
708
  `);
685
709
  // Wait for Floating UI.
686
710
  await aTimeout(0);
687
- component.focus();
711
+ component.querySelector('button')?.focus();
688
712
  const links = component.querySelectorAll('glide-core-menu-link');
689
713
  const options = component.querySelector('glide-core-menu-options');
690
714
  links[1].dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
@@ -706,7 +730,7 @@ it('activates the first option on Meta + ArrowUp', async () => {
706
730
  `);
707
731
  // Wait for Floating UI.
708
732
  await aTimeout(0);
709
- component.focus();
733
+ component.querySelector('button')?.focus();
710
734
  const links = component.querySelectorAll('glide-core-menu-link');
711
735
  const options = component.querySelector('glide-core-menu-options');
712
736
  links[1].dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
@@ -730,7 +754,7 @@ it('activates the last option on End', async () => {
730
754
  `);
731
755
  // Wait for Floating UI.
732
756
  await aTimeout(0);
733
- component.focus();
757
+ component.querySelector('button')?.focus();
734
758
  await sendKeys({ press: 'End' });
735
759
  const links = component.querySelectorAll('glide-core-menu-link');
736
760
  const options = component.querySelector('glide-core-menu-options');
@@ -752,7 +776,7 @@ it('activates the last option on PageDown', async () => {
752
776
  component.querySelector('button')?.click();
753
777
  // Wait for Floating UI.
754
778
  await aTimeout(0);
755
- component.focus();
779
+ component.querySelector('button')?.focus();
756
780
  const links = component.querySelectorAll('glide-core-menu-link');
757
781
  const options = component.querySelector('glide-core-menu-options');
758
782
  links[0].dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
@@ -774,7 +798,7 @@ it('activates the last option on Meta + ArrowDown', async () => {
774
798
  `);
775
799
  // Wait for Floating UI.
776
800
  await aTimeout(0);
777
- component.focus();
801
+ component.querySelector('button')?.focus();
778
802
  const links = component.querySelectorAll('glide-core-menu-link');
779
803
  const options = component.querySelector('glide-core-menu-options');
780
804
  links[0].dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
package/dist/modal.d.ts CHANGED
@@ -6,31 +6,20 @@ declare global {
6
6
  }
7
7
  }
8
8
  /**
9
- * @description A Modal dialog component which interrupts interaction with the rest of the page.
10
- *
11
- * @event close - Emitted when the Modal closes.
9
+ * @event close - `(event: "close", listener: (event: Event)) => void) => void`
12
10
  *
13
11
  * @slot - The content of the modal.
14
- *
15
- * @slot header-actions - A slot for placing additional header actions. These are co-located with the close button.
16
- * Use the `glide-core-modal-icon-button` component only.
17
- *
18
- * @slot primary - A slot for rendering a primary action button. Normally a "Continue", "Next", or "Submit" action.
19
- *
20
- * @slot secondary - A slot for rendering a secondary action button. Normally a "Cancel" action.
21
- *
22
- * @slot tertiary - A slot for rendering an icon+tooltip for additional information,
23
- * or a tertiary action button.
12
+ * @slot header-actions - One or more of `<glide-core-modal-icon-button>`.
13
+ * @slot primary - One of `<glide-core-button>`.
14
+ * @slot secondary - One of `<glide-core-button>`.
15
+ * @slot tertiary - One or more of `<glide-core-button>` or `<glide-core-modal-tertiary-icon>`.
24
16
  */
25
17
  export default class GlideCoreModal extends LitElement {
26
18
  #private;
27
19
  static shadowRootOptions: ShadowRootInit;
28
20
  static styles: import("lit").CSSResult[];
29
- /** The title text for the Modal. */
30
21
  label: string;
31
- /** Adds a back/dismiss button in the Modal header. */
32
- showBackButton: boolean;
33
- /** Fixed-size options for the Modal. */
22
+ backButton: boolean;
34
23
  size?: 'small' | 'medium' | 'large' | 'xlarge';
35
24
  close(): void;
36
25
  connectedCallback(): void;
@@ -6,8 +6,6 @@ declare global {
6
6
  }
7
7
  }
8
8
  /**
9
- * @description A Modal Icon Button. Should be used only in the "header-actions" slot of a Modal.
10
- *
11
9
  * @slot - The content of the button. Should only be an icon. The icon should also leverage the
12
10
  * "label" attribute for accessibility so that it is read to screenreaders.
13
11
  *
@@ -18,19 +18,19 @@ it('renders and sets default attributes', async () => {
18
18
  expect(component).to.be.ok;
19
19
  const buttonElement = component.shadowRoot?.querySelector('glide-core-icon-button');
20
20
  expect(buttonElement).to.be.not.null;
21
- expect(buttonElement).to.have.attribute('variant', 'tertiary');
21
+ expect(buttonElement?.getAttribute('variant')).to.equal('tertiary');
22
22
  });
23
23
  it('adds an accessible label when given', async () => {
24
24
  const component = await fixture(html `<glide-core-modal-icon-button label="test-label"
25
25
  >Test</glide-core-modal-icon-button
26
26
  >`);
27
27
  const buttonElement = component.shadowRoot?.querySelector('glide-core-icon-button');
28
- expect(buttonElement).to.have.attribute('label', 'test-label');
28
+ expect(buttonElement?.getAttribute('label')).to.equal('test-label');
29
29
  });
30
30
  it('does not add an acceessible label when not given', async () => {
31
31
  const component = await fixture(html `<glide-core-modal-icon-button>Test</glide-core-modal-icon-button>`);
32
32
  const buttonElement = component.shadowRoot?.querySelector('glide-core-icon-button');
33
- expect(buttonElement).to.have.attribute('label', '');
33
+ expect(buttonElement?.getAttribute('label')).to.equal('');
34
34
  });
35
35
  it('throws if it does not have a default slot', async () => {
36
36
  const spy = sinon.spy();
package/dist/modal.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,o,l){var n,r=arguments.length,i=r<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,o,l);else for(var s=e.length-1;s>=0;s--)(n=e[s])&&(i=(r<3?n(i):r>3?n(t,o,i):n(t,o))||i);return r>3&&i&&Object.defineProperty(t,o,i),i};import"./modal.icon-button.js";import{LitElement,html}from"lit";import{LocalizeController}from"./library/localize.js";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{when}from"lit/directives/when.js";import GlideCoreButton from"./button.js";import GlideCoreModalIconButton from"./modal.icon-button.js";import GlideCoreModalTertiaryIcon from"./modal.tertiary-icon.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./modal.styles.js";const globalStylesheet=new CSSStyleSheet;globalStylesheet.insertRule("\n @supports (scrollbar-gutter: stable) {\n .private-glide-core-modal-lock-scroll {\n scrollbar-gutter: stable !important;\n overflow: hidden !important;\n }\n }\n"),globalStylesheet.insertRule("\n @supports not (scrollbar-gutter: stable) {\n .private-glide-core-modal-lock-scroll {\n padding-right: var(--glide-scroll-size, 0.9375rem) !important;\n overflow: hidden !important;\n }\n }\n");let GlideCoreModal=class GlideCoreModal extends LitElement{constructor(){super(...arguments),this.label="",this.showBackButton=!1,this.size="medium",this.#e=createRef(),this.#t=createRef(),this.#o=createRef(),this.#l=createRef(),this.#n=createRef(),this.#r=createRef(),this.#i=new LocalizeController(this)}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}close(){this.#e.value?.open&&(document.documentElement.classList.remove("private-glide-core-modal-lock-scroll"),this.dispatchEvent(new Event("close")),this.#e.value?.close())}connectedCallback(){super.connectedCallback();document.adoptedStyleSheets.includes(globalStylesheet)||document.adoptedStyleSheets.push(globalStylesheet)}disconnectedCallback(){super.disconnectedCallback(),document.documentElement.classList.remove("private-glide-core-modal-lock-scroll"),document.adoptedStyleSheets=document.adoptedStyleSheets.filter((e=>e!==globalStylesheet))}firstUpdated(){owSlot(this.#t.value),owSlotType(this.#r.value,[GlideCoreModalIconButton]),owSlotType(this.#o.value,[GlideCoreButton]),owSlotType(this.#l.value,[GlideCoreButton]),owSlotType(this.#n.value,[GlideCoreModalTertiaryIcon,GlideCoreButton])}render(){return html`<dialog class="${classMap({component:!0,small:"small"===this.size,medium:"medium"===this.size,large:"large"===this.size,xlarge:"xlarge"===this.size})}" tabindex="-1" @keydown="${this.#s}" @mousedown="${this.#a}" ${ref(this.#e)}><header class="header"><h2 class="label" data-test="heading" id="heading">${when(this.showBackButton,(()=>html`<glide-core-modal-icon-button data-test="back-button" @click="${this.#c}"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><title>${this.#i.term("dismiss")}</title><path d="M12 18C11.4477 18 11 18.4477 11 19C11 19.5523 11.4477 20 12 20V18ZM20 14.5C20 16.433 18.433 18 16.5 18V20C19.5376 20 22 17.5376 22 14.5H20ZM16.5 11C18.433 11 20 12.567 20 14.5H22C22 11.4624 19.5376 9 16.5 9V11ZM16.5 18H12V20H16.5V18ZM16.5 9H3V11H16.5V9Z" fill="currentColor"/><path d="M7 6L3 10L7 14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></glide-core-modal-icon-button>`))} ${this.label}</h2><div class="header-actions" role="toolbar"><slot name="header-actions" @slotchange="${this.#d}" ${ref(this.#r)}></slot><glide-core-modal-icon-button data-test="close-button" @click="${this.#c}"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><title>${this.#i.term("close")}</title><path d="M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></glide-core-modal-icon-button></div></header><article aria-labelledby="heading" class="body" role="region" tabindex="0"><slot @slotchange="${this.#m}" ${ref(this.#t)}></slot></article><footer class="footer"><menu class="menu"><li class="flex align-center"><slot name="tertiary" @slotchange="${this.#h}" ${ref(this.#n)}></slot></li><li><menu class="actions"><li><slot name="secondary" @slotchange="${this.#u}" ${ref(this.#l)}></slot></li><li><slot name="primary" @slotchange="${this.#f}" ${ref(this.#o)}></slot></li></menu></li></menu></footer></dialog>`}showModal(){if(!this.#e.value?.open){if(document.documentElement.classList.add("private-glide-core-modal-lock-scroll"),!window.CSS.supports("scrollbar-gutter","stable")){const e=Math.abs(window.innerWidth-document.documentElement.clientWidth);document.documentElement.style.setProperty("--glide-scroll-size",`${e}px`)}this.#e.value?.showModal(),this.#e.value?.focus()}}#e;#t;#o;#l;#n;#r;#i;#c(){document.documentElement.classList.remove("private-glide-core-modal-lock-scroll"),this.dispatchEvent(new Event("close")),this.#e.value?.close()}#m(){ow(this.#e.value,ow.object.instanceOf(HTMLDialogElement)),owSlot(this.#t.value)}#f(){owSlotType(this.#o.value,[GlideCoreButton])}#u(){owSlotType(this.#l.value,[GlideCoreButton])}#h(){ow(this.#e.value,ow.object.instanceOf(HTMLDialogElement)),owSlotType(this.#n.value,[GlideCoreModalTertiaryIcon,GlideCoreButton])}#d(){owSlotType(this.#r.value,[GlideCoreModalIconButton])}#s(e){"Escape"===e.key&&(document.documentElement.classList.remove("private-glide-core-modal-lock-scroll"),this.dispatchEvent(new Event("close")),this.#e.value?.close())}#a(e){if(e.target!==this.#e.value)return;const t=this.#e.value?.getBoundingClientRect();if(t){t.top<=e.clientY&&e.clientY<=t.top+t.height&&t.left<=e.clientX&&e.clientX<=t.left+t.width||(document.documentElement.classList.remove("private-glide-core-modal-lock-scroll"),this.dispatchEvent(new Event("close")),this.#e.value?.close())}}};__decorate([property({reflect:!0})],GlideCoreModal.prototype,"label",void 0),__decorate([property({attribute:"show-back-button",type:Boolean,reflect:!0})],GlideCoreModal.prototype,"showBackButton",void 0),__decorate([property({reflect:!0})],GlideCoreModal.prototype,"size",void 0),GlideCoreModal=__decorate([customElement("glide-core-modal")],GlideCoreModal);export default GlideCoreModal;
1
+ var __decorate=this&&this.__decorate||function(e,t,o,l){var n,r=arguments.length,i=r<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,o,l);else for(var s=e.length-1;s>=0;s--)(n=e[s])&&(i=(r<3?n(i):r>3?n(t,o,i):n(t,o))||i);return r>3&&i&&Object.defineProperty(t,o,i),i};import"./modal.icon-button.js";import{LitElement,html}from"lit";import{LocalizeController}from"./library/localize.js";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{when}from"lit/directives/when.js";import GlideCoreButton from"./button.js";import GlideCoreModalIconButton from"./modal.icon-button.js";import GlideCoreModalTertiaryIcon from"./modal.tertiary-icon.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./modal.styles.js";const globalStylesheet=new CSSStyleSheet;globalStylesheet.insertRule("\n @supports (scrollbar-gutter: stable) {\n .private-glide-core-modal-lock-scroll {\n scrollbar-gutter: stable !important;\n overflow: hidden !important;\n }\n }\n"),globalStylesheet.insertRule("\n @supports not (scrollbar-gutter: stable) {\n .private-glide-core-modal-lock-scroll {\n padding-right: var(--glide-scroll-size, 0.9375rem) !important;\n overflow: hidden !important;\n }\n }\n");let GlideCoreModal=class GlideCoreModal extends LitElement{constructor(){super(...arguments),this.label="",this.backButton=!1,this.size="medium",this.#e=createRef(),this.#t=createRef(),this.#o=createRef(),this.#l=createRef(),this.#n=createRef(),this.#r=createRef(),this.#i=new LocalizeController(this)}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}close(){this.#e.value?.open&&(document.documentElement.classList.remove("private-glide-core-modal-lock-scroll"),this.dispatchEvent(new Event("close")),this.#e.value?.close())}connectedCallback(){super.connectedCallback();document.adoptedStyleSheets.includes(globalStylesheet)||document.adoptedStyleSheets.push(globalStylesheet)}disconnectedCallback(){super.disconnectedCallback(),document.documentElement.classList.remove("private-glide-core-modal-lock-scroll"),document.adoptedStyleSheets=document.adoptedStyleSheets.filter((e=>e!==globalStylesheet))}firstUpdated(){owSlot(this.#t.value),owSlotType(this.#r.value,[GlideCoreModalIconButton]),owSlotType(this.#o.value,[GlideCoreButton]),owSlotType(this.#l.value,[GlideCoreButton]),owSlotType(this.#n.value,[GlideCoreModalTertiaryIcon,GlideCoreButton])}render(){return html`<dialog class="${classMap({component:!0,small:"small"===this.size,medium:"medium"===this.size,large:"large"===this.size,xlarge:"xlarge"===this.size})}" tabindex="-1" @keydown="${this.#s}" @mousedown="${this.#a}" ${ref(this.#e)}><header class="header"><h2 class="label" data-test="heading" id="heading">${when(this.backButton,(()=>html`<glide-core-modal-icon-button class="icon-button" data-test="back-button" @click="${this.#c}"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><title>${this.#i.term("dismiss")}</title><path d="M12 18C11.4477 18 11 18.4477 11 19C11 19.5523 11.4477 20 12 20V18ZM20 14.5C20 16.433 18.433 18 16.5 18V20C19.5376 20 22 17.5376 22 14.5H20ZM16.5 11C18.433 11 20 12.567 20 14.5H22C22 11.4624 19.5376 9 16.5 9V11ZM16.5 18H12V20H16.5V18ZM16.5 9H3V11H16.5V9Z" fill="currentColor"/><path d="M7 6L3 10L7 14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></glide-core-modal-icon-button>`))} ${this.label}</h2><div class="header-actions" role="toolbar"><slot name="header-actions" @slotchange="${this.#d}" ${ref(this.#r)}></slot><glide-core-modal-icon-button class="icon-button" data-test="close-button" @click="${this.#c}"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><title>${this.#i.term("close")}</title><path d="M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></glide-core-modal-icon-button></div></header><article aria-labelledby="heading" class="body" role="region" tabindex="0"><slot @slotchange="${this.#m}" ${ref(this.#t)}></slot></article><footer class="footer"><menu class="menu"><li class="flex align-center"><slot name="tertiary" @slotchange="${this.#u}" ${ref(this.#n)}></slot></li><li><menu class="actions"><li><slot name="secondary" @slotchange="${this.#h}" ${ref(this.#l)}></slot></li><li><slot name="primary" @slotchange="${this.#f}" ${ref(this.#o)}></slot></li></menu></li></menu></footer></dialog>`}showModal(){if(!this.#e.value?.open){if(document.documentElement.classList.add("private-glide-core-modal-lock-scroll"),!window.CSS.supports("scrollbar-gutter","stable")){const e=Math.abs(window.innerWidth-document.documentElement.clientWidth);document.documentElement.style.setProperty("--glide-scroll-size",`${e}px`)}this.#e.value?.showModal(),this.#e.value?.focus()}}#e;#t;#o;#l;#n;#r;#i;#c(){document.documentElement.classList.remove("private-glide-core-modal-lock-scroll"),this.dispatchEvent(new Event("close")),this.#e.value?.close()}#m(){ow(this.#e.value,ow.object.instanceOf(HTMLDialogElement)),owSlot(this.#t.value)}#f(){owSlotType(this.#o.value,[GlideCoreButton])}#h(){owSlotType(this.#l.value,[GlideCoreButton])}#u(){ow(this.#e.value,ow.object.instanceOf(HTMLDialogElement)),owSlotType(this.#n.value,[GlideCoreModalTertiaryIcon,GlideCoreButton])}#d(){owSlotType(this.#r.value,[GlideCoreModalIconButton])}#s(e){"Escape"===e.key&&(document.documentElement.classList.remove("private-glide-core-modal-lock-scroll"),this.dispatchEvent(new Event("close")),this.#e.value?.close())}#a(e){if(e.target!==this.#e.value)return;const t=this.#e.value?.getBoundingClientRect();if(t){t.top<=e.clientY&&e.clientY<=t.top+t.height&&t.left<=e.clientX&&e.clientX<=t.left+t.width||(document.documentElement.classList.remove("private-glide-core-modal-lock-scroll"),this.dispatchEvent(new Event("close")),this.#e.value?.close())}}};__decorate([property({reflect:!0})],GlideCoreModal.prototype,"label",void 0),__decorate([property({attribute:"back-button",type:Boolean,reflect:!0})],GlideCoreModal.prototype,"backButton",void 0),__decorate([property({reflect:!0})],GlideCoreModal.prototype,"size",void 0),GlideCoreModal=__decorate([customElement("glide-core-modal")],GlideCoreModal);export default GlideCoreModal;
@@ -24,22 +24,6 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
24
24
  }
25
25
  }
26
26
 
27
- @media (prefers-reduced-motion) {
28
- /**
29
- ':host' is targeted here to increase specificity so that
30
- we don't need to use '!important' to turn off the animation.
31
- */
32
- :host .component {
33
- &[open] {
34
- animation: none;
35
- }
36
-
37
- &::backdrop {
38
- animation: none;
39
- }
40
- }
41
- }
42
-
43
27
  .component {
44
28
  backdrop-filter: blur(100px);
45
29
  background-color: var(--glide-core-surface-modal);
@@ -54,8 +38,11 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
54
38
  padding: 1.25rem;
55
39
 
56
40
  &[open] {
57
- animation: modal-open 250ms;
58
41
  opacity: 1;
42
+
43
+ @media (prefers-reduced-motion: no-preference) {
44
+ animation: modal-open 250ms;
45
+ }
59
46
  }
60
47
 
61
48
  &:focus {
@@ -63,18 +50,21 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
63
50
  }
64
51
 
65
52
  &::backdrop {
66
- animation: backdrop-fade-in 250ms;
67
-
68
53
  /* prefix required for Safari */
69
54
  /* stylelint-disable-next-line property-no-vendor-prefix */
70
55
  -webkit-backdrop-filter: blur(3px);
71
56
  backdrop-filter: blur(3px);
72
57
  background-color: rgba(0 0 0 / 40%);
58
+
59
+ @media (prefers-reduced-motion: no-preference) {
60
+ animation: backdrop-fade-in 250ms;
61
+ }
73
62
  }
74
63
 
75
64
  ::slotted([slot='tertiary']) {
76
65
  --size: 1rem;
77
66
 
67
+ display: contents;
78
68
  size: 1rem;
79
69
  }
80
70
  }
@@ -123,6 +113,10 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
123
113
  line-height: 1;
124
114
  }
125
115
 
116
+ .icon-button {
117
+ display: contents;
118
+ }
119
+
126
120
  .body {
127
121
  line-height: 1;
128
122
  overflow: auto;
@@ -6,9 +6,6 @@ declare global {
6
6
  }
7
7
  }
8
8
  /**
9
- * @description A Modal tertiary icon wrapper. Provides opinionated styling and accessibility for icons in Modals.
10
- * Should be used only in the "tertiary" slot of a Modal.
11
- *
12
9
  * @slot - The icon to be rendered.
13
10
  */
14
11
  export default class GlideCoreModalTertiaryIcon extends LitElement {