@noctuatech/uswds 1.3.1 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/package.json +6 -6
  2. package/src/lib/accordion/accordion.element.ts +18 -26
  3. package/src/lib/alert/alert.element.ts +21 -20
  4. package/src/lib/alert/alert.stories.ts +10 -15
  5. package/src/lib/file-input/file-input.element.ts +36 -31
  6. package/src/lib/icon/icon.element.ts +37 -27
  7. package/src/lib/input/input.element.ts +30 -39
  8. package/src/lib/input/input.test.ts +14 -16
  9. package/src/lib/input-mask/input-mask.element.ts +13 -13
  10. package/src/lib/input-mask/input-mask.stories.ts +7 -12
  11. package/src/lib/input-mask/input-mask.test.ts +45 -50
  12. package/src/lib/services/icon.service.test.ts +14 -14
  13. package/src/lib/services/icon.service.ts +18 -17
  14. package/src/lib/textarea/textarea.element.ts +14 -18
  15. package/target/lib/accordion/accordion.element.d.ts +4 -3
  16. package/target/lib/accordion/accordion.element.js +20 -12
  17. package/target/lib/accordion/accordion.element.js.map +1 -1
  18. package/target/lib/alert/alert.element.d.ts +4 -4
  19. package/target/lib/alert/alert.element.js +20 -12
  20. package/target/lib/alert/alert.element.js.map +1 -1
  21. package/target/lib/alert/alert.stories.d.ts +2 -2
  22. package/target/lib/alert/alert.stories.js +3 -3
  23. package/target/lib/alert/alert.stories.js.map +1 -1
  24. package/target/lib/file-input/file-input.element.d.ts +0 -1
  25. package/target/lib/file-input/file-input.element.js +6 -14
  26. package/target/lib/file-input/file-input.element.js.map +1 -1
  27. package/target/lib/icon/icon.element.d.ts +4 -4
  28. package/target/lib/icon/icon.element.js +35 -25
  29. package/target/lib/icon/icon.element.js.map +1 -1
  30. package/target/lib/input/input.element.d.ts +5 -5
  31. package/target/lib/input/input.element.js +20 -22
  32. package/target/lib/input/input.element.js.map +1 -1
  33. package/target/lib/input/input.test.d.ts +1 -1
  34. package/target/lib/input/input.test.js +13 -13
  35. package/target/lib/input/input.test.js.map +1 -1
  36. package/target/lib/input-mask/input-mask.element.d.ts +1 -1
  37. package/target/lib/input-mask/input-mask.element.js +11 -11
  38. package/target/lib/input-mask/input-mask.element.js.map +1 -1
  39. package/target/lib/input-mask/input-mask.stories.d.ts +2 -2
  40. package/target/lib/input-mask/input-mask.stories.js +5 -5
  41. package/target/lib/input-mask/input-mask.stories.js.map +1 -1
  42. package/target/lib/input-mask/input-mask.test.d.ts +2 -2
  43. package/target/lib/input-mask/input-mask.test.js +43 -43
  44. package/target/lib/input-mask/input-mask.test.js.map +1 -1
  45. package/target/lib/services/icon.service.d.ts +2 -1
  46. package/target/lib/services/icon.service.js +15 -15
  47. package/target/lib/services/icon.service.js.map +1 -1
  48. package/target/lib/services/icon.service.test.js +14 -14
  49. package/target/lib/services/icon.service.test.js.map +1 -1
  50. package/target/lib/textarea/textarea.element.d.ts +1 -1
  51. package/target/lib/textarea/textarea.element.js +10 -10
  52. package/target/lib/textarea/textarea.element.js.map +1 -1
@@ -1,18 +1,16 @@
1
- import "./input.element.js";
1
+ import './input.element.js';
2
2
 
3
- import { assert, fixture, html } from "@open-wc/testing";
4
- import { userEvent } from "@testing-library/user-event";
3
+ import { assert, fixture, html } from '@open-wc/testing';
4
+ import { userEvent } from '@testing-library/user-event';
5
5
 
6
- describe("usa-input", () => {
7
- it("should be accessible", async () => {
8
- const form = await fixture<HTMLFormElement>(html`
9
- <usa-input name="fname" value="Foo">Hello World</usa-input>
10
- `);
6
+ describe('usa-input', () => {
7
+ it('should be accessible', async () => {
8
+ const form = await fixture<HTMLFormElement>(html` <usa-input name="fname" value="Foo">Hello World</usa-input> `);
11
9
 
12
10
  return assert.isAccessible(form);
13
11
  });
14
12
 
15
- it("should submit form with default values", async () => {
13
+ it('should submit form with default values', async () => {
16
14
  const form = await fixture<HTMLFormElement>(html`
17
15
  <form>
18
16
  <usa-input name="fname" value="Foo">Hello World</usa-input>
@@ -23,10 +21,10 @@ describe("usa-input", () => {
23
21
 
24
22
  const value = new FormData(form);
25
23
 
26
- assert.equal(value.get("fname"), "Foo");
24
+ assert.equal(value.get('fname'), 'Foo');
27
25
  });
28
26
 
29
- it("should update form value as input value changed", async () => {
27
+ it('should update form value as input value changed', async () => {
30
28
  const form = await fixture<HTMLFormElement>(html`
31
29
  <form>
32
30
  <usa-input name="fname">Hello World</usa-input>
@@ -35,19 +33,19 @@ describe("usa-input", () => {
35
33
  </form>
36
34
  `);
37
35
 
38
- const input = form.querySelector("usa-input");
39
- const nativeInput = input?.shadowRoot?.querySelector("input");
36
+ const input = form.querySelector('usa-input');
37
+ const nativeInput = input?.shadowRoot?.querySelector('input');
40
38
 
41
39
  if (nativeInput) {
42
- await userEvent.type(nativeInput, "Bar");
40
+ await userEvent.type(nativeInput, 'Bar');
43
41
  }
44
42
 
45
43
  const value = new FormData(form);
46
44
 
47
- assert.equal(value.get("fname"), "Bar");
45
+ assert.equal(value.get('fname'), 'Bar');
48
46
  });
49
47
 
50
- it("should not submit when not valid", async () => {
48
+ it('should not submit when not valid', async () => {
51
49
  const form = await fixture<HTMLFormElement>(html`
52
50
  <form>
53
51
  <usa-input name="fname" required>Hello World</usa-input>
@@ -1,16 +1,16 @@
1
- import { attr, css, element, html, listen, queryAll } from "@joist/element";
1
+ import { attr, css, element, html, listen, queryAll } from '@joist/element';
2
2
 
3
- import { PATTERN_CHARS, type PatternChar, REG_EXPS, format } from "./format.js";
4
- import type { MaskableElement } from "./maskable.element.js";
3
+ import { PATTERN_CHARS, type PatternChar, REG_EXPS, format } from './format.js';
4
+ import type { MaskableElement } from './maskable.element.js';
5
5
 
6
6
  declare global {
7
7
  interface HTMLElementTagNameMap {
8
- "usa-input-mask": USAInputMaskElement;
8
+ 'usa-input-mask': USAInputMaskElement;
9
9
  }
10
10
  }
11
11
 
12
12
  @element({
13
- tagName: "usa-input-mask",
13
+ tagName: 'usa-input-mask',
14
14
  shadowDom: [
15
15
  css`
16
16
  :host {
@@ -22,13 +22,13 @@ declare global {
22
22
  })
23
23
  export class USAInputMaskElement extends HTMLElement {
24
24
  @attr()
25
- accessor mask = "";
25
+ accessor mask = '';
26
26
 
27
- #maskables = queryAll<MaskableElement>("[mask]", this);
27
+ #maskables = queryAll<MaskableElement>('[mask]', this);
28
28
 
29
29
  connectedCallback() {
30
30
  for (const input of this.#maskables()) {
31
- const { formatted } = format(input.value, this.#getMaskFor(input));
31
+ const { formatted } = format(input.value || input.getAttribute('value') || '', this.#getMaskFor(input));
32
32
 
33
33
  if (formatted) {
34
34
  input.value = formatted;
@@ -36,7 +36,7 @@ export class USAInputMaskElement extends HTMLElement {
36
36
  }
37
37
  }
38
38
 
39
- @listen("input")
39
+ @listen('input')
40
40
  onInput(e: Event) {
41
41
  const input = e.target as MaskableElement;
42
42
  const selectionStart = input.selectionStart || 0;
@@ -60,7 +60,7 @@ export class USAInputMaskElement extends HTMLElement {
60
60
  }
61
61
  }
62
62
 
63
- @listen("keydown")
63
+ @listen('keydown')
64
64
  onKeyDown(e: KeyboardEvent) {
65
65
  const input = e.target as MaskableElement;
66
66
  const mask = this.#getMaskFor(input);
@@ -72,12 +72,12 @@ export class USAInputMaskElement extends HTMLElement {
72
72
  if (input.value.length >= mask.length) {
73
73
  // prevent default once value is the same as the mask length
74
74
  e.preventDefault();
75
- } else if (patternChar === "9") {
75
+ } else if (patternChar === '9') {
76
76
  if (!REG_EXPS.Numbers.test(e.key)) {
77
77
  // if pattern char specifies number and is not
78
78
  e.preventDefault();
79
79
  }
80
- } else if (patternChar === "A") {
80
+ } else if (patternChar === 'A') {
81
81
  if (!REG_EXPS.Letters.test(e.key)) {
82
82
  // if pattern char specifies letter and is not
83
83
  e.preventDefault();
@@ -87,6 +87,6 @@ export class USAInputMaskElement extends HTMLElement {
87
87
  }
88
88
 
89
89
  #getMaskFor(input: MaskableElement) {
90
- return this.mask || input.getAttribute("mask") || "";
90
+ return this.mask || input.getAttribute('mask') || '';
91
91
  }
92
92
  }
@@ -1,21 +1,16 @@
1
- import type { Meta, StoryObj } from "@storybook/web-components";
2
- import { html } from "lit";
1
+ import type { Meta, StoryObj } from '@storybook/web-components';
2
+ import { html } from 'lit';
3
3
 
4
- import type { USAInputMaskElement } from "./input-mask.element.js";
4
+ import type { USAInputMaskElement } from './input-mask.element.js';
5
5
 
6
6
  // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
7
7
  const meta = {
8
- title: "input-mask",
9
- tags: ["autodocs"],
8
+ title: 'input-mask',
9
+ tags: ['autodocs'],
10
10
  render(args) {
11
11
  return html`
12
12
  <usa-input-mask>
13
- <usa-input
14
- name="phone"
15
- placeholder=${args.mask}
16
- autocomplete="off"
17
- mask=${args.mask}
18
- >
13
+ <usa-input name="phone" placeholder=${args.mask} autocomplete="off" mask=${args.mask} value="1234567890">
19
14
  Phone:
20
15
  </usa-input>
21
16
  </usa-input-mask>
@@ -23,7 +18,7 @@ const meta = {
23
18
  },
24
19
  argTypes: {},
25
20
  args: {
26
- mask: "(999) 999-9999",
21
+ mask: '(999) 999-9999',
27
22
  },
28
23
  } satisfies Meta<USAInputMaskElement>;
29
24
 
@@ -1,110 +1,105 @@
1
- import "./input-mask.element.js";
2
- import "../input/input.element.js";
1
+ import './input-mask.element.js';
2
+ import '../input/input.element.js';
3
3
 
4
- import { assert, fixture, html } from "@open-wc/testing";
4
+ import { assert, fixture, html } from '@open-wc/testing';
5
5
 
6
- import { format } from "./format.js";
7
- import type { USAInputMaskElement } from "./input-mask.element.js";
6
+ import { format } from './format.js';
7
+ import type { USAInputMaskElement } from './input-mask.element.js';
8
8
 
9
- describe("format", () => {
10
- it("should retrn the correct raw value", () => {
11
- assert.deepEqual(format("(123) 456 7890", "(***) ***-****"), {
12
- raw: "1234567890",
13
- formatted: "(123) 456-7890",
9
+ describe('format', () => {
10
+ it('should retrn the correct raw value', () => {
11
+ assert.deepEqual(format('(123) 456 7890', '(***) ***-****'), {
12
+ raw: '1234567890',
13
+ formatted: '(123) 456-7890',
14
14
  });
15
15
  });
16
16
 
17
- it("should return a formatted phone number (***) ***-****", () => {
18
- assert.deepEqual(format("1234567890", "(***) ***-****"), {
19
- raw: "1234567890",
20
- formatted: "(123) 456-7890",
17
+ it('should return a formatted phone number (***) ***-****', () => {
18
+ assert.deepEqual(format('1234567890', '(***) ***-****'), {
19
+ raw: '1234567890',
20
+ formatted: '(123) 456-7890',
21
21
  });
22
22
  });
23
23
 
24
- it("should return a formatted phone number ***-***-****", () => {
25
- assert.deepEqual(format("1234567890", "***-***-****"), {
26
- raw: "1234567890",
27
- formatted: "123-456-7890",
24
+ it('should return a formatted phone number ***-***-****', () => {
25
+ assert.deepEqual(format('1234567890', '***-***-****'), {
26
+ raw: '1234567890',
27
+ formatted: '123-456-7890',
28
28
  });
29
29
  });
30
30
 
31
- it("should only allow numbers", () => {
32
- assert.deepEqual(format("304213abcd", "999-999-9999"), {
33
- raw: "304213abcd",
34
- formatted: "304-213-",
31
+ it('should only allow numbers', () => {
32
+ assert.deepEqual(format('304213abcd', '999-999-9999'), {
33
+ raw: '304213abcd',
34
+ formatted: '304-213-',
35
35
  });
36
36
  });
37
37
 
38
- it("should only allow a mix of letters and numbers", () => {
39
- assert.deepEqual(format("C94749", "A-99999"), {
40
- raw: "C94749",
41
- formatted: "C-94749",
38
+ it('should only allow a mix of letters and numbers', () => {
39
+ assert.deepEqual(format('C94749', 'A-99999'), {
40
+ raw: 'C94749',
41
+ formatted: 'C-94749',
42
42
  });
43
43
  });
44
44
  });
45
45
 
46
- describe("usa-input-mask", () => {
47
- it("should format default value", async () => {
46
+ describe('usa-input-mask', () => {
47
+ it('should format default value', async () => {
48
48
  const el = await fixture<USAInputMaskElement>(html`
49
49
  <usa-input-mask mask="(999) 999-9999">
50
50
  <input name="phone" value="1234567890" mask />
51
51
  </usa-input-mask>
52
52
  `);
53
53
 
54
- const input = el.querySelector("input");
54
+ const input = el.querySelector('input');
55
55
 
56
- assert.equal(input?.value, "(123) 456-7890");
56
+ assert.equal(input?.value, '(123) 456-7890');
57
57
  });
58
58
 
59
- it("should update value when on input event", async () => {
59
+ it('should update value when on input event', async () => {
60
60
  const el = await fixture<USAInputMaskElement>(html`
61
61
  <usa-input-mask>
62
62
  <input name="phone" mask="(999) 999-9999" />
63
63
  </usa-input-mask>
64
64
  `);
65
65
 
66
- const input = el.querySelector("input");
66
+ const input = el.querySelector('input');
67
67
 
68
68
  if (input) {
69
- input.value = "8888888888";
70
- input.dispatchEvent(new Event("input", { bubbles: true }));
69
+ input.value = '8888888888';
70
+ input.dispatchEvent(new Event('input', { bubbles: true }));
71
71
  }
72
-
73
- assert.equal(input?.value, "(888) 888-8888");
72
+ assert.equal(input?.value, '(888) 888-8888');
74
73
  });
75
74
  });
76
75
 
77
- describe("usa-input-mask with usa-input", () => {
78
- it("should format default value", async () => {
76
+ describe('usa-input-mask with usa-input', () => {
77
+ it('should format default value', async () => {
79
78
  const el = await fixture<USAInputMaskElement>(html`
80
79
  <usa-input-mask mask="(999) 999-9999">
81
80
  <usa-input name="phone" value="1234567890" id="TEST" mask></usa-input>
82
81
  </usa-input-mask>
83
82
  `);
84
83
 
85
- const input = el.querySelector("usa-input");
84
+ const input = el.querySelector('usa-input');
86
85
 
87
- assert.equal(input?.value, "(123) 456-7890");
86
+ assert.equal(input?.value, '(123) 456-7890');
88
87
  });
89
88
 
90
- it("should update value when on input event", async () => {
89
+ it('should update value when on input event', async () => {
91
90
  const el = await fixture<USAInputMaskElement>(html`
92
91
  <usa-input-mask>
93
- <usa-input
94
- name="phone"
95
- value="1234567890"
96
- mask="(999) 999-9999"
97
- ></usa-input>
92
+ <usa-input name="phone" value="1234567890" mask="(999) 999-9999"></usa-input>
98
93
  </usa-input-mask>
99
94
  `);
100
95
 
101
- const input = el.querySelector("usa-input");
96
+ const input = el.querySelector('usa-input');
102
97
 
103
98
  if (input) {
104
- input.value = "8888888888";
105
- input.dispatchEvent(new Event("input", { bubbles: true }));
99
+ input.value = '8888888888';
100
+ input.dispatchEvent(new Event('input', { bubbles: true }));
106
101
  }
107
102
 
108
- assert.equal(input?.value, "(888) 888-8888");
103
+ assert.equal(input?.value, '(888) 888-8888');
109
104
  });
110
105
  });
@@ -1,11 +1,11 @@
1
- import { Injector } from "@joist/di";
2
- import { assert } from "@open-wc/testing";
1
+ import { Injector } from '@joist/di';
2
+ import { assert } from '@open-wc/testing';
3
3
 
4
- import { HttpService } from "./http.service.js";
5
- import { IconService } from "./icon.service.js";
4
+ import { HttpService } from './http.service.js';
5
+ import { IconService } from './icon.service.js';
6
6
 
7
- describe("IconService", () => {
8
- it("should fetch icon if not in cache", async () => {
7
+ describe('IconService', () => {
8
+ it('should fetch icon if not in cache', async () => {
9
9
  let callCount = 0;
10
10
 
11
11
  const app = new Injector({
@@ -16,7 +16,7 @@ describe("IconService", () => {
16
16
  use: class extends HttpService {
17
17
  async fetch(): Promise<Response> {
18
18
  callCount++;
19
- return new Response("<svg></svg>");
19
+ return new Response('<svg></svg>');
20
20
  }
21
21
  },
22
22
  },
@@ -26,13 +26,13 @@ describe("IconService", () => {
26
26
 
27
27
  const icon = app.inject(IconService);
28
28
 
29
- const res = await icon.getIcon("test");
29
+ const res = await icon.getIcon('test' as any);
30
30
 
31
- assert.equal(res.nodeName, "svg");
31
+ assert.equal(res.nodeName, 'svg');
32
32
  assert.equal(callCount, 1);
33
33
  });
34
34
 
35
- it("should not fetch new icon if the icon is found in the cache", async () => {
35
+ it('should not fetch new icon if the icon is found in the cache', async () => {
36
36
  let callCount = 0;
37
37
 
38
38
  const app = new Injector({
@@ -43,7 +43,7 @@ describe("IconService", () => {
43
43
  use: class extends HttpService {
44
44
  async fetch(): Promise<Response> {
45
45
  callCount++;
46
- return new Response("<svg></svg>");
46
+ return new Response('<svg></svg>');
47
47
  }
48
48
  },
49
49
  },
@@ -53,11 +53,11 @@ describe("IconService", () => {
53
53
 
54
54
  const icon = app.inject(IconService);
55
55
 
56
- await icon.getIcon("test");
56
+ await icon.getIcon('accessibility_new');
57
57
 
58
- const res = await icon.getIcon("test");
58
+ const res = await icon.getIcon('accessibility_new');
59
59
 
60
- assert.equal(res.nodeName, "svg");
60
+ assert.equal(res.nodeName, 'svg');
61
61
  assert.equal(callCount, 1);
62
62
  });
63
63
  });
@@ -1,52 +1,53 @@
1
- import { inject, injectable } from "@joist/di";
1
+ import { inject, injectable } from '@joist/di';
2
2
 
3
- import { USAConfig } from "../config/config.element.js";
4
- import { HttpService } from "./http.service.js";
3
+ import { USAConfig } from '../config/config.element.js';
4
+ import { HttpService } from './http.service.js';
5
+ import { USAIcon } from '../icon/icon-types.js';
5
6
 
6
7
  @injectable()
7
8
  export class IconService {
8
9
  #config = inject(USAConfig);
9
10
  #http = inject(HttpService);
10
- #iconCache: Map<string, Promise<HTMLTemplateElement>> = new Map();
11
+ #iconCache: Map<USAIcon, HTMLTemplateElement> = new Map();
11
12
 
12
- async getIcon(icon: string): Promise<Node> {
13
+ async getIcon(icon: USAIcon, abortSignal?: AbortSignal): Promise<Node> {
13
14
  const config = this.#config();
14
15
  const http = this.#http();
15
16
 
16
17
  const cached = this.#iconCache.get(icon);
17
18
 
18
19
  if (cached) {
19
- return cached.then((res) => {
20
- if (!res.content.firstElementChild) {
21
- throw Error("cached value is not valid");
22
- }
20
+ if (!cached.content.firstElementChild) {
21
+ throw Error('cached value is not valid');
22
+ }
23
23
 
24
- return res.content.firstElementChild.cloneNode(true);
25
- });
24
+ return cached.content.firstElementChild.cloneNode(true);
26
25
  }
27
26
 
28
27
  const svg = http
29
- .fetch(`${config.iconPath}${icon}.svg`)
28
+ .fetch(`${config.iconPath}${icon}.svg`, {
29
+ signal: abortSignal,
30
+ })
30
31
  .then((res) => {
31
32
  switch (res.status) {
32
33
  case 200:
33
34
  return res.text();
34
35
  }
35
36
 
36
- return "";
37
+ return '';
37
38
  })
38
39
  .then((res) => {
39
- const template = document.createElement("template");
40
+ const template = document.createElement('template');
40
41
  template.innerHTML = res;
41
42
 
43
+ this.#iconCache.set(icon, template);
44
+
42
45
  return template;
43
46
  });
44
47
 
45
- this.#iconCache.set(icon, svg);
46
-
47
48
  return svg.then((res) => {
48
49
  if (!res.content.firstElementChild) {
49
- throw Error("ICON is not valid");
50
+ throw Error('ICON is not valid');
50
51
  }
51
52
 
52
53
  return res.content.firstElementChild.cloneNode(true);
@@ -1,14 +1,14 @@
1
- import { attr, css, element, html, listen, query, ready } from "@joist/element";
2
- import { effect, observe } from "@joist/observable";
1
+ import { attr, css, element, html, listen, query, ready } from '@joist/element';
2
+ import { effect, observe } from '@joist/observable';
3
3
 
4
4
  declare global {
5
5
  interface HTMLElementTagNameMap {
6
- "usa-textarea": USATextareaElement;
6
+ 'usa-textarea': USATextareaElement;
7
7
  }
8
8
  }
9
9
 
10
10
  @element({
11
- tagName: "usa-textarea",
11
+ tagName: 'usa-textarea',
12
12
  shadowDom: [
13
13
  css`
14
14
  * {
@@ -34,7 +34,7 @@ declare global {
34
34
  border-radius: 0;
35
35
  color: #1b1b1b;
36
36
  display: block;
37
- padding: .5rem;
37
+ padding: 0.5rem;
38
38
  border-width: 1px;
39
39
  border-color: #5c5c5c;
40
40
  border-style: solid;
@@ -62,7 +62,7 @@ declare global {
62
62
  <label for="textarea" part="label">
63
63
  <slot></slot>
64
64
  </label>
65
-
65
+
66
66
  <textarea id="textarea" part="textarea"></textarea>
67
67
  `,
68
68
  ],
@@ -71,13 +71,13 @@ export class USATextareaElement extends HTMLElement {
71
71
  static formAssociated = true;
72
72
 
73
73
  @attr()
74
- accessor name = "";
74
+ accessor name = '';
75
75
 
76
76
  @attr()
77
- accessor autocomplete: AutoFill = "on";
77
+ accessor autocomplete: AutoFill = 'on';
78
78
 
79
79
  @attr()
80
- accessor placeholder = "";
80
+ accessor placeholder = '';
81
81
 
82
82
  @attr()
83
83
  accessor required = false;
@@ -86,10 +86,10 @@ export class USATextareaElement extends HTMLElement {
86
86
  reflect: false,
87
87
  })
88
88
  @observe()
89
- accessor value = "";
89
+ accessor value = '';
90
90
 
91
91
  #internals = this.attachInternals();
92
- #input = query("textarea");
92
+ #input = query('textarea');
93
93
 
94
94
  @ready()
95
95
  onReady() {
@@ -116,7 +116,7 @@ export class USATextareaElement extends HTMLElement {
116
116
  this.#syncFormState();
117
117
  }
118
118
 
119
- @listen("input")
119
+ @listen('input')
120
120
  onInputChange() {
121
121
  this.value = this.#input().value;
122
122
  }
@@ -124,15 +124,11 @@ export class USATextareaElement extends HTMLElement {
124
124
  #syncFormState() {
125
125
  const input = this.#input();
126
126
 
127
- this.#internals.setFormValue(input.value);
127
+ this.#internals.setFormValue(this.value);
128
128
  this.#internals.setValidity({});
129
129
 
130
130
  if (input.validationMessage) {
131
- this.#internals.setValidity(
132
- { customError: true },
133
- input.validationMessage,
134
- input,
135
- );
131
+ this.#internals.setValidity({ customError: true }, input.validationMessage, input);
136
132
  }
137
133
  }
138
134
  }
@@ -1,13 +1,14 @@
1
- import "@joist/templating/define.js";
2
- import { USAAccordionToggleEvent } from "./events.js";
1
+ import '@joist/templating/define.js';
2
+ import { USAAccordionToggleEvent } from './events.js';
3
3
  declare global {
4
4
  interface HTMLElementTagNameMap {
5
- "usa-accordion": USAAccordionElement;
5
+ 'usa-accordion': USAAccordionElement;
6
6
  }
7
7
  }
8
8
  export declare class USAAccordionElement extends HTMLElement {
9
9
  accessor name: string;
10
10
  accessor open: boolean;
11
+ accessor icon: 'add' | 'remove';
11
12
  onClick(e: Event): void;
12
13
  onAccordionToggle(e: USAAccordionToggleEvent): void;
13
14
  }