@crowdstrike/glide-core 0.9.5 → 0.10.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 +17 -53
- package/dist/accordion.d.ts +10 -10
- package/dist/accordion.js +1 -1
- package/dist/accordion.stories.d.ts +0 -1
- package/dist/accordion.styles.js +36 -38
- package/dist/accordion.test.basics.js +13 -95
- package/dist/accordion.test.events.js +21 -33
- package/dist/accordion.test.focus.d.ts +1 -0
- package/dist/accordion.test.focus.js +11 -0
- package/dist/accordion.test.interactions.d.ts +1 -0
- package/dist/accordion.test.interactions.js +75 -0
- package/dist/button-group.button.d.ts +2 -4
- package/dist/button-group.button.js +1 -1
- package/dist/button-group.button.styles.js +6 -14
- package/dist/button-group.button.test.basics.js +8 -17
- package/dist/button-group.button.test.interactions.js +4 -4
- package/dist/button-group.d.ts +0 -2
- package/dist/button-group.test.basics.js +10 -10
- package/dist/button-group.test.events.js +2 -2
- package/dist/button-group.test.interactions.js +1 -1
- package/dist/button.d.ts +7 -10
- package/dist/button.js +1 -1
- package/dist/button.styles.js +4 -7
- package/dist/button.test.basics.js +10 -26
- package/dist/button.test.events.js +9 -9
- package/dist/checkbox-group.d.ts +3 -4
- package/dist/checkbox-group.js +1 -1
- package/dist/checkbox-group.styles.js +13 -1
- package/dist/checkbox-group.test.basics.js +8 -12
- package/dist/checkbox-group.test.focus.js +7 -7
- package/dist/checkbox-group.test.interactions.d.ts +1 -0
- package/dist/checkbox-group.test.interactions.js +82 -0
- package/dist/checkbox.d.ts +5 -4
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.styles.js +35 -15
- package/dist/checkbox.test.basics.js +6 -15
- package/dist/checkbox.test.focus.js +4 -2
- package/dist/checkbox.test.interactions.js +11 -11
- package/dist/drawer.d.ts +2 -5
- package/dist/drawer.js +1 -1
- package/dist/drawer.test.accessibility.js +8 -8
- package/dist/drawer.test.basics.js +16 -16
- package/dist/drawer.test.closing.js +18 -16
- package/dist/drawer.test.events.js +13 -24
- package/dist/drawer.test.methods.js +22 -22
- package/dist/dropdown.d.ts +7 -5
- package/dist/dropdown.js +1 -1
- package/dist/dropdown.option.d.ts +1 -3
- package/dist/dropdown.option.js +1 -1
- package/dist/dropdown.option.styles.js +31 -19
- package/dist/dropdown.option.test.basics.js +4 -4
- package/dist/dropdown.styles.js +39 -3
- package/dist/dropdown.test.basics.js +8 -13
- package/dist/dropdown.test.basics.multiple.js +63 -31
- package/dist/dropdown.test.basics.single.js +49 -0
- package/dist/dropdown.test.focus.filterable.js +12 -3
- package/dist/dropdown.test.focus.js +18 -2
- package/dist/dropdown.test.interactions.filterable.js +121 -45
- package/dist/dropdown.test.interactions.multiple.js +71 -30
- package/dist/dropdown.test.interactions.single.js +26 -4
- package/dist/form-controls-layout.d.ts +0 -2
- package/dist/icon-button.d.ts +2 -4
- package/dist/icon-button.js +1 -1
- package/dist/icon-button.test.basics.js +14 -82
- package/dist/icon-button.test.focus.d.ts +1 -0
- package/dist/icon-button.test.focus.js +13 -0
- package/dist/input.d.ts +4 -5
- package/dist/input.js +1 -1
- package/dist/input.styles.js +4 -4
- package/dist/input.test.basics.js +0 -52
- package/dist/input.test.events.js +27 -27
- package/dist/input.test.focus.js +27 -26
- package/dist/input.test.form.js +6 -6
- package/dist/input.test.validity.js +130 -130
- package/dist/label.d.ts +1 -3
- package/dist/label.js +1 -1
- package/dist/label.styles.js +5 -6
- package/dist/label.test.basics.js +4 -4
- package/dist/library/ow.js +1 -1
- package/dist/menu.button.d.ts +0 -2
- package/dist/menu.button.test.basics.js +3 -3
- package/dist/menu.d.ts +1 -4
- package/dist/menu.js +1 -1
- package/dist/menu.link.d.ts +1 -2
- package/dist/menu.link.js +1 -1
- package/dist/menu.options.d.ts +0 -2
- package/dist/menu.test.events.js +6 -6
- package/dist/menu.test.focus.js +5 -18
- package/dist/menu.test.interactions.js +48 -24
- package/dist/modal.d.ts +6 -17
- package/dist/modal.icon-button.d.ts +0 -2
- package/dist/modal.icon-button.test.basics.js +3 -3
- package/dist/modal.js +1 -1
- package/dist/modal.styles.js +13 -19
- package/dist/modal.tertiary-icon.d.ts +0 -3
- package/dist/modal.tertiary-icon.test.basics.js +3 -3
- package/dist/modal.test.basics.js +9 -5
- package/dist/modal.test.close.js +2 -2
- package/dist/modal.test.events.js +2 -2
- package/dist/radio-group.d.ts +0 -3
- package/dist/radio-group.js +1 -1
- package/dist/radio-group.test.basics.js +61 -61
- package/dist/radio-group.test.events.js +13 -13
- package/dist/radio-group.test.focus.js +1 -1
- package/dist/radio-group.test.form.js +2 -2
- package/dist/radio-group.test.validity.js +12 -12
- package/dist/radio.d.ts +0 -3
- package/dist/radio.styles.js +4 -12
- package/dist/split-button.d.ts +8 -11
- package/dist/split-button.js +1 -1
- package/dist/split-button.primary-button.d.ts +21 -0
- package/dist/split-button.primary-button.js +1 -0
- package/dist/split-button.primary-button.styles.js +96 -0
- package/dist/split-button.primary-button.test.basics.d.ts +1 -0
- package/dist/split-button.primary-button.test.basics.js +31 -0
- package/dist/split-button.primary-button.test.focus.d.ts +1 -0
- package/dist/split-button.primary-button.test.focus.js +14 -0
- package/dist/split-button.primary-link.d.ts +19 -0
- package/dist/split-button.primary-link.js +1 -0
- package/dist/split-button.primary-link.test.basics.d.ts +1 -0
- package/dist/split-button.primary-link.test.basics.js +30 -0
- package/dist/split-button.primary-link.test.focus.d.ts +1 -0
- package/dist/split-button.primary-link.test.focus.js +15 -0
- package/dist/split-button.secondary-button.d.ts +25 -0
- package/dist/split-button.secondary-button.js +1 -0
- package/dist/split-button.secondary-button.styles.js +103 -0
- package/dist/split-button.secondary-button.test.basics.d.ts +1 -0
- package/dist/split-button.secondary-button.test.basics.js +58 -0
- package/dist/split-button.secondary-button.test.focus.d.ts +1 -0
- package/dist/split-button.secondary-button.test.focus.js +14 -0
- package/dist/split-button.secondary-button.test.interactions.d.ts +2 -0
- package/dist/split-button.secondary-button.test.interactions.js +30 -0
- package/dist/split-button.stories.d.ts +4 -3
- package/dist/split-button.styles.js +1 -94
- package/dist/split-button.test.basics.d.ts +2 -1
- package/dist/split-button.test.basics.js +67 -80
- package/dist/split-button.test.interactions.d.ts +4 -0
- package/dist/split-button.test.interactions.js +51 -0
- package/dist/styles/opacity-and-scale-animation.js +2 -6
- package/dist/styles/variables.css +1 -1
- package/dist/tab.d.ts +2 -11
- package/dist/tab.group.d.ts +2 -5
- package/dist/tab.group.styles.js +12 -15
- package/dist/tab.group.test.basics.js +49 -34
- package/dist/tab.group.test.interactions.js +17 -14
- package/dist/tab.panel.d.ts +0 -3
- package/dist/tab.test.basics.js +6 -5
- package/dist/tag.d.ts +6 -4
- package/dist/tag.js +1 -1
- package/dist/tag.styles.js +36 -36
- package/dist/tag.test.basics.js +16 -109
- package/dist/tag.test.events.js +12 -8
- package/dist/tag.test.focus.js +2 -3
- package/dist/tag.test.interactions.d.ts +1 -0
- package/dist/tag.test.interactions.js +34 -0
- package/dist/textarea.d.ts +2 -3
- package/dist/textarea.js +2 -2
- package/dist/textarea.test.basics.js +8 -8
- package/dist/textarea.test.events.js +55 -55
- package/dist/textarea.test.form.js +9 -9
- package/dist/textarea.test.validity.js +167 -135
- package/dist/toasts.d.ts +1 -5
- package/dist/toasts.test.basics.js +2 -1
- package/dist/toasts.toast.d.ts +1 -4
- package/dist/toasts.toast.js +1 -1
- package/dist/toasts.toast.styles.js +12 -0
- package/dist/toggle.d.ts +0 -2
- package/dist/toggle.styles.js +1 -5
- package/dist/toggle.test.basics.js +2 -2
- package/dist/toggle.test.interactions.js +7 -7
- package/dist/tooltip.d.ts +2 -1
- package/dist/tooltip.js +1 -1
- package/dist/tooltip.styles.js +37 -14
- package/dist/tooltip.test.basics.d.ts +1 -1
- package/dist/tooltip.test.basics.js +19 -19
- package/dist/tree.d.ts +0 -2
- package/dist/tree.item.d.ts +5 -7
- package/dist/tree.item.icon-button.d.ts +1 -4
- package/dist/tree.item.js +1 -1
- package/dist/tree.item.menu.d.ts +0 -2
- package/dist/tree.item.menu.test.basics.js +9 -9
- package/dist/tree.item.styles.js +4 -3
- package/dist/tree.item.test.basics.js +43 -31
- package/dist/tree.test.basics.js +29 -29
- package/dist/tree.test.focus.js +77 -74
- package/package.json +12 -14
- package/dist/split-container.d.ts +0 -31
- package/dist/split-container.js +0 -1
- package/dist/split-container.styles.js +0 -132
- package/dist/split-container.test.basics.d.ts +0 -3
- package/dist/split-container.test.basics.js +0 -445
- package/dist/split-container.test.interactions.d.ts +0 -1
- package/dist/split-container.test.interactions.js +0 -20
- package/dist/split-link.d.ts +0 -25
- package/dist/split-link.js +0 -1
- package/dist/split-link.test.basics.d.ts +0 -1
- package/dist/split-link.test.basics.js +0 -93
- package/dist/split-link.test.interactions.d.ts +0 -1
- package/dist/split-link.test.interactions.js +0 -20
- package/dist/status-indicator.d.ts +0 -30
- package/dist/status-indicator.js +0 -1
- package/dist/status-indicator.stories.d.ts +0 -5
- package/dist/status-indicator.styles.js +0 -58
- package/dist/status-indicator.test.basics.d.ts +0 -1
- package/dist/status-indicator.test.basics.js +0 -102
- /package/dist/{split-container.styles.d.ts → split-button.primary-button.styles.d.ts} +0 -0
- /package/dist/{status-indicator.styles.d.ts → split-button.secondary-button.styles.d.ts} +0 -0
@@ -119,10 +119,8 @@ it('selects an option when its icon is clicked', async () => {
|
|
119
119
|
// Wait for it to open.
|
120
120
|
await aTimeout(0);
|
121
121
|
const option = component.querySelector('glide-core-dropdown-option');
|
122
|
-
option
|
123
|
-
?.querySelector('[
|
124
|
-
?.assignedElements()
|
125
|
-
?.at(0)
|
122
|
+
option
|
123
|
+
?.querySelector('[slot="icon"]')
|
126
124
|
?.dispatchEvent(new Event('click', { bubbles: true }));
|
127
125
|
expect(option?.selected).to.be.true;
|
128
126
|
});
|
@@ -549,3 +547,27 @@ it('clicks the button when `click()` is called', async () => {
|
|
549
547
|
const event = await oneEvent(button, 'click');
|
550
548
|
expect(event instanceof PointerEvent).to.be.true;
|
551
549
|
});
|
550
|
+
it('unhides its options when made unfilterable', async () => {
|
551
|
+
const component = await fixture(html `<glide-core-dropdown
|
552
|
+
label="Label"
|
553
|
+
placeholder="Placeholder"
|
554
|
+
filterable
|
555
|
+
>
|
556
|
+
<glide-core-dropdown-option
|
557
|
+
label="One"
|
558
|
+
value="one"
|
559
|
+
></glide-core-dropdown-option>
|
560
|
+
|
561
|
+
<glide-core-dropdown-option
|
562
|
+
label="Two"
|
563
|
+
value="two"
|
564
|
+
></glide-core-dropdown-option>
|
565
|
+
</glide-core-dropdown>`);
|
566
|
+
component.focus();
|
567
|
+
await sendKeys({ type: 'one' });
|
568
|
+
component.filterable = false;
|
569
|
+
const options = [
|
570
|
+
...component.querySelectorAll('glide-core-dropdown-option'),
|
571
|
+
].filter(({ hidden }) => !hidden);
|
572
|
+
expect(options.length).to.equal(2);
|
573
|
+
});
|
@@ -8,8 +8,6 @@ declare global {
|
|
8
8
|
}
|
9
9
|
}
|
10
10
|
/**
|
11
|
-
* @description Aligns form control labels and the controls themselves in two columns. Only horizontally oriented controls are supported.
|
12
|
-
*
|
13
11
|
* @slot - GlideCoreCheckbox | GlideCoreCheckboxGroup | GlideCoreDropdown | GlideCoreInput | GlideCoreTextArea.
|
14
12
|
*/
|
15
13
|
export default class GlideCoreFormControlsLayout extends LitElement {
|
package/dist/icon-button.d.ts
CHANGED
@@ -5,9 +5,7 @@ declare global {
|
|
5
5
|
}
|
6
6
|
}
|
7
7
|
/**
|
8
|
-
* @
|
9
|
-
*
|
10
|
-
* @slot - Reserved for the icon to display inside of the button.
|
8
|
+
* @slot - An icon.
|
11
9
|
*/
|
12
10
|
export default class GlideCoreIconButton extends LitElement {
|
13
11
|
#private;
|
@@ -17,9 +15,9 @@ export default class GlideCoreIconButton extends LitElement {
|
|
17
15
|
ariaExpanded: 'true' | 'false' | null;
|
18
16
|
ariaHasPopup: 'true' | 'false' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog' | null;
|
19
17
|
disabled: boolean;
|
20
|
-
/** For screenreaders. Required. */
|
21
18
|
label: string;
|
22
19
|
variant: 'primary' | 'secondary' | 'tertiary';
|
20
|
+
click(): void;
|
23
21
|
firstUpdated(): void;
|
24
22
|
render(): import("lit").TemplateResult<1>;
|
25
23
|
}
|
package/dist/icon-button.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(t,e,o,r){var i,a=arguments.length,l=a<3?e:null===r?r=Object.getOwnPropertyDescriptor(e,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(t,e,o,r);else for(var n=t.length-1;n>=0;n--)(i=t[n])&&(l=(a<3?i(l):a>3?i(e,o,l):i(e,o))||l);return a>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{ifDefined}from"lit/directives/if-defined.js";import{owSlot}from"./library/ow.js";import styles from"./icon-button.styles.js";let GlideCoreIconButton=class GlideCoreIconButton extends LitElement{constructor(){super(...arguments),this.ariaControls=null,this.ariaExpanded=null,this.ariaHasPopup=null,this.disabled=!1,this.label="",this.variant="primary",this.#t=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#
|
1
|
+
var __decorate=this&&this.__decorate||function(t,e,o,r){var i,a=arguments.length,l=a<3?e:null===r?r=Object.getOwnPropertyDescriptor(e,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(t,e,o,r);else for(var n=t.length-1;n>=0;n--)(i=t[n])&&(l=(a<3?i(l):a>3?i(e,o,l):i(e,o))||l);return a>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{ifDefined}from"lit/directives/if-defined.js";import{owSlot}from"./library/ow.js";import styles from"./icon-button.styles.js";let GlideCoreIconButton=class GlideCoreIconButton extends LitElement{constructor(){super(...arguments),this.ariaControls=null,this.ariaExpanded=null,this.ariaHasPopup=null,this.disabled=!1,this.label="",this.variant="primary",this.#t=createRef(),this.#e=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}click(){this.#t.value?.click()}firstUpdated(){owSlot(this.#e.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)}" aria-label="${this.label}" class="${classMap({component:!0,primary:"primary"===this.variant,secondary:"secondary"===this.variant,tertiary:"tertiary"===this.variant})}" data-test="button" type="button" ?disabled="${this.disabled}" ${ref(this.#t)}><slot @slotchange="${this.#o}" ${ref(this.#e)}></slot></button>`}#t;#e;#o(){owSlot(this.#e.value)}};__decorate([property({attribute:"aria-controls",reflect:!0})],GlideCoreIconButton.prototype,"ariaControls",void 0),__decorate([property({attribute:"aria-expanded",reflect:!0})],GlideCoreIconButton.prototype,"ariaExpanded",void 0),__decorate([property({attribute:"aria-haspopup",reflect:!0})],GlideCoreIconButton.prototype,"ariaHasPopup",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreIconButton.prototype,"disabled",void 0),__decorate([property()],GlideCoreIconButton.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreIconButton.prototype,"variant",void 0),GlideCoreIconButton=__decorate([customElement("glide-core-icon-button")],GlideCoreIconButton);export default GlideCoreIconButton;
|
@@ -1,106 +1,38 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
2
2
|
import './icon-button.js';
|
3
3
|
import { ArgumentError } from 'ow';
|
4
|
-
import {
|
4
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
5
5
|
import GlideCoreIconButton from './icon-button.js';
|
6
6
|
import sinon from 'sinon';
|
7
7
|
GlideCoreIconButton.shadowRootOptions.mode = 'open';
|
8
|
-
const icon = html `<svg
|
9
|
-
width="16"
|
10
|
-
height="16"
|
11
|
-
stroke="currentColor"
|
12
|
-
fill="none"
|
13
|
-
stroke-linecap="round"
|
14
|
-
stroke-linejoin="round"
|
15
|
-
stroke-width="2"
|
16
|
-
viewBox="0 0 24 24"
|
17
|
-
aria-hidden="true"
|
18
|
-
>
|
19
|
-
<path d="M16.51 9.873l-4.459 4.31-4.458-4.31"></path>
|
20
|
-
</svg>`;
|
21
8
|
it('registers', async () => {
|
22
9
|
expect(window.customElements.get('glide-core-icon-button')).to.equal(GlideCoreIconButton);
|
23
10
|
});
|
24
11
|
it('is accessible', async () => {
|
25
|
-
const component = await fixture(html `<glide-core-icon-button label="
|
26
|
-
|
27
|
-
>`);
|
12
|
+
const component = await fixture(html `<glide-core-icon-button label="Label">
|
13
|
+
<div>Icon</div>
|
14
|
+
</glide-core-icon-button>`);
|
28
15
|
await expect(component).to.be.accessible();
|
29
16
|
});
|
30
17
|
it('has defaults', async () => {
|
31
|
-
const component = await fixture(html `<glide-core-icon-button label="
|
32
|
-
|
33
|
-
>`);
|
34
|
-
const button = component.shadowRoot?.querySelector('button');
|
35
|
-
assert(button);
|
18
|
+
const component = await fixture(html `<glide-core-icon-button label="Label">
|
19
|
+
<div>Icon</div>
|
20
|
+
</glide-core-icon-button>`);
|
21
|
+
const button = component.shadowRoot?.querySelector('[data-test="button"]');
|
36
22
|
expect(component.ariaControls).to.equal(null);
|
37
23
|
expect(component.ariaExpanded).to.equal(null);
|
38
24
|
expect(component.ariaHasPopup).to.equal(null);
|
39
|
-
expect(component.disabled).to.
|
25
|
+
expect(component.disabled).to.be.false;
|
40
26
|
expect(component.variant).to.equal('primary');
|
41
|
-
expect(button
|
42
|
-
expect(button
|
43
|
-
expect(button
|
44
|
-
expect(button
|
45
|
-
expect([...button.classList]).to.deep.equal(['component', 'primary']);
|
46
|
-
});
|
47
|
-
it('delegates focus', async () => {
|
48
|
-
const component = await fixture(html `<glide-core-icon-button label="test-icon-button"
|
49
|
-
>${icon}</glide-core-icon-button
|
50
|
-
>`);
|
51
|
-
component.focus();
|
52
|
-
expect(component.shadowRoot?.activeElement).to.equal(component.shadowRoot?.querySelector('button'));
|
53
|
-
});
|
54
|
-
it('uses the provided "label" for the aria-label', async () => {
|
55
|
-
const component = await fixture(html `<glide-core-icon-button label="test-icon-button"
|
56
|
-
>${icon}</glide-core-icon-button
|
57
|
-
>`);
|
58
|
-
expect(component.shadowRoot?.querySelector('button')?.getAttribute('aria-label')).to.equal('test-icon-button');
|
59
|
-
});
|
60
|
-
it('renders a default slot', async () => {
|
61
|
-
const component = await fixture(html `<glide-core-icon-button label="test-icon-button"
|
62
|
-
><span data-content>Inner content</span></glide-core-icon-button
|
63
|
-
>`);
|
64
|
-
expect(component.querySelector('[data-content]')).to.be.ok;
|
65
|
-
expect(component.querySelector('[data-content]')).to.be.visible;
|
66
|
-
});
|
67
|
-
it('renders a primary variant', async () => {
|
68
|
-
const component = await fixture(html `<glide-core-icon-button label="test-icon-button" variant="primary"
|
69
|
-
>${icon}</glide-core-icon-button
|
70
|
-
>`);
|
71
|
-
expect([
|
72
|
-
...component.shadowRoot.querySelector('button').classList,
|
73
|
-
]).to.deep.equal(['component', 'primary']);
|
74
|
-
});
|
75
|
-
it('renders a secondary variant', async () => {
|
76
|
-
const component = await fixture(html `<glide-core-icon-button label="test-icon-button" variant="secondary"
|
77
|
-
>${icon}</glide-core-icon-button
|
78
|
-
>`);
|
79
|
-
expect([
|
80
|
-
...component.shadowRoot.querySelector('button').classList,
|
81
|
-
]).to.deep.equal(['component', 'secondary']);
|
82
|
-
});
|
83
|
-
it('renders a tertiary variant', async () => {
|
84
|
-
const component = await fixture(html `<glide-core-icon-button label="test-icon-button" variant="tertiary"
|
85
|
-
>${icon}</glide-core-icon-button
|
86
|
-
>`);
|
87
|
-
expect([
|
88
|
-
...component.shadowRoot.querySelector('button').classList,
|
89
|
-
]).to.deep.equal(['component', 'tertiary']);
|
90
|
-
});
|
91
|
-
it('sets the disabled attribute', async () => {
|
92
|
-
const component = await fixture(html `<glide-core-icon-button label="test-icon-button" disabled
|
93
|
-
>${icon}</glide-core-icon-button
|
94
|
-
>`);
|
95
|
-
expect(component.disabled).to.equal(true);
|
96
|
-
expect(component.shadowRoot?.querySelector('button')?.disabled).to.equal(true);
|
27
|
+
expect(button?.getAttribute('aria-controls')).to.equal(null);
|
28
|
+
expect(button?.ariaExpanded).to.equal(null);
|
29
|
+
expect(button?.ariaHasPopup).to.equal(null);
|
30
|
+
expect(button?.disabled).to.be.false;
|
97
31
|
});
|
98
32
|
it('throws if it does not have a default slot', async () => {
|
99
33
|
const spy = sinon.spy();
|
100
34
|
try {
|
101
|
-
await fixture(html `<glide-core-icon-button
|
102
|
-
label="test-icon-button"
|
103
|
-
></glide-core-icon-button>`);
|
35
|
+
await fixture(html `<glide-core-icon-button label="Label"></glide-core-icon-button>`);
|
104
36
|
}
|
105
37
|
catch (error) {
|
106
38
|
if (error instanceof ArgumentError) {
|
@@ -0,0 +1 @@
|
|
1
|
+
import './icon-button.js';
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
2
|
+
import './icon-button.js';
|
3
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
4
|
+
import GlideCoreIconButton from './icon-button.js';
|
5
|
+
GlideCoreIconButton.shadowRootOptions.mode = 'open';
|
6
|
+
it('focuses its button when `focus()` is called', async () => {
|
7
|
+
const component = await fixture(html `<glide-core-icon-button label="Label">
|
8
|
+
<div>Icon</div>
|
9
|
+
</glide-core-icon-button>`);
|
10
|
+
component.focus();
|
11
|
+
const button = component.shadowRoot?.querySelector('[data-test="button"]');
|
12
|
+
expect(component.shadowRoot?.activeElement).to.equal(button);
|
13
|
+
});
|
package/dist/input.d.ts
CHANGED
@@ -9,16 +9,14 @@ declare global {
|
|
9
9
|
export declare const SUPPORTED_TYPES: readonly ["email", "number", "password", "search", "tel", "text", "url"];
|
10
10
|
type SupportedTypes = (typeof SUPPORTED_TYPES)[number];
|
11
11
|
/**
|
12
|
-
* @description An input with a label and optional description and tooltip. Participates in forms and validation via `FormData` and various methods.
|
13
|
-
*
|
14
12
|
* @event change - `(event: Event) => void`
|
15
13
|
* @event input - `(event: Event) => void`
|
16
14
|
* @event invalid - `(event: Event) => void`
|
17
15
|
*
|
18
16
|
* @slot tooltip - Content for the tooltip.
|
19
17
|
* @slot description - Additional information or context.
|
20
|
-
* @slot prefix - An optional icon
|
21
|
-
* @slot suffix - An optional icon
|
18
|
+
* @slot prefix-icon - An optional icon before the input field.
|
19
|
+
* @slot suffix-icon - An optional icon after the input field.
|
22
20
|
*/
|
23
21
|
export default class GlideCoreInput extends LitElement {
|
24
22
|
#private;
|
@@ -26,7 +24,7 @@ export default class GlideCoreInput extends LitElement {
|
|
26
24
|
static shadowRootOptions: ShadowRootInit;
|
27
25
|
static styles: import("lit").CSSResult[];
|
28
26
|
type: SupportedTypes;
|
29
|
-
name
|
27
|
+
name: string;
|
30
28
|
value: string;
|
31
29
|
label?: string;
|
32
30
|
hideLabel: boolean;
|
@@ -35,6 +33,7 @@ export default class GlideCoreInput extends LitElement {
|
|
35
33
|
clearable: boolean;
|
36
34
|
spellcheck: boolean;
|
37
35
|
autocapitalize: 'on' | 'off' | 'none' | 'sentences' | 'words' | 'characters';
|
36
|
+
autocomplete: 'on' | 'off';
|
38
37
|
/** For 'password' type, whether to show a button to toggle the password's visibility */
|
39
38
|
passwordToggle: boolean;
|
40
39
|
required: boolean;
|
package/dist/input.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(e,t,i,o){var r,s=arguments.length,a=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,i,o);else for(var l=e.length-1;l>=0;l--)(r=e[l])&&(a=(s<3?r(a):s>3?r(t,i,a):r(t,i))||a);return s>3&&a&&Object.defineProperty(t,i,a),a};import"./icon-button.js";import"./label.js";import{LitElement,html,nothing}from"lit";import{LocalizeController}from"./library/localize.js";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import magnifyingGlassIcon from"./icons/magnifying-glass.js";import ow from"./library/ow.js";import styles from"./input.styles.js";export const SUPPORTED_TYPES=["email","number","password","search","tel","text","url"];let GlideCoreInput=class GlideCoreInput extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed",delegatesFocus:!0}}static{this.styles=styles}get form(){return this.#e.form}get validity(){return!this.required||this.value||this.disabled?this.#t?this.#e.setValidity({tooLong:!0}," ",this.#i.value):this.#e.setValidity({}):this.#e.setValidity({valueMissing:!0}," ",this.#i.value),this.#e.validity}get willValidate(){return this.#e.willValidate}blur(){this.#i.value?.blur()}checkValidity(){this.isCheckingValidity=!0;const e=this.#e.checkValidity();return this.isCheckingValidity=!1,e}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#o)}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#o)}formResetCallback(){this.value=this.getAttribute("value")??""}get hasClearIcon(){return this.clearable&&!this.disabled&&!this.readonly}get isClearIconVisible(){return this.hasClearIcon&&this.value.length>0}render(){return html`<glide-core-private-label class="${classMap({left:"left"===this.privateSplit,middle:"middle"===this.privateSplit})}" orientation="${this.orientation}" split="${ifDefined(this.privateSplit??void 0)}" ?disabled="${this.disabled}" ?error="${this.#r||this.#t}" ?hide="${this.hideLabel}" ?required="${this.required}"><slot name="tooltip" slot="tooltip"></slot><label for="input">${this.label}</label><div class="${classMap({"input-container":!0,focused:this.hasFocus,empty:""===this.value,disabled:this.disabled,readonly:this.readonly&&!this.disabled,error:this.#r||this.#t})}" slot="control"><slot name="prefix"></slot><input aria-describedby="meta" aria-invalid="${this.#r||this.#t}" id="input" type="${"password"===this.type&&this.passwordVisible?"text":this.type}" .value="${this.value}" placeholder="${ifDefined(this.placeholder)}" autocapitalize="${
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,i,o){var r,s=arguments.length,a=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,i,o);else for(var l=e.length-1;l>=0;l--)(r=e[l])&&(a=(s<3?r(a):s>3?r(t,i,a):r(t,i))||a);return s>3&&a&&Object.defineProperty(t,i,a),a};import"./icon-button.js";import"./label.js";import{LitElement,html,nothing}from"lit";import{LocalizeController}from"./library/localize.js";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import magnifyingGlassIcon from"./icons/magnifying-glass.js";import ow from"./library/ow.js";import styles from"./input.styles.js";export const SUPPORTED_TYPES=["email","number","password","search","tel","text","url"];let GlideCoreInput=class GlideCoreInput extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed",delegatesFocus:!0}}static{this.styles=styles}get form(){return this.#e.form}get validity(){return!this.required||this.value||this.disabled?this.#t?this.#e.setValidity({tooLong:!0}," ",this.#i.value):this.#e.setValidity({}):this.#e.setValidity({valueMissing:!0}," ",this.#i.value),this.#e.validity}get willValidate(){return this.#e.willValidate}blur(){this.#i.value?.blur()}checkValidity(){this.isCheckingValidity=!0;const e=this.#e.checkValidity();return this.isCheckingValidity=!1,e}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#o)}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#o)}formResetCallback(){this.value=this.getAttribute("value")??""}get hasClearIcon(){return this.clearable&&!this.disabled&&!this.readonly}get isClearIconVisible(){return this.hasClearIcon&&this.value.length>0}render(){return html`<glide-core-private-label class="${classMap({left:"left"===this.privateSplit,middle:"middle"===this.privateSplit})}" orientation="${this.orientation}" split="${ifDefined(this.privateSplit??void 0)}" ?disabled="${this.disabled}" ?error="${this.#r||this.#t}" ?hide="${this.hideLabel}" ?required="${this.required}"><slot name="tooltip" slot="tooltip"></slot><label for="input">${this.label}</label><div class="${classMap({"input-container":!0,focused:this.hasFocus,empty:""===this.value,disabled:this.disabled,readonly:this.readonly&&!this.disabled,error:this.#r||this.#t})}" slot="control"><slot name="prefix-icon"></slot><input aria-describedby="meta" aria-invalid="${this.#r||this.#t}" id="input" type="${"password"===this.type&&this.passwordVisible?"text":this.type}" .value="${this.value}" placeholder="${ifDefined(this.placeholder)}" autocapitalize="${this.autocapitalize}" autocomplete="${this.autocomplete}" spellcheck="${this.spellcheck}" ?required="${this.required}" ?readonly="${this.readonly}" ?disabled="${this.disabled}" @focus="${this.#s}" @blur="${this.#a}" @change="${this.#l}" @input="${this.#n}" @keydown="${this.#d}" ${ref(this.#i)}> ${this.hasClearIcon?html`<glide-core-icon-button variant="tertiary" class="${classMap({"clear-icon-button":!0,"clear-icon-button--visible":this.isClearIconVisible})}" data-test="clear-button" label="${this.#h.term("clearEntry",this.label)}" @click="${this.#p}"><svg aria-hidden="true" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M6 6L18 18" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M18 6L6 18" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></glide-core-icon-button>`:nothing} ${"password"===this.type&&this.passwordToggle&&!this.disabled?html`<glide-core-icon-button variant="tertiary" class="password-toggle" data-test="password-toggle" label="${this.passwordVisible?"Hide password":"Show password"}" aria-controls="input" aria-expanded="${this.passwordVisible?"true":"false"}" @click="${this.#c}">${this.passwordVisible?html`<svg aria-hidden="true" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88"/></svg>`:html`<svg aria-hidden="true" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/></svg>`}</glide-core-icon-button>`:nothing}<div class="suffix-icon">${"search"===this.type?magnifyingGlassIcon:html`<slot name="suffix-icon"></slot>`}</div></div><div class="meta" id="meta" slot="description"><slot class="description" name="description"></slot>${this.maxlength?html`<div class="${classMap({"character-count":!0,error:this.#t})}" data-test="character-count-container"><span aria-hidden="true" data-test="character-count-text">${this.#h.term("displayedCharacterCount",this.#u,this.maxlength)} </span><span class="hidden" data-test="character-count-announcement">${this.#h.term("announcedCharacterCount",this.#u,this.maxlength)}</span></div>`:nothing}</div></glide-core-private-label>`}reportValidity(){this.isReportValidityOrSubmit=!0;const e=this.#e.reportValidity();return this.requestUpdate(),e}constructor(){super(),this.type="text",this.name="",this.value="",this.hideLabel=!1,this.orientation="horizontal",this.clearable=!1,this.spellcheck=!1,this.autocapitalize="on",this.autocomplete="on",this.passwordToggle=!1,this.required=!1,this.readonly=!1,this.disabled=!1,this.hasFocus=!1,this.isBlurring=!1,this.isCheckingValidity=!1,this.isReportValidityOrSubmit=!1,this.passwordVisible=!1,this.#i=createRef(),this.#h=new LocalizeController(this),this.#o=({formData:e})=>{this.name&&this.value&&!this.disabled&&e.append(this.name,this.value)},this.#e=this.attachInternals(),this.addEventListener("invalid",(e=>{if(e?.preventDefault(),this.isCheckingValidity||this.isBlurring)return;this.isReportValidityOrSubmit=!0;this.form?.querySelector(":invalid")===this&&this.focus()}))}#i;#e;#h;get#u(){return this.value.length}#o;get#t(){return Boolean(!this.disabled&&!this.readonly&&this.maxlength&&this.#u>this.maxlength)}get#r(){return!this.disabled&&!this.validity?.valid&&this.isReportValidityOrSubmit}#a(){this.isBlurring=!0,this.reportValidity(),this.isBlurring=!1,this.hasFocus=!1}#l(e){ow(this.#i.value,ow.object.instanceOf(HTMLInputElement)),this.value=this.#i.value?.value,this.dispatchEvent(new Event(e.type,e))}#p(e){this.value="",this.dispatchEvent(new Event("clear",{bubbles:!0})),this.#i.value?.focus(),e.stopPropagation()}#s(){this.hasFocus=!0}#n(){ow(this.#i.value,ow.object.instanceOf(HTMLInputElement)),this.value=this.#i.value.value}#d(e){"Enter"===e.key&&this.form?.requestSubmit()}#c(){this.passwordVisible=!this.passwordVisible}};__decorate([property()],GlideCoreInput.prototype,"type",void 0),__decorate([property({reflect:!0})],GlideCoreInput.prototype,"name",void 0),__decorate([property()],GlideCoreInput.prototype,"value",void 0),__decorate([property({reflect:!0})],GlideCoreInput.prototype,"label",void 0),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreInput.prototype,"hideLabel",void 0),__decorate([property({reflect:!0})],GlideCoreInput.prototype,"orientation",void 0),__decorate([property({reflect:!0})],GlideCoreInput.prototype,"placeholder",void 0),__decorate([property({type:Boolean})],GlideCoreInput.prototype,"clearable",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreInput.prototype,"spellcheck",void 0),__decorate([property({reflect:!0})],GlideCoreInput.prototype,"autocapitalize",void 0),__decorate([property({reflect:!0})],GlideCoreInput.prototype,"autocomplete",void 0),__decorate([property({attribute:"password-toggle",type:Boolean})],GlideCoreInput.prototype,"passwordToggle",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreInput.prototype,"required",void 0),__decorate([property({type:Boolean})],GlideCoreInput.prototype,"readonly",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreInput.prototype,"disabled",void 0),__decorate([property()],GlideCoreInput.prototype,"privateSplit",void 0),__decorate([property({type:Number,converter:e=>e&&Number.parseInt(e,10),reflect:!0})],GlideCoreInput.prototype,"maxlength",void 0),__decorate([state()],GlideCoreInput.prototype,"hasFocus",void 0),__decorate([state()],GlideCoreInput.prototype,"isBlurring",void 0),__decorate([state()],GlideCoreInput.prototype,"isCheckingValidity",void 0),__decorate([state()],GlideCoreInput.prototype,"isReportValidityOrSubmit",void 0),__decorate([state()],GlideCoreInput.prototype,"passwordVisible",void 0),GlideCoreInput=__decorate([customElement("glide-core-input")],GlideCoreInput);export default GlideCoreInput;
|
package/dist/input.styles.js
CHANGED
@@ -83,7 +83,7 @@ import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";exp
|
|
83
83
|
}
|
84
84
|
}
|
85
85
|
|
86
|
-
.suffix {
|
86
|
+
.suffix-icon {
|
87
87
|
align-items: center;
|
88
88
|
display: flex;
|
89
89
|
}
|
@@ -91,7 +91,7 @@ import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";exp
|
|
91
91
|
|
92
92
|
.clear-icon-button,
|
93
93
|
.password-toggle,
|
94
|
-
::slotted([slot='suffix']) {
|
94
|
+
::slotted([slot='suffix-icon']) {
|
95
95
|
align-items: center;
|
96
96
|
background: none;
|
97
97
|
border: none;
|
@@ -104,8 +104,8 @@ import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";exp
|
|
104
104
|
.clear-icon-button,
|
105
105
|
.password-toggle,
|
106
106
|
.search-icon,
|
107
|
-
::slotted([slot='prefix']),
|
108
|
-
::slotted([slot='suffix']) {
|
107
|
+
::slotted([slot='prefix-icon']),
|
108
|
+
::slotted([slot='suffix-icon']) {
|
109
109
|
display: flex;
|
110
110
|
}
|
111
111
|
|
@@ -136,55 +136,3 @@ it('does not render a character count when attribute `maxlength` is set less tha
|
|
136
136
|
const container = component.shadowRoot?.querySelector('[data-test="character-count-container"]');
|
137
137
|
expect(container).to.be.null;
|
138
138
|
});
|
139
|
-
it('supports a "tooltip" slot', async () => {
|
140
|
-
const component = await fixture(html `<glide-core-input label="test">
|
141
|
-
<div slot="tooltip">Tooltip</div>
|
142
|
-
</glide-core-input>`);
|
143
|
-
const assignedElements = component.shadowRoot
|
144
|
-
?.querySelector('slot[name="tooltip"]')
|
145
|
-
?.assignedElements();
|
146
|
-
expect(assignedElements?.at(0)?.textContent).to.equal('Tooltip');
|
147
|
-
});
|
148
|
-
it('supports a "description" slot', async () => {
|
149
|
-
const component = await fixture(html `
|
150
|
-
<glide-core-input label="Test">
|
151
|
-
<div slot="description">Description</div>
|
152
|
-
</glide-core-input>
|
153
|
-
`);
|
154
|
-
const assignedElements = component.shadowRoot
|
155
|
-
?.querySelector('slot[name="description"]')
|
156
|
-
?.assignedElements();
|
157
|
-
expect(assignedElements?.at(0)?.textContent).to.equal('Description');
|
158
|
-
});
|
159
|
-
it('supports a "prefix" icon slot', async () => {
|
160
|
-
const component = await fixture(html `
|
161
|
-
<glide-core-input label="Test">
|
162
|
-
<div slot="prefix">
|
163
|
-
<span data-svg></span>
|
164
|
-
</div>
|
165
|
-
</glide-core-input>
|
166
|
-
`);
|
167
|
-
const assignedElements = component.shadowRoot
|
168
|
-
?.querySelector('slot[name="prefix"]')
|
169
|
-
?.assignedElements();
|
170
|
-
const slottedSvg = assignedElements
|
171
|
-
?.at(0)
|
172
|
-
?.querySelector('[data-svg]');
|
173
|
-
expect(slottedSvg).to.exist;
|
174
|
-
});
|
175
|
-
it('supports a "suffix" icon slot', async () => {
|
176
|
-
const component = await fixture(html `
|
177
|
-
<glide-core-input label="Test">
|
178
|
-
<div slot="suffix">
|
179
|
-
<span data-svg></span>
|
180
|
-
</div>
|
181
|
-
</glide-core-input>
|
182
|
-
`);
|
183
|
-
const assignedElements = component.shadowRoot
|
184
|
-
?.querySelector('slot[name="suffix"]')
|
185
|
-
?.assignedElements();
|
186
|
-
const slottedSvg = assignedElements
|
187
|
-
?.at(0)
|
188
|
-
?.querySelector('[data-svg]');
|
189
|
-
expect(slottedSvg).to.exist;
|
190
|
-
});
|
@@ -9,90 +9,90 @@ import { sendKeys } from '@web/test-runner-commands';
|
|
9
9
|
// configured. But waiting a turn of the event loop, after which the event
|
10
10
|
// will have been dispatched, gets the job done as well.
|
11
11
|
it('dispatches a "change" event when typed in', async () => {
|
12
|
-
const
|
12
|
+
const component = await fixture(html `<glide-core-input></glide-core-input>`);
|
13
13
|
setTimeout(async () => {
|
14
|
-
|
14
|
+
component.focus();
|
15
15
|
await sendKeys({ type: 'testing' });
|
16
|
-
|
16
|
+
component.blur();
|
17
17
|
});
|
18
|
-
const event = await oneEvent(
|
18
|
+
const event = await oneEvent(component, 'change');
|
19
19
|
expect(event instanceof Event).to.be.true;
|
20
20
|
expect(event.bubbles).to.be.true;
|
21
21
|
});
|
22
22
|
it('dispatches an "input" event when typed in', async () => {
|
23
|
-
const
|
23
|
+
const component = await fixture(html `<glide-core-input></glide-core-input>`);
|
24
24
|
setTimeout(() => {
|
25
|
-
|
25
|
+
component.focus();
|
26
26
|
sendKeys({ type: 'testing' });
|
27
27
|
});
|
28
|
-
const event = await oneEvent(
|
28
|
+
const event = await oneEvent(component, 'input');
|
29
29
|
expect(event instanceof Event).to.be.true;
|
30
30
|
expect(event.bubbles).to.be.true;
|
31
31
|
});
|
32
32
|
it('dispatches an "invalid" event on submit when required and no value', async () => {
|
33
33
|
const form = document.createElement('form');
|
34
|
-
const
|
34
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
35
35
|
parentNode: form,
|
36
36
|
});
|
37
37
|
setTimeout(() => form.requestSubmit());
|
38
|
-
const event = await oneEvent(
|
38
|
+
const event = await oneEvent(component, 'invalid');
|
39
39
|
expect(event instanceof Event).to.be.true;
|
40
40
|
});
|
41
41
|
it('dispatches an "invalid" event after `checkValidity` is called when required and no value', async () => {
|
42
42
|
const form = document.createElement('form');
|
43
|
-
const
|
43
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
44
44
|
parentNode: form,
|
45
45
|
});
|
46
|
-
setTimeout(() =>
|
47
|
-
const event = await oneEvent(
|
46
|
+
setTimeout(() => component.checkValidity());
|
47
|
+
const event = await oneEvent(component, 'invalid');
|
48
48
|
expect(event instanceof Event).to.be.true;
|
49
49
|
});
|
50
50
|
it('dispatches an "invalid" event after `reportValidity` is called when required and no value', async () => {
|
51
51
|
const form = document.createElement('form');
|
52
|
-
const
|
52
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
53
53
|
parentNode: form,
|
54
54
|
});
|
55
|
-
setTimeout(() =>
|
56
|
-
const event = await oneEvent(
|
55
|
+
setTimeout(() => component.reportValidity());
|
56
|
+
const event = await oneEvent(component, 'invalid');
|
57
57
|
expect(event instanceof Event).to.be.true;
|
58
58
|
});
|
59
59
|
it('does not dispatch an "invalid" event after `checkValidity` is called when not required', async () => {
|
60
60
|
const form = document.createElement('form');
|
61
|
-
const
|
61
|
+
const component = await fixture(html `<glide-core-input></glide-core-input>`, {
|
62
62
|
parentNode: form,
|
63
63
|
});
|
64
64
|
const spy = sinon.spy();
|
65
|
-
|
66
|
-
|
65
|
+
component.addEventListener('invalid', spy);
|
66
|
+
component.checkValidity();
|
67
67
|
await aTimeout(0);
|
68
68
|
expect(spy.callCount).to.equal(0);
|
69
69
|
});
|
70
70
|
it('does not dispatch an "invalid" event after `checkValidity` is called when required and no value but disabled', async () => {
|
71
71
|
const form = document.createElement('form');
|
72
|
-
const
|
72
|
+
const component = await fixture(html `<glide-core-input disabled required></glide-core-input>`, { parentNode: form });
|
73
73
|
const spy = sinon.spy();
|
74
|
-
|
75
|
-
|
74
|
+
component.addEventListener('invalid', spy);
|
75
|
+
component.checkValidity();
|
76
76
|
await aTimeout(0);
|
77
77
|
expect(spy.callCount).to.equal(0);
|
78
78
|
});
|
79
79
|
it('does not dispatch an "invalid" event when `reportValidity` is called when not required,', async () => {
|
80
80
|
const form = document.createElement('form');
|
81
|
-
const
|
81
|
+
const component = await fixture(html `<glide-core-input></glide-core-input>`, {
|
82
82
|
parentNode: form,
|
83
83
|
});
|
84
84
|
const spy = sinon.spy();
|
85
|
-
|
86
|
-
|
85
|
+
component.addEventListener('invalid', spy);
|
86
|
+
component.reportValidity();
|
87
87
|
await aTimeout(0);
|
88
88
|
expect(spy.callCount).to.equal(0);
|
89
89
|
});
|
90
90
|
it('does not dispatch an "invalid" event when `reportValidity` is called when required and no value but disabled', async () => {
|
91
91
|
const form = document.createElement('form');
|
92
|
-
const
|
92
|
+
const component = await fixture(html `<glide-core-input disabled required></glide-core-input>`, { parentNode: form });
|
93
93
|
const spy = sinon.spy();
|
94
|
-
|
95
|
-
|
94
|
+
component.addEventListener('invalid', spy);
|
95
|
+
component.reportValidity();
|
96
96
|
await aTimeout(0);
|
97
97
|
expect(spy.callCount).to.equal(0);
|
98
98
|
});
|
package/dist/input.test.focus.js
CHANGED
@@ -4,54 +4,55 @@ import { expect, fixture, html } from '@open-wc/testing';
|
|
4
4
|
import GlideCoreInput from './input.js';
|
5
5
|
GlideCoreInput.shadowRootOptions.mode = 'open';
|
6
6
|
it('focuses the input when `focus()` is called', async () => {
|
7
|
-
const
|
8
|
-
|
9
|
-
const inputElement =
|
10
|
-
expect(
|
7
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`);
|
8
|
+
component.focus();
|
9
|
+
const inputElement = component.shadowRoot?.querySelector('input');
|
10
|
+
expect(component.shadowRoot?.activeElement).to.equal(inputElement);
|
11
11
|
});
|
12
12
|
it('focuses the input after submit when required and no value', async () => {
|
13
13
|
const form = document.createElement('form');
|
14
|
-
const
|
14
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
15
15
|
parentNode: form,
|
16
16
|
});
|
17
17
|
form.requestSubmit();
|
18
|
-
const inputElement =
|
19
|
-
expect(
|
18
|
+
const inputElement = component.shadowRoot?.querySelector('input');
|
19
|
+
expect(component.shadowRoot?.activeElement).to.be.equal(inputElement);
|
20
20
|
});
|
21
21
|
it('blurs the input and reports validity if `blur` is called', async () => {
|
22
|
-
const
|
23
|
-
|
24
|
-
const inputElement =
|
25
|
-
expect(
|
26
|
-
|
27
|
-
await
|
28
|
-
expect(
|
29
|
-
expect(
|
30
|
-
expect(
|
22
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`);
|
23
|
+
component.focus();
|
24
|
+
const inputElement = component.shadowRoot?.querySelector('input');
|
25
|
+
expect(component.shadowRoot?.activeElement).to.equal(inputElement);
|
26
|
+
component.blur();
|
27
|
+
await component.updateComplete;
|
28
|
+
expect(component.shadowRoot?.activeElement).to.equal(null);
|
29
|
+
expect(component.validity.valid).to.be.false;
|
30
|
+
expect(component.shadowRoot?.querySelector('glide-core-private-label')?.error)
|
31
|
+
.to.be.true;
|
31
32
|
});
|
32
33
|
it('focuses the input after `reportValidity` is called when required and no value', async () => {
|
33
34
|
const form = document.createElement('form');
|
34
|
-
const
|
35
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
35
36
|
parentNode: form,
|
36
37
|
});
|
37
|
-
|
38
|
-
const inputElement =
|
39
|
-
expect(
|
38
|
+
component.reportValidity();
|
39
|
+
const inputElement = component.shadowRoot?.querySelector('input');
|
40
|
+
expect(component.shadowRoot?.activeElement).to.equal(inputElement);
|
40
41
|
});
|
41
42
|
it('focuses the input after `requestSubmit` is called when required and no value', async () => {
|
42
43
|
const form = document.createElement('form');
|
43
|
-
const
|
44
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
44
45
|
parentNode: form,
|
45
46
|
});
|
46
47
|
form.requestSubmit();
|
47
|
-
const inputElement =
|
48
|
-
expect(
|
48
|
+
const inputElement = component.shadowRoot?.querySelector('input');
|
49
|
+
expect(component.shadowRoot?.activeElement === inputElement).to.be.true;
|
49
50
|
});
|
50
51
|
it('does not focus the input after `checkValidity` is called', async () => {
|
51
52
|
const form = document.createElement('form');
|
52
|
-
const
|
53
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
53
54
|
parentNode: form,
|
54
55
|
});
|
55
|
-
|
56
|
-
expect(
|
56
|
+
component.checkValidity();
|
57
|
+
expect(component.shadowRoot?.activeElement === null).to.be.true;
|
57
58
|
});
|
package/dist/input.test.form.js
CHANGED
@@ -6,21 +6,21 @@ import GlideCoreInput from './input.js';
|
|
6
6
|
import sinon from 'sinon';
|
7
7
|
it('can be reset to initial value', async () => {
|
8
8
|
const form = document.createElement('form');
|
9
|
-
const
|
9
|
+
const component = await fixture(html `<glide-core-input value="value"></glide-core-input>`, {
|
10
10
|
parentNode: form,
|
11
11
|
});
|
12
|
-
|
12
|
+
component.value = '';
|
13
13
|
form.reset();
|
14
|
-
expect(
|
14
|
+
expect(component.value).to.equal('value');
|
15
15
|
});
|
16
16
|
it('can be reset if there was no initial value', async () => {
|
17
17
|
const form = document.createElement('form');
|
18
|
-
const
|
18
|
+
const component = await fixture(html `<glide-core-input></glide-core-input>`, {
|
19
19
|
parentNode: form,
|
20
20
|
});
|
21
|
-
|
21
|
+
component.value = 'value';
|
22
22
|
form.reset();
|
23
|
-
expect(
|
23
|
+
expect(component.value).to.equal('');
|
24
24
|
});
|
25
25
|
it('has `formData` value when it has a value', async () => {
|
26
26
|
const form = document.createElement('form');
|