@crowdstrike/glide-core 0.9.6 → 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.
Files changed (207) hide show
  1. package/README.md +17 -53
  2. package/dist/accordion.d.ts +10 -10
  3. package/dist/accordion.js +1 -1
  4. package/dist/accordion.stories.d.ts +0 -1
  5. package/dist/accordion.styles.js +36 -38
  6. package/dist/accordion.test.basics.js +13 -95
  7. package/dist/accordion.test.events.js +21 -33
  8. package/dist/accordion.test.focus.d.ts +1 -0
  9. package/dist/accordion.test.focus.js +11 -0
  10. package/dist/accordion.test.interactions.d.ts +1 -0
  11. package/dist/accordion.test.interactions.js +75 -0
  12. package/dist/button-group.button.d.ts +2 -4
  13. package/dist/button-group.button.js +1 -1
  14. package/dist/button-group.button.styles.js +6 -14
  15. package/dist/button-group.button.test.basics.js +8 -17
  16. package/dist/button-group.button.test.interactions.js +4 -4
  17. package/dist/button-group.d.ts +0 -2
  18. package/dist/button-group.test.basics.js +10 -10
  19. package/dist/button-group.test.events.js +2 -2
  20. package/dist/button-group.test.interactions.js +1 -1
  21. package/dist/button.d.ts +7 -10
  22. package/dist/button.js +1 -1
  23. package/dist/button.styles.js +4 -7
  24. package/dist/button.test.basics.js +10 -26
  25. package/dist/button.test.events.js +9 -9
  26. package/dist/checkbox-group.d.ts +3 -4
  27. package/dist/checkbox-group.js +1 -1
  28. package/dist/checkbox-group.styles.js +13 -1
  29. package/dist/checkbox-group.test.basics.js +8 -12
  30. package/dist/checkbox-group.test.focus.js +7 -7
  31. package/dist/checkbox-group.test.interactions.d.ts +1 -0
  32. package/dist/checkbox-group.test.interactions.js +82 -0
  33. package/dist/checkbox.d.ts +5 -4
  34. package/dist/checkbox.js +1 -1
  35. package/dist/checkbox.styles.js +35 -15
  36. package/dist/checkbox.test.basics.js +6 -15
  37. package/dist/checkbox.test.focus.js +4 -2
  38. package/dist/checkbox.test.interactions.js +11 -11
  39. package/dist/drawer.d.ts +2 -5
  40. package/dist/drawer.js +1 -1
  41. package/dist/drawer.test.accessibility.js +8 -8
  42. package/dist/drawer.test.basics.js +16 -16
  43. package/dist/drawer.test.closing.js +18 -16
  44. package/dist/drawer.test.events.js +13 -24
  45. package/dist/drawer.test.methods.js +22 -22
  46. package/dist/dropdown.d.ts +7 -5
  47. package/dist/dropdown.js +1 -1
  48. package/dist/dropdown.option.d.ts +1 -3
  49. package/dist/dropdown.option.js +1 -1
  50. package/dist/dropdown.option.styles.js +31 -19
  51. package/dist/dropdown.option.test.basics.js +4 -4
  52. package/dist/dropdown.styles.js +39 -3
  53. package/dist/dropdown.test.basics.js +8 -13
  54. package/dist/dropdown.test.basics.multiple.js +63 -31
  55. package/dist/dropdown.test.basics.single.js +49 -0
  56. package/dist/dropdown.test.focus.filterable.js +12 -3
  57. package/dist/dropdown.test.focus.js +18 -2
  58. package/dist/dropdown.test.interactions.filterable.js +121 -45
  59. package/dist/dropdown.test.interactions.multiple.js +71 -30
  60. package/dist/dropdown.test.interactions.single.js +26 -4
  61. package/dist/form-controls-layout.d.ts +0 -2
  62. package/dist/icon-button.d.ts +2 -4
  63. package/dist/icon-button.js +1 -1
  64. package/dist/icon-button.test.basics.js +14 -82
  65. package/dist/icon-button.test.focus.d.ts +1 -0
  66. package/dist/icon-button.test.focus.js +13 -0
  67. package/dist/input.d.ts +4 -5
  68. package/dist/input.js +1 -1
  69. package/dist/input.styles.js +4 -4
  70. package/dist/input.test.basics.js +0 -52
  71. package/dist/input.test.events.js +27 -27
  72. package/dist/input.test.focus.js +27 -26
  73. package/dist/input.test.form.js +6 -6
  74. package/dist/input.test.validity.js +130 -130
  75. package/dist/label.d.ts +1 -3
  76. package/dist/label.js +1 -1
  77. package/dist/label.styles.js +5 -6
  78. package/dist/label.test.basics.js +4 -4
  79. package/dist/library/ow.js +1 -1
  80. package/dist/menu.button.d.ts +0 -2
  81. package/dist/menu.button.test.basics.js +3 -3
  82. package/dist/menu.d.ts +1 -4
  83. package/dist/menu.js +1 -1
  84. package/dist/menu.link.d.ts +1 -2
  85. package/dist/menu.link.js +1 -1
  86. package/dist/menu.options.d.ts +0 -2
  87. package/dist/menu.test.events.js +6 -6
  88. package/dist/menu.test.focus.js +5 -18
  89. package/dist/menu.test.interactions.js +48 -24
  90. package/dist/modal.d.ts +6 -17
  91. package/dist/modal.icon-button.d.ts +0 -2
  92. package/dist/modal.icon-button.test.basics.js +3 -3
  93. package/dist/modal.js +1 -1
  94. package/dist/modal.styles.js +13 -19
  95. package/dist/modal.tertiary-icon.d.ts +0 -3
  96. package/dist/modal.tertiary-icon.test.basics.js +3 -3
  97. package/dist/modal.test.basics.js +9 -5
  98. package/dist/modal.test.close.js +2 -2
  99. package/dist/modal.test.events.js +2 -2
  100. package/dist/radio-group.d.ts +0 -3
  101. package/dist/radio-group.js +1 -1
  102. package/dist/radio-group.test.basics.js +61 -61
  103. package/dist/radio-group.test.events.js +13 -13
  104. package/dist/radio-group.test.focus.js +1 -1
  105. package/dist/radio-group.test.form.js +2 -2
  106. package/dist/radio-group.test.validity.js +12 -12
  107. package/dist/radio.d.ts +0 -3
  108. package/dist/radio.styles.js +4 -12
  109. package/dist/split-button.d.ts +8 -11
  110. package/dist/split-button.js +1 -1
  111. package/dist/split-button.primary-button.d.ts +21 -0
  112. package/dist/split-button.primary-button.js +1 -0
  113. package/dist/split-button.primary-button.styles.js +96 -0
  114. package/dist/split-button.primary-button.test.basics.d.ts +1 -0
  115. package/dist/split-button.primary-button.test.basics.js +31 -0
  116. package/dist/split-button.primary-button.test.focus.d.ts +1 -0
  117. package/dist/split-button.primary-button.test.focus.js +14 -0
  118. package/dist/split-button.primary-link.d.ts +19 -0
  119. package/dist/split-button.primary-link.js +1 -0
  120. package/dist/split-button.primary-link.test.basics.d.ts +1 -0
  121. package/dist/split-button.primary-link.test.basics.js +30 -0
  122. package/dist/split-button.primary-link.test.focus.d.ts +1 -0
  123. package/dist/split-button.primary-link.test.focus.js +15 -0
  124. package/dist/split-button.secondary-button.d.ts +25 -0
  125. package/dist/split-button.secondary-button.js +1 -0
  126. package/dist/split-button.secondary-button.styles.js +103 -0
  127. package/dist/split-button.secondary-button.test.basics.d.ts +1 -0
  128. package/dist/split-button.secondary-button.test.basics.js +58 -0
  129. package/dist/split-button.secondary-button.test.focus.d.ts +1 -0
  130. package/dist/split-button.secondary-button.test.focus.js +14 -0
  131. package/dist/split-button.secondary-button.test.interactions.d.ts +2 -0
  132. package/dist/split-button.secondary-button.test.interactions.js +30 -0
  133. package/dist/split-button.stories.d.ts +4 -3
  134. package/dist/split-button.styles.js +1 -94
  135. package/dist/split-button.test.basics.d.ts +2 -1
  136. package/dist/split-button.test.basics.js +67 -80
  137. package/dist/split-button.test.interactions.d.ts +4 -0
  138. package/dist/split-button.test.interactions.js +51 -0
  139. package/dist/styles/opacity-and-scale-animation.js +2 -6
  140. package/dist/styles/variables.css +1 -1
  141. package/dist/tab.d.ts +2 -11
  142. package/dist/tab.group.d.ts +2 -5
  143. package/dist/tab.group.styles.js +12 -15
  144. package/dist/tab.group.test.basics.js +49 -34
  145. package/dist/tab.group.test.interactions.js +17 -14
  146. package/dist/tab.panel.d.ts +0 -3
  147. package/dist/tab.test.basics.js +6 -5
  148. package/dist/tag.d.ts +6 -4
  149. package/dist/tag.js +1 -1
  150. package/dist/tag.styles.js +36 -36
  151. package/dist/tag.test.basics.js +16 -109
  152. package/dist/tag.test.events.js +12 -8
  153. package/dist/tag.test.focus.js +2 -3
  154. package/dist/tag.test.interactions.d.ts +1 -0
  155. package/dist/tag.test.interactions.js +34 -0
  156. package/dist/textarea.d.ts +2 -3
  157. package/dist/textarea.js +2 -2
  158. package/dist/textarea.test.basics.js +8 -8
  159. package/dist/textarea.test.events.js +55 -55
  160. package/dist/textarea.test.form.js +9 -9
  161. package/dist/textarea.test.validity.js +167 -135
  162. package/dist/toasts.d.ts +1 -5
  163. package/dist/toasts.test.basics.js +2 -1
  164. package/dist/toasts.toast.d.ts +1 -4
  165. package/dist/toasts.toast.js +1 -1
  166. package/dist/toasts.toast.styles.js +12 -0
  167. package/dist/toggle.d.ts +0 -2
  168. package/dist/toggle.styles.js +1 -5
  169. package/dist/toggle.test.basics.js +2 -2
  170. package/dist/toggle.test.interactions.js +7 -7
  171. package/dist/tooltip.d.ts +2 -1
  172. package/dist/tooltip.js +1 -1
  173. package/dist/tooltip.styles.js +36 -13
  174. package/dist/tooltip.test.basics.d.ts +1 -1
  175. package/dist/tooltip.test.basics.js +19 -19
  176. package/dist/tree.d.ts +0 -2
  177. package/dist/tree.item.d.ts +5 -7
  178. package/dist/tree.item.icon-button.d.ts +1 -4
  179. package/dist/tree.item.js +1 -1
  180. package/dist/tree.item.menu.d.ts +0 -2
  181. package/dist/tree.item.menu.test.basics.js +9 -9
  182. package/dist/tree.item.styles.js +4 -3
  183. package/dist/tree.item.test.basics.js +43 -31
  184. package/dist/tree.test.basics.js +29 -29
  185. package/dist/tree.test.focus.js +77 -74
  186. package/package.json +12 -14
  187. package/dist/split-container.d.ts +0 -31
  188. package/dist/split-container.js +0 -1
  189. package/dist/split-container.styles.js +0 -132
  190. package/dist/split-container.test.basics.d.ts +0 -3
  191. package/dist/split-container.test.basics.js +0 -445
  192. package/dist/split-container.test.interactions.d.ts +0 -1
  193. package/dist/split-container.test.interactions.js +0 -20
  194. package/dist/split-link.d.ts +0 -25
  195. package/dist/split-link.js +0 -1
  196. package/dist/split-link.test.basics.d.ts +0 -1
  197. package/dist/split-link.test.basics.js +0 -93
  198. package/dist/split-link.test.interactions.d.ts +0 -1
  199. package/dist/split-link.test.interactions.js +0 -20
  200. package/dist/status-indicator.d.ts +0 -30
  201. package/dist/status-indicator.js +0 -1
  202. package/dist/status-indicator.stories.d.ts +0 -5
  203. package/dist/status-indicator.styles.js +0 -58
  204. package/dist/status-indicator.test.basics.d.ts +0 -1
  205. package/dist/status-indicator.test.basics.js +0 -102
  206. /package/dist/{split-container.styles.d.ts → split-button.primary-button.styles.d.ts} +0 -0
  207. /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?.shadowRoot
123
- ?.querySelector('[data-test="icon-slot"]')
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 {
@@ -5,9 +5,7 @@ declare global {
5
5
  }
6
6
  }
7
7
  /**
8
- * @description A button with only an icon.
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
  }
@@ -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.#t.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})}" type="button" ?disabled="${this.disabled}"><slot @slotchange="${this.#e}" ${ref(this.#t)}></slot></button>`}#t;#e(){owSlot(this.#t.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
+ 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 { assert, expect, fixture, html } from '@open-wc/testing';
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="test-icon-button"
26
- >${icon}</glide-core-icon-button
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="test-icon-button"
32
- >${icon}</glide-core-icon-button
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.equal(false);
25
+ expect(component.disabled).to.be.false;
40
26
  expect(component.variant).to.equal('primary');
41
- expect(button.getAttribute('aria-controls')).to.equal(null);
42
- expect(button.ariaExpanded).to.equal(null);
43
- expect(button.ariaHasPopup).to.equal(null);
44
- expect(button.disabled).to.equal(false);
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 slot to display before the input.
21
- * @slot suffix - An optional icon slot to display after the input.
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?: string;
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="${ifDefined(this.autocapitalize)}" 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">${"search"===this.type?magnifyingGlassIcon:html`<slot name="suffix"></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.value="",this.hideLabel=!1,this.orientation="horizontal",this.clearable=!1,this.spellcheck=!1,this.autocapitalize="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()],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()],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()],GlideCoreInput.prototype,"autocapitalize",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({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)})],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;
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;
@@ -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 input = await fixture(html `<glide-core-input></glide-core-input>`);
12
+ const component = await fixture(html `<glide-core-input></glide-core-input>`);
13
13
  setTimeout(async () => {
14
- input.focus();
14
+ component.focus();
15
15
  await sendKeys({ type: 'testing' });
16
- input.blur();
16
+ component.blur();
17
17
  });
18
- const event = await oneEvent(input, 'change');
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 input = await fixture(html `<glide-core-input></glide-core-input>`);
23
+ const component = await fixture(html `<glide-core-input></glide-core-input>`);
24
24
  setTimeout(() => {
25
- input.focus();
25
+ component.focus();
26
26
  sendKeys({ type: 'testing' });
27
27
  });
28
- const event = await oneEvent(input, 'input');
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 input = await fixture(html `<glide-core-input required></glide-core-input>`, {
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(input, 'invalid');
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 input = await fixture(html `<glide-core-input required></glide-core-input>`, {
43
+ const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
44
44
  parentNode: form,
45
45
  });
46
- setTimeout(() => input.checkValidity());
47
- const event = await oneEvent(input, 'invalid');
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 input = await fixture(html `<glide-core-input required></glide-core-input>`, {
52
+ const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
53
53
  parentNode: form,
54
54
  });
55
- setTimeout(() => input.reportValidity());
56
- const event = await oneEvent(input, 'invalid');
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 input = await fixture(html `<glide-core-input></glide-core-input>`, {
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
- input.addEventListener('invalid', spy);
66
- input.checkValidity();
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 input = await fixture(html `<glide-core-input disabled required></glide-core-input>`, { parentNode: form });
72
+ const component = await fixture(html `<glide-core-input disabled required></glide-core-input>`, { parentNode: form });
73
73
  const spy = sinon.spy();
74
- input.addEventListener('invalid', spy);
75
- input.checkValidity();
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 input = await fixture(html `<glide-core-input></glide-core-input>`, {
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
- input.addEventListener('invalid', spy);
86
- input.reportValidity();
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 input = await fixture(html `<glide-core-input disabled required></glide-core-input>`, { parentNode: form });
92
+ const component = await fixture(html `<glide-core-input disabled required></glide-core-input>`, { parentNode: form });
93
93
  const spy = sinon.spy();
94
- input.addEventListener('invalid', spy);
95
- input.reportValidity();
94
+ component.addEventListener('invalid', spy);
95
+ component.reportValidity();
96
96
  await aTimeout(0);
97
97
  expect(spy.callCount).to.equal(0);
98
98
  });
@@ -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 input = await fixture(html `<glide-core-input required></glide-core-input>`);
8
- input.focus();
9
- const inputElement = input.shadowRoot?.querySelector('input');
10
- expect(input.shadowRoot?.activeElement).to.equal(inputElement);
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 input = await fixture(html `<glide-core-input required></glide-core-input>`, {
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 = input.shadowRoot?.querySelector('input');
19
- expect(input.shadowRoot?.activeElement).to.be.equal(inputElement);
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 input = await fixture(html `<glide-core-input required></glide-core-input>`);
23
- input.focus();
24
- const inputElement = input.shadowRoot?.querySelector('input');
25
- expect(input.shadowRoot?.activeElement).to.equal(inputElement);
26
- input.blur();
27
- await input.updateComplete;
28
- expect(input.shadowRoot?.activeElement).to.equal(null);
29
- expect(input.validity.valid).to.equal(false);
30
- expect(input.shadowRoot?.querySelector('glide-core-private-label')?.error).to.equal(true);
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 input = await fixture(html `<glide-core-input required></glide-core-input>`, {
35
+ const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
35
36
  parentNode: form,
36
37
  });
37
- input.reportValidity();
38
- const inputElement = input.shadowRoot?.querySelector('input');
39
- expect(input.shadowRoot?.activeElement).to.equal(inputElement);
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 input = await fixture(html `<glide-core-input required></glide-core-input>`, {
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 = input.shadowRoot?.querySelector('input');
48
- expect(input.shadowRoot?.activeElement === inputElement).to.be.true;
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 input = await fixture(html `<glide-core-input required></glide-core-input>`, {
53
+ const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
53
54
  parentNode: form,
54
55
  });
55
- input.checkValidity();
56
- expect(input.shadowRoot?.activeElement === null).to.be.true;
56
+ component.checkValidity();
57
+ expect(component.shadowRoot?.activeElement === null).to.be.true;
57
58
  });
@@ -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 input = await fixture(html `<glide-core-input value="value"></glide-core-input>`, {
9
+ const component = await fixture(html `<glide-core-input value="value"></glide-core-input>`, {
10
10
  parentNode: form,
11
11
  });
12
- input.value = '';
12
+ component.value = '';
13
13
  form.reset();
14
- expect(input.value).to.equal('value');
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 input = await fixture(html `<glide-core-input></glide-core-input>`, {
18
+ const component = await fixture(html `<glide-core-input></glide-core-input>`, {
19
19
  parentNode: form,
20
20
  });
21
- input.value = 'value';
21
+ component.value = 'value';
22
22
  form.reset();
23
- expect(input.value).to.equal('');
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');