@crowdstrike/glide-core 0.8.0 → 0.9.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 (152) hide show
  1. package/dist/button-group.button.d.ts +14 -15
  2. package/dist/button-group.button.js +1 -1
  3. package/dist/button-group.button.styles.js +75 -52
  4. package/dist/button-group.button.test.basics.d.ts +1 -1
  5. package/dist/button-group.button.test.basics.js +83 -147
  6. package/dist/button-group.button.test.events.js +8 -67
  7. package/dist/button-group.button.test.focus.js +13 -0
  8. package/dist/button-group.button.test.interactions.d.ts +1 -0
  9. package/dist/button-group.button.test.interactions.js +42 -0
  10. package/dist/button-group.d.ts +7 -10
  11. package/dist/button-group.js +1 -1
  12. package/dist/button-group.stories.d.ts +1 -5
  13. package/dist/button-group.styles.js +18 -6
  14. package/dist/button-group.test.basics.js +113 -234
  15. package/dist/button-group.test.events.js +210 -263
  16. package/dist/button-group.test.focus.d.ts +1 -0
  17. package/dist/button-group.test.focus.js +39 -0
  18. package/dist/button-group.test.interactions.d.ts +1 -0
  19. package/dist/button-group.test.interactions.js +91 -0
  20. package/dist/button.test.basics.js +1 -1
  21. package/dist/checkbox-group.js +1 -1
  22. package/dist/checkbox-group.styles.js +1 -1
  23. package/dist/checkbox-group.test.basics.js +1 -1
  24. package/dist/checkbox-group.test.events.js +4 -4
  25. package/dist/checkbox-group.test.focus.js +4 -3
  26. package/dist/checkbox.d.ts +7 -1
  27. package/dist/checkbox.js +1 -1
  28. package/dist/checkbox.styles.js +10 -0
  29. package/dist/checkbox.test.events.js +4 -4
  30. package/dist/checkbox.test.focus.js +2 -2
  31. package/dist/{checkbox.test.states.js → checkbox.test.interactions.js} +24 -1
  32. package/dist/drawer.js +1 -1
  33. package/dist/dropdown.d.ts +6 -4
  34. package/dist/dropdown.js +1 -1
  35. package/dist/dropdown.option.d.ts +6 -2
  36. package/dist/dropdown.option.js +1 -1
  37. package/dist/dropdown.option.styles.js +13 -0
  38. package/dist/dropdown.option.test.basics.js +6 -3
  39. package/dist/dropdown.option.test.events.js +1 -1
  40. package/dist/dropdown.option.test.focus.js +1 -1
  41. package/dist/dropdown.option.test.interactions.multiple.js +1 -54
  42. package/dist/dropdown.option.test.interactions.single.js +51 -9
  43. package/dist/dropdown.styles.js +20 -19
  44. package/dist/dropdown.test.basics.js +143 -2
  45. package/dist/dropdown.test.basics.multiple.js +5 -2
  46. package/dist/dropdown.test.events.filterable.js +74 -0
  47. package/dist/dropdown.test.events.js +49 -160
  48. package/dist/dropdown.test.events.multiple.js +265 -8
  49. package/dist/dropdown.test.events.single.js +199 -2
  50. package/dist/dropdown.test.focus.filterable.js +9 -5
  51. package/dist/dropdown.test.focus.js +1 -1
  52. package/dist/dropdown.test.focus.multiple.js +1 -1
  53. package/dist/dropdown.test.focus.single.js +1 -1
  54. package/dist/dropdown.test.interactions.filterable.js +68 -11
  55. package/dist/dropdown.test.interactions.js +94 -5
  56. package/dist/dropdown.test.interactions.multiple.js +202 -5
  57. package/dist/dropdown.test.interactions.single.js +68 -6
  58. package/dist/form-controls-layout.test.basics.js +1 -1
  59. package/dist/icon-button.test.basics.js +1 -1
  60. package/dist/icons/checked.d.ts +1 -1
  61. package/dist/icons/checked.js +1 -1
  62. package/dist/icons/magnifying-glass.js +1 -1
  63. package/dist/input.d.ts +0 -6
  64. package/dist/input.js +1 -1
  65. package/dist/input.styles.js +7 -2
  66. package/dist/input.test.basics.js +19 -5
  67. package/dist/input.test.events.js +4 -4
  68. package/dist/input.test.focus.js +4 -4
  69. package/dist/input.test.translations.d.ts +1 -0
  70. package/dist/input.test.translations.js +38 -0
  71. package/dist/input.test.validity.js +133 -4
  72. package/dist/label.d.ts +1 -1
  73. package/dist/label.js +1 -1
  74. package/dist/label.styles.js +22 -13
  75. package/dist/label.test.basics.js +26 -24
  76. package/dist/library/expect-argument-error.js +1 -1
  77. package/dist/library/localize.d.ts +3 -1
  78. package/dist/menu.d.ts +3 -5
  79. package/dist/menu.js +1 -1
  80. package/dist/menu.options.test.basics.js +2 -2
  81. package/dist/menu.styles.js +1 -15
  82. package/dist/menu.test.basics.d.ts +1 -2
  83. package/dist/menu.test.basics.js +22 -6
  84. package/dist/menu.test.focus.d.ts +1 -0
  85. package/dist/menu.test.focus.js +13 -6
  86. package/dist/menu.test.interactions.js +212 -56
  87. package/dist/modal.icon-button.test.basics.js +1 -1
  88. package/dist/modal.js +1 -1
  89. package/dist/modal.styles.js +18 -13
  90. package/dist/modal.tertiary-icon.d.ts +0 -1
  91. package/dist/modal.tertiary-icon.js +1 -1
  92. package/dist/modal.tertiary-icon.test.basics.js +1 -1
  93. package/dist/modal.test.basics.js +1 -1
  94. package/dist/modal.test.events.js +10 -10
  95. package/dist/radio-group.js +1 -1
  96. package/dist/radio-group.styles.js +1 -1
  97. package/dist/radio-group.test.focus.js +3 -3
  98. package/dist/radio.d.ts +1 -0
  99. package/dist/radio.js +1 -1
  100. package/dist/radio.styles.js +33 -0
  101. package/dist/split-container.test.basics.js +4 -0
  102. package/dist/split-link.test.interactions.js +1 -1
  103. package/dist/styles/variables.css +1 -1
  104. package/dist/tab.d.ts +1 -1
  105. package/dist/tab.group.js +1 -1
  106. package/dist/tab.group.test.basics.js +1 -1
  107. package/dist/tab.group.test.interactions.js +198 -2
  108. package/dist/tab.js +1 -1
  109. package/dist/tab.panel.d.ts +1 -0
  110. package/dist/tab.panel.js +1 -1
  111. package/dist/tab.panel.styles.js +11 -1
  112. package/dist/tag.test.basics.js +2 -2
  113. package/dist/textarea.d.ts +0 -1
  114. package/dist/textarea.js +2 -2
  115. package/dist/textarea.stories.d.ts +3 -4
  116. package/dist/textarea.styles.js +14 -3
  117. package/dist/textarea.test.basics.js +80 -44
  118. package/dist/textarea.test.events.js +56 -41
  119. package/dist/textarea.test.translations.d.ts +1 -0
  120. package/dist/textarea.test.translations.js +34 -0
  121. package/dist/textarea.test.validity.js +104 -20
  122. package/dist/toasts.js +1 -1
  123. package/dist/toasts.styles.js +8 -1
  124. package/dist/toasts.test.basics.js +20 -0
  125. package/dist/toggle.js +1 -1
  126. package/dist/toggle.test.focus.js +1 -1
  127. package/dist/toggle.test.interactions.d.ts +1 -0
  128. package/dist/tooltip.d.ts +7 -5
  129. package/dist/tooltip.js +1 -1
  130. package/dist/tooltip.styles.js +90 -25
  131. package/dist/tooltip.test.basics.js +38 -3
  132. package/dist/tooltip.test.interactions.js +136 -34
  133. package/dist/translations/en.js +1 -1
  134. package/dist/translations/fr.js +1 -1
  135. package/dist/translations/ja.js +1 -1
  136. package/dist/tree.d.ts +0 -1
  137. package/dist/tree.item.d.ts +1 -2
  138. package/dist/tree.item.js +1 -1
  139. package/dist/tree.item.menu.d.ts +0 -1
  140. package/dist/tree.item.menu.js +1 -1
  141. package/dist/tree.js +1 -1
  142. package/dist/tree.test.basics.js +1 -1
  143. package/package.json +2 -4
  144. package/dist/drawer.test.floating-components.d.ts +0 -1
  145. package/dist/drawer.test.floating-components.js +0 -52
  146. package/dist/library/set-containing-block.d.ts +0 -15
  147. package/dist/library/set-containing-block.js +0 -1
  148. package/dist/modal.test.floating-components.js +0 -63
  149. /package/dist/{checkbox.test.states.d.ts → button-group.button.test.focus.d.ts} +0 -0
  150. /package/dist/{modal.test.floating-components.d.ts → checkbox.test.interactions.d.ts} +0 -0
  151. /package/dist/{toggle.test.states.d.ts → dropdown.test.events.filterable.d.ts} +0 -0
  152. /package/dist/{toggle.test.states.js → toggle.test.interactions.js} +0 -0
@@ -1,26 +1,23 @@
1
- import { LitElement, type PropertyValueMap } from 'lit';
2
- import GlideCoreButtonGroupButton from './button-group.button.js';
1
+ import { LitElement } from 'lit';
3
2
  declare global {
4
3
  interface HTMLElementTagNameMap {
5
4
  'glide-core-button-group': GlideCoreButtonGroup;
6
5
  }
7
6
  }
8
- export type ButtonGroupVariant = 'icon-only';
9
- export type ButtonGroupOrientation = 'vertical' | 'horizontal';
10
7
  /**
11
- * @description A button group for use with `<glide-core-button-group-button>`.
8
+ * @description A button group.
12
9
  *
13
- * @slot - One or more `<glide-core-button-group-button>` components.
10
+ * @slot - One or more of `<glide-core-button-group-button>`.
14
11
  */
15
12
  export default class GlideCoreButtonGroup extends LitElement {
16
13
  #private;
17
14
  static shadowRootOptions: ShadowRootInit;
18
15
  static styles: import("lit").CSSResult[];
19
16
  label?: string | undefined;
20
- listItems: GlideCoreButtonGroupButton[];
21
- variant?: ButtonGroupVariant;
22
- orientation: ButtonGroupOrientation;
17
+ get variant(): 'icon-only' | undefined;
18
+ set variant(variant: 'icon-only' | undefined);
19
+ get orientation(): 'horizontal' | 'vertical';
20
+ set orientation(orientation: 'horizontal' | 'vertical');
23
21
  firstUpdated(): void;
24
22
  render(): import("lit").TemplateResult<1>;
25
- willUpdate(changedProperties: PropertyValueMap<GlideCoreButtonGroup>): void;
26
23
  }
@@ -1 +1 @@
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
+ var __decorate=this&&this.__decorate||function(t,e,o,n){var r,i=arguments.length,l=i<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,o):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(t,e,o,n);else for(var s=t.length-1;s>=0;s--)(r=t[s])&&(l=(i<3?r(l):i>3?r(e,o,l):r(e,o))||l);return i>3&&l&&Object.defineProperty(e,o,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 GlideCoreButtonGroupButton from"./button-group.button.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./button-group.styles.js";let GlideCoreButtonGroup=class GlideCoreButtonGroup extends LitElement{constructor(){super(...arguments),this.label="",this.#t="horizontal",this.#e=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get variant(){return this.#o}set variant(t){for(const e of this.#n)e.privateVariant=t;this.#o=t}get orientation(){return this.#t}set orientation(t){for(const e of this.#n)e.privateOrientation=t;this.#t=t}firstUpdated(){owSlot(this.#e.value),owSlotType(this.#e.value,[GlideCoreButtonGroupButton])}render(){return html`<div class="${classMap({component:!0,horizontal:"horizontal"===this.orientation,vertical:"vertical"===this.orientation})}"><div class="label" id="label" data-test="label">${this.label}</div><div aria-labelledby="label" role="radiogroup" class="${classMap({container:!0,vertical:"vertical"===this.orientation})}"><slot @click="${this.#r}" @keydown="${this.#i}" @private-selected="${this.#l}" @slotchange="${this.#s}" ${ref(this.#e)}></slot></div></div>`}#t;#e;#o;get#n(){return[...this.querySelectorAll("glide-core-button-group-button")]}#s(){ow(this.#n.length,ow.number.greaterThan(1).message("A Button Group must contain two or more Button Group Buttons.")),owSlot(this.#e.value),owSlotType(this.#e.value,[GlideCoreButtonGroupButton]);if(!this.#n.find((({disabled:t,selected:e})=>!t&&e))){const t=this.#n.find((({disabled:t})=>!t));t&&(t.selected=!0)}for(const t of this.#n)t.privateVariant=this.variant,this.orientation&&(t.privateOrientation=this.orientation)}#r(t){if(t.target instanceof HTMLElement){const e=t.target.closest("glide-core-button-group-button");!e||e.disabled||e.selected||(e.selected=!0)}}#i(t){const e=this.querySelector("glide-core-button-group-button[selected]");switch(ow(e,ow.object.instanceOf(GlideCoreButtonGroupButton)),t.key){case"ArrowUp":case"ArrowLeft":{t.preventDefault();let o=e?.previousElementSibling??this.#n.at(-1);for(;o instanceof GlideCoreButtonGroupButton&&o.disabled;)o=o.previousElementSibling??this.#n.at(-1);o instanceof GlideCoreButtonGroupButton&&(o.selected=!0);break}case"ArrowDown":case"ArrowRight":{t.preventDefault();let o=e?.nextElementSibling??this.#n.at(0);for(;o instanceof GlideCoreButtonGroupButton&&o.disabled;)o=o.nextElementSibling??this.#n.at(0);o instanceof GlideCoreButtonGroupButton&&(o.selected=!0);break}case" ":if(t.preventDefault(),t.target instanceof HTMLElement){const e=t.target.closest("glide-core-button-group-button");e&&!e.disabled&&(e.selected=!0)}}}#l(t){if(t.target instanceof GlideCoreButtonGroupButton&&t.target.selected){for(const e of this.#n)e!==t.target&&(e.selected=!1);t.target.focus(),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new Event("input",{bubbles:!0}))}}};__decorate([property({reflect:!0})],GlideCoreButtonGroup.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreButtonGroup.prototype,"variant",null),__decorate([property({reflect:!0})],GlideCoreButtonGroup.prototype,"orientation",null),GlideCoreButtonGroup=__decorate([customElement("glide-core-button-group")],GlideCoreButtonGroup);export default GlideCoreButtonGroup;
@@ -8,9 +8,5 @@ export declare const Default: StoryObj;
8
8
  export declare const DefaultWithOrientationVertical: StoryObj;
9
9
  export declare const DefaultWithPrefixIcon: StoryObj;
10
10
  export declare const DefaultWithOrientationVerticalPrefixIcon: StoryObj;
11
- export declare const DefaultWithVariantIconOnly: StoryObj;
11
+ export declare const DefaultWithIconOnly: StoryObj;
12
12
  export declare const DefaultWithOrientationVerticalOnlyIcon: StoryObj;
13
- export declare const DefaultWithNoneSelected: StoryObj;
14
- export declare const DefaultWithSelected: StoryObj;
15
- export declare const DefaultWithDisabled: StoryObj;
16
- export declare const DefaultWithOneButton: StoryObj;
@@ -1,8 +1,24 @@
1
1
  import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
2
- .radio-group {
3
- appearance: none;
2
+ .component {
4
3
  border: 1px solid var(--glide-core-border-base);
5
4
  border-radius: 0.75rem;
5
+ display: inline-block;
6
+ }
7
+
8
+ .label {
9
+ /*
10
+ Colored to pass the contrast check in the "is accessible" test. It's visually
11
+ hidden and doesn't need to meet contrast requirements. But the alternative
12
+ is to add "ignoredRules: ['color-contrast']" to that test, disabling contrast
13
+ checking for the entire component.
14
+ */
15
+ color: var(--glide-core-color-white);
16
+
17
+ ${visuallyHidden};
18
+ }
19
+
20
+ .container {
21
+ appearance: none;
6
22
  display: inline-flex;
7
23
  margin: 0;
8
24
  padding: 0;
@@ -11,8 +27,4 @@ import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";exp
11
27
  flex-direction: column;
12
28
  }
13
29
  }
14
-
15
- .label {
16
- ${visuallyHidden};
17
- }
18
30
  `];
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
2
  import './button-group.js';
3
- import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
3
+ import { expect, fixture, html } from '@open-wc/testing';
4
4
  import GlideCoreButtonGroup from './button-group.js';
5
5
  import GlideCoreButtonGroupButton from './button-group.button.js';
6
6
  import expectArgumentError from './library/expect-argument-error.js';
@@ -9,261 +9,140 @@ GlideCoreButtonGroupButton.shadowRootOptions.mode = 'open';
9
9
  it('registers', async () => {
10
10
  expect(window.customElements.get('glide-core-button-group')).to.equal(GlideCoreButtonGroup);
11
11
  });
12
- it('is accessible', async () => {
13
- const element = await fixture(html `<glide-core-button-group label="label"
14
- ><glide-core-button-group-button value="value"
15
- >Button</glide-core-button-group-button
16
- ></glide-core-button-group
17
- >`);
18
- await expect(element).to.be.accessible();
19
- });
20
- it('renders a label and unordered list', async () => {
21
- const element = await fixture(html `<glide-core-button-group label="label"
22
- ><glide-core-button-group-button value="value"
23
- >Button</glide-core-button-group-button
24
- ></glide-core-button-group
25
- >`);
26
- const ulElement = element.shadowRoot?.querySelector('ul');
27
- const labelElement = element.shadowRoot?.querySelector('div.label');
28
- expect(ulElement).to.not.be.null;
29
- expect(labelElement).to.not.be.null;
30
- expect(ulElement).to.have.attribute('aria-labelledby', labelElement?.id);
31
- });
32
- it('does not render a label when not given', async () => {
33
- const element = await fixture(html `<glide-core-button-group
34
- ><glide-core-button-group-button value="value"
35
- >Button</glide-core-button-group-button
36
- ></glide-core-button-group
37
- >`);
38
- const ulElement = element.shadowRoot?.querySelector('ul');
39
- const labelElement = element.shadowRoot?.querySelector('label');
40
- expect(ulElement).to.not.be.null;
41
- expect(labelElement).to.be.null;
42
- });
43
- it('assigns buttons the correct positional presentation when in a group', async () => {
44
- await fixture(html `<glide-core-button-group>
45
- <glide-core-button-group-button value="value-1"
46
- >Button 1</glide-core-button-group-button
47
- >
48
- <glide-core-button-group-button value="value-2"
49
- >Button 2</glide-core-button-group-button
50
- >
51
- <glide-core-button-group-button value="value-3"
52
- >Button 3</glide-core-button-group-button
53
- >
54
- <glide-core-button-group-button value="value-4"
55
- >Button 4</glide-core-button-group-button
56
- >
12
+ it('has defaults', async () => {
13
+ const component = await fixture(html `<glide-core-button-group label="Label">
14
+ <glide-core-button-group-button
15
+ label="One"
16
+ ></glide-core-button-group-button>
17
+
18
+ <glide-core-button-group-button
19
+ label="Two"
20
+ ></glide-core-button-group-button>
57
21
  </glide-core-button-group>`);
58
- const buttonElements = document.querySelectorAll('glide-core-button-group-button');
59
- expect(buttonElements.length).to.equal(4);
60
- const liElement1 = buttonElements[0].shadowRoot?.querySelector('li');
61
- expect(liElement1).to.have.class('first');
62
- const liElement2 = buttonElements[1].shadowRoot?.querySelector('li');
63
- expect(liElement2).to.have.class('inner');
64
- const liElement3 = buttonElements[2].shadowRoot?.querySelector('li');
65
- expect(liElement3).to.have.class('inner');
66
- const liElement4 = buttonElements[3].shadowRoot?.querySelector('li');
67
- expect(liElement4).to.have.class('last');
22
+ expect(component.orientation).to.equal('horizontal');
23
+ expect(component.variant).to.equal(undefined);
24
+ expect(component).to.have.attribute('orientation', 'horizontal');
25
+ expect(component).to.not.have.attribute('variant');
68
26
  });
69
- it('buttons have a vertical presention when attribute "orientation" is set to "vertical"', async () => {
70
- await fixture(html `<glide-core-button-group orientation="vertical"
71
- ><glide-core-button-group-button value="value"
72
- >Button</glide-core-button-group-button
73
- >
74
- <glide-core-button-group-button value="value-2"
75
- >Button 2</glide-core-button-group-button
76
- >
27
+ it('is accessible', async () => {
28
+ const component = await fixture(html `<glide-core-button-group label="label">
29
+ <glide-core-button-group-button
30
+ label="One"
31
+ ></glide-core-button-group-button>
32
+
33
+ <glide-core-button-group-button
34
+ label="Two"
35
+ ></glide-core-button-group-button>
77
36
  </glide-core-button-group>`);
78
- const buttonElements = document.querySelectorAll('glide-core-button-group-button');
79
- const liElement1 = buttonElements[0]?.shadowRoot?.querySelector('li');
80
- const liElement2 = buttonElements[1]?.shadowRoot?.querySelector('li');
81
- expect(buttonElements[0]).to.have.attribute('vertical');
82
- expect(liElement1).to.have.class('vertical');
83
- expect(buttonElements[1]).to.have.attribute('vertical');
84
- expect(liElement2).to.have.class('vertical');
37
+ // It's unfortunate to ignore this rule. But the label doesn't meet color
38
+ // contrast requirements.
39
+ // Axe has an `ignoreTags` but no `ignoreSelectors`.
40
+ await expect(component).to.be.accessible({
41
+ ignoredRules: ['color-contrast'],
42
+ });
85
43
  });
86
- it('does not have a vertical presention when the "orientation" is not set to "vertical"', async () => {
87
- await fixture(html `<glide-core-button-group label="label">
88
- <glide-core-button-group-button value="value"
89
- >Button</glide-core-button-group-button
90
- >
91
- <glide-core-button-group-button value="value-2"
92
- >Button 2</glide-core-button-group-button
93
- >
44
+ it('can have a label', async () => {
45
+ const component = await fixture(html `<glide-core-button-group label="label">
46
+ <glide-core-button-group-button
47
+ label="One"
48
+ ></glide-core-button-group-button>
49
+
50
+ <glide-core-button-group-button
51
+ label="Two"
52
+ ></glide-core-button-group-button>
94
53
  </glide-core-button-group>`);
95
- const buttonElements = document.querySelectorAll('glide-core-button-group-button');
96
- const liElement1 = buttonElements[0]?.shadowRoot?.querySelector('li');
97
- const liElement2 = buttonElements[1]?.shadowRoot?.querySelector('li');
98
- expect(buttonElements[0]).to.not.have.attribute('vertical');
99
- expect(liElement1).to.not.have.class('vertical');
100
- expect(buttonElements[1]).to.not.have.attribute('vertical');
101
- expect(liElement2).to.not.have.class('vertical');
102
- });
103
- it('reacts to "orientation" attribute when changed from "horizontal" to "vertical"', async () => {
104
- const element = await fixture(html `<glide-core-button-group label="label" orientation="horizontal"
105
- ><glide-core-button-group-button value="value"
106
- >Button</glide-core-button-group-button
107
- ></glide-core-button-group
108
- >`);
109
- const buttonElement = document.querySelector('glide-core-button-group-button');
110
- const liElement = buttonElement?.shadowRoot?.querySelector('li');
111
- expect(liElement).to.not.have.class('vertical');
112
- element.setAttribute('orientation', 'vertical');
113
- // wait for attributes to be set on li
114
- await elementUpdated(element);
115
- expect(liElement).to.have.class('vertical');
116
- element.setAttribute('orientation', 'horizontal');
117
- // wait for attributes to be set on li
118
- await elementUpdated(element);
119
- await expect(liElement).to.not.have.class('vertical');
54
+ const label = component.shadowRoot?.querySelector('[data-test="label"]');
55
+ const radioGroup = component.shadowRoot?.querySelector('[role="radiogroup"]');
56
+ expect(label?.textContent).to.equal('label');
57
+ expect(radioGroup).to.have.attribute('aria-labelledby', label?.id);
120
58
  });
121
- it('applies an "icon-only" variant to buttons when set on the group', async () => {
122
- await fixture(html `<glide-core-button-group label="label" variant="icon-only"
123
- ><glide-core-button-group-button value="value"
124
- ><span slot="prefix">Prefix 1</span>Button
125
- 1</glide-core-button-group-button
126
- >
127
- <glide-core-button-group-button value="value-2"
128
- ><span slot="prefix">Prefix 2</span>Button
129
- 2</glide-core-button-group-button
130
- >
59
+ it('sets the orientation of each button when horizontal', async () => {
60
+ await fixture(html `<glide-core-button-group>
61
+ <glide-core-button-group-button
62
+ label="One"
63
+ ></glide-core-button-group-button>
64
+
65
+ <glide-core-button-group-button
66
+ label="Two"
67
+ ></glide-core-button-group-button>
131
68
  </glide-core-button-group>`);
132
- const buttonElements = document.querySelectorAll('glide-core-button-group-button');
133
- const liElement1 = buttonElements[0]?.shadowRoot?.querySelector('li');
134
- const liElement2 = buttonElements[1]?.shadowRoot?.querySelector('li');
135
- expect(buttonElements[0]).to.have.attribute('variant', 'icon-only');
136
- expect(liElement1).to.have.class('icon-only');
137
- expect(buttonElements[1]).to.have.attribute('variant', 'icon-only');
138
- expect(liElement2).to.have.class('icon-only');
139
- });
140
- it('does not apply an "icon-only" variant to buttons when not set on the group', async () => {
141
- await fixture(html `<glide-core-button-group label="label"
142
- ><glide-core-button-group-button value="value"
143
- >Button</glide-core-button-group-button
144
- >
145
- <glide-core-button-group-button value="value-2"
146
- >Button 2</glide-core-button-group-button
147
- >
69
+ const buttons = document.querySelectorAll('glide-core-button-group-button');
70
+ expect(buttons[0]?.privateOrientation).to.equal('horizontal');
71
+ expect(buttons[1]?.privateOrientation).to.equal('horizontal');
72
+ });
73
+ it('sets the orientation of each button when vertical', async () => {
74
+ await fixture(html `<glide-core-button-group orientation="vertical">
75
+ <glide-core-button-group-button
76
+ label="One"
77
+ ></glide-core-button-group-button>
78
+
79
+ <glide-core-button-group-button
80
+ label="Two"
81
+ ></glide-core-button-group-button>
148
82
  </glide-core-button-group>`);
149
- const buttonElements = document.querySelectorAll('glide-core-button-group-button');
150
- const liElement1 = buttonElements[0]?.shadowRoot?.querySelector('li');
151
- const liElement2 = buttonElements[1]?.shadowRoot?.querySelector('li');
152
- expect(buttonElements[0]).to.not.have.attribute('variant');
153
- expect(liElement1).to.not.have.class('icon-only');
154
- expect(buttonElements[1]).to.not.have.attribute('variant');
155
- expect(liElement2).to.not.have.class('icon-only');
156
- });
157
- it('reacts to variant "icon-only" attribute when added and removed', async () => {
158
- await fixture(html `<glide-core-button-group label="label"
159
- ><glide-core-button-group-button value="value"
160
- ><span slot="prefix">Prefix</span>Button</glide-core-button-group-button
161
- ></glide-core-button-group
162
- >`);
163
- const element = document.querySelector('glide-core-button-group');
164
- const buttonElement = document.querySelector('glide-core-button-group-button');
165
- expect(element).to.not.be.null;
166
- expect(buttonElement).to.not.be.null;
167
- expect(buttonElement).to.not.have.attribute('variant');
168
- element?.setAttribute('variant', 'icon-only');
169
- // wait for attributes to be set
170
- await elementUpdated(element);
171
- expect(buttonElement).to.have.attribute('variant', 'icon-only');
172
- element?.removeAttribute('variant');
173
- // wait for attributes to be set
174
- await elementUpdated(element);
175
- expect(buttonElement).to.not.have.attribute('variant');
83
+ const buttons = document.querySelectorAll('glide-core-button-group-button');
84
+ expect(buttons[0]?.privateOrientation).to.equal('vertical');
85
+ expect(buttons[1]?.privateOrientation).to.equal('vertical');
86
+ });
87
+ it('sets `privateVariant` on each button', async () => {
88
+ await fixture(html `<glide-core-button-group label="label" variant="icon-only">
89
+ <glide-core-button-group-button label="One">
90
+ <div slot="prefix">Prefix</div>
91
+ </glide-core-button-group-button>
92
+
93
+ <glide-core-button-group-button label="Two">
94
+ <div slot="prefix">Prefix</div>
95
+ </glide-core-button-group-button>
96
+ </glide-core-button-group>`);
97
+ const buttons = document.querySelectorAll('glide-core-button-group-button');
98
+ expect(buttons[0].privateVariant).to.equal('icon-only');
99
+ expect(buttons[1].privateVariant).to.equal('icon-only');
176
100
  });
177
- it('throws an error when an element other than `glide-core-button-group-button` is a child of the default slot', async () => {
101
+ it('throws when its default slot is the wrong type', async () => {
178
102
  await expectArgumentError(() => {
179
103
  return fixture(html `
180
104
  <glide-core-button-group label="label">
181
- <div>Content</div>
105
+ <div></div>
182
106
  </glide-core-button-group>
183
107
  `);
184
108
  });
185
- });
186
- it('throws an error when the group has no children', async () => {
187
109
  await expectArgumentError(() => {
188
110
  return fixture(html `<glide-core-button-group label="label"> </glide-core-button-group>`);
189
111
  });
190
112
  });
191
- it("has a tabble button if it's the first element in a button group", async () => {
192
- await fixture(html `<glide-core-button-group>
193
- <glide-core-button-group-button value="value-1"
194
- >Button 1</glide-core-button-group-button
195
- >
196
- <glide-core-button-group-button value="value-2"
197
- >Button 2</glide-core-button-group-button
198
- >
199
- <glide-core-button-group-button value="value-3"
200
- >Button 3</glide-core-button-group-button
201
- >
202
- </glide-core-button-group>`);
203
- const buttonElements = document.querySelectorAll('glide-core-button-group-button');
204
- expect(buttonElements.length).to.equal(3);
205
- const liElement1 = buttonElements[0].shadowRoot?.querySelector('li');
206
- expect(liElement1).to.have.attribute('tabindex', '0');
207
- const liElement2 = buttonElements[1].shadowRoot?.querySelector('li');
208
- expect(liElement2).to.have.attribute('tabindex', '-1');
209
- const liElement3 = buttonElements[2].shadowRoot?.querySelector('li');
210
- expect(liElement3).to.have.attribute('tabindex', '-1');
211
- });
212
- it('has the first non-disabled button set as tabbable when in a group', async () => {
213
- await fixture(html `<glide-core-button-group>
214
- <glide-core-button-group-button value="value-1" disabled
215
- >Button 1</glide-core-button-group-button
216
- >
217
- <glide-core-button-group-button value="value-2"
218
- >Button 2</glide-core-button-group-button
219
- >
220
- <glide-core-button-group-button value="value-3"
221
- >Button 3</glide-core-button-group-button
222
- >
223
- </glide-core-button-group>`);
224
- const buttonElements = document.querySelectorAll('glide-core-button-group-button');
225
- expect(buttonElements.length).to.equal(3);
226
- const liElement1 = buttonElements[0].shadowRoot?.querySelector('li');
227
- expect(liElement1).to.have.attribute('tabindex', '-1');
228
- const liElement2 = buttonElements[1].shadowRoot?.querySelector('li');
229
- expect(liElement2).to.have.attribute('tabindex', '0');
230
- const liElement3 = buttonElements[2].shadowRoot?.querySelector('li');
231
- expect(liElement3).to.have.attribute('tabindex', '-1');
232
- });
233
- it('has the "selected" button as tabbable and others are not when in a group', async () => {
113
+ it('selects the first button not disabled', async () => {
234
114
  await fixture(html `<glide-core-button-group>
235
- <glide-core-button-group-button value="value-1"
236
- >Button 1</glide-core-button-group-button
237
- >
238
- <glide-core-button-group-button value="value-2" selected
239
- >Button 2</glide-core-button-group-button
240
- >
241
- <glide-core-button-group-button value="value-3"
242
- >Button 3</glide-core-button-group-button
243
- >
115
+ <glide-core-button-group-button
116
+ label="One"
117
+ disabled
118
+ ></glide-core-button-group-button>
119
+
120
+ <glide-core-button-group-button
121
+ label="Two"
122
+ ></glide-core-button-group-button>
123
+
124
+ <glide-core-button-group-button
125
+ label="Three"
126
+ ></glide-core-button-group-button>
244
127
  </glide-core-button-group>`);
245
- const buttonElements = document.querySelectorAll('glide-core-button-group-button');
246
- expect(buttonElements.length).to.equal(3);
247
- const liElement1 = buttonElements[0].shadowRoot?.querySelector('li');
248
- expect(liElement1).to.have.attribute('tabindex', '-1');
249
- const liElement2 = buttonElements[1].shadowRoot?.querySelector('li');
250
- expect(liElement2).to.have.attribute('tabindex', '0');
251
- const liElement3 = buttonElements[2].shadowRoot?.querySelector('li');
252
- expect(liElement3).to.have.attribute('tabindex', '-1');
128
+ const buttons = document.querySelectorAll('glide-core-button-group-button');
129
+ expect(buttons[0].selected).to.be.false;
130
+ expect(buttons[1].selected).to.be.true;
131
+ expect(buttons[2].selected).to.be.false;
253
132
  });
254
- it('initially no button sets itself as tabbable if all are disabled in a group', async () => {
133
+ it('selects no buttons when all are disabled', async () => {
255
134
  await fixture(html `<glide-core-button-group>
256
- <glide-core-button-group-button value="value-1" disabled
257
- >Button 1</glide-core-button-group-button
258
- >
259
- <glide-core-button-group-button value="value-2" disabled
260
- >Button 2</glide-core-button-group-button
261
- >
135
+ <glide-core-button-group-button
136
+ label="One"
137
+ disabled
138
+ ></glide-core-button-group-button>
139
+
140
+ <glide-core-button-group-button
141
+ label="Two"
142
+ disabled
143
+ ></glide-core-button-group-button>
262
144
  </glide-core-button-group>`);
263
- const buttonElements = document.querySelectorAll('glide-core-button-group-button');
264
- expect(buttonElements.length).to.equal(2);
265
- const liElement1 = buttonElements[0].shadowRoot?.querySelector('li');
266
- expect(liElement1).to.have.attribute('tabindex', '-1');
267
- const liElement2 = buttonElements[1].shadowRoot?.querySelector('li');
268
- expect(liElement2).to.have.attribute('tabindex', '-1');
145
+ const buttons = document.querySelectorAll('glide-core-button-group-button');
146
+ expect(buttons[0].selected).to.be.false;
147
+ expect(buttons[1].selected).to.be.false;
269
148
  });