@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.
- package/package.json +6 -6
- package/src/lib/accordion/accordion.element.ts +18 -26
- package/src/lib/alert/alert.element.ts +21 -20
- package/src/lib/alert/alert.stories.ts +10 -15
- package/src/lib/file-input/file-input.element.ts +36 -31
- package/src/lib/icon/icon.element.ts +37 -27
- package/src/lib/input/input.element.ts +30 -39
- package/src/lib/input/input.test.ts +14 -16
- package/src/lib/input-mask/input-mask.element.ts +13 -13
- package/src/lib/input-mask/input-mask.stories.ts +7 -12
- package/src/lib/input-mask/input-mask.test.ts +45 -50
- package/src/lib/services/icon.service.test.ts +14 -14
- package/src/lib/services/icon.service.ts +18 -17
- package/src/lib/textarea/textarea.element.ts +14 -18
- package/target/lib/accordion/accordion.element.d.ts +4 -3
- package/target/lib/accordion/accordion.element.js +20 -12
- package/target/lib/accordion/accordion.element.js.map +1 -1
- package/target/lib/alert/alert.element.d.ts +4 -4
- package/target/lib/alert/alert.element.js +20 -12
- package/target/lib/alert/alert.element.js.map +1 -1
- package/target/lib/alert/alert.stories.d.ts +2 -2
- package/target/lib/alert/alert.stories.js +3 -3
- package/target/lib/alert/alert.stories.js.map +1 -1
- package/target/lib/file-input/file-input.element.d.ts +0 -1
- package/target/lib/file-input/file-input.element.js +6 -14
- package/target/lib/file-input/file-input.element.js.map +1 -1
- package/target/lib/icon/icon.element.d.ts +4 -4
- package/target/lib/icon/icon.element.js +35 -25
- package/target/lib/icon/icon.element.js.map +1 -1
- package/target/lib/input/input.element.d.ts +5 -5
- package/target/lib/input/input.element.js +20 -22
- package/target/lib/input/input.element.js.map +1 -1
- package/target/lib/input/input.test.d.ts +1 -1
- package/target/lib/input/input.test.js +13 -13
- package/target/lib/input/input.test.js.map +1 -1
- package/target/lib/input-mask/input-mask.element.d.ts +1 -1
- package/target/lib/input-mask/input-mask.element.js +11 -11
- package/target/lib/input-mask/input-mask.element.js.map +1 -1
- package/target/lib/input-mask/input-mask.stories.d.ts +2 -2
- package/target/lib/input-mask/input-mask.stories.js +5 -5
- package/target/lib/input-mask/input-mask.stories.js.map +1 -1
- package/target/lib/input-mask/input-mask.test.d.ts +2 -2
- package/target/lib/input-mask/input-mask.test.js +43 -43
- package/target/lib/input-mask/input-mask.test.js.map +1 -1
- package/target/lib/services/icon.service.d.ts +2 -1
- package/target/lib/services/icon.service.js +15 -15
- package/target/lib/services/icon.service.js.map +1 -1
- package/target/lib/services/icon.service.test.js +14 -14
- package/target/lib/services/icon.service.test.js.map +1 -1
- package/target/lib/textarea/textarea.element.d.ts +1 -1
- package/target/lib/textarea/textarea.element.js +10 -10
- package/target/lib/textarea/textarea.element.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noctuatech/uswds",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
"packages/**"
|
|
@@ -103,10 +103,10 @@
|
|
|
103
103
|
"license": "ISC",
|
|
104
104
|
"description": "",
|
|
105
105
|
"dependencies": {
|
|
106
|
-
"@joist/di": "^4.2.3
|
|
107
|
-
"@joist/element": "^4.2.3
|
|
108
|
-
"@joist/observable": "^4.2.3
|
|
109
|
-
"@joist/templating": "^4.2.3
|
|
106
|
+
"@joist/di": "^4.2.3",
|
|
107
|
+
"@joist/element": "^4.2.3",
|
|
108
|
+
"@joist/observable": "^4.2.3",
|
|
109
|
+
"@joist/templating": "^4.2.3",
|
|
110
110
|
"tslib": "2.8.1"
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
"@web/test-runner": "^0.20.0",
|
|
125
125
|
"husky": "^9.0.11",
|
|
126
126
|
"js-beautify": "^1.15.1",
|
|
127
|
-
"lint-staged": "^
|
|
127
|
+
"lint-staged": "^16.0.0",
|
|
128
128
|
"lit": "^3.2.1",
|
|
129
129
|
"minify-literals": "^1.0.10",
|
|
130
130
|
"mocha": "^11.0.0",
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import
|
|
1
|
+
import '@joist/templating/define.js';
|
|
2
2
|
|
|
3
|
-
import { attr, css, element, html, listen } from
|
|
4
|
-
import { bind } from
|
|
3
|
+
import { attr, css, element, html, listen } from '@joist/element';
|
|
4
|
+
import { bind } from '@joist/templating';
|
|
5
5
|
|
|
6
|
-
import { USAAccordionToggleEvent } from
|
|
6
|
+
import { USAAccordionToggleEvent } from './events.js';
|
|
7
7
|
|
|
8
8
|
declare global {
|
|
9
9
|
interface HTMLElementTagNameMap {
|
|
10
|
-
|
|
10
|
+
'usa-accordion': USAAccordionElement;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
@element({
|
|
15
|
-
tagName:
|
|
15
|
+
tagName: 'usa-accordion',
|
|
16
16
|
shadowDomOpts: {
|
|
17
|
-
mode:
|
|
17
|
+
mode: 'open',
|
|
18
18
|
delegatesFocus: true,
|
|
19
19
|
},
|
|
20
20
|
shadowDom: [
|
|
@@ -54,12 +54,12 @@ declare global {
|
|
|
54
54
|
display: none;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
slot[name=
|
|
57
|
+
slot[name='heading'] {
|
|
58
58
|
display: block;
|
|
59
59
|
flex: 1 1 auto;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
slot[name=
|
|
62
|
+
slot[name='heading']::slotted(*) {
|
|
63
63
|
margin: 0;
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -69,18 +69,6 @@ declare global {
|
|
|
69
69
|
padding-top: 1.5rem;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
usa-icon[icon="remove"] {
|
|
73
|
-
display: none;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
details[open] usa-icon[icon="add"] {
|
|
77
|
-
display: none;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
details[open] usa-icon[icon="remove"] {
|
|
81
|
-
display: block;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
72
|
summary:hover {
|
|
85
73
|
background-color: #e6e6e6;
|
|
86
74
|
}
|
|
@@ -96,8 +84,9 @@ declare global {
|
|
|
96
84
|
<summary>
|
|
97
85
|
<slot name="heading"></slot>
|
|
98
86
|
|
|
99
|
-
<
|
|
100
|
-
|
|
87
|
+
<j-props>
|
|
88
|
+
<usa-icon $.icon="icon"></usa-icon>
|
|
89
|
+
</j-props>
|
|
101
90
|
</summary>
|
|
102
91
|
|
|
103
92
|
<div class="content">
|
|
@@ -110,20 +99,23 @@ declare global {
|
|
|
110
99
|
})
|
|
111
100
|
export class USAAccordionElement extends HTMLElement {
|
|
112
101
|
@attr()
|
|
113
|
-
accessor name =
|
|
102
|
+
accessor name = '';
|
|
114
103
|
|
|
115
104
|
@attr()
|
|
116
105
|
@bind()
|
|
117
106
|
accessor open = false;
|
|
118
107
|
|
|
119
|
-
@
|
|
108
|
+
@bind((i) => (i.open ? 'remove' : 'add'))
|
|
109
|
+
accessor icon: 'add' | 'remove' = 'add';
|
|
110
|
+
|
|
111
|
+
@listen('click', 'summary')
|
|
120
112
|
onClick(e: Event) {
|
|
121
113
|
e.preventDefault();
|
|
122
114
|
|
|
123
115
|
this.dispatchEvent(new USAAccordionToggleEvent(!this.open));
|
|
124
116
|
}
|
|
125
117
|
|
|
126
|
-
@listen(
|
|
118
|
+
@listen('usa::accordion::toggle', () => document.body)
|
|
127
119
|
onAccordionToggle(e: USAAccordionToggleEvent) {
|
|
128
120
|
if (e.target.name === this.name) {
|
|
129
121
|
this.open = e.target === this && e.open;
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { attr, css, element, html, query } from
|
|
1
|
+
import { attr, css, element, html, query } from '@joist/element';
|
|
2
2
|
|
|
3
|
-
import { type USAAlertType, USA_ALERT_CONFIG } from
|
|
3
|
+
import { type USAAlertType, USA_ALERT_CONFIG } from './alert-types.js';
|
|
4
|
+
import { bind } from '@joist/templating';
|
|
5
|
+
import { USAIcon } from '../icon/icon-types.js';
|
|
6
|
+
import { observe } from '@joist/observable';
|
|
4
7
|
|
|
5
8
|
declare global {
|
|
6
9
|
interface HTMLElementTagNameMap {
|
|
7
|
-
|
|
10
|
+
'usa-alert': USAAlertElement;
|
|
8
11
|
}
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
@element({
|
|
12
|
-
tagName:
|
|
15
|
+
tagName: 'usa-alert',
|
|
13
16
|
shadowDomOpts: {
|
|
14
|
-
mode:
|
|
17
|
+
mode: 'open',
|
|
15
18
|
delegatesFocus: true,
|
|
16
19
|
},
|
|
17
20
|
shadowDom: [
|
|
@@ -24,33 +27,33 @@ declare global {
|
|
|
24
27
|
margin-bottom: 1rem;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
:host([type=
|
|
30
|
+
:host([type='info']) {
|
|
28
31
|
border-left-color: #00bde3;
|
|
29
32
|
background-color: #e7f6f8;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
:host([type=
|
|
35
|
+
:host([type='warning']) {
|
|
33
36
|
background-color: #faf3d1;
|
|
34
37
|
border-left-color: #ffbe2e;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
:host([type=
|
|
40
|
+
:host([type='success']) {
|
|
38
41
|
background-color: #ecf3ec;
|
|
39
42
|
border-left-color: #00a91c;
|
|
40
43
|
}
|
|
41
44
|
|
|
42
|
-
:host([type=
|
|
45
|
+
:host([type='error']) {
|
|
43
46
|
background-color: #f4e3db;
|
|
44
47
|
border-left-color: #d54309;
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
:host([type=
|
|
50
|
+
:host([type='emergency']) {
|
|
48
51
|
background-color: #9c3d10;
|
|
49
52
|
border-left-color: #9c3d10;
|
|
50
53
|
color: #fff;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
:host([type=
|
|
56
|
+
:host([type='emergency']) ::slotted(*) {
|
|
54
57
|
color: #fff;
|
|
55
58
|
}
|
|
56
59
|
|
|
@@ -73,7 +76,9 @@ declare global {
|
|
|
73
76
|
`,
|
|
74
77
|
html`
|
|
75
78
|
<div class="alert-heading">
|
|
76
|
-
<
|
|
79
|
+
<j-props>
|
|
80
|
+
<usa-icon $.icon="icon"></usa-icon>
|
|
81
|
+
</j-props>
|
|
77
82
|
|
|
78
83
|
<div>
|
|
79
84
|
<slot id="heading" name="heading"></slot>
|
|
@@ -90,13 +95,9 @@ declare global {
|
|
|
90
95
|
})
|
|
91
96
|
export class USAAlertElement extends HTMLElement {
|
|
92
97
|
@attr()
|
|
93
|
-
|
|
98
|
+
@observe()
|
|
99
|
+
accessor type: USAAlertType = 'info';
|
|
94
100
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
attributeChangedCallback() {
|
|
98
|
-
this.#icon({
|
|
99
|
-
icon: USA_ALERT_CONFIG[this.type].icon,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
101
|
+
@bind((i) => USA_ALERT_CONFIG[i.type].icon)
|
|
102
|
+
accessor icon: USAIcon = 'info';
|
|
102
103
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from
|
|
2
|
-
import { html } from
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/web-components';
|
|
2
|
+
import { html } from 'lit';
|
|
3
3
|
|
|
4
|
-
import type { USAAlertElement } from
|
|
4
|
+
import type { USAAlertElement } from './alert.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:
|
|
9
|
-
tags: [
|
|
8
|
+
title: 'usa-alert',
|
|
9
|
+
tags: ['autodocs'],
|
|
10
10
|
argTypes: {},
|
|
11
11
|
args: {},
|
|
12
12
|
} satisfies Meta<USAAlertElement>;
|
|
@@ -22,8 +22,7 @@ export const Info: Story = {
|
|
|
22
22
|
<h3 slot="heading">Informative status</h3>
|
|
23
23
|
|
|
24
24
|
Lorem ipsum dolor sit amet,
|
|
25
|
-
<usa-link href="#">consectetur adipiscing</usa-link> elit, sed do
|
|
26
|
-
eiusmod.
|
|
25
|
+
<usa-link href="#">consectetur adipiscing</usa-link> elit, sed do eiusmod.
|
|
27
26
|
</usa-alert>
|
|
28
27
|
`;
|
|
29
28
|
},
|
|
@@ -36,8 +35,7 @@ export const Warning: Story = {
|
|
|
36
35
|
<h3 slot="heading">Warning status</h3>
|
|
37
36
|
|
|
38
37
|
Lorem ipsum dolor sit amet,
|
|
39
|
-
<usa-link href="#">consectetur adipiscing</usa-link> elit, sed do
|
|
40
|
-
eiusmod.
|
|
38
|
+
<usa-link href="#">consectetur adipiscing</usa-link> elit, sed do eiusmod.
|
|
41
39
|
</usa-alert>
|
|
42
40
|
`;
|
|
43
41
|
},
|
|
@@ -50,8 +48,7 @@ export const Success: Story = {
|
|
|
50
48
|
<h3 slot="heading">Success status</h3>
|
|
51
49
|
|
|
52
50
|
Lorem ipsum dolor sit amet,
|
|
53
|
-
<usa-link href="#">consectetur adipiscing</usa-link> elit, sed do
|
|
54
|
-
eiusmod.
|
|
51
|
+
<usa-link href="#">consectetur adipiscing</usa-link> elit, sed do eiusmod.
|
|
55
52
|
</usa-alert>
|
|
56
53
|
`;
|
|
57
54
|
},
|
|
@@ -65,8 +62,7 @@ export const Error: Story = {
|
|
|
65
62
|
<h3 slot="heading">Error status</h3>
|
|
66
63
|
|
|
67
64
|
Lorem ipsum dolor sit amet,
|
|
68
|
-
<usa-link href="#">consectetur adipiscing</usa-link> elit, sed do
|
|
69
|
-
eiusmod.
|
|
65
|
+
<usa-link href="#">consectetur adipiscing</usa-link> elit, sed do eiusmod.
|
|
70
66
|
</usa-alert>
|
|
71
67
|
`;
|
|
72
68
|
},
|
|
@@ -79,8 +75,7 @@ export const Emergency: Story = {
|
|
|
79
75
|
<h3 slot="heading">Emergency status</h3>
|
|
80
76
|
|
|
81
77
|
Lorem ipsum dolor sit amet,
|
|
82
|
-
<usa-link href="#">consectetur adipiscing</usa-link> elit, sed do
|
|
83
|
-
eiusmod.
|
|
78
|
+
<usa-link href="#">consectetur adipiscing</usa-link> elit, sed do eiusmod.
|
|
84
79
|
</usa-alert>
|
|
85
80
|
`;
|
|
86
81
|
},
|
|
@@ -77,29 +77,39 @@ declare global {
|
|
|
77
77
|
}
|
|
78
78
|
`,
|
|
79
79
|
html`
|
|
80
|
-
<label>
|
|
80
|
+
<label for="file-input">
|
|
81
81
|
<slot class="label"></slot>
|
|
82
|
-
|
|
83
|
-
<div class="container">
|
|
84
|
-
<input type="file" tabindex="0" />
|
|
85
|
-
|
|
86
|
-
<j-if bind="filesVisible">
|
|
87
|
-
<template>
|
|
88
|
-
<j-props>
|
|
89
|
-
<usa-file-input-preview $.files="files" part="preview" exportparts="heading, item">
|
|
90
|
-
Selected file <usa-link>Change file</usa-link>
|
|
91
|
-
</usa-file-input-preview>
|
|
92
|
-
</j-props>
|
|
93
|
-
</template>
|
|
94
|
-
|
|
95
|
-
<template else>
|
|
96
|
-
<div class="box" part="input">
|
|
97
|
-
<slot name="description"> Drag file here or <usa-link>choose from folder</usa-link> </slot>
|
|
98
|
-
</div>
|
|
99
|
-
</template>
|
|
100
|
-
</j-if>
|
|
101
|
-
</div>
|
|
102
82
|
</label>
|
|
83
|
+
|
|
84
|
+
<div class="container">
|
|
85
|
+
<j-props>
|
|
86
|
+
<input
|
|
87
|
+
id="file-input"
|
|
88
|
+
type="file"
|
|
89
|
+
tabindex="0"
|
|
90
|
+
$.name="name"
|
|
91
|
+
$.multiple="multiple"
|
|
92
|
+
$.accept="accept"
|
|
93
|
+
$.required="required"
|
|
94
|
+
/>
|
|
95
|
+
</j-props>
|
|
96
|
+
|
|
97
|
+
<j-if bind="filesVisible">
|
|
98
|
+
<template>
|
|
99
|
+
<j-props>
|
|
100
|
+
<usa-file-input-preview $.files="files" part="preview" exportparts="heading, item">
|
|
101
|
+
Selected file <usa-link>Change file</usa-link>
|
|
102
|
+
</usa-file-input-preview>
|
|
103
|
+
</j-props>
|
|
104
|
+
</template>
|
|
105
|
+
|
|
106
|
+
<template else>
|
|
107
|
+
<div class="box" part="input">
|
|
108
|
+
<slot name="description"> Drag file here or <usa-link>choose from folder</usa-link> </slot>
|
|
109
|
+
</div>
|
|
110
|
+
</template>
|
|
111
|
+
</j-if>
|
|
112
|
+
</div>
|
|
103
113
|
`,
|
|
104
114
|
],
|
|
105
115
|
})
|
|
@@ -107,15 +117,19 @@ export class USAFileInputElement extends HTMLElement {
|
|
|
107
117
|
static formAssociated = true;
|
|
108
118
|
|
|
109
119
|
@attr()
|
|
120
|
+
@bind()
|
|
110
121
|
accessor name = '';
|
|
111
122
|
|
|
112
123
|
@attr()
|
|
124
|
+
@bind()
|
|
113
125
|
accessor multiple = true;
|
|
114
126
|
|
|
115
127
|
@attr()
|
|
128
|
+
@bind()
|
|
116
129
|
accessor accept = '';
|
|
117
130
|
|
|
118
131
|
@attr()
|
|
132
|
+
@bind()
|
|
119
133
|
accessor required = false;
|
|
120
134
|
|
|
121
135
|
@bind()
|
|
@@ -127,15 +141,6 @@ export class USAFileInputElement extends HTMLElement {
|
|
|
127
141
|
#internals = this.attachInternals();
|
|
128
142
|
#input = query('input');
|
|
129
143
|
|
|
130
|
-
attributeChangedCallback() {
|
|
131
|
-
this.#input({
|
|
132
|
-
name: this.name,
|
|
133
|
-
multiple: this.multiple,
|
|
134
|
-
accept: this.accept,
|
|
135
|
-
required: this.required,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
144
|
connectedCallback() {
|
|
140
145
|
const input = this.#input();
|
|
141
146
|
|
|
@@ -146,7 +151,7 @@ export class USAFileInputElement extends HTMLElement {
|
|
|
146
151
|
|
|
147
152
|
@effect()
|
|
148
153
|
syncFormValues() {
|
|
149
|
-
const input = this.#input(
|
|
154
|
+
const input = this.#input();
|
|
150
155
|
|
|
151
156
|
const formData = new FormData();
|
|
152
157
|
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { inject, injectable } from
|
|
2
|
-
import { attr, css, element } from
|
|
1
|
+
import { inject, injectable, injected } from '@joist/di';
|
|
2
|
+
import { attr, css, element } from '@joist/element';
|
|
3
3
|
|
|
4
|
-
import { IconService } from
|
|
5
|
-
import type { USAIcon } from
|
|
4
|
+
import { IconService } from '../services/icon.service.js';
|
|
5
|
+
import type { USAIcon } from './icon-types.js';
|
|
6
|
+
import { effect, observe } from '@joist/observable';
|
|
6
7
|
|
|
7
8
|
declare global {
|
|
8
9
|
interface HTMLElementTagNameMap {
|
|
9
|
-
|
|
10
|
+
'usa-icon': USAIconElement;
|
|
10
11
|
}
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
@element({
|
|
14
|
-
tagName:
|
|
15
|
+
tagName: 'usa-icon',
|
|
15
16
|
shadowDom: [
|
|
16
17
|
css`
|
|
17
18
|
:host {
|
|
@@ -30,41 +31,50 @@ declare global {
|
|
|
30
31
|
],
|
|
31
32
|
})
|
|
32
33
|
@injectable({
|
|
33
|
-
name:
|
|
34
|
+
name: 'usa-icon-ctx',
|
|
34
35
|
})
|
|
35
36
|
export class USAIconElement extends HTMLElement {
|
|
36
37
|
@attr()
|
|
37
|
-
|
|
38
|
+
@observe()
|
|
39
|
+
accessor icon: USAIcon | '' = '';
|
|
38
40
|
|
|
39
|
-
ariaHidden: string | null =
|
|
41
|
+
ariaHidden: string | null = 'true';
|
|
40
42
|
|
|
41
43
|
#icon = inject(IconService);
|
|
42
|
-
#
|
|
44
|
+
#abortController: AbortController | null = null;
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (newVal !== oldVal) {
|
|
47
|
-
this.#updateIcon();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
46
|
+
connectedCallback() {
|
|
47
|
+
this.#updateIcon();
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
@effect()
|
|
51
|
+
onIconUpdate() {
|
|
52
|
+
console.log('onIconUpdate', this.icon);
|
|
53
|
+
|
|
54
54
|
this.#updateIcon();
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
async #updateIcon() {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (this.shadowRoot) {
|
|
61
|
-
const currentIcon = await icon.getIcon(this.icon);
|
|
58
|
+
this.#abortController?.abort();
|
|
59
|
+
this.#abortController = new AbortController();
|
|
62
60
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
} else {
|
|
66
|
-
this.shadowRoot.append(currentIcon);
|
|
67
|
-
}
|
|
61
|
+
if (!this.icon) {
|
|
62
|
+
return;
|
|
68
63
|
}
|
|
64
|
+
|
|
65
|
+
const icon = this.#icon();
|
|
66
|
+
|
|
67
|
+
icon
|
|
68
|
+
.getIcon(this.icon, this.#abortController?.signal)
|
|
69
|
+
.then((currentIcon) => {
|
|
70
|
+
if (this.shadowRoot) {
|
|
71
|
+
if (this.shadowRoot.firstElementChild) {
|
|
72
|
+
this.shadowRoot.firstElementChild.replaceWith(currentIcon);
|
|
73
|
+
} else {
|
|
74
|
+
this.shadowRoot.append(currentIcon);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
.catch(() => {});
|
|
69
79
|
}
|
|
70
80
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { attr, css, element, html, listen, query, ready } from
|
|
2
|
-
import { effect, observe } from
|
|
1
|
+
import { attr, css, element, html, listen, query, ready } from '@joist/element';
|
|
2
|
+
import { effect, observe } from '@joist/observable';
|
|
3
3
|
|
|
4
|
-
import type { MaskableElement } from
|
|
4
|
+
import type { MaskableElement } from '../input-mask/maskable.element.js';
|
|
5
5
|
|
|
6
6
|
declare global {
|
|
7
7
|
interface HTMLElementTagNameMap {
|
|
8
|
-
|
|
8
|
+
'usa-input': USATextInputElement;
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
@element({
|
|
13
|
-
tagName:
|
|
13
|
+
tagName: 'usa-input',
|
|
14
14
|
shadowDom: [
|
|
15
15
|
css`
|
|
16
16
|
* {
|
|
@@ -54,31 +54,31 @@ declare global {
|
|
|
54
54
|
color: #757575;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
slot[name=
|
|
57
|
+
slot[name='detail']::slotted(*) {
|
|
58
58
|
color: #757575;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
slot[name=
|
|
61
|
+
slot[name='detail']::slotted(usa-icon) {
|
|
62
62
|
width: 1.5rem;
|
|
63
63
|
height: 1.5rem;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
slot[name=
|
|
66
|
+
slot[name='detail'] {
|
|
67
67
|
display: block;
|
|
68
68
|
position: absolute;
|
|
69
69
|
bottom: 0.21rem;
|
|
70
70
|
left: 0.5rem;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
:host([detail=
|
|
73
|
+
:host([detail='pfx']) input {
|
|
74
74
|
padding-left: 2.5rem;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
:host([detail=
|
|
77
|
+
:host([detail='sfx']) input {
|
|
78
78
|
padding-right: 2.5rem;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
:host([detail=
|
|
81
|
+
:host([detail='sfx']) slot[name='detail'] {
|
|
82
82
|
right: 0.5rem;
|
|
83
83
|
left: auto;
|
|
84
84
|
}
|
|
@@ -94,26 +94,23 @@ declare global {
|
|
|
94
94
|
`,
|
|
95
95
|
],
|
|
96
96
|
})
|
|
97
|
-
export class USATextInputElement
|
|
98
|
-
extends HTMLElement
|
|
99
|
-
implements MaskableElement
|
|
100
|
-
{
|
|
97
|
+
export class USATextInputElement extends HTMLElement implements MaskableElement {
|
|
101
98
|
static formAssociated = true;
|
|
102
99
|
|
|
103
100
|
@attr()
|
|
104
|
-
accessor name =
|
|
101
|
+
accessor name = '';
|
|
105
102
|
|
|
106
103
|
@attr()
|
|
107
|
-
accessor autocomplete: AutoFill =
|
|
104
|
+
accessor autocomplete: AutoFill = 'on';
|
|
108
105
|
|
|
109
106
|
@attr()
|
|
110
|
-
accessor placeholder =
|
|
107
|
+
accessor placeholder = '';
|
|
111
108
|
|
|
112
109
|
@attr()
|
|
113
|
-
accessor min =
|
|
110
|
+
accessor min = '';
|
|
114
111
|
|
|
115
112
|
@attr()
|
|
116
|
-
accessor max =
|
|
113
|
+
accessor max = '';
|
|
117
114
|
|
|
118
115
|
@attr()
|
|
119
116
|
accessor minLength = -1;
|
|
@@ -128,18 +125,16 @@ export class USATextInputElement
|
|
|
128
125
|
accessor disabled = false;
|
|
129
126
|
|
|
130
127
|
@attr()
|
|
131
|
-
accessor type:
|
|
128
|
+
accessor type: 'text' | 'password' | 'number' = 'text';
|
|
132
129
|
|
|
133
|
-
@attr(
|
|
134
|
-
|
|
135
|
-
})
|
|
136
|
-
accessor detail: "pfx" | "sfx" | "" = "";
|
|
130
|
+
@attr()
|
|
131
|
+
accessor detail: 'pfx' | 'sfx' | '' = '';
|
|
137
132
|
|
|
138
133
|
@attr({
|
|
139
134
|
reflect: false,
|
|
140
135
|
})
|
|
141
136
|
@observe()
|
|
142
|
-
accessor value =
|
|
137
|
+
accessor value = '';
|
|
143
138
|
|
|
144
139
|
@observe()
|
|
145
140
|
accessor selectionStart: number | null = null;
|
|
@@ -152,14 +147,14 @@ export class USATextInputElement
|
|
|
152
147
|
}
|
|
153
148
|
|
|
154
149
|
#internals = this.attachInternals();
|
|
155
|
-
#input = query(
|
|
150
|
+
#input = query('input');
|
|
156
151
|
|
|
157
152
|
@ready()
|
|
158
153
|
onReady() {
|
|
159
154
|
this.#input({ autofocus: this.autofocus });
|
|
160
155
|
}
|
|
161
156
|
|
|
162
|
-
attributeChangedCallback(
|
|
157
|
+
attributeChangedCallback() {
|
|
163
158
|
this.#input({
|
|
164
159
|
autocomplete: this.autocomplete,
|
|
165
160
|
placeholder: this.placeholder,
|
|
@@ -191,14 +186,14 @@ export class USATextInputElement
|
|
|
191
186
|
this.#syncFormState();
|
|
192
187
|
}
|
|
193
188
|
|
|
194
|
-
@listen(
|
|
189
|
+
@listen('keydown')
|
|
195
190
|
onKeyDown(e: KeyboardEvent) {
|
|
196
191
|
const form = this.#internals.form;
|
|
197
192
|
|
|
198
193
|
if (form) {
|
|
199
194
|
const hasModifier = e.metaKey || e.ctrlKey || e.shiftKey || e.altKey;
|
|
200
195
|
|
|
201
|
-
if (e.key.toUpperCase() ===
|
|
196
|
+
if (e.key.toUpperCase() === 'ENTER' && !hasModifier) {
|
|
202
197
|
// this makes sure that the user has a chance to cancel the event before submitting
|
|
203
198
|
setTimeout(() => {
|
|
204
199
|
if (!e.defaultPrevented && !e.isComposing) {
|
|
@@ -209,7 +204,7 @@ export class USATextInputElement
|
|
|
209
204
|
}
|
|
210
205
|
}
|
|
211
206
|
|
|
212
|
-
@listen(
|
|
207
|
+
@listen('input')
|
|
213
208
|
onInputChange() {
|
|
214
209
|
const input = this.#input();
|
|
215
210
|
|
|
@@ -222,20 +217,16 @@ export class USATextInputElement
|
|
|
222
217
|
const input = this.#input();
|
|
223
218
|
|
|
224
219
|
this.#internals.setValidity({});
|
|
225
|
-
this.#internals.setFormValue(
|
|
220
|
+
this.#internals.setFormValue(this.value);
|
|
226
221
|
|
|
227
222
|
if (input.validationMessage) {
|
|
228
|
-
this.#internals.setValidity(
|
|
229
|
-
{ customError: true },
|
|
230
|
-
input.validationMessage,
|
|
231
|
-
input,
|
|
232
|
-
);
|
|
223
|
+
this.#internals.setValidity({ customError: true }, input.validationMessage, input);
|
|
233
224
|
}
|
|
234
225
|
}
|
|
235
226
|
|
|
236
227
|
#submit(form: HTMLFormElement) {
|
|
237
|
-
const btn = document.createElement(
|
|
238
|
-
btn.type =
|
|
228
|
+
const btn = document.createElement('button');
|
|
229
|
+
btn.type = 'submit';
|
|
239
230
|
form.append(btn);
|
|
240
231
|
|
|
241
232
|
btn.click();
|