@crowdstrike/glide-core 0.7.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.
- package/README.md +44 -5
- package/dist/accordion.test.basics.js +1 -0
- package/dist/accordion.test.events.js +1 -0
- package/dist/button-group.button.d.ts +14 -15
- package/dist/button-group.button.js +1 -1
- package/dist/button-group.button.styles.js +75 -52
- package/dist/button-group.button.test.basics.d.ts +1 -1
- package/dist/button-group.button.test.basics.js +84 -147
- package/dist/button-group.button.test.events.js +9 -67
- package/dist/button-group.button.test.focus.js +13 -0
- package/dist/button-group.button.test.interactions.d.ts +1 -0
- package/dist/button-group.button.test.interactions.js +42 -0
- package/dist/button-group.d.ts +7 -10
- package/dist/button-group.js +1 -1
- package/dist/button-group.stories.d.ts +1 -5
- package/dist/button-group.styles.js +18 -6
- package/dist/button-group.test.basics.js +114 -234
- package/dist/button-group.test.events.js +211 -263
- package/dist/button-group.test.focus.d.ts +1 -0
- package/dist/button-group.test.focus.js +39 -0
- package/dist/button-group.test.interactions.d.ts +1 -0
- package/dist/button-group.test.interactions.js +91 -0
- package/dist/button.test.basics.js +2 -1
- package/dist/button.test.events.js +1 -0
- package/dist/button.test.form.js +1 -0
- package/dist/checkbox-group.js +1 -1
- package/dist/checkbox-group.styles.js +1 -1
- package/dist/checkbox-group.test.basics.js +2 -1
- package/dist/checkbox-group.test.events.js +5 -4
- package/dist/checkbox-group.test.focus.js +5 -3
- package/dist/checkbox-group.test.form.js +1 -0
- package/dist/checkbox-group.test.validity.js +1 -0
- package/dist/checkbox.d.ts +7 -1
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.styles.js +11 -3
- package/dist/checkbox.test.basics.js +1 -0
- package/dist/checkbox.test.events.js +5 -4
- package/dist/checkbox.test.focus.js +2 -2
- package/dist/checkbox.test.form.js +1 -0
- package/dist/{checkbox.test.states.js → checkbox.test.interactions.js} +25 -1
- package/dist/checkbox.test.validity.js +1 -0
- package/dist/drawer.js +1 -1
- package/dist/drawer.test.basics.js +1 -0
- package/dist/drawer.test.closing.js +1 -0
- package/dist/drawer.test.events.js +1 -0
- package/dist/drawer.test.methods.js +1 -0
- package/dist/dropdown.d.ts +6 -4
- package/dist/dropdown.js +1 -1
- package/dist/dropdown.option.d.ts +7 -2
- package/dist/dropdown.option.js +1 -1
- package/dist/dropdown.option.styles.js +13 -0
- package/dist/dropdown.option.test.basics.js +7 -3
- package/dist/dropdown.option.test.basics.multiple.js +1 -0
- package/dist/dropdown.option.test.basics.single.js +1 -0
- package/dist/dropdown.option.test.events.js +2 -1
- package/dist/dropdown.option.test.focus.js +1 -1
- package/dist/dropdown.option.test.interactions.multiple.js +2 -54
- package/dist/dropdown.option.test.interactions.single.js +52 -9
- package/dist/dropdown.styles.js +20 -19
- package/dist/dropdown.test.basics.filterable.js +1 -0
- package/dist/dropdown.test.basics.js +144 -2
- package/dist/dropdown.test.basics.multiple.js +6 -3
- package/dist/dropdown.test.basics.single.js +1 -1
- package/dist/dropdown.test.events.filterable.js +74 -0
- package/dist/dropdown.test.events.js +50 -160
- package/dist/dropdown.test.events.multiple.js +268 -10
- package/dist/dropdown.test.events.single.js +202 -4
- package/dist/dropdown.test.focus.filterable.js +9 -5
- package/dist/dropdown.test.focus.js +2 -1
- package/dist/dropdown.test.focus.multiple.js +1 -2
- package/dist/dropdown.test.focus.single.js +1 -1
- package/dist/dropdown.test.form.js +1 -0
- package/dist/dropdown.test.form.multiple.js +1 -0
- package/dist/dropdown.test.form.single.js +1 -0
- package/dist/dropdown.test.interactions.filterable.js +69 -11
- package/dist/dropdown.test.interactions.js +95 -5
- package/dist/dropdown.test.interactions.multiple.js +203 -6
- package/dist/dropdown.test.interactions.single.js +69 -6
- package/dist/dropdown.test.validity.js +1 -0
- package/dist/form-controls-layout.test.basics.js +2 -1
- package/dist/icon-button.test.basics.js +2 -1
- package/dist/icons/checked.d.ts +1 -1
- package/dist/icons/checked.js +1 -1
- package/dist/icons/magnifying-glass.js +1 -1
- package/dist/input.d.ts +0 -6
- package/dist/input.js +1 -1
- package/dist/input.styles.js +7 -2
- package/dist/input.test.basics.js +20 -5
- package/dist/input.test.events.js +5 -4
- package/dist/input.test.focus.js +5 -4
- package/dist/input.test.form.js +1 -0
- package/dist/input.test.translations.d.ts +1 -0
- package/dist/input.test.translations.js +38 -0
- package/dist/input.test.validity.js +134 -4
- package/dist/label.d.ts +1 -1
- package/dist/label.js +1 -1
- package/dist/label.styles.js +29 -20
- package/dist/label.test.basics.js +27 -24
- package/dist/library/expect-argument-error.js +1 -1
- package/dist/library/localize.d.ts +5 -1
- package/dist/library/ow.test.d.ts +2 -1
- package/dist/library/ow.test.js +8 -3
- package/dist/menu.button.test.basics.js +1 -0
- package/dist/menu.d.ts +3 -5
- package/dist/menu.js +1 -1
- package/dist/menu.link.test.basics.js +1 -0
- package/dist/menu.options.test.basics.js +3 -2
- package/dist/menu.styles.js +1 -15
- package/dist/menu.test.basics.d.ts +1 -2
- package/dist/menu.test.basics.js +23 -6
- package/dist/menu.test.events.d.ts +1 -0
- package/dist/menu.test.events.js +2 -1
- package/dist/menu.test.focus.d.ts +1 -0
- package/dist/menu.test.focus.js +14 -6
- package/dist/menu.test.interactions.js +213 -56
- package/dist/modal.icon-button.test.basics.js +2 -1
- package/dist/modal.js +1 -1
- package/dist/modal.styles.js +18 -13
- package/dist/modal.tertiary-icon.d.ts +0 -1
- package/dist/modal.tertiary-icon.js +1 -1
- package/dist/modal.tertiary-icon.test.basics.js +2 -1
- package/dist/modal.test.accessibility.js +1 -0
- package/dist/modal.test.basics.js +2 -1
- package/dist/modal.test.close.js +1 -0
- package/dist/modal.test.events.js +11 -10
- package/dist/modal.test.lock-scroll.js +1 -0
- package/dist/modal.test.methods.js +1 -0
- package/dist/modal.test.scrollbars.js +1 -0
- package/dist/radio-group.js +1 -1
- package/dist/radio-group.styles.js +1 -1
- package/dist/radio-group.test.basics.js +1 -0
- package/dist/radio-group.test.events.js +1 -0
- package/dist/radio-group.test.focus.js +4 -3
- package/dist/radio-group.test.form.js +1 -0
- package/dist/radio-group.test.validity.js +1 -0
- package/dist/radio.d.ts +1 -0
- package/dist/radio.js +1 -1
- package/dist/radio.styles.js +33 -0
- package/dist/split-button.test.basics.js +1 -0
- package/dist/split-container.test.basics.js +5 -0
- package/dist/split-link.test.basics.js +1 -0
- package/dist/split-link.test.interactions.js +2 -1
- package/dist/styles/variables.css +1 -1
- package/dist/tab.d.ts +1 -3
- package/dist/tab.group.d.ts +3 -5
- package/dist/tab.group.js +1 -1
- package/dist/tab.group.styles.js +27 -13
- package/dist/tab.group.test.basics.js +8 -57
- package/dist/tab.group.test.interactions.d.ts +3 -0
- package/dist/tab.group.test.interactions.js +454 -0
- package/dist/tab.js +1 -1
- package/dist/tab.panel.d.ts +1 -0
- package/dist/tab.panel.js +1 -1
- package/dist/tab.panel.styles.js +11 -1
- package/dist/tab.styles.js +7 -68
- package/dist/tab.test.basics.js +0 -20
- package/dist/tabs.stories.d.ts +1 -2
- package/dist/tag.test.basics.js +3 -2
- package/dist/textarea.d.ts +0 -1
- package/dist/textarea.js +2 -2
- package/dist/textarea.stories.d.ts +3 -4
- package/dist/textarea.styles.js +14 -3
- package/dist/textarea.test.basics.js +81 -44
- package/dist/textarea.test.events.js +57 -41
- package/dist/textarea.test.form.js +1 -0
- package/dist/textarea.test.translations.d.ts +1 -0
- package/dist/textarea.test.translations.js +34 -0
- package/dist/textarea.test.validity.js +105 -20
- package/dist/toasts.js +1 -1
- package/dist/toasts.styles.js +8 -1
- package/dist/toasts.test.basics.js +20 -0
- package/dist/toggle.js +1 -1
- package/dist/toggle.test.basics.js +1 -0
- package/dist/toggle.test.events.js +1 -0
- package/dist/toggle.test.focus.js +1 -1
- package/dist/toggle.test.interactions.d.ts +1 -0
- package/dist/{toggle.test.states.js → toggle.test.interactions.js} +1 -0
- package/dist/tooltip.d.ts +7 -5
- package/dist/tooltip.js +1 -1
- package/dist/tooltip.styles.js +90 -25
- package/dist/tooltip.test.basics.js +39 -3
- package/dist/tooltip.test.interactions.js +137 -34
- package/dist/translations/en.js +1 -1
- package/dist/translations/fr.js +1 -1
- package/dist/translations/ja.js +1 -1
- package/dist/tree.d.ts +0 -1
- package/dist/tree.item.d.ts +2 -3
- package/dist/tree.item.js +1 -1
- package/dist/tree.item.menu.d.ts +0 -1
- package/dist/tree.item.menu.js +1 -1
- package/dist/tree.item.test.basics.js +1 -0
- package/dist/tree.js +1 -1
- package/dist/tree.test.basics.js +2 -1
- package/dist/tree.test.events.js +1 -1
- package/package.json +40 -29
- package/dist/drawer.test.floating-components.d.ts +0 -1
- package/dist/drawer.test.floating-components.js +0 -51
- package/dist/library/set-containing-block.d.ts +0 -15
- package/dist/library/set-containing-block.js +0 -1
- package/dist/modal.test.floating-components.js +0 -62
- /package/dist/{checkbox.test.states.d.ts → button-group.button.test.focus.d.ts} +0 -0
- /package/dist/{modal.test.floating-components.d.ts → checkbox.test.interactions.d.ts} +0 -0
- /package/dist/{toggle.test.states.d.ts → dropdown.test.events.filterable.d.ts} +0 -0
@@ -1,73 +1,15 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
1
2
|
import './button-group.button.js';
|
2
3
|
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
|
3
|
-
import { sendKeys } from '@web/test-runner-commands';
|
4
4
|
import GlideCoreButtonGroupButton from './button-group.button.js';
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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.
|
5
|
+
it('emits a "private-selected" event when selected', async () => {
|
6
|
+
const component = await fixture(html `<glide-core-button-group-button
|
7
|
+
label="Button"
|
8
|
+
></glide-core-button-group-button>`);
|
15
9
|
setTimeout(() => {
|
16
|
-
|
10
|
+
component.selected = true;
|
17
11
|
});
|
18
|
-
const
|
19
|
-
expect(
|
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;
|
12
|
+
const event = await oneEvent(component, 'private-selected');
|
13
|
+
expect(event instanceof Event).to.be.true;
|
14
|
+
expect(event.bubbles).to.be.true;
|
73
15
|
});
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
2
|
+
import GlideCoreButtonGroupButton from './button-group.button.js';
|
3
|
+
GlideCoreButtonGroupButton.shadowRootOptions.mode = 'open';
|
4
|
+
it('focuses itself when `focus()` is called ', async () => {
|
5
|
+
const component = await fixture(html `
|
6
|
+
<glide-core-button-group-button
|
7
|
+
label="Button"
|
8
|
+
></glide-core-button-group-button>
|
9
|
+
`);
|
10
|
+
component.focus();
|
11
|
+
const radio = component.shadowRoot?.querySelector('[role="radio"]');
|
12
|
+
expect(component.shadowRoot?.activeElement).to.equal(radio);
|
13
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
import './button-group.button.js';
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import './button-group.button.js';
|
2
|
+
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
|
3
|
+
import GlideCoreButtonGroupButton from './button-group.button.js';
|
4
|
+
GlideCoreButtonGroupButton.shadowRootOptions.mode = 'open';
|
5
|
+
it('sets `aria-checked` when selected programmatically', async () => {
|
6
|
+
const component = await fixture(html `<glide-core-button-group-button
|
7
|
+
label="Button"
|
8
|
+
></glide-core-button-group-button>`);
|
9
|
+
component.selected = true;
|
10
|
+
await elementUpdated(component);
|
11
|
+
const radio = component.shadowRoot?.querySelector('[role="radio"]');
|
12
|
+
expect(radio).to.have.attribute('aria-checked', 'true');
|
13
|
+
});
|
14
|
+
it('sets `aria-checked` when deselected programmatically', async () => {
|
15
|
+
const component = await fixture(html `<glide-core-button-group-button
|
16
|
+
label="Button"
|
17
|
+
selected
|
18
|
+
></glide-core-button-group-button>`);
|
19
|
+
component.selected = false;
|
20
|
+
await elementUpdated(component);
|
21
|
+
const radio = component.shadowRoot?.querySelector('[role="radio"]');
|
22
|
+
expect(radio).to.have.attribute('aria-checked', 'false');
|
23
|
+
});
|
24
|
+
it('sets `aria-disabled` when disabled programmatically', async () => {
|
25
|
+
const component = await fixture(html `<glide-core-button-group-button
|
26
|
+
label="Button"
|
27
|
+
></glide-core-button-group-button>`);
|
28
|
+
component.disabled = true;
|
29
|
+
await elementUpdated(component);
|
30
|
+
const radio = component.shadowRoot?.querySelector('[role="radio"]');
|
31
|
+
expect(radio).to.have.attribute('aria-disabled', 'true');
|
32
|
+
});
|
33
|
+
it('sets `aria-disabled` when enabled programmatically', async () => {
|
34
|
+
const component = await fixture(html `<glide-core-button-group-button
|
35
|
+
label="Button"
|
36
|
+
disabled
|
37
|
+
></glide-core-button-group-button>`);
|
38
|
+
component.disabled = false;
|
39
|
+
await elementUpdated(component);
|
40
|
+
const radio = component.shadowRoot?.querySelector('[role="radio"]');
|
41
|
+
expect(radio).to.have.attribute('aria-disabled', 'false');
|
42
|
+
});
|
package/dist/button-group.d.ts
CHANGED
@@ -1,26 +1,23 @@
|
|
1
|
-
import { LitElement
|
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
|
8
|
+
* @description A button group.
|
12
9
|
*
|
13
|
-
* @slot - One or more `<glide-core-button-group-button
|
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
|
-
|
21
|
-
variant
|
22
|
-
orientation:
|
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
|
}
|
package/dist/button-group.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(t,e,o,
|
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
|
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
|
-
.
|
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,5 +1,6 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
1
2
|
import './button-group.js';
|
2
|
-
import {
|
3
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
3
4
|
import GlideCoreButtonGroup from './button-group.js';
|
4
5
|
import GlideCoreButtonGroupButton from './button-group.button.js';
|
5
6
|
import expectArgumentError from './library/expect-argument-error.js';
|
@@ -8,261 +9,140 @@ GlideCoreButtonGroupButton.shadowRootOptions.mode = 'open';
|
|
8
9
|
it('registers', async () => {
|
9
10
|
expect(window.customElements.get('glide-core-button-group')).to.equal(GlideCoreButtonGroup);
|
10
11
|
});
|
11
|
-
it('
|
12
|
-
const
|
13
|
-
|
14
|
-
|
15
|
-
></glide-core-button-group
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
const element = await fixture(html `<glide-core-button-group label="label"
|
21
|
-
><glide-core-button-group-button value="value"
|
22
|
-
>Button</glide-core-button-group-button
|
23
|
-
></glide-core-button-group
|
24
|
-
>`);
|
25
|
-
const ulElement = element.shadowRoot?.querySelector('ul');
|
26
|
-
const labelElement = element.shadowRoot?.querySelector('div.label');
|
27
|
-
expect(ulElement).to.not.be.null;
|
28
|
-
expect(labelElement).to.not.be.null;
|
29
|
-
expect(ulElement).to.have.attribute('aria-labelledby', labelElement?.id);
|
30
|
-
});
|
31
|
-
it('does not render a label when not given', async () => {
|
32
|
-
const element = await fixture(html `<glide-core-button-group
|
33
|
-
><glide-core-button-group-button value="value"
|
34
|
-
>Button</glide-core-button-group-button
|
35
|
-
></glide-core-button-group
|
36
|
-
>`);
|
37
|
-
const ulElement = element.shadowRoot?.querySelector('ul');
|
38
|
-
const labelElement = element.shadowRoot?.querySelector('label');
|
39
|
-
expect(ulElement).to.not.be.null;
|
40
|
-
expect(labelElement).to.be.null;
|
41
|
-
});
|
42
|
-
it('assigns buttons the correct positional presentation when in a group', async () => {
|
43
|
-
await fixture(html `<glide-core-button-group>
|
44
|
-
<glide-core-button-group-button value="value-1"
|
45
|
-
>Button 1</glide-core-button-group-button
|
46
|
-
>
|
47
|
-
<glide-core-button-group-button value="value-2"
|
48
|
-
>Button 2</glide-core-button-group-button
|
49
|
-
>
|
50
|
-
<glide-core-button-group-button value="value-3"
|
51
|
-
>Button 3</glide-core-button-group-button
|
52
|
-
>
|
53
|
-
<glide-core-button-group-button value="value-4"
|
54
|
-
>Button 4</glide-core-button-group-button
|
55
|
-
>
|
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>
|
56
21
|
</glide-core-button-group>`);
|
57
|
-
|
58
|
-
expect(
|
59
|
-
|
60
|
-
expect(
|
61
|
-
const liElement2 = buttonElements[1].shadowRoot?.querySelector('li');
|
62
|
-
expect(liElement2).to.have.class('inner');
|
63
|
-
const liElement3 = buttonElements[2].shadowRoot?.querySelector('li');
|
64
|
-
expect(liElement3).to.have.class('inner');
|
65
|
-
const liElement4 = buttonElements[3].shadowRoot?.querySelector('li');
|
66
|
-
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');
|
67
26
|
});
|
68
|
-
it('
|
69
|
-
await fixture(html `<glide-core-button-group
|
70
|
-
|
71
|
-
|
72
|
-
>
|
73
|
-
|
74
|
-
|
75
|
-
|
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>
|
76
36
|
</glide-core-button-group>`);
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
expect(
|
81
|
-
|
82
|
-
|
83
|
-
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
|
+
});
|
84
43
|
});
|
85
|
-
it('
|
86
|
-
await fixture(html `<glide-core-button-group label="label">
|
87
|
-
<glide-core-button-group-button
|
88
|
-
|
89
|
-
>
|
90
|
-
|
91
|
-
|
92
|
-
|
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>
|
93
53
|
</glide-core-button-group>`);
|
94
|
-
const
|
95
|
-
const
|
96
|
-
|
97
|
-
expect(
|
98
|
-
expect(liElement1).to.not.have.class('vertical');
|
99
|
-
expect(buttonElements[1]).to.not.have.attribute('vertical');
|
100
|
-
expect(liElement2).to.not.have.class('vertical');
|
101
|
-
});
|
102
|
-
it('reacts to "orientation" attribute when changed from "horizontal" to "vertical"', async () => {
|
103
|
-
const element = await fixture(html `<glide-core-button-group label="label" orientation="horizontal"
|
104
|
-
><glide-core-button-group-button value="value"
|
105
|
-
>Button</glide-core-button-group-button
|
106
|
-
></glide-core-button-group
|
107
|
-
>`);
|
108
|
-
const buttonElement = document.querySelector('glide-core-button-group-button');
|
109
|
-
const liElement = buttonElement?.shadowRoot?.querySelector('li');
|
110
|
-
expect(liElement).to.not.have.class('vertical');
|
111
|
-
element.setAttribute('orientation', 'vertical');
|
112
|
-
// wait for attributes to be set on li
|
113
|
-
await elementUpdated(element);
|
114
|
-
expect(liElement).to.have.class('vertical');
|
115
|
-
element.setAttribute('orientation', 'horizontal');
|
116
|
-
// wait for attributes to be set on li
|
117
|
-
await elementUpdated(element);
|
118
|
-
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);
|
119
58
|
});
|
120
|
-
it('
|
121
|
-
await fixture(html `<glide-core-button-group
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
<glide-core-button-group-button
|
127
|
-
|
128
|
-
|
129
|
-
>
|
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>
|
130
68
|
</glide-core-button-group>`);
|
131
|
-
const
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
>
|
144
|
-
<glide-core-button-group-button value="value-2"
|
145
|
-
>Button 2</glide-core-button-group-button
|
146
|
-
>
|
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>
|
147
82
|
</glide-core-button-group>`);
|
148
|
-
const
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
>`);
|
162
|
-
const
|
163
|
-
|
164
|
-
expect(
|
165
|
-
expect(buttonElement).to.not.be.null;
|
166
|
-
expect(buttonElement).to.not.have.attribute('variant');
|
167
|
-
element?.setAttribute('variant', 'icon-only');
|
168
|
-
// wait for attributes to be set
|
169
|
-
await elementUpdated(element);
|
170
|
-
expect(buttonElement).to.have.attribute('variant', 'icon-only');
|
171
|
-
element?.removeAttribute('variant');
|
172
|
-
// wait for attributes to be set
|
173
|
-
await elementUpdated(element);
|
174
|
-
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');
|
175
100
|
});
|
176
|
-
it('throws
|
101
|
+
it('throws when its default slot is the wrong type', async () => {
|
177
102
|
await expectArgumentError(() => {
|
178
103
|
return fixture(html `
|
179
104
|
<glide-core-button-group label="label">
|
180
|
-
<div
|
105
|
+
<div></div>
|
181
106
|
</glide-core-button-group>
|
182
107
|
`);
|
183
108
|
});
|
184
|
-
});
|
185
|
-
it('throws an error when the group has no children', async () => {
|
186
109
|
await expectArgumentError(() => {
|
187
110
|
return fixture(html `<glide-core-button-group label="label"> </glide-core-button-group>`);
|
188
111
|
});
|
189
112
|
});
|
190
|
-
it(
|
191
|
-
await fixture(html `<glide-core-button-group>
|
192
|
-
<glide-core-button-group-button value="value-1"
|
193
|
-
>Button 1</glide-core-button-group-button
|
194
|
-
>
|
195
|
-
<glide-core-button-group-button value="value-2"
|
196
|
-
>Button 2</glide-core-button-group-button
|
197
|
-
>
|
198
|
-
<glide-core-button-group-button value="value-3"
|
199
|
-
>Button 3</glide-core-button-group-button
|
200
|
-
>
|
201
|
-
</glide-core-button-group>`);
|
202
|
-
const buttonElements = document.querySelectorAll('glide-core-button-group-button');
|
203
|
-
expect(buttonElements.length).to.equal(3);
|
204
|
-
const liElement1 = buttonElements[0].shadowRoot?.querySelector('li');
|
205
|
-
expect(liElement1).to.have.attribute('tabindex', '0');
|
206
|
-
const liElement2 = buttonElements[1].shadowRoot?.querySelector('li');
|
207
|
-
expect(liElement2).to.have.attribute('tabindex', '-1');
|
208
|
-
const liElement3 = buttonElements[2].shadowRoot?.querySelector('li');
|
209
|
-
expect(liElement3).to.have.attribute('tabindex', '-1');
|
210
|
-
});
|
211
|
-
it('has the first non-disabled button set as tabbable when in a group', async () => {
|
212
|
-
await fixture(html `<glide-core-button-group>
|
213
|
-
<glide-core-button-group-button value="value-1" disabled
|
214
|
-
>Button 1</glide-core-button-group-button
|
215
|
-
>
|
216
|
-
<glide-core-button-group-button value="value-2"
|
217
|
-
>Button 2</glide-core-button-group-button
|
218
|
-
>
|
219
|
-
<glide-core-button-group-button value="value-3"
|
220
|
-
>Button 3</glide-core-button-group-button
|
221
|
-
>
|
222
|
-
</glide-core-button-group>`);
|
223
|
-
const buttonElements = document.querySelectorAll('glide-core-button-group-button');
|
224
|
-
expect(buttonElements.length).to.equal(3);
|
225
|
-
const liElement1 = buttonElements[0].shadowRoot?.querySelector('li');
|
226
|
-
expect(liElement1).to.have.attribute('tabindex', '-1');
|
227
|
-
const liElement2 = buttonElements[1].shadowRoot?.querySelector('li');
|
228
|
-
expect(liElement2).to.have.attribute('tabindex', '0');
|
229
|
-
const liElement3 = buttonElements[2].shadowRoot?.querySelector('li');
|
230
|
-
expect(liElement3).to.have.attribute('tabindex', '-1');
|
231
|
-
});
|
232
|
-
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 () => {
|
233
114
|
await fixture(html `<glide-core-button-group>
|
234
|
-
<glide-core-button-group-button
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
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>
|
243
127
|
</glide-core-button-group>`);
|
244
|
-
const
|
245
|
-
expect(
|
246
|
-
|
247
|
-
expect(
|
248
|
-
const liElement2 = buttonElements[1].shadowRoot?.querySelector('li');
|
249
|
-
expect(liElement2).to.have.attribute('tabindex', '0');
|
250
|
-
const liElement3 = buttonElements[2].shadowRoot?.querySelector('li');
|
251
|
-
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;
|
252
132
|
});
|
253
|
-
it('
|
133
|
+
it('selects no buttons when all are disabled', async () => {
|
254
134
|
await fixture(html `<glide-core-button-group>
|
255
|
-
<glide-core-button-group-button
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
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>
|
261
144
|
</glide-core-button-group>`);
|
262
|
-
const
|
263
|
-
expect(
|
264
|
-
|
265
|
-
expect(liElement1).to.have.attribute('tabindex', '-1');
|
266
|
-
const liElement2 = buttonElements[1].shadowRoot?.querySelector('li');
|
267
|
-
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;
|
268
148
|
});
|