@crowdstrike/glide-core 0.5.1 → 0.5.2

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/accordion.js +1 -1
  2. package/dist/accordion.styles.js +4 -4
  3. package/dist/accordion.test.basics.js +109 -0
  4. package/dist/accordion.test.events.js +39 -0
  5. package/dist/button-group.button.js +1 -1
  6. package/dist/button-group.button.styles.js +4 -4
  7. package/dist/button-group.button.test.basics.js +169 -0
  8. package/dist/button-group.button.test.events.js +73 -0
  9. package/dist/button-group.js +1 -1
  10. package/dist/button-group.styles.js +3 -3
  11. package/dist/button-group.test.basics.js +268 -0
  12. package/dist/button-group.test.events.js +291 -0
  13. package/dist/button.js +1 -1
  14. package/dist/button.styles.js +4 -4
  15. package/dist/button.test.basics.js +196 -0
  16. package/dist/button.test.events.js +25 -0
  17. package/dist/button.test.form.js +49 -0
  18. package/dist/checkbox-group.js +1 -1
  19. package/dist/checkbox-group.styles.js +2 -2
  20. package/dist/checkbox-group.test.basics.js +119 -0
  21. package/dist/checkbox-group.test.events.js +110 -0
  22. package/dist/checkbox-group.test.focus.js +45 -0
  23. package/dist/checkbox-group.test.form.js +130 -0
  24. package/dist/checkbox-group.test.validity.js +75 -0
  25. package/dist/checkbox.js +1 -1
  26. package/dist/checkbox.styles.js +3 -3
  27. package/dist/checkbox.test.basics.js +89 -0
  28. package/dist/checkbox.test.events.js +87 -0
  29. package/dist/checkbox.test.focus.js +38 -0
  30. package/dist/checkbox.test.form.js +115 -0
  31. package/dist/checkbox.test.states.js +62 -0
  32. package/dist/checkbox.test.validity.js +51 -0
  33. package/dist/drawer.d.ts +2 -2
  34. package/dist/drawer.js +1 -15
  35. package/dist/drawer.styles.js +18 -4
  36. package/dist/drawer.test.accessibility.js +22 -0
  37. package/dist/drawer.test.basics.js +43 -0
  38. package/dist/drawer.test.closing.js +37 -0
  39. package/dist/drawer.test.events.js +52 -0
  40. package/dist/drawer.test.methods.js +34 -0
  41. package/dist/dropdown.d.ts +4 -2
  42. package/dist/dropdown.js +1 -1
  43. package/dist/dropdown.option.d.ts +0 -2
  44. package/dist/dropdown.option.js +1 -1
  45. package/dist/dropdown.option.styles.js +2 -2
  46. package/dist/dropdown.option.test.basics.js +59 -0
  47. package/dist/dropdown.option.test.basics.multiple.js +26 -0
  48. package/dist/dropdown.option.test.basics.single.js +20 -0
  49. package/dist/dropdown.option.test.events.js +27 -0
  50. package/dist/dropdown.option.test.focus.js +11 -0
  51. package/dist/dropdown.option.test.interactions.multiple.js +87 -0
  52. package/dist/dropdown.option.test.interactions.single.js +22 -0
  53. package/dist/dropdown.styles.js +25 -6
  54. package/dist/dropdown.test.basics.filterable.js +84 -0
  55. package/dist/dropdown.test.basics.js +233 -0
  56. package/dist/dropdown.test.basics.multiple.js +270 -0
  57. package/dist/dropdown.test.basics.single.js +79 -0
  58. package/dist/dropdown.test.events.js +268 -0
  59. package/dist/dropdown.test.events.multiple.js +130 -0
  60. package/dist/dropdown.test.focus.d.ts +1 -0
  61. package/dist/dropdown.test.focus.filterable.js +154 -0
  62. package/dist/dropdown.test.focus.js +18 -0
  63. package/dist/dropdown.test.focus.multiple.js +181 -0
  64. package/dist/dropdown.test.focus.single.js +53 -0
  65. package/dist/dropdown.test.form.js +140 -0
  66. package/dist/dropdown.test.form.multiple.js +149 -0
  67. package/dist/dropdown.test.form.single.js +128 -0
  68. package/dist/dropdown.test.interactions.filterable.js +385 -0
  69. package/dist/dropdown.test.interactions.js +446 -0
  70. package/dist/dropdown.test.interactions.multiple.js +908 -0
  71. package/dist/dropdown.test.interactions.single.js +466 -0
  72. package/dist/dropdown.test.validity.js +46 -0
  73. package/dist/icon-button.js +1 -1
  74. package/dist/icon-button.styles.js +3 -3
  75. package/dist/icon-button.test.basics.js +103 -0
  76. package/dist/icons/checked.js +1 -1
  77. package/dist/icons/magnifying-glass.js +1 -1
  78. package/dist/input.js +1 -1
  79. package/dist/input.styles.js +3 -3
  80. package/dist/input.test.basics.js +169 -0
  81. package/dist/input.test.events.js +97 -0
  82. package/dist/input.test.focus.js +54 -0
  83. package/dist/input.test.form.js +56 -0
  84. package/dist/input.test.validity.js +50 -0
  85. package/dist/label.js +1 -1
  86. package/dist/label.styles.js +3 -3
  87. package/dist/label.test.basics.js +129 -0
  88. package/dist/library/expect-argument-error.js +1 -1
  89. package/dist/library/ow.js +1 -1
  90. package/dist/library/ow.test.js +55 -0
  91. package/dist/menu.button.d.ts +1 -2
  92. package/dist/menu.button.js +1 -1
  93. package/dist/menu.button.styles.js +3 -3
  94. package/dist/menu.button.test.basics.js +42 -0
  95. package/dist/menu.d.ts +4 -0
  96. package/dist/menu.js +1 -1
  97. package/dist/menu.link.d.ts +1 -2
  98. package/dist/menu.link.js +1 -1
  99. package/dist/menu.link.styles.js +3 -3
  100. package/dist/menu.link.test.basics.js +46 -0
  101. package/dist/menu.styles.js +6 -6
  102. package/dist/menu.test.basics.js +161 -0
  103. package/dist/menu.test.focus.d.ts +0 -1
  104. package/dist/menu.test.focus.js +66 -0
  105. package/dist/menu.test.interactions.d.ts +0 -1
  106. package/dist/menu.test.interactions.js +522 -0
  107. package/dist/modal.icon-button.js +1 -1
  108. package/dist/modal.icon-button.styles.js +2 -2
  109. package/dist/modal.icon-button.test.basics.js +45 -0
  110. package/dist/modal.js +1 -15
  111. package/dist/modal.styles.js +4 -4
  112. package/dist/modal.tertiary-icon.js +1 -1
  113. package/dist/modal.tertiary-icon.test.basics.js +59 -0
  114. package/dist/modal.test.accessibility.js +48 -0
  115. package/dist/modal.test.basics.js +203 -0
  116. package/dist/modal.test.close.js +38 -0
  117. package/dist/modal.test.events.js +110 -0
  118. package/dist/modal.test.lock-scroll.js +76 -0
  119. package/dist/modal.test.methods.js +23 -0
  120. package/dist/modal.test.scrollbars.js +19 -0
  121. package/dist/radio-group.js +1 -1
  122. package/dist/radio-group.styles.js +2 -2
  123. package/dist/radio-group.test.basics.js +323 -0
  124. package/dist/radio-group.test.events.js +277 -0
  125. package/dist/radio-group.test.focus.js +75 -0
  126. package/dist/radio-group.test.form.js +104 -0
  127. package/dist/radio-group.test.validity.js +228 -0
  128. package/dist/radio.js +1 -1
  129. package/dist/radio.styles.js +4 -4
  130. package/dist/split-button.d.ts +24 -0
  131. package/dist/split-button.js +1 -0
  132. package/dist/split-button.stories.d.ts +17 -0
  133. package/dist/split-button.styles.d.ts +2 -0
  134. package/dist/split-button.styles.js +103 -0
  135. package/dist/split-button.test.basics.d.ts +1 -0
  136. package/dist/split-button.test.basics.js +84 -0
  137. package/dist/split-container.d.ts +30 -0
  138. package/dist/split-container.js +1 -0
  139. package/dist/split-container.styles.d.ts +2 -0
  140. package/dist/split-container.styles.js +132 -0
  141. package/dist/split-container.test.basics.d.ts +3 -0
  142. package/dist/split-container.test.basics.js +445 -0
  143. package/dist/split-container.test.interactions.d.ts +1 -0
  144. package/dist/split-container.test.interactions.js +20 -0
  145. package/dist/split-link.d.ts +25 -0
  146. package/dist/split-link.js +1 -0
  147. package/dist/split-link.test.basics.d.ts +1 -0
  148. package/dist/split-link.test.basics.js +92 -0
  149. package/dist/split-link.test.interactions.d.ts +1 -0
  150. package/dist/split-link.test.interactions.js +19 -0
  151. package/dist/status-indicator.js +1 -1
  152. package/dist/status-indicator.styles.js +2 -2
  153. package/dist/status-indicator.test.basics.js +102 -0
  154. package/dist/styles/focus-outline.js +1 -4
  155. package/dist/styles/visually-hidden.js +1 -11
  156. package/dist/tab.group.js +1 -1
  157. package/dist/tab.group.styles.js +2 -2
  158. package/dist/tab.group.test.basics.js +185 -0
  159. package/dist/tab.js +1 -1
  160. package/dist/tab.panel.js +1 -1
  161. package/dist/tab.panel.styles.js +3 -3
  162. package/dist/tab.styles.js +2 -2
  163. package/dist/tab.test.basics.js +71 -0
  164. package/dist/tag.js +1 -1
  165. package/dist/tag.styles.js +3 -3
  166. package/dist/tag.test.basics.js +118 -0
  167. package/dist/tag.test.events.js +16 -0
  168. package/dist/tag.test.focus.js +11 -0
  169. package/dist/textarea.js +2 -2
  170. package/dist/textarea.styles.js +3 -3
  171. package/dist/textarea.test.basics.js +140 -0
  172. package/dist/textarea.test.events.js +204 -0
  173. package/dist/textarea.test.form.js +70 -0
  174. package/dist/textarea.test.validity.js +83 -0
  175. package/dist/toasts.js +1 -1
  176. package/dist/toasts.styles.js +2 -2
  177. package/dist/toasts.test.basics.js +94 -0
  178. package/dist/toasts.toast.js +1 -1
  179. package/dist/toasts.toast.styles.js +5 -2
  180. package/dist/toasts.toast.test.basics.js +139 -0
  181. package/dist/toggle.js +1 -1
  182. package/dist/toggle.styles.js +3 -3
  183. package/dist/toggle.test.basics.js +64 -0
  184. package/dist/toggle.test.events.js +29 -0
  185. package/dist/toggle.test.focus.js +9 -0
  186. package/dist/toggle.test.states.js +35 -0
  187. package/dist/tooltip.js +1 -1
  188. package/dist/tooltip.styles.js +3 -3
  189. package/dist/tooltip.test.basics.js +64 -0
  190. package/dist/tooltip.test.interactions.js +78 -0
  191. package/dist/tree.item.icon-button.js +1 -1
  192. package/dist/tree.item.icon-button.styles.js +2 -2
  193. package/dist/tree.item.icon-button.test.basics.js +13 -0
  194. package/dist/tree.item.js +1 -1
  195. package/dist/tree.item.menu.js +1 -1
  196. package/dist/tree.item.menu.styles.js +2 -2
  197. package/dist/tree.item.menu.test.basics.js +34 -0
  198. package/dist/tree.item.styles.js +2 -2
  199. package/dist/tree.item.test.basics.js +102 -0
  200. package/dist/tree.js +1 -1
  201. package/dist/tree.styles.js +2 -2
  202. package/dist/tree.test.aria.js +86 -0
  203. package/dist/tree.test.basics.js +123 -0
  204. package/dist/tree.test.events.js +19 -0
  205. package/dist/tree.test.focus.js +261 -0
  206. package/package.json +18 -16
  207. /package/dist/{dropdown.option.test.focus.multiple.d.ts → dropdown.option.test.focus.d.ts} +0 -0
  208. /package/dist/{dropdown.option.test.focus.single.d.ts → dropdown.test.events.multiple.d.ts} +0 -0
package/dist/accordion.js CHANGED
@@ -1 +1 @@
1
- "use strict";var D=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var h=(s,e,t,n)=>{for(var a=n>1?void 0:n?B(e,t):e,m=s.length-1,r;m>=0;m--)(r=s[m])&&(a=(n?r(e,t,a):r(a))||a);return n&&a&&D(e,t,a),a};var y=(s,e,t)=>{if(!e.has(s))throw TypeError("Cannot "+t)};var o=(s,e,t)=>(y(s,e,"read from private field"),t?t.call(s):e.get(s)),l=(s,e,t)=>{if(e.has(s))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(s):e.set(s,t)};var d=(s,e,t)=>(y(s,e,"access private method"),t);var c,f,g,v,x,S,T,E,k,$,N,w,P;import{LitElement as L,html as O}from"lit";import{classMap as b}from"lit/directives/class-map.js";import{createRef as p,ref as u}from"lit/directives/ref.js";import{customElement as C,property as M,state as R}from"lit/decorators.js";import{owSlot as H}from"./library/ow.js";import F from"./accordion.styles.js";let i=class extends L{constructor(){super(...arguments);l(this,S);l(this,E);l(this,$);l(this,w);this.label="";this.open=!1;this.hasPrefixSlot=!1;this.hasSuffixSlot=!1;l(this,c,p());l(this,f,p());l(this,g,p());l(this,v,p());l(this,x,p())}firstUpdated(){H(o(this,f).value)}render(){return O`<details class="component" ?open="${this.open}" ${u(o(this,g))}><summary class="summary" @click="${d(this,w,P)}" data-test="summary"><svg class="chevron" width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg><div class="${b({"heading-box":!0,"heading-box-with-prefix":this.hasPrefixSlot})}" data-test="label"><div class="prefix-slot-box"><slot name="prefix" @slotchange="${d(this,E,k)}" ${u(o(this,v))}></slot></div><span class="label">${this.label}</span></div><div class="${b({"suffix-slot-box":!0,"suffix-slot-box-with-content":this.hasSuffixSlot})}" data-test="suffix"><slot name="suffix" @slotchange="${d(this,$,N)}" ${u(o(this,x))}></slot></div></summary><div class="${b({content:!0,"content-with-prefix":this.hasPrefixSlot})}" data-test="content" ${u(o(this,c))}><slot @slotchange="${d(this,S,T)}" ${u(o(this,f))}></slot></div></details>`}};c=new WeakMap,f=new WeakMap,g=new WeakMap,v=new WeakMap,x=new WeakMap,S=new WeakSet,T=function(){H(o(this,f).value)},E=new WeakSet,k=function(){const t=o(this,v).value?.assignedNodes();this.hasPrefixSlot=!!(t&&t.length>0)},$=new WeakSet,N=function(){const t=o(this,x).value?.assignedNodes();this.hasSuffixSlot=!!(t&&t.length>0)},w=new WeakSet,P=function(t){const n=o(this,g).value,a=o(this,c).value,m=!n.open,r=Number.parseFloat(getComputedStyle(a)?.paddingBottom);m?requestAnimationFrame(()=>{a.animate({height:["0px",`${a.offsetHeight-r}px`],opacity:[0,1]},{duration:150,easing:"ease-in"}),this.dispatchEvent(new CustomEvent("toggle",{detail:{newState:"open",oldState:"closed"}}))}):(t.preventDefault(),a.animate({height:[`${a.offsetHeight-r}px`,"0px"],opacity:[1,0]},{duration:100,easing:"ease-out"}).addEventListener("finish",()=>{n.open=!1,this.dispatchEvent(new CustomEvent("toggle",{detail:{newState:"closed",oldState:"open"}}))},{once:!0}))},i.shadowRootOptions={...L.shadowRootOptions,mode:"closed"},i.styles=F,h([M({reflect:!0})],i.prototype,"label",2),h([M({type:Boolean,reflect:!0})],i.prototype,"open",2),h([R()],i.prototype,"hasPrefixSlot",2),h([R()],i.prototype,"hasSuffixSlot",2),i=h([C("glide-core-accordion")],i);export{i as default};
1
+ var __decorate=this&&this.__decorate||function(e,t,o,s){var i,l=arguments.length,a=l<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,o):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,o,s);else for(var n=e.length-1;n>=0;n--)(i=e[n])&&(a=(l<3?i(a):l>3?i(t,o,a):i(t,o))||a);return l>3&&a&&Object.defineProperty(t,o,a),a};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{owSlot}from"./library/ow.js";import styles from"./accordion.styles.js";let GlideCoreAccordion=class GlideCoreAccordion extends LitElement{constructor(){super(...arguments),this.label="",this.open=!1,this.hasPrefixSlot=!1,this.hasSuffixSlot=!1,this.#e=createRef(),this.#t=createRef(),this.#o=createRef(),this.#s=createRef(),this.#i=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#t.value)}render(){return html`<details class="component" ?open="${this.open}" ${ref(this.#o)}><summary class="summary" @click="${this.#l}" data-test="summary"><svg class="chevron" width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg><div class="${classMap({"heading-box":!0,"heading-box-with-prefix":this.hasPrefixSlot})}" data-test="label"><div class="prefix-slot-box"><slot name="prefix" @slotchange="${this.#a}" ${ref(this.#s)}></slot></div><span class="label">${this.label}</span></div><div class="${classMap({"suffix-slot-box":!0,"suffix-slot-box-with-content":this.hasSuffixSlot})}" data-test="suffix"><slot name="suffix" @slotchange="${this.#n}" ${ref(this.#i)}></slot></div></summary><div class="${classMap({content:!0,"content-with-prefix":this.hasPrefixSlot})}" data-test="content" ${ref(this.#e)}><slot @slotchange="${this.#r}" ${ref(this.#t)}></slot></div></details>`}#e;#t;#o;#s;#i;#r(){owSlot(this.#t.value)}#a(){const e=this.#s.value?.assignedNodes();this.hasPrefixSlot=!!(e&&e.length>0)}#n(){const e=this.#i.value?.assignedNodes();this.hasSuffixSlot=!!(e&&e.length>0)}#l(e){const t=this.#o.value,o=this.#e.value,s=!t.open,i=Number.parseFloat(getComputedStyle(o)?.paddingBottom);if(s)requestAnimationFrame((()=>{o.animate({height:["0px",o.offsetHeight-i+"px"],opacity:[0,1]},{duration:150,easing:"ease-in"}),this.dispatchEvent(new CustomEvent("toggle",{detail:{newState:"open",oldState:"closed"}}))}));else{e.preventDefault();o.animate({height:[o.offsetHeight-i+"px","0px"],opacity:[1,0]},{duration:100,easing:"ease-out"}).addEventListener("finish",(()=>{t.open=!1,this.dispatchEvent(new CustomEvent("toggle",{detail:{newState:"closed",oldState:"open"}}))}),{once:!0})}}};__decorate([property({reflect:!0})],GlideCoreAccordion.prototype,"label",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreAccordion.prototype,"open",void 0),__decorate([state()],GlideCoreAccordion.prototype,"hasPrefixSlot",void 0),__decorate([state()],GlideCoreAccordion.prototype,"hasSuffixSlot",void 0),GlideCoreAccordion=__decorate([customElement("glide-core-accordion")],GlideCoreAccordion);export default GlideCoreAccordion;
@@ -1,4 +1,4 @@
1
- "use strict";import{css as e}from"lit";import i from"./styles/focus-outline.js";export default[e`
1
+ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
2
2
  .component {
3
3
  border-radius: 0.625rem;
4
4
  box-shadow: var(--glide-core-shadow-sm);
@@ -24,7 +24,7 @@
24
24
  }
25
25
 
26
26
  &:focus-visible {
27
- ${i};
27
+ ${focusOutline};
28
28
  }
29
29
 
30
30
  &::marker,
@@ -56,7 +56,7 @@
56
56
 
57
57
  .suffix-slot-box {
58
58
  align-items: center;
59
- color: #00000080;
59
+ color: var(--glide-core-icon-primary);
60
60
  display: flex;
61
61
  gap: 0.625rem;
62
62
 
@@ -95,4 +95,4 @@
95
95
  .content-with-prefix {
96
96
  padding-inline-start: 3.5rem;
97
97
  }
98
- `];
98
+ `];
@@ -0,0 +1,109 @@
1
+ import './accordion.js';
2
+ import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
3
+ import GlideCoreAccordion from './accordion.js';
4
+ GlideCoreAccordion.shadowRootOptions.mode = 'open';
5
+ it('registers', async () => {
6
+ expect(window.customElements.get('glide-core-accordion')).to.equal(GlideCoreAccordion);
7
+ });
8
+ it('is accessible', async () => {
9
+ const component = await fixture(html `<glide-core-accordion label="label">
10
+ Inner content
11
+ </glide-core-accordion>`);
12
+ await expect(component).to.be.accessible();
13
+ });
14
+ it('is closed by default', async () => {
15
+ const component = await fixture(html `<glide-core-accordion label="label">
16
+ Inner content
17
+ </glide-core-accordion>`);
18
+ const accordion = component.shadowRoot?.querySelector('details');
19
+ expect(accordion).to.be.ok;
20
+ expect(accordion?.hasAttribute('open')).to.be.false;
21
+ });
22
+ it('defaults to "open" when provided with the attribute', async () => {
23
+ const component = await fixture(html `<glide-core-accordion label="label" open>
24
+ Inner content
25
+ </glide-core-accordion>`);
26
+ const accordion = component.shadowRoot?.querySelector('details');
27
+ expect(accordion).to.be.ok;
28
+ expect(accordion?.hasAttribute('open')).to.be.true;
29
+ });
30
+ it('renders the provided "label"', async () => {
31
+ const component = await fixture(html `<glide-core-accordion label="Accordion Title">
32
+ Inner content
33
+ </glide-core-accordion>`);
34
+ const label = component.shadowRoot?.querySelector('[data-test="label"]');
35
+ expect(label).to.be.ok;
36
+ expect(label?.textContent?.trim()).to.equal('Accordion Title');
37
+ });
38
+ it('renders the provided default slotted content', async () => {
39
+ const component = await fixture(html `<glide-core-accordion label="label"
40
+ ><p data-body>Inner content</p></glide-core-accordion
41
+ >`);
42
+ const body = component.querySelector('[data-body]');
43
+ expect(body).to.be.ok;
44
+ });
45
+ it('renders with a prefix slot and applies the appropriate classes', async () => {
46
+ const component = await fixture(html `<glide-core-accordion label="label">
47
+ Inner content
48
+ <span slot="prefix" data-prefix>prefix</span>
49
+ </glide-core-accordion>`);
50
+ expect(document.querySelector('[data-prefix]')).to.be.ok;
51
+ expect([
52
+ ...component.shadowRoot.querySelector('[data-test="label"]').classList,
53
+ ]).to.deep.equal(['heading-box', 'heading-box-with-prefix']);
54
+ expect([
55
+ ...component.shadowRoot.querySelector('[data-test="content"]').classList,
56
+ ]).to.deep.equal(['content', 'content-with-prefix']);
57
+ });
58
+ it('does not apply prefix classes when no prefix slot is provided', async () => {
59
+ const component = await fixture(html `<glide-core-accordion label="label">
60
+ Inner content
61
+ </glide-core-accordion>`);
62
+ expect([
63
+ ...component.shadowRoot.querySelector('[data-test="label"]').classList,
64
+ ]).to.deep.equal(['heading-box']);
65
+ expect([
66
+ ...component.shadowRoot.querySelector('[data-test="content"]').classList,
67
+ ]).to.deep.equal(['content']);
68
+ });
69
+ it('renders with a suffix slot and applies the appropriate class', async () => {
70
+ const component = await fixture(html `<glide-core-accordion label="label">
71
+ Inner content
72
+ <span slot="suffix" data-suffix>suffix</span>
73
+ </glide-core-accordion>`);
74
+ expect(component.querySelector('[data-suffix]')).to.be.ok;
75
+ expect([
76
+ ...component.shadowRoot.querySelector('[data-test="suffix"]').classList,
77
+ ]).to.deep.equal(['suffix-slot-box', 'suffix-slot-box-with-content']);
78
+ });
79
+ it('does not apply the suffix class when no suffix slot is provided', async () => {
80
+ const component = await fixture(html `<glide-core-accordion label="label">
81
+ Inner content
82
+ </glide-core-accordion>`);
83
+ expect([
84
+ ...component.shadowRoot.querySelector('[data-test="suffix"]').classList,
85
+ ]).to.deep.equal(['suffix-slot-box']);
86
+ });
87
+ it('renders without prefix and suffix classes after both are removed', async () => {
88
+ const component = await fixture(html `
89
+ <glide-core-accordion label="label">
90
+ Inner content
91
+ <span slot="prefix">prefix</span>
92
+ <span slot="suffix">suffix</span>
93
+ </glide-core-accordion>
94
+ `);
95
+ component.querySelector('[slot="prefix"]')?.remove();
96
+ component.querySelector('[slot="suffix"]')?.remove();
97
+ await elementUpdated(component);
98
+ // prefix
99
+ expect([
100
+ ...component.shadowRoot.querySelector('[data-test="label"]').classList,
101
+ ]).to.deep.equal(['heading-box']);
102
+ expect([
103
+ ...component.shadowRoot.querySelector('[data-test="content"]').classList,
104
+ ]).to.deep.equal(['content']);
105
+ // suffix
106
+ expect([
107
+ ...component.shadowRoot.querySelector('[data-test="suffix"]').classList,
108
+ ]).to.deep.equal(['suffix-slot-box']);
109
+ });
@@ -0,0 +1,39 @@
1
+ import './accordion.js';
2
+ import { elementUpdated, expect, fixture, html, oneEvent, } from '@open-wc/testing';
3
+ import GlideCoreAccordion from './accordion.js';
4
+ GlideCoreAccordion.shadowRootOptions.mode = 'open';
5
+ it('dispatches a "toggle" event when the Accordion opens', async () => {
6
+ let hasToggleBeenCalled = false;
7
+ const component = await fixture(html `<glide-core-accordion label="label">
8
+ Inner content
9
+ </glide-core-accordion>`);
10
+ component.addEventListener('toggle', () => (hasToggleBeenCalled = true));
11
+ const summary = component.shadowRoot?.querySelector('[data-test="summary"]');
12
+ expect(summary).to.be.ok;
13
+ summary?.click();
14
+ await oneEvent(component, 'toggle');
15
+ expect(hasToggleBeenCalled).to.be.true;
16
+ });
17
+ it('dispatches a "toggle" event when the Accordion closes', async () => {
18
+ let hasToggleBeenCalled = false;
19
+ const component = await fixture(html `<glide-core-accordion label="label" open>
20
+ Inner content
21
+ </glide-core-accordion>`);
22
+ component.addEventListener('toggle', () => (hasToggleBeenCalled = true));
23
+ const summary = component.shadowRoot?.querySelector('[data-test="summary"]');
24
+ expect(summary).to.be.ok;
25
+ summary?.click();
26
+ // Force the animations to complete with javascript
27
+ // and by triggering a `finish` event ourselves.
28
+ component.shadowRoot
29
+ ?.querySelector('[data-test="content"]')
30
+ ?.getAnimations()
31
+ ?.at(0)
32
+ ?.finish();
33
+ component.shadowRoot
34
+ ?.querySelector('[data-test="content"]')
35
+ ?.dispatchEvent(new AnimationEvent('finish'));
36
+ await elementUpdated(component);
37
+ await oneEvent(component, 'toggle');
38
+ expect(hasToggleBeenCalled).to.be.true;
39
+ });
@@ -1 +1 @@
1
- "use strict";var V=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var f=(n,a,s,e)=>{for(var l=e>1?void 0:e?O(a,s):a,S=n.length-1,T;S>=0;S--)(T=n[S])&&(l=(e?T(a,s,l):T(l))||l);return e&&l&&V(a,s,l),l};var R=(n,a,s)=>{if(!a.has(n))throw TypeError("Cannot "+s)};var i=(n,a,s)=>(R(n,a,"read from private field"),s?s.call(n):a.get(n)),r=(n,a,s)=>{if(a.has(n))throw TypeError("Cannot add the same private member more than once");a instanceof WeakSet?a.add(n):a.set(n,s)};var d=(n,a,s)=>(R(n,a,"access private method"),s);var b,p,g,h,c,o,v,y,u,E,H,w,U;import{LitElement as L,html as I}from"lit";import{classMap as A}from"lit/directives/class-map.js";import{createRef as $,ref as k}from"lit/directives/ref.js";import{customElement as K,property as m,state as x}from"lit/decorators.js";import{owSlot as M,owSlotType as D}from"./library/ow.js";import j from"./button-group.button.styles.js";let t=class extends L{constructor(){super(...arguments);r(this,h);r(this,o);r(this,y);r(this,E);r(this,w);this.selected=!1;this.disabled=!1;this.value="";this.vertical=!1;this.isSingleButton=!1;this.isTabbable=!1;this.position="inner";r(this,b,$());r(this,p,$());r(this,g,$())}firstUpdated(){if(M(i(this,b).value),D(i(this,b).value,[Text]),this.selected&&(this.isTabbable=!0),this.variant==="icon-only"&&M(i(this,g).value),i(this,h,c).length>0){if(i(this,h,c).length>1&&i(this,h,c).at(0)===this?this.position="first":i(this,h,c).length>1&&i(this,h,c).at(-1)===this?this.position="last":i(this,h,c).length===1&&(this.isSingleButton=!0),i(this,h,c).every(e=>e.disabled))return;const s=i(this,h,c).find(e=>!e.disabled&&e.selected);if(s&&s===this)this.isTabbable=!0;else if(!s){const e=i(this,h,c).find(l=>!l.disabled);e&&e===this&&(this.isTabbable=!0)}}}focus(s){i(this,p).value?.focus(s)}render(){return I`<li role="radio" aria-checked="${this.selected}" aria-disabled="${this.disabled}" tabindex="${!this.isTabbable||this.disabled?-1:0}" @click="${d(this,y,u)}" @keydown="${d(this,w,U)}" ${k(i(this,p))} class="${A({component:!0,selected:this.selected,disabled:!!this.disabled,[this.position]:!0,vertical:this.vertical,single:this.isSingleButton,"icon-only":this.variant==="icon-only"})}"><slot name="prefix" ${k(i(this,g))}></slot><span class="${A({"visually-hidden":this.variant==="icon-only"})}"><slot @slotchange="${d(this,E,H)}" ${k(i(this,b))}></slot></span></li>`}willUpdate(s){if(this.hasUpdated&&s.has("selected")){const e=s.get("selected");if(e===!0)this.isTabbable=!1;else if(e===!1){this.isTabbable=!0,this.focus();for(const l of i(this,h,c))l!==this&&l.selected&&(l.selected=!1)}}}};b=new WeakMap,p=new WeakMap,g=new WeakMap,h=new WeakSet,c=function(){return[...this.closest("glide-core-button-group")?.querySelectorAll("glide-core-button-group-button")??[]]},o=new WeakSet,v=function(s=this){s.dispatchEvent(new CustomEvent("change",{bubbles:!0,detail:s.value})),s.dispatchEvent(new CustomEvent("input",{bubbles:!0,detail:s.value}))},y=new WeakSet,u=function(){!this.disabled&&!this.selected&&(this.selected=!0,d(this,o,v).call(this))},E=new WeakSet,H=function(){M(i(this,b).value),D(i(this,b).value,[Text])},w=new WeakSet,U=function(s){if(!(this.disabled||i(this,h,c).length<2&&s.key!==" "))switch(s.key){case"ArrowUp":case"ArrowLeft":{s.preventDefault(),this.selected=!1;let e=this.previousElementSibling;for(;!e||e instanceof t&&e.disabled;)if(e===null){const l=i(this,h,c).at(-1);l&&(e=l)}else e=e.previousElementSibling;e&&e instanceof t&&(e.selected=!0,d(this,o,v).call(this,e));break}case"ArrowDown":case"ArrowRight":{s.preventDefault(),this.selected=!1;let e=this.nextElementSibling;for(;!e||e instanceof t&&e.disabled;)if(e===null){const l=i(this,h,c).at(0);l&&(e=l)}else e=e.nextElementSibling;e&&e instanceof t&&(e.selected=!0,d(this,o,v).call(this,e));break}case" ":{s.preventDefault(),!this.disabled&&!this.selected&&(this.selected=!0,d(this,o,v).call(this));break}}},t.shadowRootOptions={...L.shadowRootOptions,mode:"closed"},t.styles=j,f([m({type:Boolean,reflect:!0})],t.prototype,"selected",2),f([m({type:Boolean,reflect:!0})],t.prototype,"disabled",2),f([m()],t.prototype,"value",2),f([m()],t.prototype,"variant",2),f([m({type:Boolean})],t.prototype,"vertical",2),f([x()],t.prototype,"isSingleButton",2),f([x()],t.prototype,"isTabbable",2),f([x()],t.prototype,"position",2),t=f([K("glide-core-button-group-button")],t);export{t as default};
1
+ var _a,GlideCoreButtonGroupButton_1,__decorate=this&&this.__decorate||function(t,e,o,i){var s,l=arguments.length,n=l<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(t,e,o,i);else for(var r=t.length-1;r>=0;r--)(s=t[r])&&(n=(l<3?s(n):l>3?s(e,o,n):s(e,o))||n);return l>3&&n&&Object.defineProperty(e,o,n),n};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{owSlot,owSlotType}from"./library/ow.js";import styles from"./button-group.button.styles.js";let GlideCoreButtonGroupButton=class GlideCoreButtonGroupButton extends LitElement{constructor(){super(...arguments),this.selected=!1,this.disabled=!1,this.value="",this.vertical=!1,this.isSingleButton=!1,this.isTabbable=!1,this.position="inner",this.#t=createRef(),this.#e=createRef(),this.#o=createRef()}static{GlideCoreButtonGroupButton_1=this}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){if(owSlot(this.#t.value),owSlotType(this.#t.value,[Text]),this.selected&&(this.isTabbable=!0),"icon-only"===this.variant&&owSlot(this.#o.value),this.#i.length>0){if(this.#i.length>1&&this.#i.at(0)===this?this.position="first":this.#i.length>1&&this.#i.at(-1)===this?this.position="last":1===this.#i.length&&(this.isSingleButton=!0),this.#i.every((t=>t.disabled)))return;const t=this.#i.find((t=>!t.disabled&&t.selected));if(t&&t===this)this.isTabbable=!0;else if(!t){const t=this.#i.find((t=>!t.disabled));t&&t===this&&(this.isTabbable=!0)}}}focus(t){this.#e.value?.focus(t)}render(){return html`<li role="radio" aria-checked="${this.selected}" aria-disabled="${this.disabled}" tabindex="${!this.isTabbable||this.disabled?-1:0}" @click="${this.#s}" @keydown="${this.#l}" ${ref(this.#e)} class="${classMap({component:!0,selected:this.selected,disabled:Boolean(this.disabled),[this.position]:!0,vertical:this.vertical,single:this.isSingleButton,"icon-only":"icon-only"===this.variant})}"><slot name="prefix" ${ref(this.#o)}></slot><span class="${classMap({"visually-hidden":"icon-only"===this.variant})}"><slot @slotchange="${this.#n}" ${ref(this.#t)}></slot></span></li>`}willUpdate(t){if(this.hasUpdated&&t.has("selected")){const e=t.get("selected");if(!0===e)this.isTabbable=!1;else if(!1===e){this.isTabbable=!0,this.focus();for(const t of this.#i)t!==this&&t.selected&&(t.selected=!1)}}}#t;#e;#o;get#i(){return[...this.closest("glide-core-button-group")?.querySelectorAll("glide-core-button-group-button")??[]]}#r(t=this){t.dispatchEvent(new CustomEvent("change",{bubbles:!0,detail:t.value})),t.dispatchEvent(new CustomEvent("input",{bubbles:!0,detail:t.value}))}#s(){this.disabled||this.selected||(this.selected=!0,this.#r())}#n(){owSlot(this.#t.value),owSlotType(this.#t.value,[Text])}#l(t){if(!(this.disabled||this.#i.length<2&&" "!==t.key))switch(t.key){case"ArrowUp":case"ArrowLeft":{t.preventDefault(),this.selected=!1;let e=this.previousElementSibling;for(;!e||e instanceof GlideCoreButtonGroupButton_1&&e.disabled;)if(null===e){const t=this.#i.at(-1);t&&(e=t)}else e=e.previousElementSibling;e&&e instanceof GlideCoreButtonGroupButton_1&&(e.selected=!0,this.#r(e));break}case"ArrowDown":case"ArrowRight":{t.preventDefault(),this.selected=!1;let e=this.nextElementSibling;for(;!e||e instanceof GlideCoreButtonGroupButton_1&&e.disabled;)if(null===e){const t=this.#i.at(0);t&&(e=t)}else e=e.nextElementSibling;e&&e instanceof GlideCoreButtonGroupButton_1&&(e.selected=!0,this.#r(e));break}case" ":t.preventDefault(),this.disabled||this.selected||(this.selected=!0,this.#r())}}};__decorate([property({type:Boolean,reflect:!0})],GlideCoreButtonGroupButton.prototype,"selected",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreButtonGroupButton.prototype,"disabled",void 0),__decorate([property()],GlideCoreButtonGroupButton.prototype,"value",void 0),__decorate([property()],GlideCoreButtonGroupButton.prototype,"variant",void 0),__decorate([property({type:Boolean})],GlideCoreButtonGroupButton.prototype,"vertical",void 0),__decorate([state()],GlideCoreButtonGroupButton.prototype,"isSingleButton",void 0),__decorate([state()],GlideCoreButtonGroupButton.prototype,"isTabbable",void 0),__decorate([state()],GlideCoreButtonGroupButton.prototype,"position",void 0),GlideCoreButtonGroupButton=GlideCoreButtonGroupButton_1=__decorate([customElement("glide-core-button-group-button")],GlideCoreButtonGroupButton);export default GlideCoreButtonGroupButton;
@@ -1,4 +1,4 @@
1
- "use strict";import{css as e}from"lit";import r from"./styles/focus-outline.js";import o from"./styles/visually-hidden.js";export default[e`
1
+ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
2
2
  .component {
3
3
  align-items: center;
4
4
  appearance: none;
@@ -72,7 +72,7 @@
72
72
  border-color: var(--glide-core-border-focus);
73
73
  color: var(--glide-core-color-white);
74
74
 
75
- ${r};
75
+ ${focusOutline};
76
76
 
77
77
  /* create a stacking context so the outline doesn't become obscured behind other elements */
78
78
  transform: translateX(0);
@@ -94,6 +94,6 @@
94
94
  }
95
95
 
96
96
  .visually-hidden {
97
- ${o};
97
+ ${visuallyHidden};
98
98
  }
99
- `];
99
+ `];
@@ -0,0 +1,169 @@
1
+ import { ArgumentError } from 'ow';
2
+ import { expect, fixture, html } from '@open-wc/testing';
3
+ import GlideCoreButtonGroupButton from './button-group.button.js';
4
+ import sinon from 'sinon';
5
+ GlideCoreButtonGroupButton.shadowRootOptions.mode = 'open';
6
+ it('registers', async () => {
7
+ expect(window.customElements.get('glide-core-button-group-button')).to.equal(GlideCoreButtonGroupButton);
8
+ });
9
+ it('is accessible', async () => {
10
+ const element = await fixture(html `<glide-core-button-group-button value="value"
11
+ >Button</glide-core-button-group-button
12
+ >`);
13
+ await expect(element).to.be.accessible();
14
+ });
15
+ it('renders an li with role "radio"', async () => {
16
+ const element = await fixture(html `<glide-core-button-group-button value="value"
17
+ >Button</glide-core-button-group-button
18
+ >`);
19
+ const liElement = element.shadowRoot?.querySelector('li');
20
+ expect(liElement).to.have.attribute('role', 'radio');
21
+ });
22
+ it('renders "aria-checked" equal to "false" and "tabindex" equal to "-1" by default', async () => {
23
+ const element = await fixture(html `<glide-core-button-group-button value="value"
24
+ >Button</glide-core-button-group-button
25
+ >`);
26
+ const liElement = element.shadowRoot?.querySelector('li');
27
+ expect(liElement).to.not.be.null;
28
+ expect(liElement).to.have.attribute('aria-checked', 'false');
29
+ expect(liElement).to.have.attribute('tabindex', '-1');
30
+ });
31
+ it('renders "aria-checked" equal to "true" and "tabindex" equal to "0" when attribute "selected" exists', async () => {
32
+ const element = await fixture(html `<glide-core-button-group-button value="value" selected
33
+ >Button</glide-core-button-group-button
34
+ >`);
35
+ const liElement = element.shadowRoot?.querySelector('li');
36
+ expect(liElement).to.have.attribute('aria-checked', 'true');
37
+ expect(liElement).to.have.attribute('tabindex', '0');
38
+ });
39
+ it('renders two slots, where one has name "prefix", and the other is default with given text', async () => {
40
+ const element = await fixture(html `<glide-core-button-group-button value="value" selected
41
+ ><span slot="prefix" data-prefix>Prefix</span
42
+ >Button</glide-core-button-group-button
43
+ >`);
44
+ const prefixSlot = element.shadowRoot?.querySelector('slot[name="prefix"]');
45
+ const defaultSlot = element.shadowRoot?.querySelector('slot:not([name="prefix"])');
46
+ // verify the slots exist
47
+ expect(prefixSlot).to.not.be.null;
48
+ expect(defaultSlot).to.not.be.null;
49
+ const prefixContent = document.querySelector('[data-prefix]');
50
+ const content = document.querySelector('glide-core-button-group-button');
51
+ // verify the content of the slots exist
52
+ expect(prefixContent).to.not.be.null;
53
+ expect(prefixContent?.textContent).to.equal('Prefix');
54
+ expect(content?.textContent).to.contain('Button');
55
+ });
56
+ it('is has a disabled presentation when the "disabled" attribute is true', async () => {
57
+ const element = await fixture(html `<glide-core-button-group-button value="value" disabled
58
+ >Button</glide-core-button-group-button
59
+ >`);
60
+ const liElement = element.shadowRoot?.querySelector('li');
61
+ expect(liElement).to.have.attribute('aria-disabled', 'true');
62
+ });
63
+ it('does not have a disabled presentation when "disabled" attribute is false', async () => {
64
+ const element = await fixture(html `<glide-core-button-group-button value="value"
65
+ >Button</glide-core-button-group-button
66
+ >`);
67
+ const liElement = element.shadowRoot?.querySelector('li');
68
+ expect(liElement).to.have.attribute('aria-disabled', 'false');
69
+ });
70
+ it('has a vertical presention when the "vertical" attribute is set', async () => {
71
+ await fixture(html ` <glide-core-button-group-button value="value" vertical
72
+ >Button</glide-core-button-group-button
73
+ >`);
74
+ const buttonElement = document.querySelector('glide-core-button-group-button');
75
+ const liElement = buttonElement?.shadowRoot?.querySelector('li');
76
+ expect(liElement).to.have.class('vertical');
77
+ });
78
+ it('does not have a vertical presention when the "vertical" attribute is not set', async () => {
79
+ await fixture(html ` <glide-core-button-group-button value="value"
80
+ >Button</glide-core-button-group-button
81
+ >`);
82
+ const buttonElement = document.querySelector('glide-core-button-group-button');
83
+ const liElement = buttonElement?.shadowRoot?.querySelector('li');
84
+ expect(liElement).to.not.have.class('vertical');
85
+ });
86
+ it('sets buttons as not tabbable by default', async () => {
87
+ const element = await fixture(html `<glide-core-button-group-button value="value"
88
+ >Button</glide-core-button-group-button
89
+ >`);
90
+ const liElement = element.shadowRoot?.querySelector('li');
91
+ await expect(liElement).to.have.attribute('tabindex', '-1');
92
+ });
93
+ it('sets a "selected" button as tabbable', async () => {
94
+ const element = await fixture(html `<glide-core-button-group-button value="value" selected
95
+ >Button</glide-core-button-group-button
96
+ >`);
97
+ const liElement = element.shadowRoot?.querySelector('li');
98
+ await expect(liElement).to.have.attribute('tabindex', '0');
99
+ });
100
+ it('has a presentation for variant "icon-only"', async () => {
101
+ const element = await fixture(html `<glide-core-button-group-button
102
+ value="value"
103
+ selected
104
+ variant="icon-only"
105
+ ><span slot="prefix">Prefix</span>Button</glide-core-button-group-button
106
+ >`);
107
+ const liElement = element.shadowRoot?.querySelector('li');
108
+ expect(liElement).to.have.class('icon-only');
109
+ });
110
+ it('does not apply class "icon-only" when variant "icon-only" is absent', async () => {
111
+ const element = await fixture(html `<glide-core-button-group-button value="value"
112
+ >Button</glide-core-button-group-button
113
+ >`);
114
+ const liElement = element.shadowRoot?.querySelector('li');
115
+ expect(liElement).to.not.have.class('icon-only');
116
+ });
117
+ it('throws an error when no label is present and variant is `icon-only`', async () => {
118
+ const spy = sinon.spy();
119
+ try {
120
+ await fixture(html `<glide-core-button-group-button
121
+ value="value"
122
+ selected
123
+ variant="icon-only"
124
+ ><span slot="prefix">Prefix</span></glide-core-button-group-button
125
+ >`);
126
+ }
127
+ catch (error) {
128
+ if (error instanceof ArgumentError) {
129
+ spy();
130
+ }
131
+ }
132
+ expect(spy.called).to.be.true;
133
+ });
134
+ it('throws an error when prefix slot is empty and variant is `icon-only`', async () => {
135
+ const spy = sinon.spy();
136
+ // Not sure how to resolve the below, despite the test passing, so disabling console errors for now:
137
+ //
138
+ // Browser logs:
139
+ // An error was thrown in a Promise outside a test. Did you forget to await a function or assertion?
140
+ sinon.stub(console, 'error'); // Disable console.error
141
+ try {
142
+ await fixture(html `<glide-core-button-group-button
143
+ value="value"
144
+ selected
145
+ variant="icon-only"
146
+ >Button</glide-core-button-group-button
147
+ >`);
148
+ }
149
+ catch (error) {
150
+ if (error instanceof ArgumentError) {
151
+ spy();
152
+ }
153
+ }
154
+ expect(spy.called).to.be.true;
155
+ });
156
+ it('does not throw an error when prefix slot is empty and no variant is set', async () => {
157
+ const spy = sinon.spy();
158
+ try {
159
+ await fixture(html `<glide-core-button-group-button value="value" selected
160
+ >Button</glide-core-button-group-button
161
+ >`);
162
+ }
163
+ catch (error) {
164
+ if (error instanceof ArgumentError) {
165
+ spy();
166
+ }
167
+ }
168
+ expect(spy.notCalled).to.be.true;
169
+ });
@@ -0,0 +1,73 @@
1
+ import './button-group.button.js';
2
+ import { expect, fixture, html, oneEvent } from '@open-wc/testing';
3
+ import { sendKeys } from '@web/test-runner-commands';
4
+ import GlideCoreButtonGroupButton from './button-group.button.js';
5
+ import sinon from 'sinon';
6
+ GlideCoreButtonGroupButton.shadowRootOptions.mode = 'open';
7
+ it('emits a change event when clicked', async () => {
8
+ const element = await fixture(html `<glide-core-button-group-button value="value"
9
+ >Button</glide-core-button-group-button
10
+ >`);
11
+ const liElement = element.shadowRoot?.querySelector('li');
12
+ // This pattern is adopted from https://open-wc.org/docs/testing/helpers/#testing-events
13
+ // Without setTimeout the test fails. The suspicion is this is related to task scheduling,
14
+ // however this can be investigated later.
15
+ setTimeout(() => {
16
+ liElement?.click();
17
+ });
18
+ const changeEvent = await oneEvent(element, 'change');
19
+ expect(changeEvent instanceof Event).to.be.true;
20
+ });
21
+ it('emits an input event when clicked', async () => {
22
+ const element = await fixture(html `<glide-core-button-group-button value="value"
23
+ >Button</glide-core-button-group-button
24
+ >`);
25
+ const liElement = element.shadowRoot.querySelector('li');
26
+ setTimeout(() => {
27
+ liElement?.click();
28
+ });
29
+ const inputEvent = await oneEvent(element, 'input');
30
+ expect(inputEvent instanceof Event).to.be.true;
31
+ });
32
+ it('emits a change event when a space key is pressed and is not already selected', async () => {
33
+ const buttonElement = await fixture(html `<glide-core-button-group-button value="value-1"
34
+ >Button 1</glide-core-button-group-button
35
+ >`);
36
+ buttonElement.focus();
37
+ setTimeout(async () => {
38
+ await sendKeys({ press: ' ' });
39
+ });
40
+ const changeEvent = await oneEvent(buttonElement, 'change');
41
+ expect(changeEvent instanceof Event).to.be.true;
42
+ });
43
+ it('does not emit change event when a space key is pressed and is selected', async () => {
44
+ const buttonElement = await fixture(html `<glide-core-button-group-button value="value-1" selected
45
+ >Button 1</glide-core-button-group-button
46
+ > `);
47
+ const spy = sinon.spy();
48
+ buttonElement.addEventListener('change', spy);
49
+ buttonElement.focus();
50
+ await sendKeys({ press: ' ' });
51
+ expect(spy.notCalled).to.be.true;
52
+ });
53
+ it('emits an input event when a space key is pressed and is not already selected', async () => {
54
+ const buttonElement = await fixture(html ` <glide-core-button-group-button value="value-1"
55
+ >Button 1</glide-core-button-group-button
56
+ >`);
57
+ buttonElement.focus();
58
+ setTimeout(async () => {
59
+ await sendKeys({ press: ' ' });
60
+ });
61
+ const inputEvent = await oneEvent(buttonElement, 'input');
62
+ expect(inputEvent instanceof Event).to.be.true;
63
+ });
64
+ it('does not emit an input event when a space key is pressed and is selected', async () => {
65
+ const buttonElement = await fixture(html `<glide-core-button-group-button value="value-1" selected
66
+ >Button 1</glide-core-button-group-button
67
+ >`);
68
+ buttonElement.focus();
69
+ const spy = sinon.spy();
70
+ buttonElement.addEventListener('input', spy);
71
+ await sendKeys({ press: ' ' });
72
+ expect(spy.notCalled).to.be.true;
73
+ });
@@ -1 +1 @@
1
- "use strict";var A=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var a=(o,e,t,l)=>{for(var i=l>1?void 0:l?w(e,t):e,c=o.length-1,f;c>=0;c--)(f=o[c])&&(i=(l?f(e,t,i):f(i))||i);return l&&i&&A(e,t,i),i};var v=(o,e,t)=>{if(!e.has(o))throw TypeError("Cannot "+t)};var n=(o,e,t)=>(v(o,e,"read from private field"),t?t.call(o):e.get(o)),u=(o,e,t)=>{if(e.has(o))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(o):e.set(o,t)};var h=(o,e,t)=>(v(o,e,"access private method"),t);var s,m,I;import{LitElement as d,html as g}from"lit";import{classMap as E}from"lit/directives/class-map.js";import{createRef as M,ref as R}from"lit/directives/ref.js";import{customElement as S,property as p,queryAssignedElements as $}from"lit/decorators.js";import{owSlotType as b}from"./library/ow.js";import{when as x}from"lit/directives/when.js";import y from"./button-group.button.js";import O from"./button-group.styles.js";let r=class extends d{constructor(){super(...arguments);u(this,m);this.label="";this.orientation="horizontal";u(this,s,M())}firstUpdated(){if(b(n(this,s).value,[y]),this.orientation==="vertical")for(const t of this.listItems)t.toggleAttribute("vertical");if(this.variant==="icon-only")for(const t of this.listItems)t.setAttribute("variant","icon-only")}render(){return g`${x(!!this.label,()=>g`<div class="label" id="glide-core-button-group">${this.label}</div>`)}<ul aria-labelledby="glide-core-button-group" role="radiogroup" class="${E({"radio-group":!0,vertical:this.orientation==="vertical"})}"><slot @slotchange="${h(this,m,I)}" ${R(n(this,s))}></slot></ul>`}willUpdate(t){if(this.hasUpdated&&t.has("variant"))if(t.get("variant")==="icon-only")for(const i of this.listItems)i.removeAttribute("variant");else for(const i of this.listItems)i.setAttribute("variant","icon-only");if(this.hasUpdated&&t.has("orientation")){const l=t.get("orientation");if(l==="vertical")for(const i of this.listItems)i.removeAttribute("vertical");else if(l==="horizontal")for(const i of this.listItems)i.toggleAttribute("vertical")}}};s=new WeakMap,m=new WeakSet,I=function(){b(n(this,s).value,[y])},r.shadowRootOptions={...d.shadowRootOptions,mode:"closed"},r.styles=O,a([p()],r.prototype,"label",2),a([$({selector:"glide-core-button-group-button"})],r.prototype,"listItems",2),a([p()],r.prototype,"variant",2),a([p()],r.prototype,"orientation",2),r=a([S("glide-core-button-group")],r);export{r as default};
1
+ var __decorate=this&&this.__decorate||function(t,e,o,r){var i,l=arguments.length,s=l<3?e:null===r?r=Object.getOwnPropertyDescriptor(e,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,o,r);else for(var n=t.length-1;n>=0;n--)(i=t[n])&&(s=(l<3?i(s):l>3?i(e,o,s):i(e,o))||s);return l>3&&s&&Object.defineProperty(e,o,s),s};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,queryAssignedElements}from"lit/decorators.js";import{owSlotType}from"./library/ow.js";import{when}from"lit/directives/when.js";import GlideCoreButtonGroupButton from"./button-group.button.js";import styles from"./button-group.styles.js";let GlideCoreButtonGroup=class GlideCoreButtonGroup extends LitElement{constructor(){super(...arguments),this.label="",this.orientation="horizontal",this.#t=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){if(owSlotType(this.#t.value,[GlideCoreButtonGroupButton]),"vertical"===this.orientation)for(const t of this.listItems)t.toggleAttribute("vertical");if("icon-only"===this.variant)for(const t of this.listItems)t.setAttribute("variant","icon-only")}render(){return html`${when(Boolean(this.label),(()=>html`<div class="label" id="glide-core-button-group">${this.label}</div>`))}<ul aria-labelledby="glide-core-button-group" role="radiogroup" class="${classMap({"radio-group":!0,vertical:"vertical"===this.orientation})}"><slot @slotchange="${this.#e}" ${ref(this.#t)}></slot></ul>`}willUpdate(t){if(this.hasUpdated&&t.has("variant")){if("icon-only"===t.get("variant"))for(const t of this.listItems)t.removeAttribute("variant");else for(const t of this.listItems)t.setAttribute("variant","icon-only")}if(this.hasUpdated&&t.has("orientation")){const e=t.get("orientation");if("vertical"===e)for(const t of this.listItems)t.removeAttribute("vertical");else if("horizontal"===e)for(const t of this.listItems)t.toggleAttribute("vertical")}}#t;#e(){owSlotType(this.#t.value,[GlideCoreButtonGroupButton])}};__decorate([property()],GlideCoreButtonGroup.prototype,"label",void 0),__decorate([queryAssignedElements({selector:"glide-core-button-group-button"})],GlideCoreButtonGroup.prototype,"listItems",void 0),__decorate([property()],GlideCoreButtonGroup.prototype,"variant",void 0),__decorate([property()],GlideCoreButtonGroup.prototype,"orientation",void 0),GlideCoreButtonGroup=__decorate([customElement("glide-core-button-group")],GlideCoreButtonGroup);export default GlideCoreButtonGroup;
@@ -1,4 +1,4 @@
1
- "use strict";import{css as r}from"lit";import e from"./styles/visually-hidden.js";export default[r`
1
+ import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
2
2
  .radio-group {
3
3
  appearance: none;
4
4
  border: 1px solid var(--glide-core-border-base);
@@ -13,6 +13,6 @@
13
13
  }
14
14
 
15
15
  .label {
16
- ${e};
16
+ ${visuallyHidden};
17
17
  }
18
- `];
18
+ `];