@crowdstrike/glide-core 0.9.0 → 0.9.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.
- package/dist/accordion.d.ts +7 -3
- package/dist/accordion.styles.js +2 -4
- package/dist/button-group.button.d.ts +1 -4
- package/dist/button-group.button.styles.js +4 -8
- package/dist/button-group.d.ts +3 -0
- package/dist/button-group.styles.js +2 -2
- package/dist/button.d.ts +4 -0
- package/dist/button.js +1 -1
- package/dist/button.styles.js +2 -4
- package/dist/button.test.events.js +86 -10
- package/dist/checkbox-group.d.ts +6 -2
- package/dist/checkbox-group.stories.d.ts +1 -1
- package/dist/checkbox.d.ts +5 -4
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.stories.d.ts +1 -1
- package/dist/checkbox.styles.js +43 -6
- package/dist/checkbox.test.basics.js +15 -6
- package/dist/checkbox.test.events.js +12 -4
- package/dist/checkbox.test.focus.js +1 -1
- package/dist/checkbox.test.form.js +17 -0
- package/dist/checkbox.test.interactions.js +52 -7
- package/dist/drawer.d.ts +5 -5
- package/dist/drawer.js +1 -1
- package/dist/drawer.stories.d.ts +0 -1
- package/dist/dropdown.d.ts +7 -4
- package/dist/dropdown.js +1 -1
- package/dist/dropdown.option.js +1 -1
- package/dist/dropdown.option.styles.js +1 -0
- package/dist/dropdown.styles.js +47 -26
- package/dist/dropdown.test.focus.filterable.js +20 -0
- package/dist/dropdown.test.focus.js +1 -0
- package/dist/dropdown.test.form.js +23 -112
- package/dist/dropdown.test.interactions.filterable.js +121 -17
- package/dist/dropdown.test.interactions.multiple.js +15 -22
- package/dist/dropdown.test.interactions.single.js +44 -22
- package/dist/icon-button.d.ts +2 -0
- package/dist/icon-button.styles.js +2 -4
- package/dist/icons/checked.d.ts +5 -0
- package/dist/icons/checked.js +1 -1
- package/dist/input.d.ts +5 -4
- package/dist/input.js +1 -1
- package/dist/input.stories.d.ts +0 -4
- package/dist/input.styles.d.ts +1 -1
- package/dist/input.styles.js +93 -93
- package/dist/input.test.basics.js +45 -45
- package/dist/input.test.form.js +17 -0
- package/dist/label.styles.js +11 -13
- package/dist/library/localize.d.ts +1 -0
- package/dist/library/localize.test.js +45 -0
- package/dist/menu.button.styles.js +1 -0
- package/dist/menu.js +1 -1
- package/dist/menu.link.styles.js +1 -0
- package/dist/menu.styles.js +3 -1
- package/dist/menu.test.events.js +101 -7
- package/dist/menu.test.focus.js +26 -3
- package/dist/menu.test.interactions.js +5 -2
- package/dist/modal.d.ts +0 -7
- package/dist/modal.icon-button.test.basics.js +9 -9
- package/dist/modal.stories.d.ts +1 -0
- package/dist/modal.styles.js +2 -4
- package/dist/modal.tertiary-icon.test.basics.js +15 -15
- package/dist/modal.test.accessibility.js +16 -27
- package/dist/modal.test.basics.js +64 -68
- package/dist/modal.test.close.js +12 -16
- package/dist/modal.test.events.js +32 -44
- package/dist/modal.test.lock-scroll.js +15 -25
- package/dist/modal.test.methods.js +8 -12
- package/dist/modal.test.scrollbars.js +2 -4
- package/dist/radio-group.d.ts +4 -3
- package/dist/radio-group.js +1 -1
- package/dist/radio-group.stories.d.ts +1 -1
- package/dist/radio-group.test.basics.js +3 -3
- package/dist/radio-group.test.events.js +6 -6
- package/dist/radio-group.test.form.js +19 -0
- package/dist/radio.d.ts +1 -2
- package/dist/radio.js +1 -1
- package/dist/radio.styles.js +2 -6
- package/dist/split-button.styles.js +2 -4
- package/dist/split-container.d.ts +1 -1
- package/dist/split-container.styles.js +2 -4
- package/dist/status-indicator.d.ts +1 -1
- package/dist/styles/focus-outline.d.ts +1 -1
- package/dist/styles/focus-outline.js +7 -1
- package/dist/styles/menu-opening-animation.d.ts +2 -0
- package/dist/styles/menu-opening-animation.js +26 -0
- package/dist/styles/variables.css +1 -1
- package/dist/styles/visually-hidden.d.ts +1 -1
- package/dist/styles/visually-hidden.js +14 -1
- package/dist/tab.group.d.ts +6 -6
- package/dist/tab.group.js +1 -1
- package/dist/tab.group.styles.js +46 -5
- package/dist/tab.group.test.basics.js +9 -2
- package/dist/tab.group.test.interactions.js +70 -93
- package/dist/tab.js +1 -1
- package/dist/tab.panel.styles.js +3 -9
- package/dist/tab.styles.js +6 -13
- package/dist/tab.test.basics.js +15 -17
- package/dist/tabs.stories.d.ts +1 -0
- package/dist/tag.d.ts +3 -6
- package/dist/tag.js +1 -1
- package/dist/tag.styles.js +2 -4
- package/dist/tag.test.basics.js +28 -27
- package/dist/tag.test.events.js +3 -3
- package/dist/tag.test.focus.js +4 -4
- package/dist/textarea.d.ts +5 -4
- package/dist/textarea.stories.d.ts +0 -4
- package/dist/textarea.styles.d.ts +1 -1
- package/dist/textarea.styles.js +63 -67
- package/dist/textarea.test.basics.js +52 -52
- package/dist/toasts.d.ts +5 -0
- package/dist/toasts.styles.js +1 -1
- package/dist/toggle.d.ts +3 -3
- package/dist/toggle.js +1 -1
- package/dist/toggle.stories.d.ts +1 -1
- package/dist/toggle.styles.js +2 -1
- package/dist/toggle.test.interactions.js +37 -0
- package/dist/tooltip.d.ts +2 -2
- package/dist/tooltip.js +1 -1
- package/dist/tooltip.styles.js +22 -18
- package/dist/tooltip.test.interactions.js +6 -6
- package/dist/translations/en.js +1 -1
- package/dist/translations/fr.d.ts +3 -1
- package/dist/translations/fr.js +1 -1
- package/dist/translations/ja.d.ts +3 -1
- package/dist/translations/ja.js +1 -1
- package/dist/tree.d.ts +1 -1
- package/dist/tree.item.d.ts +0 -3
- package/dist/tree.item.icon-button.d.ts +1 -0
- package/dist/tree.item.icon-button.js +1 -1
- package/dist/tree.item.icon-button.test.basics.js +9 -0
- package/dist/tree.item.js +1 -1
- package/dist/tree.item.menu.d.ts +2 -0
- package/dist/tree.item.menu.js +1 -1
- package/dist/tree.item.menu.test.basics.js +15 -0
- package/dist/tree.item.styles.js +13 -3
- package/dist/tree.item.test.basics.d.ts +2 -1
- package/dist/tree.item.test.basics.js +16 -4
- package/dist/tree.js +1 -1
- package/dist/tree.test.focus.js +91 -4
- package/package.json +2 -1
- package/dist/button.test.form.d.ts +0 -1
- package/dist/button.test.form.js +0 -50
- package/dist/input.test.translations.js +0 -38
- package/dist/tag.test.translations.d.ts +0 -1
- package/dist/tag.test.translations.js +0 -25
- package/dist/textarea.test.translations.d.ts +0 -1
- package/dist/textarea.test.translations.js +0 -34
- /package/dist/{input.test.translations.d.ts → library/localize.test.d.ts} +0 -0
package/dist/accordion.d.ts
CHANGED
@@ -5,10 +5,14 @@ declare global {
|
|
5
5
|
}
|
6
6
|
}
|
7
7
|
/**
|
8
|
-
* @
|
9
|
-
*
|
8
|
+
* @description An accordion with optional icons.
|
9
|
+
*
|
10
|
+
* @event toggle - `(event: "toggle", listener: (event: CustomEvent<{ newState: "open" | "closed", oldState: "open" | "closed" }>) => void) => void`.
|
11
|
+
* Emitted when the Accordion opens or closes.
|
12
|
+
*
|
13
|
+
* @slot - The content of the accordion.
|
10
14
|
* @slot prefix - An optional icon to display before the label.
|
11
|
-
* @slot suffix -
|
15
|
+
* @slot suffix - Optional icons to display after the label.
|
12
16
|
*/
|
13
17
|
export default class GlideCoreAccordion extends LitElement {
|
14
18
|
#private;
|
package/dist/accordion.styles.js
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
|
2
|
+
${focusOutline(".summary:focus-visible")}
|
3
|
+
`,css`
|
2
4
|
.component {
|
3
5
|
border-radius: 0.625rem;
|
4
6
|
box-shadow: var(--glide-core-shadow-sm);
|
@@ -24,10 +26,6 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
24
26
|
outline: none;
|
25
27
|
}
|
26
28
|
|
27
|
-
&:focus-visible {
|
28
|
-
${focusOutline};
|
29
|
-
}
|
30
|
-
|
31
29
|
&::marker,
|
32
30
|
&::-webkit-details-marker {
|
33
31
|
display: none;
|
@@ -7,11 +7,8 @@ declare global {
|
|
7
7
|
/**
|
8
8
|
* @description A button with a label and optional icon for use in a `<glide-core-button-group>`.
|
9
9
|
*
|
10
|
-
* @event change - Dispatched when the button is selected.
|
11
|
-
* @event input - Dispatched when the button is selected.
|
12
|
-
|
13
|
-
* @slot prefix - An icon.
|
14
10
|
* @slot - A label.
|
11
|
+
* @slot prefix - An optional icon to display before the label.
|
15
12
|
*/
|
16
13
|
export default class GlideCoreButtonGroupButton extends LitElement {
|
17
14
|
#private;
|
@@ -1,4 +1,7 @@
|
|
1
1
|
import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
|
2
|
+
${focusOutline(".component:focus-visible")}
|
3
|
+
${visuallyHidden(".label.visually-hidden")}
|
4
|
+
`,css`
|
2
5
|
:host(:first-of-type) {
|
3
6
|
.component {
|
4
7
|
&.horizontal {
|
@@ -30,6 +33,7 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
|
|
30
33
|
.component {
|
31
34
|
align-items: center;
|
32
35
|
appearance: none;
|
36
|
+
background-color: var(--glide-core-surface-page);
|
33
37
|
cursor: pointer;
|
34
38
|
display: flex;
|
35
39
|
font-family: var(--glide-core-font-sans);
|
@@ -57,8 +61,6 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
|
|
57
61
|
background-color: var(--glide-core-surface-selected);
|
58
62
|
border-color: var(--glide-core-border-focus);
|
59
63
|
color: var(--glide-core-color-white);
|
60
|
-
|
61
|
-
${focusOutline};
|
62
64
|
outline-offset: 2px;
|
63
65
|
|
64
66
|
/* Create a stacking context so the outline isn't obscured by other elements. */
|
@@ -114,10 +116,4 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
|
|
114
116
|
}
|
115
117
|
}
|
116
118
|
}
|
117
|
-
|
118
|
-
.label {
|
119
|
-
&.visually-hidden {
|
120
|
-
${visuallyHidden};
|
121
|
-
}
|
122
|
-
}
|
123
119
|
`];
|
package/dist/button-group.d.ts
CHANGED
@@ -7,6 +7,9 @@ declare global {
|
|
7
7
|
/**
|
8
8
|
* @description A button group.
|
9
9
|
*
|
10
|
+
* @event change - `(event: Event) => void`
|
11
|
+
* @event input - `(event: Event) => void`
|
12
|
+
*
|
10
13
|
* @slot - One or more of `<glide-core-button-group-button>`.
|
11
14
|
*/
|
12
15
|
export default class GlideCoreButtonGroup extends LitElement {
|
@@ -1,4 +1,6 @@
|
|
1
1
|
import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
|
2
|
+
${visuallyHidden(".label")}
|
3
|
+
`,css`
|
2
4
|
.component {
|
3
5
|
border: 1px solid var(--glide-core-border-base);
|
4
6
|
border-radius: 0.75rem;
|
@@ -13,8 +15,6 @@ import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";exp
|
|
13
15
|
checking for the entire component.
|
14
16
|
*/
|
15
17
|
color: var(--glide-core-color-white);
|
16
|
-
|
17
|
-
${visuallyHidden};
|
18
18
|
}
|
19
19
|
|
20
20
|
.container {
|
package/dist/button.d.ts
CHANGED
@@ -5,6 +5,9 @@ declare global {
|
|
5
5
|
}
|
6
6
|
}
|
7
7
|
/**
|
8
|
+
*
|
9
|
+
* @description A group of buttons that work like radios—with labels and optional icons.
|
10
|
+
*
|
8
11
|
* @slot - A label for the contents of the button.
|
9
12
|
* @slot prefix - An optional icon slot to display before the label.
|
10
13
|
* @slot suffix - An optional icon slot to display after the label.
|
@@ -22,6 +25,7 @@ export default class GlideCoreButton extends LitElement {
|
|
22
25
|
variant: 'primary' | 'secondary' | 'tertiary';
|
23
26
|
size: 'large' | 'small';
|
24
27
|
get form(): HTMLFormElement | null;
|
28
|
+
click(): void;
|
25
29
|
firstUpdated(): void;
|
26
30
|
render(): import("lit").TemplateResult<1>;
|
27
31
|
constructor();
|
package/dist/button.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(t,e,o,i){var r,s=arguments.length,
|
1
|
+
var __decorate=this&&this.__decorate||function(t,e,o,i){var r,s=arguments.length,l=s<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(t,e,o,i);else for(var a=t.length-1;a>=0;a--)(r=t[a])&&(l=(s<3?r(l):s>3?r(e,o,l):r(e,o))||l);return s>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,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{owSlot}from"./library/ow.js";import styles from"./button.styles.js";let GlideCoreButton=class GlideCoreButton extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}get form(){return this.#t.form}click(){this.#e.value?.click()}firstUpdated(){owSlot(this.#o.value)}render(){return html`<button aria-controls="${ifDefined(this.ariaControls??void 0)}" aria-expanded="${ifDefined(this.ariaExpanded??void 0)}" aria-haspopup="${ifDefined(this.ariaHasPopup??void 0)}" class="${classMap({component:!0,primary:"primary"===this.variant,secondary:"secondary"===this.variant,tertiary:"tertiary"===this.variant,large:"large"===this.size,small:"small"===this.size,"has-prefix":this.hasPrefixSlot,"has-suffix":this.hasSuffixSlot})}" type="${this.type}" ?disabled="${this.disabled}" @click="${this.#i}" ${ref(this.#e)}><slot name="prefix" @slotchange="${this.#r}" ${ref(this.#s)}></slot><slot @slotchange="${this.#l}" ${ref(this.#o)}></slot><slot name="suffix" @slotchange="${this.#a}" ${ref(this.#n)}></slot></button>`}constructor(){super(),this.ariaExpanded=null,this.ariaHasPopup=null,this.ariaControls=null,this.disabled=!1,this.type="button",this.variant="primary",this.size="large",this.hasPrefixSlot=!1,this.hasSuffixSlot=!1,this.#e=createRef(),this.#o=createRef(),this.#s=createRef(),this.#n=createRef(),this.#t=this.attachInternals()}#e;#o;#t;#s;#n;#i(){"submit"!==this.type?"reset"!==this.type||this.form?.reset():this.form?.requestSubmit()}#l(){owSlot(this.#o.value)}#r(){const t=this.#s.value?.assignedNodes();this.hasPrefixSlot=!!(t&&t.length>0)}#a(){const t=this.#n.value?.assignedNodes();this.hasSuffixSlot=!!(t&&t.length>0)}};__decorate([property({attribute:"aria-expanded",reflect:!0})],GlideCoreButton.prototype,"ariaExpanded",void 0),__decorate([property({attribute:"aria-haspopup",reflect:!0})],GlideCoreButton.prototype,"ariaHasPopup",void 0),__decorate([property({attribute:"aria-controls",reflect:!0})],GlideCoreButton.prototype,"ariaControls",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreButton.prototype,"disabled",void 0),__decorate([property()],GlideCoreButton.prototype,"type",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"variant",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"size",void 0),__decorate([state()],GlideCoreButton.prototype,"hasPrefixSlot",void 0),__decorate([state()],GlideCoreButton.prototype,"hasSuffixSlot",void 0),GlideCoreButton=__decorate([customElement("glide-core-button")],GlideCoreButton);export default GlideCoreButton;
|
package/dist/button.styles.js
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
|
2
|
+
${focusOutline(".component:focus-visible")}
|
3
|
+
`,css`
|
2
4
|
:host {
|
3
5
|
/* Contains elements with "padding" and "width". Inline by default. */
|
4
6
|
display: inline-block;
|
@@ -28,10 +30,6 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
28
30
|
outline: none;
|
29
31
|
}
|
30
32
|
|
31
|
-
&:focus-visible {
|
32
|
-
${focusOutline};
|
33
|
-
}
|
34
|
-
|
35
33
|
&:disabled {
|
36
34
|
cursor: not-allowed;
|
37
35
|
opacity: 1;
|
@@ -4,23 +4,99 @@ import { expect, fixture, html, oneEvent } from '@open-wc/testing';
|
|
4
4
|
import { sendKeys } from '@web/test-runner-commands';
|
5
5
|
import GlideCoreButton from './button.js';
|
6
6
|
GlideCoreButton.shadowRootOptions.mode = 'open';
|
7
|
-
it('dispatches
|
7
|
+
it('dispatches a "click" event when clicked', async () => {
|
8
8
|
const component = await fixture(html `
|
9
9
|
<glide-core-button type="button">Button</glide-core-button>
|
10
10
|
`);
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
setTimeout(() => {
|
12
|
+
component.click();
|
13
|
+
});
|
14
|
+
const event = await oneEvent(component, 'click');
|
15
|
+
expect(event instanceof PointerEvent).to.be.true;
|
16
|
+
expect(event.bubbles).to.be.true;
|
17
|
+
});
|
18
|
+
it('dispatches a "click" event on Enter', async () => {
|
19
|
+
const component = await fixture(html `
|
20
|
+
<glide-core-button type="button">Button</glide-core-button>
|
21
|
+
`);
|
22
|
+
component.focus();
|
23
|
+
sendKeys({ press: 'Enter' });
|
24
|
+
const event = await oneEvent(component, 'click');
|
25
|
+
expect(event instanceof PointerEvent).to.be.true;
|
26
|
+
expect(event.bubbles).to.be.true;
|
15
27
|
});
|
16
|
-
it('dispatches
|
28
|
+
it('dispatches a "click" event on Space', async () => {
|
17
29
|
const component = await fixture(html `
|
18
30
|
<glide-core-button type="button">Button</glide-core-button>
|
19
31
|
`);
|
20
|
-
const keyDownEvent = oneEvent(component, 'keydown');
|
21
32
|
component.focus();
|
22
|
-
|
23
|
-
const event = await
|
33
|
+
sendKeys({ press: ' ' });
|
34
|
+
const event = await oneEvent(component, 'click');
|
35
|
+
expect(event instanceof PointerEvent).to.be.true;
|
36
|
+
expect(event.bubbles).to.be.true;
|
37
|
+
});
|
38
|
+
it('dispatches a "reset" event on click', async () => {
|
39
|
+
const form = document.createElement('form');
|
40
|
+
const component = await fixture(html ` <glide-core-button type="reset">Button</glide-core-button> `, {
|
41
|
+
parentNode: form,
|
42
|
+
});
|
43
|
+
setTimeout(() => {
|
44
|
+
component.click();
|
45
|
+
});
|
46
|
+
const event = await oneEvent(form, 'reset');
|
47
|
+
expect(event instanceof Event).to.be.true;
|
48
|
+
});
|
49
|
+
it('dispatches a "reset" event on Enter', async () => {
|
50
|
+
const form = document.createElement('form');
|
51
|
+
const component = await fixture(html ` <glide-core-button type="reset">Button</glide-core-button> `, {
|
52
|
+
parentNode: form,
|
53
|
+
});
|
54
|
+
component.focus();
|
55
|
+
sendKeys({ press: 'Enter' });
|
56
|
+
const event = await oneEvent(form, 'reset');
|
57
|
+
expect(event instanceof Event).to.be.true;
|
58
|
+
});
|
59
|
+
it('dispatches a "reset" event on Space', async () => {
|
60
|
+
const form = document.createElement('form');
|
61
|
+
const component = await fixture(html ` <glide-core-button type="reset">Button</glide-core-button> `, {
|
62
|
+
parentNode: form,
|
63
|
+
});
|
64
|
+
component.focus();
|
65
|
+
sendKeys({ press: ' ' });
|
66
|
+
const event = await oneEvent(form, 'reset');
|
67
|
+
expect(event instanceof Event).to.be.true;
|
68
|
+
});
|
69
|
+
it('dispatches a "submit" event on click', async () => {
|
70
|
+
const form = document.createElement('form');
|
71
|
+
const component = await fixture(html ` <glide-core-button type="submit">Button</glide-core-button> `, {
|
72
|
+
parentNode: form,
|
73
|
+
});
|
74
|
+
form.addEventListener('submit', (event) => event.preventDefault());
|
75
|
+
setTimeout(() => {
|
76
|
+
component.click();
|
77
|
+
});
|
78
|
+
const event = await oneEvent(form, 'submit');
|
79
|
+
expect(event instanceof Event).to.be.true;
|
80
|
+
});
|
81
|
+
it('dispatches a "submit" event on Enter', async () => {
|
82
|
+
const form = document.createElement('form');
|
83
|
+
const component = await fixture(html ` <glide-core-button type="submit">Button</glide-core-button> `, {
|
84
|
+
parentNode: form,
|
85
|
+
});
|
86
|
+
form.addEventListener('submit', (event) => event.preventDefault());
|
87
|
+
component.focus();
|
88
|
+
sendKeys({ press: 'Enter' });
|
89
|
+
const event = await oneEvent(form, 'submit');
|
90
|
+
expect(event instanceof Event).to.be.true;
|
91
|
+
});
|
92
|
+
it('dispatches a "submit" event on Space', async () => {
|
93
|
+
const form = document.createElement('form');
|
94
|
+
const component = await fixture(html ` <glide-core-button type="submit">Button</glide-core-button> `, {
|
95
|
+
parentNode: form,
|
96
|
+
});
|
97
|
+
form.addEventListener('submit', (event) => event.preventDefault());
|
98
|
+
component.focus();
|
99
|
+
sendKeys({ press: ' ' });
|
100
|
+
const event = await oneEvent(form, 'submit');
|
24
101
|
expect(event instanceof Event).to.be.true;
|
25
|
-
expect(event.key).to.equal('Enter');
|
26
102
|
});
|
package/dist/checkbox-group.d.ts
CHANGED
@@ -6,7 +6,11 @@ declare global {
|
|
6
6
|
}
|
7
7
|
}
|
8
8
|
/**
|
9
|
-
* @description A group of checkboxes with a label and optional
|
9
|
+
* @description A group of checkboxes with a label and optional description and tooltip. Participates in forms and validation via `FormData` and various methods.
|
10
|
+
*
|
11
|
+
* @event change - `(event: Event) => void`
|
12
|
+
* @event input - `(event: Event) => void`
|
13
|
+
* @event invalid - `(event: Event) => void`
|
10
14
|
*
|
11
15
|
* @slot - One or more of `<glide-core-checkbox>`.
|
12
16
|
* @slot description - Additional information or context.
|
@@ -26,7 +30,7 @@ export default class GlideCoreCheckboxGroup extends LitElement {
|
|
26
30
|
get required(): boolean;
|
27
31
|
set required(isRequired: boolean);
|
28
32
|
summary?: string;
|
29
|
-
value: string[];
|
33
|
+
value: readonly string[];
|
30
34
|
checkValidity(): boolean;
|
31
35
|
disconnectedCallback(): void;
|
32
36
|
firstUpdated(): void;
|
@@ -3,5 +3,5 @@ import type { Meta, StoryObj } from '@storybook/web-components';
|
|
3
3
|
declare const meta: Meta;
|
4
4
|
export default meta;
|
5
5
|
export declare const Vertical: StoryObj;
|
6
|
-
export declare const
|
6
|
+
export declare const VerticalWithTooltip: StoryObj;
|
7
7
|
export declare const VerticalWithError: StoryObj;
|
package/dist/checkbox.d.ts
CHANGED
@@ -9,9 +9,10 @@ declare global {
|
|
9
9
|
/**
|
10
10
|
* @description A checkbox with a label and optional tooltip, summary, and description. Participates in forms and validation via `FormData` and various methods.
|
11
11
|
*
|
12
|
-
* @event change -
|
13
|
-
* @event input -
|
14
|
-
|
12
|
+
* @event change - `(event: Event) => void`
|
13
|
+
* @event input - `(event: Event) => void`
|
14
|
+
* @event invalid - `(event: Event) => void`
|
15
|
+
*
|
15
16
|
* @slot description - Additional information or context.
|
16
17
|
* @slot tooltip - Content for the tooltip.
|
17
18
|
*/
|
@@ -35,7 +36,7 @@ export default class GlideCoreCheckbox extends LitElement {
|
|
35
36
|
privateVariant?: 'minimal';
|
36
37
|
required: boolean;
|
37
38
|
summary?: string;
|
38
|
-
value
|
39
|
+
value: string;
|
39
40
|
isReportValidityOrSubmit: boolean;
|
40
41
|
get form(): HTMLFormElement | null;
|
41
42
|
blur(): void;
|
package/dist/checkbox.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(e,t,i,o){var r,a=arguments.length,s=a<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,i,o);else for(var l=e.length-1;l>=0;l--)(r=e[l])&&(s=(a<3?r(s):a>3?r(t,i,s):r(t,i))||s);return a>3&&s&&Object.defineProperty(t,i,s),s};import"./label.js";import"./tooltip.js";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{ifDefined}from"lit/directives/if-defined.js";import{when}from"lit/directives/when.js";import checkedIcon from"./icons/checked.js";import styles from"./checkbox.styles.js";const indeterminateIcon=html`<svg width="14" height="14" viewBox="0 0 14 14" fill="none" class="indeterminate-icon"><rect x="0.5" y="0.5" width="13" height="13" rx="3.5"/><path d="M3 5C3 3.89543 3.89543 3 5 3H9.79289C10.2383 3 10.4614 3.53857 10.1464 3.85355L3.85355 10.1464C3.53857 10.4614 3 10.2383 3 9.79289V5Z" fill="currentColor"/></svg>`;let GlideCoreCheckbox=class GlideCoreCheckbox extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get label(){return this.#e}set label(e){this.#e=e,setTimeout((()=>{this.#t()}))}get form(){return this.#i.form}blur(){this.#o.value?.blur()}checkValidity(){this.isCheckingValidity=!0;const e=this.#i.checkValidity();return this.isCheckingValidity=!1,e}click(){this.#o.value?.click()}connectedCallback(){super.connectedCallback(),this.#r=new IntersectionObserver((()=>{this.checkVisibility()&&this.#t()})),this.#r.observe(this)}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#a),this.#r?.disconnect()}get validity(){return"minimal"===this.privateVariant||(this.required&&!this.checked?this.#i.setValidity({valueMissing:!0}," ",this.#o.value):this.#i.setValidity({})),this.#i.validity}focus(e){this.#o.value?.focus(e)}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#a)}formResetCallback(){this.checked=""===this.getAttribute("checked"),this.indeterminate=""===this.getAttribute("indeterminate")}render(){return html`<div class="component" data-test="component">${when("minimal"===this.privateVariant,(()=>html`<label class="label-and-input-and-checkbox" part="private-label-and-input-and-checkbox"><div class="input-and-checkbox"><input aria-invalid="${this.#s}" data-test="input" type="checkbox" .checked="${this.checked}" .inert="${this.internallyInert}" ?disabled="${this.disabled}" ?required="${this.required}" @change="${this.#l}" ${ref(this.#o)}><div class="${classMap({checkbox:!0,disabled:this.disabled,error:this.#s})}"><div class="checked-icon">${checkedIcon}</div>${indeterminateIcon}</div></div><glide-core-tooltip class="label-tooltip" offset="${this.privateLabelTooltipOffset}" ?disabled="${!this.isLabelOverflow}" ?open="${this.privateShowLabelTooltip}"><div aria-hidden="true" data-test="tooltip">${this.label}</div><div class="label" slot="target" ${ref(this.#
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,i,o){var r,a=arguments.length,s=a<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,i,o);else for(var l=e.length-1;l>=0;l--)(r=e[l])&&(s=(a<3?r(s):a>3?r(t,i,s):r(t,i))||s);return a>3&&s&&Object.defineProperty(t,i,s),s};import"./label.js";import"./tooltip.js";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{ifDefined}from"lit/directives/if-defined.js";import{when}from"lit/directives/when.js";import checkedIcon from"./icons/checked.js";import styles from"./checkbox.styles.js";const indeterminateIcon=html`<svg width="14" height="14" viewBox="0 0 14 14" fill="none" class="indeterminate-icon"><rect x="0.5" y="0.5" width="13" height="13" rx="3.5"/><path d="M3 5C3 3.89543 3.89543 3 5 3H9.79289C10.2383 3 10.4614 3.53857 10.1464 3.85355L3.85355 10.1464C3.53857 10.4614 3 10.2383 3 9.79289V5Z" fill="currentColor"/></svg>`;let GlideCoreCheckbox=class GlideCoreCheckbox extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get label(){return this.#e}set label(e){this.#e=e,setTimeout((()=>{this.#t()}))}get form(){return this.#i.form}blur(){this.#o.value?.blur()}checkValidity(){this.isCheckingValidity=!0;const e=this.#i.checkValidity();return this.isCheckingValidity=!1,e}click(){this.#o.value?.click()}connectedCallback(){super.connectedCallback(),this.#r=new IntersectionObserver((()=>{this.checkVisibility()&&this.#t()})),this.#r.observe(this)}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#a),this.#r?.disconnect()}get validity(){return"minimal"===this.privateVariant||(this.required&&!this.checked?this.#i.setValidity({valueMissing:!0}," ",this.#o.value):this.#i.setValidity({})),this.#i.validity}focus(e){this.#o.value?.focus(e)}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#a)}formResetCallback(){this.checked=""===this.getAttribute("checked"),this.indeterminate=""===this.getAttribute("indeterminate")}render(){return html`<div class="component" data-test="component">${when("minimal"===this.privateVariant,(()=>html`<label class="label-and-input-and-checkbox" part="private-label-and-input-and-checkbox"><div class="input-and-checkbox"><input aria-invalid="${this.#s}" data-test="input" type="checkbox" .checked="${this.checked}" .inert="${this.internallyInert}" ?disabled="${this.disabled}" ?required="${this.required}" @change="${this.#l}" @input="${this.#l}" @keydown="${this.#n}" ${ref(this.#o)}><div class="${classMap({checkbox:!0,disabled:this.disabled,error:this.#s})}"><div class="checked-icon">${checkedIcon}</div>${indeterminateIcon}</div></div><glide-core-tooltip class="label-tooltip" offset="${this.privateLabelTooltipOffset}" ?disabled="${!this.isLabelOverflow}" ?open="${this.privateShowLabelTooltip}"><div aria-hidden="true" data-test="tooltip">${this.label}</div><div class="label" slot="target" ${ref(this.#d)}>${this.label}</div></glide-core-tooltip></label>`),(()=>html`<glide-core-private-label orientation="${this.orientation}" split="${ifDefined(this.privateSplit??void 0)}" ?disabled="${this.disabled}" ?error="${this.#s}" ?hide="${this.hideLabel}" ?required="${this.required}"><slot name="tooltip" slot="tooltip"></slot><label for="input">${this.label}</label><div class="input-and-checkbox" slot="control"><input aria-describedby="summary description" aria-invalid="${this.#s}" data-test="input" id="input" type="checkbox" .checked="${this.checked}" ?disabled="${this.disabled}" ?required="${this.required}" @blur="${this.#h}" @change="${this.#l}" @input="${this.#l}" @keydown="${this.#n}" ${ref(this.#o)}><div class="${classMap({checkbox:!0,disabled:this.disabled,error:this.#s})}"><div class="checked-icon">${checkedIcon}</div>${indeterminateIcon}</div></div><div id="summary" slot="summary">${this.summary}</div><slot id="description" name="description" slot="description"></slot></glide-core-private-label>`))}</div>`}reportValidity(){this.isReportValidityOrSubmit=!0;const e=this.#i.reportValidity();return this.requestUpdate(),e}setValidity(e,t,i){return this.#i.setValidity(e,t,i)}get willValidate(){return this.#i.willValidate}updated(){this.#o.value&&(this.#o.value.indeterminate=this.indeterminate)}constructor(){super(),this.checked=!1,this.internallyInert=!1,this.disabled=!1,this.hideLabel=!1,this.indeterminate=!1,this.orientation="horizontal",this.privateLabelTooltipOffset=4,this.privateShowLabelTooltip=!1,this.required=!1,this.value="",this.isReportValidityOrSubmit=!1,this.isBlurring=!1,this.isCheckingValidity=!1,this.isLabelOverflow=!1,this.#o=createRef(),this.#e="",this.#d=createRef(),this.#a=({formData:e})=>{this.checked&&this.name&&this.value&&!this.disabled&&e.append(this.name,this.value)},this.#i=this.attachInternals(),this.addEventListener("invalid",(e=>{if(e?.preventDefault(),this.isCheckingValidity||this.isBlurring)return;this.isReportValidityOrSubmit=!0;this.form?.querySelector(":invalid")===this&&this.focus()}))}#o;#i;#r;#e;#d;#a;get#s(){return"minimal"===this.privateVariant?!this.validity.valid&&this.isReportValidityOrSubmit:this.required&&!this.disabled&&!this.validity.valid&&this.isReportValidityOrSubmit}#h(){this.isBlurring=!0,this.reportValidity(),this.isBlurring=!1}#l(e){e.target instanceof HTMLInputElement&&(this.checked=e.target.checked),this.indeterminate=!1,"change"===e.type&&this.dispatchEvent(new Event(e.type,e))}#n(e){"Enter"===e.key&&this.form?.requestSubmit()}#t(){this.#d.value&&(this.isLabelOverflow=this.#d.value.scrollWidth>this.#d.value.clientWidth)}};__decorate([property({type:Boolean})],GlideCoreCheckbox.prototype,"checked",void 0),__decorate([property({attribute:"internally-inert",type:Boolean})],GlideCoreCheckbox.prototype,"internallyInert",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreCheckbox.prototype,"disabled",void 0),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreCheckbox.prototype,"hideLabel",void 0),__decorate([property({type:Boolean})],GlideCoreCheckbox.prototype,"indeterminate",void 0),__decorate([property({reflect:!0})],GlideCoreCheckbox.prototype,"label",null),__decorate([property({reflect:!0})],GlideCoreCheckbox.prototype,"orientation",void 0),__decorate([property({reflect:!0})],GlideCoreCheckbox.prototype,"name",void 0),__decorate([property({attribute:"private-label-tooltip-offset",reflect:!0,type:Number})],GlideCoreCheckbox.prototype,"privateLabelTooltipOffset",void 0),__decorate([property({attribute:"private-show-label-tooltip",reflect:!0,type:Boolean})],GlideCoreCheckbox.prototype,"privateShowLabelTooltip",void 0),__decorate([property()],GlideCoreCheckbox.prototype,"privateSplit",void 0),__decorate([property({attribute:"private-variant"})],GlideCoreCheckbox.prototype,"privateVariant",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreCheckbox.prototype,"required",void 0),__decorate([property({reflect:!0})],GlideCoreCheckbox.prototype,"summary",void 0),__decorate([property({reflect:!0})],GlideCoreCheckbox.prototype,"value",void 0),__decorate([state()],GlideCoreCheckbox.prototype,"isReportValidityOrSubmit",void 0),__decorate([state()],GlideCoreCheckbox.prototype,"isBlurring",void 0),__decorate([state()],GlideCoreCheckbox.prototype,"isCheckingValidity",void 0),__decorate([state()],GlideCoreCheckbox.prototype,"isLabelOverflow",void 0),GlideCoreCheckbox=__decorate([customElement("glide-core-checkbox")],GlideCoreCheckbox);export default GlideCoreCheckbox;
|
@@ -5,5 +5,5 @@ export declare const Horizontal: StoryObj;
|
|
5
5
|
export declare const HorizontalWithTooltip: StoryObj;
|
6
6
|
export declare const HorizontalWithError: StoryObj;
|
7
7
|
export declare const Vertical: StoryObj;
|
8
|
-
export declare const
|
8
|
+
export declare const VerticalWithTooltip: StoryObj;
|
9
9
|
export declare const VerticalWithError: StoryObj;
|
package/dist/checkbox.styles.js
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
|
2
|
+
${focusOutline("input:focus-visible ~ .checkbox, input:focus ~ .checkbox.error")}
|
3
|
+
`,css`
|
2
4
|
/*
|
3
5
|
Most states are handled on the host. But ":checked" and ":indeterminate" are
|
4
6
|
handled on the input because browsers don't support those classes on the host.
|
@@ -47,6 +49,7 @@ when browsers support them.
|
|
47
49
|
flex-shrink: 0; /* Don't shrink when the summary wraps. */
|
48
50
|
inline-size: 100%;
|
49
51
|
justify-content: center;
|
52
|
+
transition: box-shadow 200ms ease-in-out;
|
50
53
|
|
51
54
|
&.error:not(.disabled) {
|
52
55
|
border-color: var(--glide-core-status-error);
|
@@ -83,11 +86,6 @@ when browsers support them.
|
|
83
86
|
border-color: var(--glide-core-surface-primary-disabled);
|
84
87
|
}
|
85
88
|
|
86
|
-
&:focus-visible ~ .checkbox,
|
87
|
-
&:focus ~ .checkbox.error {
|
88
|
-
${focusOutline};
|
89
|
-
}
|
90
|
-
|
91
89
|
&:is(:checked, :indeterminate):not(:disabled) ~ .checkbox {
|
92
90
|
background-color: var(--glide-core-surface-primary);
|
93
91
|
border-color: transparent;
|
@@ -97,6 +95,24 @@ when browsers support them.
|
|
97
95
|
background-color: var(--glide-core-surface-primary-disabled);
|
98
96
|
border-color: transparent;
|
99
97
|
}
|
98
|
+
|
99
|
+
&:checked ~ .checkbox > .checked-icon {
|
100
|
+
visibility: visible;
|
101
|
+
|
102
|
+
.check {
|
103
|
+
/*
|
104
|
+
Setting the animated offset to 48 is by design and aligns with the offset and array
|
105
|
+
properties below. 48 was chosen to ensure the animation goes from left-to-right
|
106
|
+
rather than right-to-left. Since our starting location is at 24 below we begin
|
107
|
+
at the left-most corner and need to span the entire viewbox of the SVG.
|
108
|
+
|
109
|
+
To do this, we'll multiply 24 by 2, which is the entire length of the viewbox
|
110
|
+
going in the opposite direction so that it'll animate from left-to-right.
|
111
|
+
*/
|
112
|
+
stroke-dashoffset: 48;
|
113
|
+
transition: stroke-dashoffset 300ms cubic-bezier(0.32, 0, 0.67, 0);
|
114
|
+
}
|
115
|
+
}
|
100
116
|
}
|
101
117
|
|
102
118
|
.checked-icon {
|
@@ -104,13 +120,28 @@ when browsers support them.
|
|
104
120
|
|
105
121
|
align-items: center;
|
106
122
|
block-size: 100%;
|
107
|
-
display: none;
|
108
123
|
inline-size: 100%;
|
109
124
|
inset-block-start: 0;
|
110
125
|
inset-inline-start: 0;
|
111
126
|
justify-content: center;
|
112
127
|
pointer-events: none;
|
113
128
|
position: absolute;
|
129
|
+
|
130
|
+
/* We must rely on 'visibility: hidden' over 'display: none' for the animation transition to play properly. */
|
131
|
+
visibility: hidden;
|
132
|
+
|
133
|
+
.check {
|
134
|
+
/*
|
135
|
+
Safari doesn't support rem values for these CSS properties, otherwise we'd use calc() here.
|
136
|
+
|
137
|
+
With the path in our SVG, increasing the offset or array from 0 to 24 actually animates
|
138
|
+
it from right-to-left, which isn't the direction we want. To get it to go the correct
|
139
|
+
direction, from left-to-right, we have to begin at 24, which is the end of the SVG
|
140
|
+
viewbox.
|
141
|
+
*/
|
142
|
+
stroke-dasharray: 24;
|
143
|
+
stroke-dashoffset: 24;
|
144
|
+
}
|
114
145
|
}
|
115
146
|
|
116
147
|
.indeterminate-icon {
|
@@ -128,4 +159,10 @@ when browsers support them.
|
|
128
159
|
text-overflow: ellipsis;
|
129
160
|
white-space: nowrap;
|
130
161
|
}
|
162
|
+
|
163
|
+
@media (prefers-reduced-motion: reduce) {
|
164
|
+
.checked-icon .check {
|
165
|
+
transition: none !important;
|
166
|
+
}
|
167
|
+
}
|
131
168
|
`];
|
@@ -50,12 +50,18 @@ it('can have a description', async () => {
|
|
50
50
|
expect(assignedElements?.at(0)?.textContent).to.equal('Description');
|
51
51
|
});
|
52
52
|
it('can have a name', async () => {
|
53
|
-
const component = await fixture(html `<glide-core-checkbox
|
53
|
+
const component = await fixture(html `<glide-core-checkbox
|
54
|
+
label="Label"
|
55
|
+
name="name"
|
56
|
+
></glide-core-checkbox> `);
|
54
57
|
expect(component.getAttribute('name')).to.equal('name');
|
55
58
|
expect(component.name).to.equal('name');
|
56
59
|
});
|
57
60
|
it('can have a summary', async () => {
|
58
|
-
const component = await fixture(html `<glide-core-checkbox
|
61
|
+
const component = await fixture(html `<glide-core-checkbox
|
62
|
+
label="Label"
|
63
|
+
summary="Summary"
|
64
|
+
></glide-core-checkbox> `);
|
59
65
|
expect(component.getAttribute('summary')).to.equal('Summary');
|
60
66
|
expect(component.summary).to.equal('Summary');
|
61
67
|
});
|
@@ -69,22 +75,25 @@ it('can have a tooltip', async () => {
|
|
69
75
|
expect(assignedElements?.at(0)?.textContent).to.equal('Tooltip');
|
70
76
|
});
|
71
77
|
it('can be checked', async () => {
|
72
|
-
const component = await fixture(html `<glide-core-checkbox checked></glide-core-checkbox> `);
|
78
|
+
const component = await fixture(html `<glide-core-checkbox label="Label" checked></glide-core-checkbox> `);
|
73
79
|
expect(component.hasAttribute('checked')).to.be.true;
|
74
80
|
expect(component.checked).to.equal(true);
|
75
81
|
});
|
76
82
|
it('can be disabled', async () => {
|
77
|
-
const component = await fixture(html `<glide-core-checkbox disabled></glide-core-checkbox> `);
|
83
|
+
const component = await fixture(html `<glide-core-checkbox label="Label" disabled></glide-core-checkbox> `);
|
78
84
|
expect(component.hasAttribute('disabled')).to.be.true;
|
79
85
|
expect(component.disabled).to.equal(true);
|
80
86
|
});
|
81
87
|
it('can be indeterminate', async () => {
|
82
|
-
const component = await fixture(html `<glide-core-checkbox
|
88
|
+
const component = await fixture(html `<glide-core-checkbox
|
89
|
+
label="Label"
|
90
|
+
indeterminate
|
91
|
+
></glide-core-checkbox> `);
|
83
92
|
expect(component.hasAttribute('indeterminate')).to.be.true;
|
84
93
|
expect(component.indeterminate).to.equal(true);
|
85
94
|
});
|
86
95
|
it('can be required', async () => {
|
87
|
-
const component = await fixture(html `<glide-core-checkbox required></glide-core-checkbox> `);
|
96
|
+
const component = await fixture(html `<glide-core-checkbox label="Label" required></glide-core-checkbox> `);
|
88
97
|
expect(component.hasAttribute('required')).to.be.true;
|
89
98
|
expect(component.required).to.equal(true);
|
90
99
|
});
|
@@ -31,7 +31,7 @@ it('dispatches an "input" event when clicked', async () => {
|
|
31
31
|
});
|
32
32
|
it('dispatches an "invalid" event on submit when required and unchecked', async () => {
|
33
33
|
const form = document.createElement('form');
|
34
|
-
const component = await fixture(html `<glide-core-checkbox required></glide-core-checkbox>`, { parentNode: form });
|
34
|
+
const component = await fixture(html `<glide-core-checkbox label="Label" required></glide-core-checkbox>`, { parentNode: form });
|
35
35
|
setTimeout(() => form.requestSubmit());
|
36
36
|
const event = await oneEvent(component, 'invalid');
|
37
37
|
expect(event instanceof Event).to.be.true;
|
@@ -45,7 +45,7 @@ it('dispatches an "invalid" event after `checkValidity` is called when required
|
|
45
45
|
});
|
46
46
|
it('dispatches an "invalid" event after `reportValidity` is called when required and unchecked', async () => {
|
47
47
|
const form = document.createElement('form');
|
48
|
-
const component = await fixture(html `<glide-core-checkbox required></glide-core-checkbox>`, { parentNode: form });
|
48
|
+
const component = await fixture(html `<glide-core-checkbox label="Label" required></glide-core-checkbox>`, { parentNode: form });
|
49
49
|
setTimeout(() => component.reportValidity());
|
50
50
|
const event = await oneEvent(component, 'invalid');
|
51
51
|
expect(event instanceof Event).to.be.true;
|
@@ -61,7 +61,11 @@ it('does not dispatch an "invalid" event after `checkValidity` is called when no
|
|
61
61
|
});
|
62
62
|
it('does not dispatch an "invalid" event after `checkValidity` is called when required and unchecked but disabled', async () => {
|
63
63
|
const form = document.createElement('form');
|
64
|
-
const component = await fixture(html `<glide-core-checkbox
|
64
|
+
const component = await fixture(html `<glide-core-checkbox
|
65
|
+
label="Label"
|
66
|
+
disabled
|
67
|
+
required
|
68
|
+
></glide-core-checkbox>`, { parentNode: form });
|
65
69
|
const spy = sinon.spy();
|
66
70
|
component.addEventListener('invalid', spy);
|
67
71
|
component.checkValidity();
|
@@ -79,7 +83,11 @@ it('does not dispatch an "invalid" event when `reportValidity` is called when no
|
|
79
83
|
});
|
80
84
|
it('does not dispatch an "invalid" event when `reportValidity` is called when required and unchecked but disabled', async () => {
|
81
85
|
const form = document.createElement('form');
|
82
|
-
const component = await fixture(html `<glide-core-checkbox
|
86
|
+
const component = await fixture(html `<glide-core-checkbox
|
87
|
+
label="Label"
|
88
|
+
disabled
|
89
|
+
required
|
90
|
+
></glide-core-checkbox>`, { parentNode: form });
|
83
91
|
const spy = sinon.spy();
|
84
92
|
component.addEventListener('invalid', spy);
|
85
93
|
component.reportValidity();
|
@@ -37,7 +37,7 @@ it('does not focus the input after `checkValidity` is called', async () => {
|
|
37
37
|
expect(component.shadowRoot?.activeElement).to.equal(null);
|
38
38
|
});
|
39
39
|
it('blurs the input and reports validity if `blur` is called', async () => {
|
40
|
-
const component = await fixture(html `<glide-core-checkbox required></glide-core-checkbox>`);
|
40
|
+
const component = await fixture(html `<glide-core-checkbox label="Label" required></glide-core-checkbox>`);
|
41
41
|
component.focus();
|
42
42
|
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
43
43
|
expect(component.shadowRoot?.activeElement).to.equal(input);
|
@@ -1,6 +1,8 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
2
2
|
import { expect, fixture, html } from '@open-wc/testing';
|
3
|
+
import { sendKeys } from '@web/test-runner-commands';
|
3
4
|
import GlideCoreCheckbox from './checkbox.js';
|
5
|
+
import sinon from 'sinon';
|
4
6
|
GlideCoreCheckbox.shadowRootOptions.mode = 'open';
|
5
7
|
it('exposes standard form control properties and methods', async () => {
|
6
8
|
const form = document.createElement('form');
|
@@ -42,6 +44,7 @@ it('has `formData` value when checked', async () => {
|
|
42
44
|
it('has `formData` value when checked and indeterminate', async () => {
|
43
45
|
const form = document.createElement('form');
|
44
46
|
await fixture(html `<glide-core-checkbox
|
47
|
+
label="Label"
|
45
48
|
name="name"
|
46
49
|
value="value"
|
47
50
|
checked
|
@@ -114,3 +117,17 @@ it('has no `formData` value when checked but without a `value`', async () => {
|
|
114
117
|
const formData = new FormData(form);
|
115
118
|
expect(formData.get('name')).to.be.null;
|
116
119
|
});
|
120
|
+
it('submits its form on Enter', async () => {
|
121
|
+
const form = document.createElement('form');
|
122
|
+
const component = await fixture(html `<glide-core-checkbox label="Label"></glide-core-checkbox>`, {
|
123
|
+
parentNode: form,
|
124
|
+
});
|
125
|
+
const spy = sinon.spy();
|
126
|
+
form.addEventListener('submit', (event) => {
|
127
|
+
event.preventDefault();
|
128
|
+
spy();
|
129
|
+
});
|
130
|
+
component.focus();
|
131
|
+
await sendKeys({ press: 'Enter' });
|
132
|
+
expect(spy.callCount).to.equal(1);
|
133
|
+
});
|